INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Arduino kann nicht rechnen?!
12.12.2015, 13:47
Beitrag #1
Arduino kann nicht rechnen?!
Hallo allerseits,

ich programmiere gerade einen Arduino, welcher am Ende einen "Kamera Drehteller" eines Kumpels mit einem Servo exakt in einer Bestimmten Zeit drehen soll. Das funktioniert eigentlich alles perfekt, nur dass er am Ende wo es ans drehen geht auf einmal bei einer Rechnung von Positiv/Positiv als Ergebnis was Negatives bekommt, und daher der ganze Code nicht mehr das macht was er soll.

Anbei ist der Code, die betroffenen Zeile ist in der Methode AusrichtungNull() die letzte Zeile.
Ich hoffe mir kann dabei einer weiterhelfen...



Code:
//Ganz wichtig zu lcd.setCursor(x,y): x=Spalte(0-15) y=Zeile(0-1)

#include <LiquidCrystal.h>
#include <Servo.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

Servo myservo;

//Pins
int PotPinGrad = A4;
int PotPinZeit = A5;
int ButtonPinZeit = 6;
int ButtonPinGrad = 7;
int ButtonPinStart = 10;

//Zustände
int Zustand = 0;                      //Wenn 0: Stop            Wenn 1: Start
int ZustandGrad = 0;                  //Wenn 0: Uhrzeigersinn   Wenn 1: Gegen Uhrzeigersinn
int ZustandZeit = 0;                  //Wenn 0: kurze Zeit      Wenn 1: lange Zeit

//Zeiten
const int ZeitKurz = 600;                   //Zeitmaximum kurze Zeit
const int ZeitLang = 1600;                  //Zeitmaximum lange Zeit

//Parameter
int Grad = 0;                         //Zu drehender Winkel
int GradO = 0;
int Zeit = 0;                         //Dauer der Drehung

//Ausagbe Stop
String AusgabeZZeit;
String AusgabeZeit;
String AusgabeGrad;
String AusgabeZGrad;
String AusgabeZustand;

String AusgabeZZeitO;
String AusgabeZeitO;
String AusgabeGradO;
String AusgabeZGradO;
String AusgabeZustandO;

//Ausgabe Start
boolean FirstStart = true;

//Sonderzeichen Grad
char SonderzeichenGrad = 0;
byte Gradzeichen[8] = {
  B01100,
  B01100,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000
};

//Berechnung Servo
float Zeitschritte = 0;
float LaufzeitAlt = 0;
int Winkel = 0;

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.createChar(SonderzeichenGrad, Gradzeichen);

  myservo.attach(9);

  pinMode(PotPinGrad, INPUT);
  pinMode(PotPinZeit, INPUT);
  pinMode(ButtonPinZeit, INPUT);
  pinMode(ButtonPinGrad, INPUT);
  pinMode(ButtonPinStart, INPUT);
}

