Hilfe mein attachInterrupt funktioniert nicht

Moin,
ich muss für ein Schulprojekt eine Ampel Bauen ( eine Fußgänger und eine Autoampel) Die Schaltung funktioniert auch aber die 2 Ausbaustufe ist mit einem 2 Taster der die Ampel sofort auf Grün für Auto und Rot für Fußgänger macht aber bei mir macht der garnicht solange ich die schleife Ampel durlaufen lasse kann ich raufdrücken und er macht das was er soll aber wenn die Schleife angefangen hat durch auslösen des ersten Taster, reagiert der 2 Taster(Sender) überhaupt nicht mehr und ich finde meinen Fehler nicht.
Vielleicht könnt ihr mir ja helfen Danke!!

int PhaseLam[] = {136, 144, 160, 96, 160, 176, 136, 0};
int PhaseZeit[] = {1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500};
volatile int frei[] = {255};

boolean AmpelEin= false;
boolean AmpelEinNeu = false;
boolean AmpelEinschalten = false;
volatile byte i = 0;
volatile const byte Taste = 15;
volatile const byte Sender = 2;
unsigned long ZeitNeu;
unsigned long ZeitAlt = millis();
volatile int TasterStatus=0;

void setup() {
pinMode (Taste, INPUT_PULLUP);
pinMode (Sender, INPUT_PULLUP);

attachInterrupt(0, Lampe, CHANGE);
DDRD = B11111111;
Serial.begin(9600);

}
void loop() {

AmpelEin = digitalRead(Taste);

if (!AmpelEin && (i>2))
{
AmpelEinNeu = true;
}
if (!AmpelEin)
{
AmpelEinschalten = true;
}
if (AmpelEinschalten || (i>0))
{
ZeitNeu=millis();
if (ZeitAlt+PhaseZeit < ZeitNeu)

  • {*
    _ PORTD = PhaseLam*;_
    _
    ZeitAlt=millis();_
    _
    i = i + 1;_
    _
    if (i>7)_
    _
    {_
    _
    AmpelEinschalten = false;_
    _
    i = 0;_
    _
    if (AmpelEinNeu)_
    _
    {_
    _
    AmpelEinNeu = false;_
    _
    AmpelEinschalten = true;_
    _
    }_
    _
    }_
    _
    }_
    _
    }_
    delay(40);
    _
    }_
    void Lampe() {
    _
    TasterStatus = digitalRead(Sender);_
    _
    if (digitalRead(Sender))_
    _
    {_
    _ PORTD=frei;
    }
    }*_

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
So ist er auch auf portablen Geräten lesbar. Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Hallo,

tue dir bitte selbst ein Gefallen und lasse die direkten Portzugriffe weg. Da kommt sonst wie gezeigt nur Mist raus.
Interrupt brauchst du auch keinen. Hier ist blockierfreie Programmierung mit millis statt delay gefragt.

Hi

Die Namen sind nicht sonderlich gut gewählt - warum heißt der Taster 'AmpelEin'?
TasterEin hätte ich ja noch verstanden ...
In der IDE STRG+T drücken und unnötige Leerzeilen raus nehmen, dann den Kram in Code-Tags (gerne den ersten Post editieren).

In wie fern soll die Lampe DIREKT umspringen?

In Deiner ISR weist Du den Zustand des Sender TasterStatus zu - warum benutzt Du DAS nicht in der IF darunter, sondern fragst per digitalRead erneut ab?

Portzugriffe: wenn's super schnell werden soll - hier komplett fehl am Platz und sehr fehleranfällig
Magic Numbers: gebe den Zahlen sprechende Namen. Warum Interrupt 0 statt PinToInterrupt (Schreibweise müsste ich nachsehen, wird sich aber finden lassen). Dann auch einen Kommentar, warum der Taster (Dein AmpelEin) nur an Pins 2 oder 3 (an Uno/Nano) hängen darf (weil Das die einzigen Interrupt-Pins sind)
Interrupt: komplett unnötig, der Kram hat locker einige 10ms Zeit (von mir aus auch die 40ms delay() stören nicht großartig), um auf 'egal was' zu reagieren. Umbau auf State-Maschine (wobei der Ansatz schon vorhanden ist) und die Zeiten mit millis() erschlagen.
Siehe dazu combie's Antwort

  • Allgemein schaden Kommentare nicht wirklich.

Ist Das ein MUSS, oder ein WILL?
Für MUSS ist mir meine Zeit nämlich zu schade und Du solltest Deine ungeliebten Hausarbeiten verrichten, ohne, daß meine Zeit dafür drauf geht.
Bei WILL habe ich zumindest Hoffnung, daß Du Dir aneignest, was da so Alles im Arduino vorgeht - meiner Meinung nach ein sehr interessantes Hobby, für Welches wir hier ALLE unsere Zeit 'opfern' - wenn's uns (uns UND Dir) was bringt, sogar gerne.

MfG

Doc_Arduino:
Hier ist blockierfreie Programmierung mit millis statt delay gefragt.

Siehe BlinkwithoutDelay - Die Nachtwächtererklärung - Deutsch - Arduino Forum
Uwe

Hallo,

gut :wink: , dann steuer ich noch diese Erklärung bei: Theseus erklärt millis

Laut meiner vollen Überzeugung ist das Praxis bezogen erstmal leichter zu verdauen bevor man sich in die tiefere Erklärung von Gunther einlässt. Wenn man weiß das millis nur die eigene Armbanduhr ist und man sich die unbewußte Anwendung verdeutlicht was man damit tagtäglich macht, dann führt das laut meiner Meinung einfacher zum Ziel.
Der Einzigste Unterschied zwischen millis und Armbanduhr ist, dass man mit der Armbanduhr Differenzeiten von 24h abdecken kann. Mit millis sind es 49 Tage.

