Go Down

Topic: Abbruch des Sketches (Read 973 times) previous topic - next topic

Johannes81

Hallo Gemeinde,

ich stehe mal wieder vor einer Herausfoderung:
Ich habe einen Code geschrieben, der auch eigentlich problemlos funktioniert, nur bricht der Code mittendrin ab. Also genauer: Ich lese einen Analogeingang aus. Der Wert ist im sollbereich, was durch eine grüne LED sybolisiert wird(und auch im SerialMonitor). Fällt der Wert unter einen bestimmten wert soll ther code an eine neue Stelle springen. Wird auch gemacht. Nach ca 2 Minuten springt der code wieder an den Anfang des sketches, selbst wenn der Analogwert NIE unter den Schwellwert gefallen ist!
Meine Frage ist nun warum tut er das? Bzw Wie kann ich es abstellen? Hat jemand eine Idee?
Danke für eure Hilfe

Code: [Select]
#include <Servo.h>
Servo Horizontal; //Servo mit dem Namen Horizontal
Servo Vertikal; //Servo mit dem Namen Vertikal

int pos = 0; //Variable in der die Position des Servos Horizontal gespeichert wird
int poos = 0; //Variable in der die Position des Servos Vertikal gespeichert wird

int startknopf = 9; // Zuweisung an welchem pin der Suchknopf angeschlossen ist
int knopfzustand = LOW; //

int fehler = 4; // Zuweisung an welchem Pin die LED Fehler (1) angeschlossen ist
int pruefen = 5; // Zuweisung an welchem Pin die LED Suchen (2) angeschlossen ist
int gefunden = 6; //Zuweisung an welchem Pin die LED Gefunden (3) angeschlossen ist

int servosignal=10; // Zuweisung an welchem Pin die Servos hängen
int y;

int sensorValue;

int pausezeit = 100; //Pausezeit nach einer Bewegung

void setup() {
  // put your setup code here, to run once:

  pinMode(fehler, OUTPUT);
  pinMode(pruefen, OUTPUT);
  pinMode(startknopf, INPUT);
  pinMode(gefunden, OUTPUT);
  pinMode(servosignal,OUTPUT);


  Horizontal.attach(3); // an welchem Pin das Servo angeschlossen ist
  Vertikal.attach(2); // an welchem Pin das Servo angeschlossen ist

  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
  start();
}
void start(){
  Horizontal.write(0); // definiert den Startwinkel für Suchfunktion
  Vertikal.write(0); // definiert den Startwinkel für Suchfunktion
  y=LOW;
  digitalWrite(fehler, HIGH);
  digitalWrite(pruefen, LOW);
  digitalWrite(gefunden, LOW);
  digitalWrite(servosignal,HIGH);

  if (digitalRead(startknopf) == HIGH) {
    sensorValue = analogRead(A1);
    //Serial.println(sensorValue);
    delay(1);


    digitalWrite(fehler, LOW);
    digitalWrite(pruefen, HIGH);
    digitalWrite(gefunden, LOW);
    digitalWrite(servosignal,HIGH);

    for (int pos = 5; pos < 175; pos += 10) {
      Horizontal.write(pos);
      delay(pausezeit);
      sensorValue = analogRead(A1);
      //Serial.println(sensorValue);
      delay(1);
      if(sensorValue >60){//Ausläsegrenze
        solar();
      }
      if(sensorValue<50&&y==HIGH){//untere Grenze
        abbruch();
        break;
      }

      for (int poos = 5; poos < 175; poos += 10) {
        Vertikal.write(poos);
        delay(pausezeit * 5);
        sensorValue = analogRead(A1);
        Serial.println(sensorValue);
        delay(1);
        if(sensorValue >60){//Auslösegrenze
          solar();
        }
        if(sensorValue<50&&y==HIGH){//untere Grenze
          abbruch();
          break;
        }
      }

    }
  }
}

