Startampel mit Arduino R3 und der Software Z-Round

Ich seh später nochmal drauf, dass man das anders baut.
Denn in dem Moment, wo Du das $STARTbekommst, bist Du mit allem anderen raus, weil die ganze Abhandlung blockierend programmiert ist.
Also solange die Ampel läuft kein Blinken, keine Temperatur und keine Feuchte etc.

Wenn das deine Zeit erlaubt nehme ich natürlich deine Hilfe an.

Moin Moin

Hast du ( my xy projekt ) schon eine Idee ?

Mit freundlichen Grüßen

Ja, bin ich grad dran - das aufzulösen dauert aber nen Moment. Ich mach das auf nem Netbook...

Echt klasse :+1:

Moin Moin

Wollte mal hören in du schon weiter gekommen bist ?

Gruß

Moin

Ich wollte mal horchen ob ob du schon eine Lösung gefunden hast?

Gruß

AAH! Sorry, hab Dich vollkommen aus dem Auge verloren...
Ja, der Ansatz ist da - Es muss nur eine Menge umgeschrieben werden, da mit der Auflösung der delays eine Schrittkette gebaut werden muss, die auch inhaltlich noch mit Pausen versehen ist.
Gescheitert bin ich u.a. an dem französisch.


Mal sehen, ob es mir gelingt zu verstehen was da passieren soll.
Ich nehm das nochmal in die Hand.

Moin Moin.

Gibt es schon einen Lösungsansatz?

Gruß

Hallo

Ich wollte nochmal nachfragen, ob es irgendwie möglich ist.

Gruß

Als Unkundiger hinsichtlich Z-Round stellt sich mir die Frage, was möglich sein soll.

Programm als Ausgangspunkt zum Testen
#include <Adafruit_NeoPixel.h>
#include <Wire.h>

//=====[ CONSTANTS ]============================================================
#define CMD_START    "$START"
#define CMD_STOP     "$STOP"
#define ANTWORT_GO   "$GO"
#define STARTZEIT    1000
#define BLINKZEIT    500
#define BLINKZAHL    10
#define bSize        64
#define ANZAHL_PIXEL 10

//=====[ PINS ]=================================================================
#define PIN 6  // LED-Streifen

//=====[ VARIABLES ]============================================================
Adafruit_NeoPixel strip = Adafruit_NeoPixel(ANZAHL_PIXEL, PIN, NEO_GRB + NEO_KHZ800);
uint32_t SCHWARZ = 0x000000;
uint32_t ROT     = 0xFF0000;
uint32_t GRUEN   = 0x00FF00;
uint32_t GELB    = 0xFFFF00;

//=====[ ReadSerialCommand ]====================================================
byte readSerialCommand(void)
{
  char buffer[bSize];        // Serial buffer
  byte commandtyp = 255;
  Serial.setTimeout(10);
  size_t bytesCount = Serial.readBytesUntil('\n', buffer, bSize - 1);
  if (bytesCount  > 0)
  {
    buffer[bytesCount] = '\0';
    if (strcmp(buffer, CMD_STOP) == 0) commandtyp = 0;
    else if (strcmp(buffer, CMD_START) == 0) commandtyp = 1;
  }
  return commandtyp;
}

//=====[ Lights ]=============================================================
bool lightsSTOP()
{
  uint32_t jetzt = millis();
  static uint32_t vorhin = -BLINKZEIT;  // Sofortstart
  static byte blinkzahl = BLINKZAHL;
  bool fertig = false;
  static byte pixel = 0;
  static byte schritt = 0;

  if (jetzt - vorhin >= BLINKZEIT)
  {
    vorhin = jetzt;
    switch (schritt)
    {
      case 0:
        strip.fill(SCHWARZ, 0, ANZAHL_PIXEL);
        if (!--blinkzahl)
        {
          blinkzahl = BLINKZAHL;
          vorhin = 0;
          fertig = true;
        }
        else
        {
          strip.fill(ROT, 0, ANZAHL_PIXEL / 2);
          schritt++;
        }
        strip.show();
        break;
      case 1:
        strip.fill(SCHWARZ, 0, ANZAHL_PIXEL);
        strip.fill(GELB, ANZAHL_PIXEL / 2, ANZAHL_PIXEL);
        strip.show();
        schritt = 0;
        break;
    }
  }
  return fertig;
}

