Komisches Verhalten eines bisher funktionierenden Sketches

Hallo Forengemeinde

Ich habe vor einiger Zeit hier nach einer Lösung mit Timerregistern gesucht und von euch erhalten. Der Sketch ist seither in zwei weiteren Projekten verwendet worden und läuft dort einwandfrei. Einzig Werte der LED Ausgänge wurden angepasst, um andere Farben am Taster zu erhalten, ansonsten unverändert.
Jetzt will ich den Sketch ein weiteres mal nutzen, jedoch in einem neuen Projekt.
Komischerweise springt der "button_vent_count" - Wert so nach ca. 15- 25 Sekunden auf 1, auch wenn der Taster nicht betätigt wird. Ansonsten funktioniert alles wie bisher und wie gewünscht. Bauteile inklusive Platine sind dieselben, wie in den anderen Projekten.
Anpassungen des debounce delay's bringen keine Besserung, da ich zuerst dachte, da sei mit dem Signal was nicht in Ordnung.

Ich nehme an, an der Leitungslänge des Flachbandkabels (ca 1m) vom Taster zum Arduino liegt es nicht, da in den funktionierenden Aufbauten diese länger ist, und ich ja das Signal gegen GND ziehe, um einen Schaltvorgang auszulösen.
Delay(10) und Serial print im Loop nur zu Kontrollzwecken eingefügt.

Was könnte sonst noch Ursache sein, vielleicht hat jemand eine Idee...

Danke Euch
Gruss ArduBastler

Code:

/*
  Security Timer set to 5min

  Controller: OriginalArduino NanoR3 (ATmega328P)
  Button 22mm RGB (PM221-11E) w. Resistors, momentary, to GND
*/


 //variables:


#define x 80                // high value venting (0-98)
#define y 50                // mid value venting (0-98)       
#define z 30                // low value venting (0-98)
int sec_time = 5;           // security timer (minutes)

//--------------------------------------------------------------

//constants, do not change

const byte button_vent = 7;           // venting
const byte pwmv = 9;                  // pwm pin venting
const byte vred = 3;                  // red button LED venting
const byte vgreen = 5;                // green button LED venting
const byte vblue = 6;                 // blue button LED venting
#define debounce_delay 200            // debounce time (ms)


//--------------------------------------------------------------

//program variables

bool button_vent_value;
bool button_vent_value_old;
bool timerv4;                                                              //timer states for venting
bool timerv5;
bool timerv6;
unsigned long timev4;                                                      //timer values
unsigned long timev5;
unsigned long timev6;
unsigned long secura = (sec_time * 60000);                                 // security time calculation to minutes orig:(sec_time * 60 * 1000)
const unsigned int TOP = 99;                                               //
unsigned int DutyCycle = 0;                                                // 0% Pulsweite, OCR1A <= ICR1 !!!
uint8_t button_vent_count;
const byte pin_PWM   = 9;



//--------------------------------------------------------------


//program

void setup()
{
  Serial.begin(9600);

  //sets pins as input/output
  pinMode (button_vent, INPUT_PULLUP);                  // internal pullup resistor, button to GND
  pinMode (vblue, OUTPUT);                              // blue led output to button
  pinMode (vgreen, OUTPUT);                             // green led output to button
  pinMode (vred, OUTPUT);                               // red led output to button
  pinMode(pin_PWM, OUTPUT);                             // pwm output to n-channel mosfet 
  int randomSeed(analogRead(0));
  set_Timer1();
  set_pwm_DutyCycle (DutyCycle);
}

//--------------------------------------------------------------

void loop()
{
  delay(10);
  Serial.println("button_vent_count start Loop");
  Serial.println(button_vent_count);

  //button venting check
  static uint32_t debounce_time;
  if (millis() - debounce_time > debounce_delay)
    delay(20);
  { button_vent_value = digitalRead(button_vent);
    if (button_vent_value != button_vent_value_old)
    { debounce_time = millis();
      button_vent_value_old = button_vent_value;
      if (!button_vent_value)
      { button_vent_count++;
        if (button_vent_count > 3) button_vent_count = 0;
      }
    }
  }
  if (button_vent_count == 0) venting_off();
  if (button_vent_count == 1) venting_high();
  if (button_vent_count == 2) venting_mid();
  if (button_vent_count == 3) venting_low();
  delay(10);
  Serial.println("button_vent_count End Loop");
  Serial.println(button_vent_count);

}

//--------------------------------------------------------------