void solar(){
  digitalWrite(fehler, LOW);
  digitalWrite(pruefen, LOW);
  digitalWrite(gefunden, HIGH);
  digitalWrite(servosignal,LOW);
  y=HIGH;
  if(digitalRead(startknopf)==HIGH){
    digitalWrite(fehler,HIGH);
    digitalWrite(pruefen,HIGH);
    digitalWrite(gefunden,LOW);
    delay(20*pausezeit);
  }



}
void abbruch(){
  digitalWrite(fehler, HIGH);
  digitalWrite(pruefen,HIGH);
  digitalWrite(gefunden,HIGH);
  delay(3000);


}

uwefed

Welche LED ist die grüne LED?

Was macht der Servosignal-Ausgang pin 10?

Welches Signal hast Du am analogen Eingang A1? Bist Du sicher daß Du dieses Pin verwendest?

Hast Du ein Pulldown-widerstadn am Tasterpin?

Grüße Uwe

Johannes81

Hi, led grün hängt an pin 6 Prüfen.

Servosignal wird bei bedarf gegen Masse gezogen, damit sich das Servo bewegen kann. Wichtig es wird hier nicht die Steuerleitung der Servos gegen Masse gezogen.

Ich verwende noch ganz klassisch vorwiderstände und nicht die internen von Arduino.

Ja, A1/verwende ich definitiv. (Läuft ja auch die ersten 2 min Problemlos). An A1 hängt im Moment noch ein Poti, soll aber später gegen einen Lichtsensor getauscht werden

HotSystems

Hi, led grün hängt an pin 6 Prüfen.

Servosignal wird bei bedarf gegen Masse gezogen, damit sich das Servo bewegen kann. Wichtig es wird hier nicht die Steuerleitung der Servos gegen Masse gezogen.

Ich verwende noch ganz klassisch vorwiderstände und nicht die internen von Arduino.

Ja, A1/verwende ich definitiv. (Läuft ja auch die ersten 2 min Problemlos). An A1 hängt im Moment noch ein Poti, soll aber später gegen einen Lichtsensor getauscht werden
Vorwiderstand ist schonmal falsch, das müssen Pulldown- oder Pullup-Widerstände sein.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

Johannes81

Sorry meine ich natürlich

uwefed

Servosignal wird bei bedarf gegen Masse gezogen, damit sich das Servo bewegen kann. Wichtig es wird hier nicht die Steuerleitung der Servos gegen Masse gezogen.
Danke Für die Erklährungen aber das obengeschriebene verstehe ich nicht.
Was ziehst Du auf Masse wenn es nicht das Steuersignal ist? Meinst Du Die negative Spannungsversorgung der Servo? wenn ja verwendest Du Transistoren oder MOSFET?

Grüße Uwe

dony

#6
Mar 08, 2018, 08:14 am Last Edit: Mar 08, 2018, 08:18 am by dony
Hallo,

Ich habe Dir Deinen Code etwas kommentiert, muss jetzt aber los...
Denoch wirst Du wahrscheinlich Einsehen, das Du zumindest die 15 Arduino Tutorials (Beispiele->StarterKit_BasicKit) durchgehen solltest um die Grundlagen zu lernen.

Code: [Select]
#include <Servo.h>
Servo Horizontal; //Servo mit dem Namen Horizontal
Servo Vertikal; //Servo mit dem Namen Vertikal

int pos = 0; //Variable in der die Position des Servos Horizontal gespeichert wird
int poos = 0; //Variable in der die Position des Servos Vertikal gespeichert wird

int startknopf = 9; // <- Hier kannst Du in durch byte ersetzen, siehe: Forum Suche (oder Frage bevor Du es nicht verstehst!!)
int knopfzustand = LOW; // <-- Das heisst für mich Interner Pullup, Wenn du externe PullDown Widerstände verwendest:
//pinMode(pin, OUTPUT); // pin gibt es nicht, aber der kompiler nimmt es, als wird es wohl 0 sein. Das Fragst Du besser noch oder googelst es
//ABER: Eine "int pin;" == "pin = 0"; auf Pin 0 (und 1) liegt die Serielle Verbindung! <- NUR gewollt verwenden!
// Denn Code Block bitte trotzdem lesen!
/*
int pin = 12; // <- Beispiel meinerseits
pinMode(pin, OUTPUT); // pin gibt es nicht, hier wird also Pin 0 als Ausgang definiert (auf Pin 0 liegt die Serielle Verbindung)
digitalRead(pin, HIGH); // So ist ein gedrückter Taster LOW

pinMode(pin, OUTPUT);
digitalRead(pin, HIGH); // <- So kann man den internen Pullup aktivieren
digitalRead(pin, LOW); // Dann ist ein gedrückter Taster LOW
*/