void loop() {

  if (Zustand == 0) {

    BerechnungZustandZeit();
    BerechnungZeit();
    BerechnungGrad();
    BerechnungZustandGrad();
    Ausgabe();
    AusrichtungGrad();
    BerechnungZustand();

  }

  else if (Zustand == 1) {
    Ausgabe();
    BerechnungZustand();
    AusrichtungNull();  
    Drehung();              
  }

}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void BerechnungZustandZeit() {

  if (digitalRead(ButtonPinZeit) == HIGH) {
    if (ZustandZeit == 0) {

      ZustandZeit = 1;

    }
    else if (ZustandZeit == 1) {

      ZustandZeit = 0;

    }


  }

  if (ZustandZeit == 0) {

    AusgabeZZeit = "S";

  }
  else if (ZustandZeit == 1) {

    AusgabeZZeit = "L";
  }
}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void BerechnungZeit() {

  AusgabeZeit = "";
  Zeit = analogRead(PotPinZeit);
  if (ZustandZeit == 0) {
    Zeit = map(Zeit, 0, 1023, 0, ZeitKurz);
  }

  else if (ZustandZeit == 1) {
    Zeit = map(Zeit, 0, 1023, ZeitKurz, ZeitLang);
  }

  AusgabeZeit.concat(Zeit);
  AusgabeZeit += "s";
  AusgabeZeit += "   ";

}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void BerechnungGrad() {

  Grad = analogRead(PotPinGrad);
  Grad = map(Grad, 0, 1023, 1, 170);
  AusgabeGrad = "  " + String(Grad) + SonderzeichenGrad;

}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void BerechnungZustandGrad() {

  if (digitalRead(ButtonPinGrad) == HIGH) {

    if (ZustandGrad == 0) {

      ZustandGrad = 1;

    }
    else if (ZustandGrad == 1) {

      ZustandGrad = 0;

    }

  }

  if (ZustandGrad == 0) {

    AusgabeZGrad = "+";

  }
  else if (ZustandGrad == 1) {

    AusgabeZGrad = "-";

  }

}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void Ausgabe() {

  if (AusgabeZZeit != AusgabeZZeitO) {
    lcd.setCursor(0, 1);
    lcd.print(AusgabeZZeit);
    delay(200);
  }
  if (AusgabeZeit != AusgabeZeitO) {
    lcd.setCursor(0, 0);
    lcd.print(AusgabeZeit);
  }
  if (AusgabeGrad != AusgabeGradO) {

    lcd.setCursor(16 - AusgabeGrad.length(), 0);
    lcd.print(AusgabeGrad);
  }
  if (AusgabeZGrad != AusgabeZGradO) {
    lcd.setCursor(15, 1);
    lcd.print(AusgabeZGrad);
    delay(200);
  }
  if (AusgabeZustand != AusgabeZustandO) {
    lcd.setCursor(5, 1);
    lcd.print(AusgabeZustand);
    delay(200);
  }

  AusgabeZZeitO = AusgabeZZeit;
  AusgabeZeitO = AusgabeZeit;
  AusgabeGradO = AusgabeGrad;
  AusgabeZGradO = AusgabeZGrad;
  AusgabeZustandO = AusgabeZustand;

}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void AusrichtungGrad() {

  if (Grad != GradO) {
    if (ZustandGrad == 0) {
      myservo.write(Grad);
    }
    else if (ZustandGrad == 1) {
      myservo.write(170-Grad);
    }
    
  }
  GradO = Grad;
}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void BerechnungZustand() {

  if (digitalRead(ButtonPinStart) == HIGH) {

    if (Zustand == 0) {

      Zustand = 1;
      FirstStart = true;
      

    }
    else if (Zustand == 1) {

      Zustand = 0;
      FirstStart = true;
    }


  }

  if (Zustand == 1) {
    AusgabeZustand = "Start!";
  }
  else {
    AusgabeZustand = "      ";
  }
}


//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void AusrichtungNull() {

  if (FirstStart == true) {
    if (ZustandGrad == 0) {
      myservo.write(0);
      Winkel = 0;
    }
    else if (ZustandGrad == 1) {
      myservo.write(170);
      Winkel = 170;
    }
    delay(600);
    LaufzeitAlt = millis();
    FirstStart = false;

    Zeitschritte = (Zeit*1000) / Grad;
    

  }

}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void Drehung() {

  if (LaufzeitAlt + Zeitschritte <= millis()) {

    if (ZustandGrad == 0) {
      if (Winkel <= 170) {
        Winkel += 1;
        myservo.write(Winkel);
      }
      if (Winkel >= Grad){
        Zustand = 0;
      }
    }
    else if (ZustandGrad == 1) {
      if (Winkel >= 0) {
        Winkel -= 1;
        myservo.write(Winkel);
      }
      if (Winkel <= (170-Grad)) {
       Zustand = 0;
      }
    }
  LaufzeitAlt = millis();
  }
Serial.println(Zeitschritte);
}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Danke schonmal im Voraus, Max
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.12.2015, 14:42 (Dieser Beitrag wurde zuletzt bearbeitet: 12.12.2015 14:57 von Retian.)
Beitrag #2
RE: Arduino kann nicht rechnen?!
Hallo Maxi290997,
also ohne das ich mir deinen Code genauer angeschaut habe, vermute ich einen Überlauf von einen deiner Integer-Variablen. Integer hat in Arduino einen Wertebereich von 16 Bit, allerdings ist das 16. Bit das Vorzeichen, so dass sich ein Wertebereich von -32.768 bis +32.767 ergibt. Prüfe das bitte, bevor sich jemand durch deinen Code durchackert. Wenn du nur postive Zahlen verwendest bzw. nur positive Rechenergebnisse hast, dann nehme statt int-Variablen besser "unsigned int" (2Byte ohne Vorzeichen) oder Long-Variablen (4 Byte).
Gruß
Retian
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.12.2015, 14:49
Beitrag #3
RE: Arduino kann nicht rechnen?!
Also, danke schonmal für die schnelle Antwort. Es ist so, dass die Werte welche ich in der Berechnung verwende (Grad und Zeit) ein normales int sind. Die Variable Zeitschritte ist im Moment float, war aber auch schon long und double-> immer das Gleiche... An Grad und Zeit kann es doch nicht liegen oder?!, weil diese werden ja nicht verändert und beinhalten Werte von maximal 170 bzw. 1600. Ich werde sie aber trotzdem mal in long ändern. Wenn das klappt müsste mir nur noch jemand erklären können warum das so ist Wink
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.12.2015, 14:50
Beitrag #4
RE: Arduino kann nicht rechnen?!
Hallo Maxi290997,

