Ampelschaltung: Fußgängertaster zum verkürzen der Ampelphase

Heya!

ich hab ein kleines Problem mit meiner Ampelschaltung welche ich mit der Arduino Software programmiere... Ich benutze hierfür ein 16-Bit Schieberegister

die Funktion soll sein:

  • wenn schalter an Pin 2 geschaltet: gelb blinken Modus (funktioniert)

  • wenn schalter an Pin 4 geschaltet: normaler Betriebsmodus (durchläuft 8 Phasen im switch-case) (funktioniert)
    Ich benutze dafür einen Knebelschalter was gleichzeitiges aktivieren ausschliesst.

  • wenn TASTER an Pin 6 gedrückt in zB Phase 7: Ein Fußgänger möchte in einer Richtung die Straße überqueren, sprich der Phasenwechsel soll nach 5 Sekunden eintreten. "j" wird durch den Tastendruck auf 1 gesetzt.
    Drückt kein Fußgänger den Anforderungstaster innerhalb der 5 Sekunden bleibt "j" auf null, die Ampelphase 10 sek durchlaufen (funktioniert NICHT)

es ist ein hin und her zwischen den 5sek und 10sek, egal wie ich es programmiere in der phase 7 und habe es schon zig mal umgeschrieben und werde langsam wahnsinnig ^^

evtl kann mir jemand von euch da einen kurzen Geistesblitz verschaffen?

hier ein kleiner auszug:
im setup:

  attachInterrupt(tasterPin6, interruptRoutine, HIGH);
 ...
case 7:   if (j>=1)
              j = 0;
    
              AmpelP7();                                //  -   -   #   #             
              updateShiftRegister();                    //  -   #   -   -
              zeitmerker = millis();                    //  #       -  
              while(millis() - zeitmerker <= 5000)      
              {
              if (j == 0){
                  AmpelP7();                    		//  -   -   #   #             
                  updateShiftRegister();        		//  -   #   -   -
                  zeitmerker = millis();        		//  #       - 
                  while(millis() - zeitmerker <= 5000) {}
                  }           
              }
              {
              if (j>=1)
              j = 0;
              }
              i++;

   case 8:   AmpelP8();    ...

wäre super wenn jemand meinen gravierenden fehler sieht.. ich habe schon alles erdenkliche versucht aber ich glaube ich mache es nur schlimmer! sollte doch eigentlich total einfach sein..

falls ihr fragen zu den Schieberegistern habt oder sonst irgendwelche fragen, ich freu mich sie zu beantworten :wink:

grüße
felix

Einige Grundregeln:

  • Taster und Interruptroutine passt nicht zusammen.
  • Probleme sind immer im geheim gehaltenen Teil des Sketches
  • Ohne Variablendefinition ist alles nur Raterei.

Hier Konkret:
Wenn j (wofür soll das gut sein) nicht negativ werden kann, ist es in case 7 immer 0, wegen

if (j>=1)

j = 0;

Die späteren  if (j == 0){
und   if (j >= 1){
sind eher nur verwirrend.

Wenn j evtl. in

              AmpelP7();              
              updateShiftRegister();

modifiziert werden sollte, sage ich lieber nichts mehr ... (es gibt noch mehr Grundregeln, die aber beim Fragesteller meist nicht gut ankommen :wink: )

wollte nicht den ganzen code posten, wäre sehr viel gewesen :wink:

ich meine allderings das problem gefunden haben: für eine interrupt routine eignen sich am uno3 board nur die pins 2 und 3! ich hatte es auf pin 6!! ich probiere es mal aus und gebe feedback!

und wie es jetzt funktioniert!!! die größte hilfe war wohl die aufforderung des mitbewohners endlich mal was zu essen!!!! xD

für die input funktionen sind nur bestimmte pins geeignet! habe mein attachInterrupt() von pin 6 auf pin 3 umgeschrieben und endlich...!!!

variablenzuweisung

const int tasterPin3 = 3;

wertzuweisúng

int tasterState3 = 0;   // Fußgängertaster

interruptbefehl und zuweisung aufs unterprogramm

attachInterrupt(tasterPin3, interruptRoutine, HIGH);

unterprogramm

void interruptRoutine() {
  j++;
}

code der funktioniert aber noch etwas modifiziert werden muss ^^

 case 7:   AmpelP7();                                //  -   -   #   #             
              updateShiftRegister();                    //  -   #   -   -
              zeitmerker = millis();                    //  #       -  
              while(millis() - zeitmerker <= 5000)      
              switch (j) {
                case 1:   AmpelP7();                    //  -   -   #   #             
                          updateShiftRegister();        //  -   #   -   -
                          delay(5000);                  //  #       -  
                          i++;
                default:  i++;
              }

trotzdem vielen dank für die rückmeldung!!!

felixhhh:
.....für eine interrupt routine eignen sich am uno3 board nur die pins 2 und 3! ich hatte es auf pin 6!! ich probiere es mal aus und gebe feedback!

Wie Michael_x dich schon darauf hingewiesen hat, wozu für einfache Schalter/Taster-Funktionen einen Interrupt. Da reicht eine einfache Abfrage in der Loop völlig aus.

HotSystems:
... wozu für einfache Schalter/Taster-Funktionen einen Interrupt.

Weil damit auch während delay ein Tastendruck erkannt wird.

agmue:
Weil damit auch während delay ein Tastendruck erkannt wird.

Also ein Problem wird mit einem weiteren Problem umgangen.
Da sollte der Sketch unbedingt optimiert werden, dann braucht es keinen Interrupt.

Fazit: hier ist aus meiner Sicht delay ein ganz großer MIST.

Hi

Würde die Ampel als State-Maschine ausbauen.
So kann man auch einzelne States überspringen - wenn z.B. Keiner über die Fußgängerampel drüber will.

Dann gaht's auch ohne delay() (dafür gibt's dann mit millis() ).

MfG