void venting_off() //off, no color
{
  analogWrite(vred, 25);
  analogWrite(vgreen, 25);
  analogWrite(vblue, 25);
  set_pwm_DutyCycle (DutyCycle = 0);
  timerv4 = LOW;
  timerv5 = LOW;
  timerv6 = LOW;

}

//--------------------------------------------------------------

void venting_low() // color green
{
  if (timerv4 == LOW) {
    timerv4 = HIGH;
    timev4 = millis();
    set_pwm_DutyCycle (DutyCycle = z);
    analogWrite(vred, 0);
    analogWrite(vgreen, 35);
    analogWrite(vblue, 0);
  }
  else {
    if (millis() - timev4 > secura) {
      button_vent_count = 0;
      timerv4 = LOW;
      venting_off();
    }
  }
}

//--------------------------------------------------------------

void venting_mid() // color light blue
{
  if (timerv5 == LOW) {
    timerv5 = HIGH;
    timev5 = millis();
    set_pwm_DutyCycle (DutyCycle = y);
    analogWrite(vred, 0);
    analogWrite(vgreen, 70);
    analogWrite(vblue, 70);
  }
  else {
    if (millis() - timev5 > secura) {
      button_vent_count = 0;
      timerv5 = LOW;
      venting_off();
    }
  }
}

//--------------------------------------------------------------

void venting_high() // color blue
{
  if (timerv6 == LOW) {
    timerv6 = HIGH;
    timev6 = millis();
    set_pwm_DutyCycle (DutyCycle = x);
    analogWrite(vred, 0);
    analogWrite(vgreen, 0);
    analogWrite(vblue, 150);
  }
  else {
    if (millis() - timev6 > secura) {
      button_vent_count = 0;
      timerv6 = LOW;
      venting_off();
    }
  }
}

//--------------------------------------------------------------

void set_pwm_DutyCycle (unsigned int duty)
{
  if (duty <= TOP) {    // simple plausibility check
    OCR1A = duty;
  }
}

//--------------------------------------------------------------

void set_Timer1()
{
  cli();         // interrupts off
  TCCR1B = 0;    // Reset, stop Timer
  TCCR1A = 0;    // Reset
  TCNT1  = 0;    // Reset
  TIMSK1 = 0;    // Reset
  ICR1 = TOP;
  OCR1A = DutyCycle;   // pulse width, OCR1A <= ICR1
  TCCR1A = (1 << COM1A1);
  TCCR1B = (1 << WGM13) | (1 << CS12) | (1 << CS10); // Prescaler 1024
  sei();         // interrupts on
}

//----END OF FILE----------------------------------------------------------

Das sieht nicht gut aus:

int sec_time = 5;     
unsigned long secura = (sec_time * 60000);

Richtig:

unsigned long secura = (sec_time * 60000UL);

:slight_smile: :slight_smile:

Ich benutze eine schöne andere Formatierung...

Mein STRG-T bringt:

  if (millis() - debounce_time > debounce_delay)
    delay(20);
  {
    button_vent_value = digitalRead(button_vent);
    if (button_vent_value != button_vent_value_old)
    {
      debounce_time = millis();
      button_vent_value_old = button_vent_value;
      if (!button_vent_value)
      {
        button_vent_count++;
        if (button_vent_count > 3) button_vent_count = 0;
      }
    }
  }

Da ist - neben dem von @Serenifly festgestelltem fehlendem cast - etwas schief gegangen...

Hallo

den Tipp von Serenifly habe ich mal eingebaut, muss aber gestehen, dass ich das UL dort nicht ganz verstehe.
@my_xy_projekt , komme nicht drauf, was falsch ist, da der Sketch wie erwähnt in zwei anderen, identischen Anwendungen immer ohne Probleme läuft.
Um eine Beeinflussung durch anderen Code zu verhindern, habe ich im setup die Zeilen
//set_Timer1();
//set_pwm_DutyCycle (DutyCycle);
und die Funktionen und deren Aufrufe auskommentiert.
Das hat auch nichts gebracht.
Parallel habe ich noch Google befragt, und unteren Alternativcode auch ausprobiert.

Auch da springt mir der Zähler nach ca. 25 Sekunden auf 1, ohne dass der Taster betätigt wurde.
Ich habe auch mit debounce_delay Zeiten gespielt, um auzuschliessen, dass das Tasterprellen Einfluss nimmt,. Der Reset auf "0" erfolgt immer nach der eingestellten Zeit (zum testen 1 Minute)