bool lightsSTART()
{
  uint32_t jetzt = millis();
  uint32_t intervall = STARTZEIT;
  static uint32_t vorhin = -intervall;  // Sofortstart
  bool fertig = false;
  static byte pixel = 0;
  static byte schritt = 0;

  if (jetzt - vorhin >= intervall)
  {
    vorhin = jetzt;
    switch (schritt)
    {
      case 0:
        strip.fill(SCHWARZ, 0, ANZAHL_PIXEL);
        strip.fill(ROT, 0, ++pixel);
        strip.show();
        if (pixel == 5)
        {
          intervall = random(200, intervall);
          schritt++;
        }
        break;
      case 1:
        Serial.println(ANTWORT_GO);
        strip.fill(SCHWARZ, 0, ANZAHL_PIXEL);
        strip.fill(GRUEN, 5, ANZAHL_PIXEL);
        strip.show();
        intervall = STARTZEIT;
        pixel = 0;
        schritt = 0;
        fertig = true;
        break;
    }
  }
  return fertig;
}

//=====[ LOOP ]===============================================================
void loop() {
  byte commandtyp = readSerialCommand();
  static byte schritt = 255;

  if ( commandtyp == 0) schritt = 0;
  if ( commandtyp == 1) schritt = 1;

  switch (schritt)
  {
    case 0:
      if (lightsSTOP()) schritt = 255;
      break;
    case 1:
      if (lightsSTART()) schritt = 255;
      break;
    default:
      break;
  }
}


//=====[ SETUP ]===============================================================
void setup()
{
  strip.begin();
  Serial.begin(9600);
  strip.show();
  randomSeed(analogRead(A0));
}

Was macht mein Programm zusammen mit Z-Round?

Ich gehe von zehn Neopixeln aus, die ersten fünf rot, die nächsten fünf grün.

Der Ablauf entspricht annähernd dem, was ich Deinem Programm entnommen habe. Mit der Startprozedur der F1 stimmt das nicht überein. Eventuell habe ich mich auch vertan :face_with_monocle:

Moin

Ich werde deinen Sketch mal testen um zu schauen was passiert.

Mein Problem ist, dass die Led's nicht synchron zu der Software Z Round laufen.
Die ersten 2 - 3 laufen einigermaßen synchron aber wen das Startsignal kommt sind meine Led's schon alle wieder aus.

Hier ein Link wie es sein sollte.

Und hier wie es bei mir ist.

Sollte das nicht für LED-Streifen gedacht sein? Ich habe mit WS2815 (vergleichbar WS2812b) probiert.

Moin

Doch das habe ich schon geändert.

Gruß

Ausgehend von dem Code den ich hier irgendwie hatte, mal schnell was geschrieben...

Da siehst Du anhand der zu sendenden Nachrichtenmessage, wie Du das lösen kannst, dass kein delay drin steckt.

Eigentlich müsste der Code noch genau das machen, was er vorher auch gemacht hat :slight_smile:
Ich hab im übrigen dein uint16_t in dem Du 120000 unterbringen wolltest für das Messintervall gleich mit berichtigt....

Bitte schalte in den Einstellungen die Compiliermeldungen (ALLE) ein, damit Du die warnngs auch bekommst...

Und hier der schnell mal umgeschriebene Code,
Wenn der das tut wie bisher, schreib ich da ggfls. noch weiter dran und nehm das aus den pixeln auch weg. (hatte ich ja schon mal angefangen ist aber irgendwie verloren gegangen... :man_shrugging:)

//==============================================================================
// Program:      ZRound_ws2811.ino
// Author:       Hernan Jardon
// Target:       UNO R3, IDE 1.6.5
// Date:         2015/07/21
// Time:         16:08
// Notes:
//               Uses Serial I/O
// Reference:    MODIFICACION CODIGO Juan Pardo, adaptacion LEDSTRIP WS-2811
//==============================================================================
#include <Adafruit_NeoPixel.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme;