Zitat:Prüfe das bitte, bevor sich jemand durch deinen Code durchackert.

Und von mir leider die Anmerkung zum Code, da dieser ohne Dokumentation daher kommt, ist es schwierig den durchzuarbeiten. Wenn wir das prüfen sollen, must du den dokumentieren.

Nur du kennst den Code und weißt was er machen soll.

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. Cool
Gruß Dieter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.12.2015, 14:52
Beitrag #5
RE: Arduino kann nicht rechnen?!
Tatsache.... kann es sein dass vorallem Zeit nicht int sein darf weil ich es *1000 rechne? Und diese Rechnung irgendwie doch auf Zeit änderungen vollzieht bzw. diese Änderungen in den Format vollzogen werden, wie Zeit es ist?
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.12.2015, 15:14
Beitrag #6
RE: Arduino kann nicht rechnen?!
(12.12.2015 14:49)Maxi290997 schrieb:  Also, danke schonmal für die schnelle Antwort. Es ist so, dass die Werte welche ich in der Berechnung verwende (Grad und Zeit) ein normales int sind. Die Variable Zeitschritte ist im Moment float, war aber auch schon long und double-> immer das Gleiche... An Grad und Zeit kann es doch nicht liegen oder?!, weil diese werden ja nicht verändert und beinhalten Werte von maximal 170 bzw. 1600. Ich werde sie aber trotzdem mal in long ändern. Wenn das klappt müsste mir nur noch jemand erklären können warum das so ist Wink

Hallo Maxi290997,
in "void AusrichtungNull()" könntest du z.B. schon einen Überlauf haben, wo du in der Zeile "Zeitschritte = (Zeit*1000) / Grad;" die int-Variable mit 1000 multiplizierst (wobei ich aber nicht weiß, welchen Wert "Zeit" hat).
Beispiel:

int a = 1000;
int b = 10;
float c;
Serial.print(c = (a * 100)/b);

ergibt im Seriellen Monitor ein Ergebnis von -3107,00 statt 10.000, weil die Zwischenberechnung von a * 100 größer 32.767 ist.
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.12.2015, 15:23
Beitrag #7
RE: Arduino kann nicht rechnen?!
Alles klar also wie ich vermutet habe hat es einen einfluss auf die rechnung 1000*100 ob der Variablenwert 1000 ein int oder long ist...
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
14.12.2015, 21:11
Beitrag #8
RE: Arduino kann nicht rechnen?!
(12.12.2015 15:14)Retian schrieb:  int a = 1000;
int b = 10;
float c;
Serial.print(c = (a * 100)/b);

ergibt im Seriellen Monitor ein Ergebnis von -3107,00 statt 10.000, weil die Zwischenberechnung von a * 100 größer 32.767 ist.

Um es allgemeiner zu sagen: gerechnet wird auf dem AVR generell mit int-Werten, also signet 16Bit. Das ergibt obigen Überlauf.

Ändern kann man es z.B. indem man dem Compiler mitteilt, daß ein größerer Zahlenbereich nötig ist.
Serial.print(c = (a * 100L)/b);
Damit wird das Zwischenergebnis als Long-Variable berechnet und das Ergebnis sollte stimmen.

Gruß aus Berlin
Michael
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Rotaryencoder funktioniert nicht richtig 123clever 18 232 Heute 21:38
Letzter Beitrag: georg01
  328P geht nicht mehr Harry 19 419 Gestern 10:28
Letzter Beitrag: Harry
  Echtzeituhrmodul läuft nicht scritch 64 2.715 28.01.2018 14:16
Letzter Beitrag: Tommy56
Bug I2C Displays wollen nicht mehr Der Ausserirdische 12 554 30.12.2017 17:11
Letzter Beitrag: hotsystems
  Uhr funktioniert nicht Jakob 8 534 30.12.2017 00:15
Letzter Beitrag: hotsystems
  BME280 wird nicht erkannt sowerum 14 664 10.12.2017 22:14
Letzter Beitrag: Tommy56
  Bootloader lässt sich nicht brennen?? dobermann145 10 874 21.11.2017 22:58
Letzter Beitrag: hotsystems
  mi Stundenwert aus DS3231 rechnen u. einfrieren... alpenpower 4 341 21.11.2017 12:54
Letzter Beitrag: hotsystems
Lightbulb Wie kann ich Daten vom Nextion Display auf Arduino Mega2560 senden und benutzen MarkusA 14 1.385 02.11.2017 23:10
Letzter Beitrag: MarkusA
Sad Nano - nicht genug Speicher torsten_156 10 1.055 30.10.2017 21:40
Letzter Beitrag: MicroBahner

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste