Blinkzeiten für Knopfdruck

Hallo Forenmitglieder, nachdem mir Anfang des Jahres mit der Soundmaschine so toll geholfen wurde, naht jetzt die Ausbaustufe mit einer blinkenden Feuerwehr zum passenden Sound. Die Feuerwehr blinkt dank des Sketches aus den MoBaTools auch sehr schön mit Blaulichtblitzen, aber ich würde das jetzt gerne mit dem Feuerwehrsound aus der Soundmaschine kombinieren.
Meine Gedanken dazu waren einfach den Attiny mit dem Licht an den Drücker der den Feuerwehrsound auslöst zu löten und somit beide Sketche auf den beiden Attinys parallel zu starten und ablaufen zu lassen. Ich würde das Blinken also gerne auf Knopfdruck nur für eine einstellbare Zeit laufen lassen.


```cpp
// ATMEL ATtiny85 1 MHz
//
//                 +-\/-+
//         Reset  1|    |8  Vcc
// Ain3 (D3) PB3  2|    |7  PB2 (D2) Ain1
// Ain2 (D4) PB4  3|    |6  PB1 (D1) pwm1
//           GND  4|    |5  PB0 (D0) pwm0
//                 +----+
//

byte led0Pin= 1;
byte led1Pin= 2;
byte led2Pin= 3;
byte led3Pin= 4;

class Blink {
private: 
  unsigned long prevtime;
  unsigned int zyklus;
  unsigned int an;
public:
   Blink(unsigned int _an, unsigned int _zyklus) { zyklus=_zyklus; an = _an;}
   boolean currentState () {
     // sollte häufig aufgerufen werden, damit der jeweils aktuelle Zustand zurückgeliefert wird
     if (millis() - prevtime >= zyklus) {
       prevtime = millis();
     }
     if (millis() - prevtime < an) return true;
     else return false;
   } 
};
Blink wechsel(600,1000);
Blink wechsel1(900,1300); 
Blink schnell(30,300); 
Blink mittel(50,350);

void setup()
{
  pinMode ( led0Pin,OUTPUT);
  pinMode ( led1Pin,OUTPUT);
  pinMode ( led2Pin,OUTPUT);
  pinMode ( led3Pin,OUTPUT);
  
  }

void loop() {
   digitalWrite(led0Pin, wechsel.currentState() );
   digitalWrite(led1Pin, wechsel1.currentState() );
   digitalWrite(led2Pin, schnell.currentState() );
   digitalWrite(led3Pin, mittel.currentState() );
}

Habt ihr eine Idee für mich, wie ich den Tastern so einbinden kann dass ein einmaliges drücken reicht und der Sketch dann für n Sekunden läuft?

Danke und Gruss
Prenzi

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Hast Du Probleme mit der Formatierung innerhalb des Forums? Das geht besser :wink:

Meinen ATtiny85 habe ich zunächst in der Bastelkiste gelassen und mit einem UNO probiert.

Hilfreich ist eine Schrittkette (=finite state machine; =endlicher Automat), die zwar ständig innerhalb loop durchlaufen wird, aber doch nur teilweise aktiv ist:

Programm für UNO
// ATMEL ATtiny85 1 MHz
//
//                 +-\/-+
//         Reset  1|    |8  Vcc
// Ain3 (D3) PB3  2|    |7  PB2 (D2) Ain1
// Ain2 (D4) PB4  3|    |6  PB1 (D1) pwm1
//           GND  4|    |5  PB0 (D0) pwm0
//                 +----+
//

const byte tasterPin = A0; //0;
const byte led0Pin = 2; //1;
const byte led1Pin = 3; //2;
const byte led2Pin = 4; //3;
const byte led3Pin = 5; //4;
const uint32_t BLINKDAUER = 5000; // in ms

class Blink {
  private:
    unsigned long prevtime;
    unsigned int zyklus;
    unsigned int an;
  public:
    Blink(unsigned int _an, unsigned int _zyklus) {
      zyklus = _zyklus;
      an = _an;
    }
    boolean currentState () {
      // sollte häufig aufgerufen werden, damit der jeweils aktuelle Zustand zurückgeliefert wird
      if (millis() - prevtime >= zyklus) {
        prevtime = millis();
      }
      if (millis() - prevtime < an) return true;
      else return false;
    }
};
Blink wechsel(600, 1000);
Blink wechsel1(900, 1300);
Blink schnell(30, 300);
Blink mittel(50, 350);

void setup()
{
  pinMode ( tasterPin, INPUT_PULLUP);
  pinMode ( led0Pin, OUTPUT);
  pinMode ( led1Pin, OUTPUT);
  pinMode ( led2Pin, OUTPUT);
  pinMode ( led3Pin, OUTPUT);
}

void loop()
{
  static uint32_t vorhin = 0;
  static byte schritt = 0;
  switch (schritt)
  {
    case 0:
      if (!digitalRead(tasterPin))
      {
        vorhin = millis();
        schritt++;
      }
      break;
    case 1:
      digitalWrite(led0Pin, wechsel.currentState() );
      digitalWrite(led1Pin, wechsel1.currentState() );
      digitalWrite(led2Pin, schnell.currentState() );
      digitalWrite(led3Pin, mittel.currentState() );
      if (millis() - vorhin >= BLINKDAUER)
      {
        digitalWrite(led0Pin, 0 );
        digitalWrite(led1Pin, 0 );
        digitalWrite(led2Pin, 0 );
        digitalWrite(led3Pin, 0 );
        schritt = 0;
      }
      break;
  }
}

Läuft das auch auf einem ATtiny85?

Hi @agmue ,

hatte die Schaltung gerade in Wokwi umgesetzt, aber Du warst schneller mit dem Code ... :wink:

Daher:

  • Meine Schaltung
  • Dein Sketch

bei Wokwi zum Testen und bei Bedarf noch anpassen:

https://wokwi.com/projects/411372918181471233

Gruß
ec2021

1 Like

Das nenne ich gute Zusammenarbeit :clap:

wenn es schon so eine Timer Klasse gibt, dann erweitert sie doch und nehmt sie her:

/*
  Forum: https://forum.arduino.cc/t/blinkzeiten-fur-knopfdruck/1309961/2
  Wowki: https://wokwi.com/projects/411372918181471233

  Schaltung: ec2021
  Sketch:    agmue
  Sketch2:   noiasca

  Stand: 2024/10/10 

*/


// ATMEL ATtiny85 1 MHz
//
//                 +-\/-+
//         Reset  1|    |8  Vcc
// Ain3 (D3) PB3  2|    |7  PB2 (D2) Ain1
// Ain2 (D4) PB4  3|    |6  PB1 (D1) pwm1
//           GND  4|    |5  PB0 (D0) pwm0
//                 +----+
//

const byte tasterPin = 5;
const byte led0Pin = 1;
const byte led1Pin = 2;
const byte led2Pin = 3;
const byte led3Pin = 4;
const uint32_t BLINKDAUER = 5000; // in ms

class Blink {
  private:
    unsigned long prevtime;
    unsigned int zyklus;
    unsigned int an;
  public:
    Blink(unsigned int _an, unsigned int _zyklus) {
      zyklus = _zyklus;
      an = _an;
    }
    boolean currentState () {
      // sollte häufig aufgerufen werden, damit der jeweils aktuelle Zustand zurückgeliefert wird
      if (millis() - prevtime >= zyklus) {
        prevtime = millis();
      }
      if (millis() - prevtime < an) return true;
      else return false;
    }

    void start () {
      prevtime = millis();
    }
};
Blink wechsel(600, 1000);
Blink wechsel1(900, 1300);
Blink schnell(30, 300);
Blink mittel(50, 350);

Blink timer (1, BLINKDAUER);   // 1 mal für Blinkdauer

void setup()
{
  pinMode ( tasterPin, INPUT_PULLUP);
  pinMode ( led0Pin, OUTPUT);
  pinMode ( led1Pin, OUTPUT);
  pinMode ( led2Pin, OUTPUT);
  pinMode ( led3Pin, OUTPUT);
}

void loop()
{
  static byte schritt = 0;
  switch (schritt)
  {
    case 0:
      if (digitalRead(tasterPin) == LOW)
      {
        timer.start();
        schritt++;
      }
      break;
    case 1:
      digitalWrite(led0Pin, wechsel.currentState() );
      digitalWrite(led1Pin, wechsel1.currentState() );
      digitalWrite(led2Pin, schnell.currentState() );
      digitalWrite(led3Pin, mittel.currentState() );
      if (timer.currentState())
      {
        digitalWrite(led0Pin, 0 );
        digitalWrite(led1Pin, 0 );
        digitalWrite(led2Pin, 0 );
        digitalWrite(led3Pin, 0 );
        schritt = 0;
      }
      break;
  }
}

Habe Deiner Änderung eine neue "Heimat" bei Wokwi gegeben:

https://wokwi.com/projects/411375371540395009

:wink:

1 Like

Vielen Dank an alle freundlichen Helfer!!!!!!!
Habe alle 3 Sketche erfolgreich ausprobiert, damit werde ich jetzt hoffentlich einen Schritt weiter kommen..... nur habe ich Dulli in der Aufregung des ersten Blinkens die Elektronik in der Feuerwehr untergebracht und das Gehäuse wieder zugeklebt.... :woozy_face:
Na irgendwie werde ich da schon wieder rankommen und bin gespannt auf die Reaktion vom Enkel wenn er den Knopf zum ersten Mal drückt!
VG Prenzi

Danke, aber das "Lösungslob" gehört eigentlich @agmue und @noiasca ... :wink:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.