float temperature, humidity;

char Tstr[10];
char Hstr[10];

char sendbuffer[62];

constexpr uint32_t messintervall {120000};
unsigned long lastmeasurement = 0;
unsigned long currentloop = 0;
uint32_t pausestart;

#define PIN 6  // PIN DE CONEXION
#define VERSION  0.7
//=====[ CONSTANTS ]============================================================
constexpr char CMD_START[] {"$START"};
constexpr char CMD_STOP[]  {"$STOP"};
constexpr char ANS_GO[]    { "$GO"};
constexpr byte bSize       {64};
constexpr bool L_OFF       {HIGH};
constexpr bool L_ON        {LOW};

const uint32_t sendpause = 200;
byte step = 0;  //
//=====[ PINS ]=================================================================
const byte DebugLed = 13;

//=====[ VARIABLES ]============================================================
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
char Buffer[bSize];        // Serial buffer
char ShadowBuffer[bSize];  // Serial buffer
char Command[10];
byte max_lights = 7; // MAX DE LEDS EN TIRA
uint32_t blinking_color_1 = strip.Color(255, 255, 0); //AMARILLO
uint32_t blinking_color_2 = strip.Color(255, 0, 0);   //ROJO
byte secuencia_de_encendido[] = {2, 3, 4, 5, 6, 7};   //ORDEN ENCENDIDO
uint32_t colores_por_bloque[] = { strip.Color(255, 0, 0), //1-Rojo
                                  strip.Color(255, 0, 0),   //2-Rojo
                                  strip.Color(255, 0, 0),   //3-Rojo
                                  strip.Color(255, 0, 0),   //4-Rojo
                                  strip.Color(255, 255, 0),   //5-Amarillo
                                  strip.Color(255, 255, 0)
                                };  //6-Amarillo
byte bloques_de_led = 6;
byte cantidad_de_led_por_bloque = 1; // CARTIDAD DE LEDS POR BLOQUE


//=====[ ReadSerialCommand ]====================================================
int ReadSerialCommand(void)
{
  int BytesCount = -1;
  BytesCount =  Serial.readBytesUntil('\n', Buffer, bSize - 1);
  if (BytesCount  > 0)
  {
    Buffer[BytesCount] = '\0';
  }
  else
  {
    Buffer[0] = '\0';
  }
  return BytesCount;
}

//=====[ Lights ]=============================================================
void LightsOFF(void)
{
  uint32_t c = strip.Color(0, 0, 0);//Negro
  for (int i = 2; i <= bloques_de_led + 1; i++)
  {
    for (int j = 0; j < cantidad_de_led_por_bloque; j++)
    {
      int num = ((i - 1) * cantidad_de_led_por_bloque ) + j;
      if (num < max_lights )
      {
        strip.setPixelColor(num, c);
      }
    }
  }
  strip.show();
}

void LightsON(uint32_t c)
{
  for (int i = 2; i <= bloques_de_led + 1; i++)
  {
    for (int j = 0; j < cantidad_de_led_por_bloque; j++)
    {
      int num = ((i - 1) * cantidad_de_led_por_bloque ) + j;
      if (num < max_lights)
      {
        strip.setPixelColor(num, c);
      }
    }
  }
  strip.show();
}

//=====[ SETUP ]===============================================================
void setup()
{
  strip.begin();
  Serial.begin(9600);
  delay(100);
  bme.begin(0x76);
  pinMode(LED_BUILTIN, OUTPUT);
  delay(100);
  LightsOFF();
}

