Schwieriges Arduino-Programm hat einen kniffligen Fehler

max

Neues Mitglied
Hallo. Ich habe eine Anlage gebaut, um Getränke zu mischen. Ich habe dazu auch ein Programm geschrieben. Das Programm ergibt aus meiner Sicht auch ziemlich Sinn. Die Beleuchtung der Taster funktioniert auch super.

Nun zum Problem: Sobald der Starttaster gedrückt wurde, wird die Variable start auf true gesetzt. Im Loop-Teil springt der Compiler dann auch in die if-Anweisung, bearbeitet aber nur den Anfang der if-Anweisung. Die Systemausgaben werden auf dem seriellen Monitor ausgegeben, die Delays aber nicht ausgeführt. Das sieht man auch an der Systemausgabe, da er nach der Ausgabe von 2000 direkt wieder loop ausgibt.

Ich bedanke mich schon mal bei jedem, der sich mein Programm durchliest, da es sich aus meiner Sicht um eine knifflige Angelegenheit handelt.

Ganzes Programm:
//---Logische Variablen festlegen
volatile boolean starten = false;
volatile char gewaehlterAlc;
volatile char gewaehlterDrink;

double flussratePumpe = 8.333;
double flussrateVentil = 35.000;              // Muss noch genau ermittelt werden
double pumpenDelay;
double ventilDelay;
int becherInhalt = 400;
int mischVerhaeltniss; // Setze hier einen Standardwert

// Variablen für Debouncing
unsigned long lastDebounceTimeAlcA = 0;
unsigned long lastDebounceTimeAlcB = 0;
unsigned long lastDebounceTimeAlcC = 0;
unsigned long lastDebounceTimeDrinkA = 0;
unsigned long lastDebounceTimeDrinkB = 0;
unsigned long lastDebounceTimeDrinkC = 0;
unsigned long lastDebounceTimeStart = 0;
const unsigned long debounceDelay = 50;  // Debounce-Verzögerung in ms

void setup() {
  pinMode(53, INPUT); // Pin 53 als Input festlegen für PinChange Interrupt
  pinMode(22, OUTPUT);  // IN1 -> AlcButtonA
  pinMode(23, OUTPUT);  // IN2 -> AlcButtonB
  pinMode(24, OUTPUT);  // IN3 -> AlcButtonC
  pinMode(25, OUTPUT);  // IN4 -> DrinkButtonA
  pinMode(26, OUTPUT);  // IN5 -> DrinkButtonB
  pinMode(27, OUTPUT);  // IN6 -> DrinkButtonC
  pinMode(28, OUTPUT);  // IN7 -> StartButton

  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(18, OUTPUT);
  pinMode(19, OUTPUT);
  pinMode(20, OUTPUT);
  pinMode(21, OUTPUT);

  //---Externe Interrupts Festlegen
  attachInterrupt(digitalPinToInterrupt(2), isrAlcButtonA, FALLING);
  attachInterrupt(digitalPinToInterrupt(3), isrAlcButtonB, FALLING);
  attachInterrupt(digitalPinToInterrupt(18), isrAlcButtonC, FALLING);
  attachInterrupt(digitalPinToInterrupt(19), isrDrinkButtonA, FALLING);
  attachInterrupt(digitalPinToInterrupt(20), isrDrinkButtonB, FALLING);
  attachInterrupt(digitalPinToInterrupt(21), isrStartButton, FALLING);

  // Pin-change-interrupt auf Pin 53 legen
  PCICR |= (1 << PCIE0);
  PCMSK0 |= (1 << PCINT0);

  //---Pins für Hardwarekomponenten festlegen
  pinMode(38, OUTPUT);  // mVentilA
  pinMode(39, OUTPUT);  // mVentilB
  pinMode(40, OUTPUT);  // mVentilC

  pinMode(32, OUTPUT);  // pumpeA
  pinMode(33, OUTPUT);  // pumpeA
  pinMode(34, OUTPUT);  // pumpeB
  pinMode(35, OUTPUT);  // pumpeB
  pinMode(36, OUTPUT);  // pumpeC
  pinMode(37, OUTPUT);  // pumpeC

  // Potentiometer
  pinMode(A1, INPUT);

  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("---loop---");

  if (starten == true) {
    // Interrupts vorrübergehend deaktivieren
    noInterrupts();


    mischVerhaeltniss = analogRead(A1);
    mischVerhaeltniss = map(mischVerhaeltniss, 0, 1023, 0, 100);

    Serial.println("Startenausgefühtt");

    pumpenDelay = 2000;  //(becherInhalt * mischVerhaeltniss) / flussratePumpe;
    ventilDelay = 2000;  //((becherInhalt * (1 - mischVerhaeltniss))/flussrateVentil);

    Serial.println(pumpenDelay);
    Serial.println(ventilDelay);

    pumpe_an(gewaehlterAlc);
    delay(pumpenDelay);
    pumpe_aus(gewaehlterAlc);

    magnetVentile_an(gewaehlterDrink);
    delay(ventilDelay);
    magnetVentile_aus(gewaehlterDrink);


    starten = false;

    delay(500);

    // Interrupts aktivieren
    interrupts();

  }
  delay(200);
}