int fehler = 4; // Zuweisung an welchem Pin die LED Fehler (1) angeschlossen ist
int pruefen = 5; // Zuweisung an welchem Pin die LED Suchen (2) angeschlossen ist
int gefunden = 6; //Zuweisung an welchem Pin die LED Gefunden (3) angeschlossen ist

int servosignal=10;
//int y; //<- Mach das bitte zu bool
bool y; // <-- Da gibt es nur true or false, also 0 oder 1

int sensorValue;

int pausezeit = 100; //Pausezeit nach einer Bewegung

void setup() {
  // put your setup code here, to run once:

  pinMode(fehler, OUTPUT);
  pinMode(pruefen, OUTPUT);
  pinMode(startknopf, INPUT);
  pinMode(gefunden, OUTPUT);
  pinMode(servosignal,OUTPUT); // Brauchst Du nicht, macht: Servo Attach


  Horizontal.attach(3); // <- Zwei Servos, zwei Pins aber nur eine Variable (?)
  Vertikal.attach(2); // Muss ein PWM Pin sein, sind die mit ~ markierten, siehe Arduino Referenz

edit: Sorry das mit der pin Variable war ich selbst. :o
Die habe ich natürlich nicht definiert, da ich anfangs nur den Block posten wollte.

Grüße,
Donny
Grüße, Donny

Johannes81

Wow, danke für die Hilfe schon mal.
Also beim Servisugnal verwende ich einen Transistor.

Und danke für die Kommentare im Code. Werde ich heute abend gleich versuchen. Gebe selbstverständlich Rückmeldung.  :)

Johannes81

Hab mir euren bisherigen Ratschläge zu Herzen genommen.
Leider ohne Erfolg. Code springt immer noch nach ca 2 Minuten von void solar() direkt hinter Void lood() ohne dass der Wert am Poti unter 50 fällt...

Bitte verzeiht mir mein unwissen (stehe noch am Anfang), aber kann es sein dass ein Speicher voll ist und dann der Code einfach von neuem beginnt?

Doc_Arduino

Hallo,

ich vermute ein Verständnisproblem mit loop.

Code springt immer noch nach ca 2 Minuten von void solar() direkt hinter Void lood() ...
start() ist dein einzigster Funktionsaufruf in loop. loop kann nichts anderes wie start() immer wieder erneut aufrufen wenn die Abarbeitung am Ende von start() angelangt ist. Derzeit kannste loop auch ohne start() betrachten. Wenn irgendwann die for Schleifen fertig sind oder break zum Zuge kam gehts von vorn los.

Code: [Select]
void loop() {

  Horizontal.write(0); // definiert den Startwinkel für Suchfunktion
  Vertikal.write(0); // definiert den Startwinkel für Suchfunktion
  y = LOW;
  digitalWrite(fehler, HIGH);
  digitalWrite(pruefen, LOW);
  digitalWrite(gefunden, LOW);
  digitalWrite(servosignal, HIGH);

  if (digitalRead(startknopf) == HIGH) {
    sensorValue = analogRead(A1);
    //Serial.println(sensorValue);
    delay(1);


    digitalWrite(fehler, LOW);
    digitalWrite(pruefen, HIGH);
    digitalWrite(gefunden, LOW);
    digitalWrite(servosignal, HIGH);

    for (int pos = 5; pos < 175; pos += 10) {
      Horizontal.write(pos);
      delay(pausezeit);
      sensorValue = analogRead(A1);
      //Serial.println(sensorValue);
      delay(1);
      if (sensorValue > 60) { //Ausläsegrenze
        solar();
      }
      if (sensorValue < 50 && y == HIGH) { //untere Grenze
        abbruch();
        break;
      }

      for (int poos = 5; poos < 175; poos += 10) {
        Vertikal.write(poos);
        delay(pausezeit * 5);
        sensorValue = analogRead(A1);
        Serial.println(sensorValue);
        delay(1);
        if (sensorValue > 60) { //Auslösegrenze
          solar();
        }
        if (sensorValue < 50 && y == HIGH) { //untere Grenze
          abbruch();
          break;
        }
      }
    }
  }
}


Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Johannes81