imho braucht man da keinen Interrupt und keine direkten Portzugriffe.

Ich arbeite gerade an einer Ampel, daher kann ich eine Variante zeigen.

Jede Ampel ist ein Objekt

Die Nord-Ampel ist rot gelb grün für Autos und kennt die Bilder rot rot-gelb, grün, gelb
Die Fußgänger-Ampel ist rot grün (war zu faul für eine eigene Klasse, daher zweimal der gleiche GPIO)

Eine Statemachine "traffic Manager" kümmert sich um den Ablauf.
Im Idle läuft das Muster durch,
Drückt ein Fußgänger auf den Button wird für die Fußgänger eine Grün-Phase forciert.
Genau genommen spring es in den Ablauf sodass die Autofahrer Gelb erhalten, dann Rot und erst dann schaltet die Fußgängerampel auf Grün (gem. Ablauf).

Für Österreicher und Ukrainer soll es leicht sein, ein "grün blinken" einzuführen.

// Traffic Lights
// by noiasca
// introduce the taffic manager and a walking light with push button
// https://forum.arduino.cc/index.php?topic=650985.0

enum trafficLightColor {red, redyellow, green, yellow};  // available colors/colorcombinations on a traffic lights

// row, colum
const uint8_t sequenceA [][3]  //interval, north, walk
{
  { 8, green, red},            //           0 Fahrt - stehen
  { 2, yellow, red},           //           1 Anhalten - stehen
  { 2, red, red},              //           2 Stop - stehen
  { 4, red, green},            //           3 Stop - gehen
  { 2, red, red},              //           4 Stop - stehen
  { 2, redyellow, red}         //           5 BereitMachen - stehen
};
const byte noOftrafficStates = 6;


byte trafficStateCurrent = 0;                          // the current state of the traffic
const uint16_t factorIntervall = 1000;                 // a factor for the intervall

const byte northWalkRequestPin = 12;                        // force Green for West
const byte northWalkRequestState = 1;                       // status if west Requests


class TrafficLight {
    byte state = red;
    unsigned long previousMillis;
    const byte ledPinRed;
    const byte ledPinYellow;
    const byte ledPinGreen;

  public:
    TrafficLight(byte red, byte yellow, byte green):
      ledPinRed(red),
      ledPinYellow(yellow),
      ledPinGreen(green)
    {}

    void begin()
    {
      pinMode(ledPinRed, OUTPUT);
      pinMode(ledPinYellow, OUTPUT);
      pinMode(ledPinGreen, OUTPUT);
    }

    void setState(byte newState)
    {
      state = newState;
      switch (state)
      {
        case red :
          digitalWrite(ledPinRed, HIGH);
          digitalWrite(ledPinYellow, LOW);
          digitalWrite(ledPinGreen, LOW);
          break;
        case redyellow :
          digitalWrite(ledPinRed, HIGH);
          digitalWrite(ledPinYellow, HIGH);
          digitalWrite(ledPinGreen, LOW);
          break;
        case green :
          digitalWrite(ledPinRed, LOW);
          digitalWrite(ledPinYellow, LOW);
          digitalWrite(ledPinGreen, HIGH);
          break;
        case yellow :
          digitalWrite(ledPinRed, LOW);
          digitalWrite(ledPinYellow, HIGH);
          digitalWrite(ledPinGreen, LOW);
          break;
      }
    }
};

TrafficLight trafficLightNorth(2, 3, 4);   // the traffic light North-South and the LED pins for red, yellow, green
TrafficLight trafficLightNorthWalk(5, 6, 6);    // the traffic light for walkway and the LED pins for red, green (no yellow

void setup() {
  Serial.begin(115200);
  Serial.println(F("traffic lights"));
  pinMode(northWalkRequestPin, INPUT_PULLUP);
  trafficLightNorth.begin();
  trafficLightNorthWalk.begin();
}

void runTrafficController() {
  static uint32_t lastMillis =  -10000;                                              // last update
  static uint8_t trafficStateIntervall = 0;                                          // current intervall for this state

  if (millis() - lastMillis >= trafficStateIntervall * factorIntervall)  // do something by time
  {
    lastMillis = millis();
    trafficStateCurrent++;                                                           // --> simple switch to next state
    trafficStateCurrent = trafficStateCurrent % noOftrafficStates;

    Serial.print(F("sequenceA:")); Serial.println(trafficStateCurrent);
    trafficStateIntervall = sequenceA[trafficStateCurrent][0];
    trafficLightNorth.setState(sequenceA[trafficStateCurrent][1]);
    trafficLightNorthWalk.setState(sequenceA[trafficStateCurrent][2]);
  }

  if (!digitalRead(northWalkRequestPin) && (trafficStateCurrent == 0 || trafficStateCurrent == 4 || trafficStateCurrent == 5))
  {
    Serial.println(F("West Request"));
    lastMillis = millis();
    trafficStateCurrent = northWalkRequestState;
    Serial.print(F("sequenceA:")); Serial.println(trafficStateCurrent);
    trafficStateIntervall = sequenceA[trafficStateCurrent][0];
    trafficLightNorth.setState(sequenceA[trafficStateCurrent][1]);
    trafficLightNorthWalk.setState(sequenceA[trafficStateCurrent][2]);
    delay(50); // Dirty debounce
  }
}

void loop()
{
  runTrafficController();
  // do what ever you want unblocked here
}