//---Interrupts mit Debouncing
void isrAlcButtonA() {
  unsigned long currentTime = millis();
  if (currentTime - lastDebounceTimeAlcA > debounceDelay) {
    lastDebounceTimeAlcA = currentTime;
    digitalWrite(22, HIGH);
    digitalWrite(23, LOW);
    digitalWrite(24, LOW);
    Serial.println("alcButtonA");

    gewaehlterAlc = 'A';
  }
}

void isrAlcButtonB() {
  unsigned long currentTime = millis();
  if (currentTime - lastDebounceTimeAlcB > debounceDelay) {
    lastDebounceTimeAlcB = currentTime;
    digitalWrite(22, LOW);
    digitalWrite(23, HIGH);
    digitalWrite(24, LOW);
    Serial.println("alcButtonB");

    gewaehlterAlc = 'B';
  }
}

void isrAlcButtonC() {
  unsigned long currentTime = millis();
  if (currentTime - lastDebounceTimeAlcC > debounceDelay) {
    lastDebounceTimeAlcC = currentTime;
    digitalWrite(22, LOW);
    digitalWrite(23, LOW);
    digitalWrite(24, HIGH);
    Serial.println("alcButtonC");

    gewaehlterAlc = 'C';
  }
}

void isrDrinkButtonA() {
  unsigned long currentTime = millis();
  if (currentTime - lastDebounceTimeDrinkA > debounceDelay) {
    lastDebounceTimeDrinkA = currentTime;
    digitalWrite(25, HIGH);
    digitalWrite(26, LOW);
    digitalWrite(27, LOW);
    Serial.println("drinkButtonA");

    gewaehlterDrink = 'A';
  }
}

void isrDrinkButtonB() {
  unsigned long currentTime = millis();
  if (currentTime - lastDebounceTimeDrinkB > debounceDelay) {
    lastDebounceTimeDrinkB = currentTime;
    digitalWrite(25, LOW);
    digitalWrite(26, HIGH);
    digitalWrite(27, LOW);
    Serial.println("drinkButtonB");

    gewaehlterDrink = 'B';
  }
}

ISR(PCINT0_vect) {  // Pin-change-interrupt für DrinkButtonC
  unsigned long currentTime = millis();
  if (currentTime - lastDebounceTimeDrinkC > debounceDelay) {
    lastDebounceTimeDrinkC = currentTime;
    digitalWrite(25, LOW);
    digitalWrite(26, LOW);
    digitalWrite(27, HIGH);
    Serial.println("drinkButtonC");

    gewaehlterDrink = 'C';
  }
}

void isrStartButton() {
  unsigned long currentTime = millis();
  if (currentTime - lastDebounceTimeStart > debounceDelay) {
    lastDebounceTimeStart = currentTime;
    Serial.println("start");
    starten = true;
  }
}

//---Methoden zur Steuerung der Hardware
void pumpe_an(char pPumpe) {
  if (pPumpe == 'A') {
    digitalWrite(32, HIGH);
    digitalWrite(33, LOW);
  } else if (pPumpe == 'B') {
    digitalWrite(34, HIGH);
    digitalWrite(35, LOW);
  } else if (pPumpe == 'C') {
    digitalWrite(36, HIGH);
    digitalWrite(37, LOW);
  } else {
    digitalWrite(32, LOW);
    digitalWrite(33, LOW);
    digitalWrite(34, LOW);
    digitalWrite(35, LOW);
    digitalWrite(36, LOW);
    digitalWrite(37, LOW);
  }
}

void pumpe_aus(char pPumpe) {
  if (pPumpe == 'A') {
    digitalWrite(32, LOW);
    digitalWrite(33, LOW);
  } else if (pPumpe == 'B') {
    digitalWrite(34, LOW);
    digitalWrite(35, LOW);
  } else if (pPumpe == 'C') {
    digitalWrite(36, LOW);
    digitalWrite(37, LOW);
  }
}

void magnetVentile_an(char pVentil) {
  if (pVentil == 'A') {
    digitalWrite(38, HIGH);
  } else if (pVentil == 'B') {
    digitalWrite(39, HIGH);
  } else if (pVentil == 'C') {
    digitalWrite(40, HIGH);
  }
}

void magnetVentile_aus(char pVentil) {
  if (pVentil == 'A') {
    digitalWrite(38, LOW);
  } else if (pVentil == 'B') {
    digitalWrite(39, LOW);
  } else if (pVentil == 'C') {
    digitalWrite(40, LOW);
  }
}
 
Ich denke, es liegt an noInterrupts();, da der Timerinterrupt nicht fällt.

https://docs.arduino.cc/language-reference/de/en/functions/external-interrupts/attachInterrupt/
Note: the attached function, delay()
won’t work and the value returned by millis()
will not increment. Serial data received while in the function may be lost. You should declare as volatile
any variables that you modify within the attached function. See the section on ISRs below for more information.
 
Zurück
Oben Unten