//=====[ LOOP ]===============================================================
void loop()
{
  currentloop = millis();
  if (currentloop - lastmeasurement > messintervall)
  {
    switch (step)
    {
      case 0:
        digitalWrite(LED_BUILTIN, HIGH);
        temperature = bme.readTemperature();
        humidity = bme.readHumidity();
        dtostrf(temperature, 3, 2, Tstr);
        dtostrf(humidity, 3, 2, Hstr);
        step++;
        break;
      case 1:
        sprintf(sendbuffer, "$HS,%s\n", Hstr);
        Serial.println(sendbuffer);
        pausestart = currentloop;
        step++;
        break;
      case 2:
        if (currentloop - pausestart > sendpause)
        {
          sprintf(sendbuffer, "$TS,%s\n", Tstr);
          Serial.println(sendbuffer);
          step++;
        }
        break;
      case 3:
        lastmeasurement = currentloop;
        digitalWrite(LED_BUILTIN, LOW);
        step = 0;
        break;
      default:
        step = 0;
        break;
    }
  }
  if (ReadSerialCommand() > 0)
  {
    strcpy(ShadowBuffer, Buffer);
    strcpy(Command, strtok(ShadowBuffer, ","));
    if (strcmp(Command, CMD_START) == 0)
    {
      LightsOFF();
      for (int i = 0; i < bloques_de_led; i++)
      {
        int bloque = secuencia_de_encendido[i];
        uint32_t c = colores_por_bloque[i];
        for (int j = 0; j < cantidad_de_led_por_bloque; j++)
        {
          int num = ((bloque - 1) * cantidad_de_led_por_bloque ) + j;
          if (num < max_lights )
          {
            strip.setPixelColor(num, c);
          }
        }
        strip.show();
        delay(1000);
      }
      // Send GO to PC
      Serial.print(ANS_GO);
      Serial.print('\n');
      Serial.flush();
      LightsON(strip.Color(0, 255, 0)); //VERDE
      delay(5000);
      LightsOFF();
    }
    else if (strcmp(Command, CMD_STOP) == 0)
    {
      LightsOFF();
      // Red lights blinking during 30 Seconds
      for (int i = 0; i < 30; i++)
      {
        LightsON(blinking_color_1 );
        delay(500);
        LightsON(blinking_color_2 );
        delay(500);
      }
      LightsOFF();
    }
  }
}

Hallo

Es hat sich etwas getan.
Ein User aus dem Mini Z Forum hat mir geantwortet.

Ein ganz simpler Sketch der aber zumindest mit "normalen" LED´s funktioniert.

//ZRound Startit light --> Zround is Master

//=====[ CONSTANTS ]============================================================
#define CMD_START   "$START"
#define CMD_STOP    "$STOP"
#define CMD_LIGHT   "$LIGHT"
#define ANS_GO      "$GO"
#define bSize       64 

//=====[ VARIABLES ]============================================================
char Zround_CMD[bSize];        // Serial buffer
char TempBuffer[bSize];  // Serial buffer
char Command[10];
int LightIndex;
int LightStatus;
byte LightPort[]={4,5,6,7,8}; //PINs for LEDS
byte lengLIGHTS;



void setup() {
  // put your setup code here, to run once:
lengLIGHTS = sizeof(LightPort);
for(int i=0;i<lengLIGHTS;i++){
    pinMode(LightPort[i], OUTPUT );		//Setup lights ports
    digitalWrite(LightPort[i], LOW);	//Switch off lights
  }  

 Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
 
  if(ReadSerialCommand()>0){
   
    strcpy(TempBuffer,Zround_CMD);        
    Serial.println(Zround_CMD);
     parseData();
    Serial.println(LightIndex);
    Serial.println(LightStatus);
   
    }

} // loop

//=====[ ReadSerialCommand ]====================================================
int ReadSerialCommand(void) {
  int BytesCount = -1;
  BytesCount =  Serial.readBytesUntil('\n',Zround_CMD,bSize-1);  
  if (BytesCount  > 0) {
    Zround_CMD[BytesCount]='\0';
  }
  else{
    Zround_CMD[0]='\0';
  } 
  return BytesCount;
}

//=====[ Zround Commands Processing ]============================================================
void parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(TempBuffer,",");      // get the first part - the string
    strcpy(Command, strtokIndx); // copy it to messageFromPC

    if (strcmp(Command,CMD_LIGHT)==0){
 
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    LightIndex = atoi(strtokIndx);     // convert this part to an integer


    strtokIndx = strtok(NULL, ",");
    LightStatus = atoi(strtokIndx);     // convert this part to a float

    
    }
digitalWrite(LightPort[LightIndex-1], LightStatus);
}