Auch habe ich das ganze auf einem Breadboard aufgebaut (ja ist nicht optimal wegen Kontaktierung), mit einzel LEDs und Vorwiderständen und anderem/ kein Taster , aber auch
da ändert sich nichts.. Ich habe keine Ahnung mehr...

Code, so wie er hochgeladen wurde:

/*


  Security Timer set to 5min

  Controller: OriginalArduino NanoR3 (ATmega328P)
  Button 22mm RGB (PM221-11E) w. Resistors, momentary, to GND



*/

//Code:

//variables:


#define x 80                // high value venting (0-98)
#define y 50                // mid value venting (0-98)       
#define z 30                // low value venting (0-98)
int sec_time = 1;           // security timer (minutes)

//--------------------------------------------------------------

//constants, do not change

int button_vent = 7;                  // venting
const byte pwmv = 9;                  // pwm pin venting
const byte vred = 3;                  // red button LED venting
const byte vgreen = 5;                // green button LED venting
const byte vblue = 6;                 // blue button LED venting
#define debounce_delay 100            // debounce time (ms)


//--------------------------------------------------------------

//program variables

bool timerv4;                                                              //timer states for venting
bool timerv5;
bool timerv6;
unsigned long timev4;                                                      //timer values
unsigned long timev5;
unsigned long timev6;
unsigned long secura = (sec_time * 60000UL);                                 // security time calculation to minutes orig:(sec_time * 60 * 1000)
const unsigned int TOP = 99;                                               //
unsigned int DutyCycle = 0;                                                // 0% Pulsweite, OCR1A <= ICR1 !!!
int button_vent_count = 0;
const byte pin_PWM   = 9;
int set = 0;


//--------------------------------------------------------------


//program

void setup()
{
  //Serial.begin(9600);

  //sets pins as input/output
  pinMode (button_vent, INPUT);                         //  button to GND
  digitalWrite(button_vent, HIGH);
  pinMode (vblue, OUTPUT);                              // blue led output to button
  pinMode (vgreen, OUTPUT);                             // green led output to button
  pinMode (vred, OUTPUT);                               // red led output to button
  pinMode(pin_PWM, OUTPUT);                             // pwm output to n-channel mosfet
  
  //set_Timer1();
  //set_pwm_DutyCycle (DutyCycle);
}

//--------------------------------------------------------------

void loop()
{
  delay(10);
  //Serial.println("button_vent_count start Loop");
  //Serial.println(button_vent_count);

  //button venting check
  digitalRead(button_vent);
  delay(debounce_delay);
  if (digitalRead(button_vent) == LOW && set == 0) {
    button_vent_count++;
    set = 1;
  }
  if (digitalRead(button_vent) == HIGH && set == 1) {
    delay(debounce_delay);
    set = 0;
  }
  
  if (button_vent_count == 0) venting_off();
  if (button_vent_count == 1) venting_high();
  if (button_vent_count == 2) venting_mid();
  if (button_vent_count == 3) venting_low();
  if (button_vent_count > 3) button_vent_count = 0;
  //delay(100);
  //Serial.println("button_vent_count End Loop");
  //Serial.println(button_vent_count);

}

//--------------------------------------------------------------

void venting_off() //off, no color
{
  analogWrite(vred, 25);
  analogWrite(vgreen, 25);
  analogWrite(vblue, 25);
  //set_pwm_DutyCycle (DutyCycle = 0);
  timerv4 = LOW;
  timerv5 = LOW;
  timerv6 = LOW;

}

//--------------------------------------------------------------

void venting_low() // color green
{
  if (timerv4 == LOW) {
    timerv4 = HIGH;
    timev4 = millis();
    //set_pwm_DutyCycle (DutyCycle = z);
    analogWrite(vred, 0);
    analogWrite(vgreen, 35);
    analogWrite(vblue, 0);
  }
  else {
    if (millis() - timev4 > secura) {
      button_vent_count = 0;
      timerv4 = LOW;
      venting_off();
    }
  }
}

//--------------------------------------------------------------

void venting_mid() // color light blue
{
  if (timerv5 == LOW) {
    timerv5 = HIGH;
    timev5 = millis();
    //set_pwm_DutyCycle (DutyCycle = y);
    analogWrite(vred, 0);
    analogWrite(vgreen, 70);
    analogWrite(vblue, 70);
  }
  else {
    if (millis() - timev5 > secura) {
      button_vent_count = 0;
      timerv5 = LOW;
      venting_off();
    }
  }
}