Ja, da gebe ich dir recht. Also schnell mal void start() auskommentiert, Sketch hochgeladen, 2 laaaannge Minuten gewartet und leider gleiches Problem... Sketch springt an die Stelle vor dem ersten if.......

michael_x

Ich sehe zwei geschachtelte for-Schleifen. Die äussere alleine braucht 17 * 0.1 sek und ruft 17 mal die innere auf. Die innere braucht 17 *0.5 sek

Zusammen also 17 * 8.6 sek = 146.2 sek, also gut zwei Minuten, wenn kein Abbruch erfolgt.


Wo ist das Problem ?
( Dass das komplett anders gemacht werden kann, soll mal egal sein )

Johannes81

ok, klingt sinnvoll. Das Problem ist, dass die for schleife nicht nach 146,2s verlassen werden soll. (es soll praktisch so lange in der For schleife geblieben werden bis der poti wert unter 50 fällt, was halt auch länger als 146,2 s dauern kann)
Wie kann ich das lösen? Verzeiht mir meine Anfängerproblematik

Doc_Arduino

#13
Mar 08, 2018, 07:06 pm Last Edit: Mar 08, 2018, 07:07 pm by Doc_Arduino
Hallo,

was Micha schreibt dachte ich mir auch insgeim, wollte dazu noch nichts sagen.
Wenn du nicht nach der Zeit abbrechen möchtest, wofür dienen dann die Pausenzeiten?

Wenn du start() auskommentierst sollte das Programm eigentlich gar nichts machen, weil deine loop damit leer ist. Irgendwas machst du demnach anders wie du denkst zu machen.

Vielleicht besser du formulierst was das Programm machen soll. Also den Programmablauf. Vielleicht können wir dann besser helfen. Und was schaltest du mit dem Transistor?
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Johannes81

Also ich versuche mein Projekt im ganzen so kurz wie möglich und dabei möglichst genau zu beschreiben:

An meinem UNO habe ich drei LEDs rot=Fehler, gelb=Suchen, grün= Gefunden
Weiter sind zwei Servos montiert, sowie ein Lichtsensor (aktuell durch ein Poti simmuliert), sowie ein Button.

Funktionsbeschreibung:
Beim Einschalten des Sketsches soll nur die rote LED läuchten.
Wird der Button betätigt, sollen sich die Servos beginnen zu bewegen und led rot aus und led gelb angehen.
Die Servos sollen sich ähnlich wie das bescheiben bei alten Fernsehern ablaufen(also vom Bewegungsprofil).
Nun kommt hinzu, dass dabei der Lichtsensor ausgewertet werden soll.
Hat der Lichtsensor einen Wert von größer 60 detektiert, sollen sich die Servos nichtmehr bewegen und die gelbe led aus und die grüne led angehen.
Wird in diesem zustand der Button erneut betätigt, sollen led rot und gelb für ca 3 Sekunden leuchten und dann alles zurück in den vorherigen zustand.
Wenn der Lichtsensor nun unter 50 fällt, sollen für drei Sekunden alle drei LEDs angehen und danach das Programm in den zustand wie nach power an zurückkehren.

Wie gesagt soweit funktioniert auch alles, nur wenn LED grün länger als 2 minuten an ist und der wert über 60 ist springt der Code in den Anfangszustand.....

Und achso, ich verwende servosignal dafür über einen Transistor die Masse der Servos zu trennen, also praktisch wie einen Schalter...

Ich hoffe ihr konntet meinen Ausführungen folgen. In meinem Kopf hat es zumindest grade noch Sinn ergeben :-)


Go Up