Pages: [1]   Go Down
Author Topic: Anfänger Problem - Programmabläufe  (Read 486 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

* problem.pde (4.75 KB - downloaded 4 times.)
* problem.txt (0.62 KB - downloaded 8 times.)
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 236
Posts: 20281
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Delay blockiert die Abarbeitung des Kode.
Während:
Code:
      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
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1405
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
void adjust_speed() {
   disbale_timer_interrrupt()
   get_last_button_state
   enable_timer_interrupt()
   adjust_blink_speed
}
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 236
Posts: 20281
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1405
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 236
Posts: 20281
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...
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.  smiley-wink smiley-wink smiley-wink
Grüße Uwe
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 236
Posts: 20281
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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
Logged

Pages: [1]   Go Up
Jump to: