Neopixel 2 verschiedene loops

Hallo Zusammen,

folgender Code habe ich auf das Wesentliche gekürzt. Er ist ein Ausschnitt aus einer Textuhr, die verschiedene Farben anzeigen kann. Jetzt möchte ich noch Musik von einem mp3-Modul hinzu fügen. Im loop sieht man verschiedene if-Abfragen für die Farben und Musik.

Hier wird das Problem deutlich. Bei data == 1 und lichtmodus == 6 soll die Lichterkette weiss sein. Eine Lichterabfolge (bucht() und buchu()) soll blinken und dabei soll ein Lied vom mp3-Modu durchlaufen.

Problem! Alle 2 Sekunden startet das Lied von vorne. Wie kann ich das ändern?

  //Modus 0 = Licht weiss _________________________________________________________________
  if (data == "1" && lichtmodus == 6 ) {
    red = 255;
    green = 255;
    blue = 255;
    bucht();
    buchu();
    play3();

Erweiterter Code:

#include "SoftwareSerial.h"
SoftwareSerial mySerial(16, 0);  // 16 ist D0 entspricht D10-Kabel , 0 ist D3 enspricht D11-Kabel
# define Start_Byte 0x7E
# define Version_Byte 0xFF
# define Command_Length 0x06
# define End_Byte 0xEF
# define Acknowledge 0x00 //Returns info with command 0x41 [0x01: info, 0x00: no info]

# define ACTIVATED LOW


//usw. zur Uebersicht gekuerzt

void loop()
{


  //Farbwechsel
  //Abfrage ob der Taster gedrückt ist
  tasterStatus = digitalRead(tasterPin);

  //Wenn Taster gedrückt ist...
  if (tasterStatus == HIGH)
  {
    lichtmodus++;
    delay(300);
  }
  if (lichtmodus == 0) {
    play();
    delay(2000);
    lichtmodus++;
    digitalWrite(15, LOW);
    goto zeitmodus;
  }
  else if (lichtmodus == 1) {
zeitmodus:
    red = 255;
    green = 255;
    blue = 255;
    uhrzeit();
    digitalWrite(15, LOW);
  }
  else if (lichtmodus == 2) {
    red = 0;
    green = 255;
    blue = 0;
    uhrzeit();
    digitalWrite(15, LOW);
  }
  else if (lichtmodus == 3) {
    red = 0;
    green = 0;
    blue = 255;
    uhrzeit();
    digitalWrite(15, LOW);
  }
  else if (lichtmodus == 4) {
    red = 255;
    green = 0;
    blue = 0;
    uhrzeit();
    digitalWrite(15, LOW);
  }
  else if (lichtmodus == 5) {
    digitalWrite(15, HIGH);
    play2();
    delay(1500);
    lichtmodus++;
    goto appmode;
  }
  else if (lichtmodus == 6) {
appmode:
    digitalWrite(15, HIGH);
    delay(500);
    digitalWrite(15, LOW);
    delay(500);
  }

  //Anzahl der Leuchtmodi auf 6 begrenzen (0 bis 6)
  else
  {
    lichtmodus = 1;
  }


  //Modus 0 = Licht weiss _________________________________________________________________
  if (data == "1" && lichtmodus == 6 ) {
    red = 255;
    green = 255;
    blue = 255;
    uhrzeit();
    bucht();
    buchu();
    play3();
  }


  //Modus 1 = blau_________________________________________________Grün_________________
  else if (data == "2" && lichtmodus == 6 )
  {
    red = 0;
    green = 0;
    blue = 255;
    uhrzeit();
    bucht();
    buchu();
    play4();
  }

  //Modus 1 = Grün_________________
  else if (data == "g" && lichtmodus == 6 )
  {
    red = 0;
    green = 255;
    blue = 0;
    uhrzeit();
    bucht();
    buchu();
    play5();
  }

  //Modus 1 = rot_________________
  else if (data == "r" && lichtmodus == 6 )
  {
    red = 255;
    green = 0;
    blue = 0;
    uhrzeit();
    bucht();
    buchu();
    play5();
  }

  delay(800);                                    // Wait 800ms

}
}


void play()
{
  execute_CMD(0x03, 0, 1);
  delay(1000);
}
void play2()
{
  execute_CMD(0x03, 0, 2);
  delay(1000);
}
void play3()
{
  execute_CMD(0x03, 0, 3);
  delay(1000);
}
void play4()
{
  execute_CMD(0x03, 0, 4);
  delay(1000);
}
void play5()
{
  execute_CMD(0x03, 0, 5);
  delay(1000);
}

void setVolume(int volume)
{
  //execute_CMD(0x06, 0, volume); // Set the volume (0x00~0x30)
  execute_CMD(0x20, 0, volume); // Set the volume (0x00~0x30)
  delay(2000);
}
void pause()
{
  execute_CMD(0x0E, 0, 0);
  delay(500);
}

