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
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
  Frage zu STM32F1xx / Was kann ich bei dieser Fehlermeldung machen? Holzwurm56 37 1.232 04.09.2017 14:14
Letzter Beitrag: Holzwurm56
  NeoPixels: Sketch will nicht - Problem mit delay? Zabsi 5 272 22.08.2017 15:17
Letzter Beitrag: Tommy56
  Kann man auf den internen Speicher zugreifen? Maxi290997 11 658 18.08.2017 19:51
Letzter Beitrag: hotsystems
  BME280 - Luftdruckoffset nicht einstellbar ? Stargazer 17 877 13.08.2017 15:38
Letzter Beitrag: hotsystems
  Ich komme mit millis nicht weiter !!! Gonmaus 8 638 09.07.2017 21:24
Letzter Beitrag: Tommy56
  WEMOS Motorshield funzt nicht Rumpl-X 8 460 07.06.2017 21:10
Letzter Beitrag: Tommy56
  LCD geht nicht - keine Ahnung warum?? DL1AKP 12 745 15.05.2017 13:17
Letzter Beitrag: DL1AKP
  433mHz Funkmodule senden/empfangen nicht metzgefa 2 653 06.05.2017 13:30
Letzter Beitrag: metzgefa
  Firmata (Daten senden an den Arduino und empfangen vom Arduino) comfan 6 929 29.04.2017 14:29
Letzter Beitrag: hotsystems
  SD Karte wird nicht erkannt Maxi290997 6 386 31.03.2017 06:05
Letzter Beitrag: Bitklopfer

Gehe zu:


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