Zwei Sketches kombinieren klappt nicht

Ich habe zwei Sketches, bei dem einen werden LEDs in bestimmer Abfolge eingeschaltet und ausgeschaltet.
Der zweite Sketch erzeugt einen Ton auf einem passiven Piezo-Buzzer Modul.
Ich bekomme es nicht hin, dass der Ton dauerhaft erzeugt wird wenn ich beide kombiniere.
Hat jemand da einen Tip Für mich?
LED Sketch:

int led1 = 5; 
int led2 = 7; 
int led3 = 9; 
int led4 = 11; 


void setup() {


pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
}


void loop() 
{

//Light Status 1
digitalWrite(led4, HIGH); 

digitalWrite(led1, HIGH); 
delay(600); 

digitalWrite(led1, LOW); 
delay(600); 

//Light Status 2
{digitalWrite(led2, HIGH);
delay(600);

digitalWrite(led2, LOW);
delay(600);}

//Light Status 3
{digitalWrite(led3, HIGH);
delay(600);

digitalWrite(led3, LOW);
delay(600);}

//Light Status 4
{digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
delay(600);

digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
delay(600);}

//Light Status 5
{digitalWrite(led1, HIGH);
digitalWrite(led3, HIGH);
delay(600);

digitalWrite(led1, LOW);
digitalWrite(led3, LOW);
delay(600);}

//Light Status 6
{digitalWrite(led3, HIGH);
delay(600);

digitalWrite(led3, LOW);
delay(600);}

//Light Status 7
{digitalWrite(led1, HIGH);
delay(600);

digitalWrite(led1, LOW);
delay(600);}

//Light Status 8
{digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
delay(600);

digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
delay(600);}

//Light Status 9
{digitalWrite(led1, HIGH);
digitalWrite(led3, HIGH);
delay(600);

digitalWrite(led1, LOW);
digitalWrite(led3, LOW);
delay(600);}

}

Ton Sketch:

int buzzer = 8; //Spezifiziert den Buzzer Pin


void setup() {


  pinMode(buzzer, OUTPUT);
}


void loop() {



  unsigned char i;
  while (1)
  {

    //Frequenz 1
    for (i = 0; i < 80; i++)
    {
      digitalWrite (buzzer, HIGH) ;
      delay (1) ;
      digitalWrite (buzzer, LOW) ;
      delay (1) ;
    }
    //Frequenz 2
    for (i = 0; i < 100; i++)
    {
      digitalWrite (buzzer, HIGH) ;
      delay (2) ;
      digitalWrite (buzzer, LOW) ;
      delay (2) ;
    }
  }

}

Dann zeig doch mal den kombinierten Sketch, dann sieht man vielleicht den Fehler.

DrBeshir:
Hat jemand da einen Tip Für mich?

Wenn Du quote durch code ertsetzt, wird der Code lesbarer.
Das kannst Du auch nachträglich noch editieren.

Gruß Tommy

Danke für den Tip mit dem Code.

Ich habe diverse Ansätze probiert, einzig ein Ticken konnte ich dem Piezo Buzzer dann entlocken.
Ich kann gerne einen meiner erfolgreicheren Sketche posten.

Hat jemand da einen Tip Für mich?

Ja!

Sogar 2 Tipps.

  1. Verzichte auf delay().
  2. Mache deinen Ton in einem Timer Interrupt.

Hi

Während delay() macht der Arduino nicht mehr viel - in Deinem LED-Sketch wartest Du 600ms - gleichzeitig willst Du aber im 1ms-Takt den Piezo ansteuern.

Deine Lösung heißt (wie eigentlich immer) State-Maschine.
In Deiner loop() prüfst Du in jedem Durchlauf, ob 'jetzt gerade' die Zeit um ist, den Piezo umzusteuern - wenn nicht, dann eben nicht.
Wenn doch, dann doch und Du merkst Dir die aktuelle Zeit.
Gleiches für die LED-Geschichte - in JEDEM loop()-Durchlauf prüfst Du, ob z.B. diese 600ms um sind.
Das sollte so schnell wie möglich durchlaufen werden, wenn also Nichts zu tun ist, tust Du: Nichts - auch kein delay()!!
Dadurch wird loop() erneut durchlaufen, erneut geprüft, erneut Nichts getan, oder der Piezo umgesteuert oder die LEDs umgeschaltet.
Du musst Dir 'nur' merken, wann Du Was zuletzt gemacht hast.

Dazu noch etwas Lesestoff - combie zum Thema State-Maschine

MfG

PS: Bei 1ms Abstand sollte noch kein Timer nötig sein, zumindest, wenn nicht mehr dazu kommt.

Während delay() macht der Arduino nicht mehr viel

Genaugesagt macht der Arduino nichts anderes als warten.

Grüße Uwe

uwefed:
Genaugesagt macht der Arduino nichts anderes als warten.

Naja...
I2C Anfragen werden, auch während ein delay() wartet, beantwortet.
Ebenso, Serielle Eingaben gepuffert.
Auch wird yield() andauernd aufgerufen.
Die Timer mit ihren ISRs laufen unbeeindruckt weiter.
usw.

z.B. könnte man den Ton in yield() oder einer Timer ISR erzeugen, unter Beibehaltung der anderen delay()


Aber auf solche Ideen kommt man wohl erst, während man lernt auf delay() zu verzichten.

Guten Morgen und vielen Dank schonmal. Ich werde mich da mal einlesen, Momentan übersteigt das offensichtlich meine Fähigkeiten.
Ich werde mich auf state machines und yiel() konzentrieren.

DrBeshir:
Ich werde mich auf state machines und yiel() konzentrieren.

Meine Empfehlung wäre state machines und millis().

Soweit bin ich nun:

class Flasher
{
  