void execute_CMD(byte CMD, byte Par1, byte Par2)
// Excecute the command and parameters
{
  // Calculate the checksum (2 bytes)
  word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);
  // Build the command line
  byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,
                            Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte
                          };
  //Send the command line to the module
  for (byte k = 0; k < 10; k++)
  {
    mySerial.write( Command_line[k]);


  }
  void bucht() {
    pixels.setPixelColor(29, pixels.Color(255, 0, 0));
    pixels.setPixelColor(34, pixels.Color(255, 0, 0));
    pixels.setPixelColor(49, pixels.Color(255, 0, 0));
    pixels.setPixelColor(54, pixels.Color(255, 0, 0));
    pixels.setPixelColor(69, pixels.Color(255, 0, 0));
    pixels.setPixelColor(74, pixels.Color(255, 0, 0));
    pixels.setPixelColor(89, pixels.Color(255, 0, 0));
    pixels.setPixelColor(55, pixels.Color(255, 0, 0));
    pixels.setPixelColor(56, pixels.Color(255, 0, 0));
    pixels.setPixelColor(57, pixels.Color(255, 0, 0));
    pixels.setPixelColor(58, pixels.Color(255, 0, 0));
    pixels.setPixelColor(59, pixels.Color(255, 0, 0));
    pixels.setPixelColor(60, pixels.Color(255, 0, 0));
    pixels.show();
    delay(1000);
  }
  void buchu() {
    pixels.setPixelColor(24, pixels.Color(255, 0, 0));
    pixels.setPixelColor(25, pixels.Color(255, 0, 0));
    pixels.setPixelColor(26, pixels.Color(255, 0, 0));
    pixels.setPixelColor(27, pixels.Color(255, 0, 0));
    pixels.setPixelColor(28, pixels.Color(255, 0, 0));
    pixels.setPixelColor(29, pixels.Color(255, 0, 0));
    pixels.setPixelColor(89, pixels.Color(255, 0, 0));
    pixels.setPixelColor(88, pixels.Color(255, 0, 0));
    pixels.setPixelColor(87, pixels.Color(255, 0, 0));
    pixels.setPixelColor(86, pixels.Color(255, 0, 0));
    pixels.setPixelColor(85, pixels.Color(255, 0, 0));
    pixels.setPixelColor(84, pixels.Color(255, 0, 0));
    pixels.setPixelColor(80, pixels.Color(255, 0, 0));
    pixels.setPixelColor(63, pixels.Color(255, 0, 0));
    pixels.setPixelColor(60, pixels.Color(255, 0, 0));
    pixels.setPixelColor(43, pixels.Color(255, 0, 0));
    pixels.setPixelColor(40, pixels.Color(255, 0, 0));
    pixels.show();
    delay(1000);
  }
}

Gruß,
Merzo

a) versiehe deinen Code mit Serial.Print Ausgaben damit du siehst was dein Code macht - in welches If er gesprungen ist.

b) ich gehe davon aus, dass (data == "1" && lichtmodus == 6 ) immer noch True ist, daher wird wieder play3 gestartet.

c) ich glaube jetzt ist es an der Zeit dass du deinen Code entwirrst, delay entfernst etc.

a) Im seriellen Monitor sehe ich die passenden ifs.

b) (data == "1" && lichtmodus == 6 ) trifft immer noch zu. Mir ist schon klar, dass so der loop immer von Vorne startet. Muss er ja auch, da ich die Farbe beibehalten möchte bzw. die Lichterkombination bucht() und buchu() abwechselnd aufleuchtet. Aber wie kann ich trotzdem ein Lied von ca. 1 Minute zeitgleich abspielen lassen?

c) Hat das Entfernen der delays einen Einfluss auf das Lied? Wie kann ich ein delay ersetzen? Durch millies?

Gruß, Merzo

b) im Prinzip brauchst du die Farbe nur einmal stellen wenn sie sich ändern soll, du brauchst das nicht permanent aufrufen wenn es immer noch gleich sein soll. Also Umbauen, dass entweder nur mehr bei Änderung aufruft, oder wenn der Song nur einmal aufgerufen werden soll, diesen wieder über eine eigene Status-Variable abfangen. Spätenstens jetzt wirds aber Spaghetti-Code wenn du nun nicht zusammenräumst.

c) das Entfernen des delays hat vermutlich massiven Einfluss auf deinen Code, er wird dadurch nicht blockierend. Ob du jedes Delay mit millis() ersetzen sollst bezweifle ich. Was soll denn das Delay(1000) nach dem Abspielen bringen? Welches Soundmodul verwendest du (anklickbaren Link setzen!)?