Go Down

Topic: Anfänger Problem - Programmabläufe (Read 630 times) previous topic - next topic

daschxx

Hallo,
Ich habe folgendes Problem, ich habe mich nun seit einigen Tagen mit Arduino beschäftigt und auch schon schicke Programme auf die Beine gestellt. Jedoch sitz ich nun seit einigen Stunden immer an demselben Problem und zwar:

Habe ich einen Code womit ich durch ein Potentiometer zwischen 4 Moden wählen kann, die verschiedenen Moden sind verschiedenen LED blink Reihenfolgen. Des Weiteren hab ich 3 Schalter:
1: Einstellungsknopf
2: +
3: -
Mit denen sich die Geschwindigkeit ändern lässt.

Nun ist aber das Problem wenn das Program gerade eine Reihe von Ein und Ausschalt befehlen für die LEDs abarbeitet reagiert es nicht auf den Einstellknopf.

Hoffe ich habe mich verständlich ausgedrückt.

Code hänge ich im Anhang an, einmal den Kompleten und einmal nur die Problemstelle.
Komplet: problem.pde
Kurz: problem.txt

Hoffe auf schnelle Hilfe und Danke.

Daniel

uwefed

Delay blockiert die Abarbeitung des Kode.
Während:
Code: [Select]

      digitalWrite(ge1, HIGH);   
      delay(geschwindigkeit);             
      digitalWrite(ge1, LOW);   
      delay(geschwindigkeit);             
      digitalWrite(ge2, HIGH);   
      delay(geschwindigkeit);             
      digitalWrite(ge2, LOW);   
      delay(geschwindigkeit);             
      digitalWrite(ge3, HIGH);   
      delay(geschwindigkeit);             
      digitalWrite(ge3, LOW);   
      delay(geschwindigkeit); 


kann Arduino nichts anderes machen.
Zeitverzögerungen mußt Du mit millis() machen.
http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

Grüße Uwe

mkl0815

Eine Möglichkeit wäre über einen Timer-Interrupt die Taster abzufragen und den Wert zwischen zu speichern. Wie oft pro Sekunde der Timer feuern muss, müßtest DU ausprobieren. Eine Funktion "adjust_speed()" kannst Du dann zusätzlich vor jedem "delay(geschwindigkeit)" aufrufen, um die Geschwindigkeit auf die letzten erkannten Tasten anzupassen. Damit kann Dein Programm quasi nebenbei die Tasten überwachen. Je nach Aufwand kann auch gleich die Interrupt Serviceroutine die Geschwindigkeit anpassen. Allerdings sollte man hier beachten, das es Probleme geben kann wenn Variablen außerhalb der Service-Routine benutzt werden, während sie jederzeit durch einen Interrupt verändert werden können. Stichwort Nebenläufigkeit und Seiteneffekte.
Um sowas zu vermeiden würde ich eher eine eigene Funktion "adjust_speed()" verwenden.
Schmatischer Abaluf:
Code: [Select]

void adjust_speed() {
   disbale_timer_interrrupt()
   get_last_button_state
   enable_timer_interrupt()
   adjust_blink_speed
}


uwefed


Eine Möglichkeit wäre über einen Timer-Interrupt die Taster abzufragen und den Wert zwischen zu speichern. ....

mkl0815, ist das für einen Anfänger nicht ein komplizierter Lösungsvorschlag?
Grüße Uwe

Ice-Man

hallo dasch

ich hatte vor einigen tages das selbe problem das sich jedesmal wegen einem delay mein progi lahm lag
ich hab es so gemacht

int lastSecond;
.....................
if (lastSecondone != millis()/1000) {     
           lastSecondone = millis()/1000;

hier wird bei jedem durchlauf geschaut ob die 1000millis abgelaufen sind und schaltet erst dann weiter solange das net der fall ist "überspringt" der µC den abschnitt

mkl0815


mkl0815, ist das für einen Anfänger nicht ein komplizierter Lösungsvorschlag?
Grüße Uwe

Früher oder später wird man sich mit Interrupts auseinandersetzen. Da der OP schreibt, das er schon einige schicke Programme geschrieben hat, halte ich das durchaus für eine Lösungsidee. Man wächst ja mit seinen Herausforderungen :-)
Außerdem bekommt man hier im Forum bei konkreten Fragen, wenn halt nicht gleich beim ersten Versuch klappt, auch super Hilfe.
Die Idee von Ice-Man ist aber auch gut. In der Loop den Code für den "Blink-Wechsel" überspringen, wenn die Zeit noch nicht "reif" ist. Allerdings wird das bei der Blink-Sequenz auch etwas komplexer bei der Programmierung.

Grüße,
Mario.

daschxx

Vielen Dank für die schnellen Antworten.
Hab das ganze jetzt so gelöst:
void loop() {
   cnt++;
   if(cnt==10) //wenn cnt = 10 (also 10*geschwindigkeit)
   {
     cnt=0;
     led(); //ruft Programm led() auf
   }
   delay(geschwindigkeit);  //1-100 also keine Lange Pause im Ablauf
 }
void led(void)
{
...
}

somit ist delay niemals länger als 100 also 0,1 sec für mich reicht das vollkommen aus.

uwefed


...
Die Idee von Ice-Man ist aber auch gut. In der Loop den Code für den "Blink-Wechsel" überspringen, wenn die Zeit noch nicht "reif" ist. Allerdings wird das bei der Blink-Sequenz auch etwas komplexer bei der Programmierung.
Grüße, Mario.


Lieber Mario.
Ist genau das, was ich gelinkt habe, aber nicht expliziert erklärt habe.  ;) ;) ;)
Grüße Uwe

uwefed


Code: [Select]
int lastSecond;
.....................
if (lastSecondone != millis()/1000) {     
    lastSecondone = millis()/1000;}



Ich würde das mit dem "durch 1000 dividieren" nicht machen da es nur mehraufwand ist und man einfach anstatt mit Sekunden zu rechnen mit Millisekunden rechenen muß.
Grüße Uwe

Go Up