  int ledPin;      
  long OnTime;     
  long OffTime;    

  
  int ledState;                 
  unsigned long previousMillis;   

 
  public:
  Flasher(int pin, long on, long off)
  {
  ledPin = pin;
  pinMode(ledPin, OUTPUT);     
    
  OnTime = on;
  OffTime = off;
  
  ledState = LOW; 
  previousMillis = 0;
  }

  void Update()
  {
    
    unsigned long currentMillis = millis();
     
    if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
    {
      ledState = LOW;  
      previousMillis = currentMillis;  
      digitalWrite(ledPin, ledState);  
    }
    else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
    {
      ledState = HIGH;  
      previousMillis = currentMillis;   
      digitalWrite(ledPin, ledState);   
    }
  }
};


Flasher led1(2, 600, 400);
Flasher led2(3, 350, 350);
Flasher led3(4, 600, 400);
Flasher led4(5, 0, 0);
Flasher buzzer1(6, 1000, 1);
Flasher buzzer2(6, 1, 5);

void setup()
{

}

void loop()
{
  led1.Update();
  led2.Update();
  led3.Update();
  led4.Update();
  buzzer1.Update();
  buzzer2.Update();
}

Immerhin blinkt und buzzt es jetzt gemeinsam.
Aber ich weiß immer noch nicht wie ich das timing der LEDs richtig einstelle und auch den Frequenzwechsel des Buzzers.

DrBeshir:
Immerhin blinkt und buzzt es jetzt gemeinsam.
Aber ich weiß immer noch nicht wie ich das timing der LEDs richtig einstelle und auch den Frequenzwechsel des Buzzers.

Das sieht doch schon ganz gut aus.

Leider verstehe ich Deine Frage nicht. Würde es Dir möglicherweise helfen, der Methode einen Parameter zu übergeben?

Ich habe ja zu Anfang mehrere LED Sequenzen. Die könnte ich hinbekommen indem ich einfach unter void loop die Positionen eintrage und austesten. Also LED1 On=x Off=x dann LED1(2) On=X Off=x

Für den Buzzer verstehe ich noch nicht ganz was das ist : unsigned char i;
while (1) und das: for (i = 0; i < 80; i++) und wie ich es dann unterbringe.

while (1) heißt bei Arduino loop(), es ist die Schleife.

Die Zeiten nicht als Konstanten, sondern als Variablen übergeben oder Blöcke von Konstanten über einen Index ansprechen. Das Weitergehen zum nächsten Block/Index dann mit der finite state machine (= Schrittkette = endlicher Automat).

Die Zeiten in Felder oder Felder von Strukturen unterbringen.

Nur mal grob skizziert.

agmue:
Die Zeiten nicht als Konstanten, sondern als Variablen übergeben oder Blöcke von Konstanten über einen Index ansprechen. Das Weitergehen zum nächsten Block/Index dann mit der finite state machine (= Schrittkette = endlicher Automat).

Die Zeiten in Felder oder Felder von Strukturen unterbringen.

Nur mal grob skizziert.

Keine Ahnung wie man das macht. Hättest du einen link zu einer Erklärung? Ich bin noch recht unerfahren und arbeite mich Schritt für Schritt vor.

Wenn Du hier im Forum nach "agmue anleitung" suchst, dann findest Du Anleitungen, die ich als Anfänger geschrieben habe. Erwarte bitte keine Perfektion!

Im Thema OOP mit einem Kringel zu viel? findest Du in #0 switch (schritt), das ist die Schrittkette, die ich gerne mittels switch/case realisiere. loop() ist blockadearm programmiert.

Bitte schaue, ob Du irgendwas davon gebrauchen kannst.

Super! Dank dir! Klar, ich als Anfänger erwarte Perfektion :grin:

DrBeshir:
Super! Dank dir! Klar, ich als Anfänger erwarte Perfektion :grin:

Was denn sonst :grin:

Unter meinem Avatar-Bild findest Du Angaben zur Quantität, nicht zur Qualität. Das gilt auch für meine Frühwerke, die ich aber möglicherweise gerade wegen mangelnder Perfektion immer noch nützlich finde. Nur geben sie halt nicht unbedingt meinen derzeitigen Wissensstand wider.

Ich hoffe, Du verstehst, was ich sagen wollte.

Hi

@DrBeshir
Wow, schöner Sketch!
Habe mir gestattet, Diesen in meinen Sketch-Ordner einzugliedern - klar, nicht ohne Änderungen :wink:
Meine Anpassungen belaufen sich auf

  • Datentyp byte für die Pins (spart ein Byte Platz zu int)
  • LED-Status als boolean (kein Platzgewinn, kann aber nur 0/1/false/true/low/high annehmen)
  • uint32_t statt unsigned long (ist aber das Gleiche)
  • lastMillis statt previousMillis (darin fehlt mir immer das S ... bei 'last' klappt Das besser)
  • wenn ich mich nicht verhaspelt habe, die Umschaltung in nur einer IF - Test steht aus.
  • entfernen einiger Leerzeilen :wink:

Alles in Allem ein schönes Stück Software, gefällt mir!
Als Quelle wird darin Dein Beitrag mit Deinem Sketch ver-url-t - Ehre, Wem Ehre gebührt.

MfG

postmaster:

  • Datentyp byte für die Pins (spart ein Byte Platz zu int)

[b]const byte [/b]ist generell nochmal besser.

Nur zur Erinnerung: const class members werden über eine Initialisierungsliste im c'tor gesetzt.

Kennst sicher noch die combiePin library, die sowas in einen template Parameter auslagert und die (in der Regel unnötige) Arduino-Flexibilität mit variabler Pin-Nummer und Bedeutung wegoptimieren hilft.

Ich hoffe, ich habe da einen einigermaßen aktuellen Link wiedergefunden.