//--------------------------------------------------------------

void venting_high() // color blue
{
  if (timerv6 == LOW) {
    timerv6 = HIGH;
    timev6 = millis();
    //set_pwm_DutyCycle (DutyCycle = x);
    analogWrite(vred, 0);
    analogWrite(vgreen, 0);
    analogWrite(vblue, 150);
  }
  else {
    if (millis() - timev6 > secura) {
      button_vent_count = 0;
      timerv6 = LOW;
      venting_off();
    }
  }
}
/*
//--------------------------------------------------------------

void set_pwm_DutyCycle (unsigned int duty)
{
  if (duty <= TOP) {    // simple plausibility check
    OCR1A = duty;
  }
}

//--------------------------------------------------------------

void set_Timer1()
{
  cli();         // interrupts off
  TCCR1B = 0;    // Reset, stop Timer
  TCCR1A = 0;    // Reset
  TCNT1  = 0;    // Reset
  TIMSK1 = 0;    // Reset
  ICR1 = TOP;
  OCR1A = DutyCycle;   // pulse width, OCR1A <= ICR1
  TCCR1A = (1 << COM1A1);
  TCCR1B = (1 << WGM13) | (1 << CS12) | (1 << CS10); // Prescaler 1024
  sei();         // interrupts on
}
*/
//----END OF FILE----------------------------------------------------------

Der Sketch ist nicht identisch mit dem aus #1.
Und ich verstehe das nicht:

if (millis() - debounce_time > debounce_delay)
    delay(20);
  {
    button_vent_value = digitalRead(button_vent);

und meine, das das nicht das macht, was Du willst.

Das delay(20) ist vollkommen überflüssig und ist auch das einzige was Du mit der vorherigen Bedingung beeinflussen kannst.
Alles was danach kommt eben nicht.

Hallo
Welcher von den beiden Sketchen ist aktuell?
Und was soll der Sketch bewirken?
Einfach mal mit einfachen Worten beschreiben und das ganze einfach.
Ich wünsche einen geschmeidigen Tag und viel Spass beim Programmieren in C++.
p.s.
Das läßt sich bestimmt ganz einfach in C++ programmieren, da sich Codeblöcke wiederholen.

Hallo
@my_xy_projekt, richtig, habe ich aber erwähnt
#4 ist der, mit dem ich jetzt experimentiert habe, eben der Alternativcode.
Der aus #1 ist bei 3 anderen Geräten drauf und läuft...

Funktion:
Der Taster soll zwischen 4 (3 Stufen und aus) die Werte x, y, z umschalten und als PWM Signal mit 79 Hz ausgeben. Die 79 Hz und die Beschaltung sind vom angeschlossenen Lüfter vorgegeben, dieser hat Vcc, GND und PWM, wobei PWM mit einem MOSFET vom Arduino gegen GND geschaltet wird. Die im Taster eingebauten LED geben eine visuelle Rückmeldung der 3 Stufen, blau, hellblau, grün. "Aus" weiss, damit wird gestartet.

Ursprung des ganzen war: Problem mit PWM Frequenz und Chrono - Deutsch - Arduino Forum

Daraus folgte: Timerregister benutzen (Nano)

@paulpaulson, ich kann leider kein C++, Arduino ist soweit die einzige "Programmiersprache", mit der ich mich etwas befasse..

Nur zu Info Du benutzt C und C++ das ist die Arduino Programiersprache :wink:

Der default Datentyp ist int. int * int ist int. Was links vom Gleichheitszeichen steht interessiert erst mal nicht. Das läuft daher mit deinen Werten sofort über. Durch das UL wird auch in unsigned long gerechnet.

Es kann sein dass der Compiler unter gewissen Umständen (vor allem wenn alles konstant ist) gleich merkt dass 60000 ist eigentlich long sein muss und das anpasst. Aber darauf sollte man sich nicht verlassen.

Das wird aber auch nicht der eigentliche Fehler sein

Du programmierst hier in C++. Es gibt keine Arduino Sprache. Die Arduino Software ist eine API die in C++ geschrieben ist

Wie schon mehrfach gesagt: Die Programmiersprache ist C++ mit vielen hardwarespezifischen "Arduino"- Funktionen. Außerdem gibt es sehr viele Bibliotheken mit funktionen für Sensoren und Aktoren.

C++ erlaubt es Funktionen zu bauen die wie Funktionen von C++ und dessen Bibliotheken verwendet werden.

Grüße Uwe