Startampel mit Arduino R3 und der Software Z-Round

Moin Moin

Ich hatte dieses Thema schon einmal im Mini-Z Forum angesprochen. Leider konnte mir nur zum Teil geholfen werden

Ich benutze den unten aufgeführten Sketch. Die RX Lampe auf dem Arduino Board läuft synchron zur Software. Dort wird eine Startampel angezeigt und diese soll wiederrum über ein ArduinoR3 angesteuert werden.

Nun ist mein Problem, dass die Adafruit NEO Pixel nicht angesprochen wird. Warum auch immer ?

Ich habe die Adafruit NEO Pixel ( 60 LED´s ) mit 5 Volt 3 A zusätzlich versorgt. Laut dem Sketch soll ich das Signalkabel an PIN 6 anlegen. Habe ich auch so gemacht. Zusätzlich habe ich GND von der NEO Pixel mit dem Board GND verbunden.

Hier der Sketch

//==============================================================================
// 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];

uint16_t messintervall = 120000;
unsigned long nextmeasurement = 0;
unsigned long currentloop = 0;


#define PIN 6  // PIN DE CONEXION
#define VERSION  0.7
//=====[ CONSTANTS ]============================================================
#define CMD_START   "$START"
#define CMD_STOP    "$STOP"
#define ANS_GO      "$GO"
#define bSize       64
#define L_OFF       HIGH
#define L_ON        LOW

//=====[ PINS ]=================================================================
int 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 (nextmeasurement < currentloop) {
    digitalWrite(LED_BUILTIN, HIGH);

    temperature = bme.readTemperature();
    humidity = bme.readHumidity();

    dtostrf(temperature, 3, 2, Tstr);
    dtostrf(humidity, 3, 2, Hstr);

    sprintf(sendbuffer, "$HS,%s\n", Hstr);
    Serial.println(sendbuffer);
    delay(200);
    sprintf(sendbuffer, "$TS,%s\n", Tstr);
    Serial.println(sendbuffer);

    nextmeasurement = currentloop + messintervall;
    digitalWrite(LED_BUILTIN, LOW);
  }

  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();
    }
  }
}

Und hier ein Bild zur Software Z-Round. Diese soll das Arduino Board ansprechen.

ZRoundJPG_2

Diese LED nutze ich
"NeoPixel"-LED-Strip (WS2812B)

neopixel_strip

Könnte mir einer bei der Verkabelung helfen und sich evtl. mal den Sketch anschauen ?
Der Sketch sollte ja eigentlich so funktionieren.

Bin für jede Hilfe dankbar.

Gruß

Geht ein "normaler" Testsketch für die WS2812? Damit man sicher ist, das die Hardware läuft.

Moin

Ja, die LED´s funktionieren mit den vorgefertigten Sketche.

Gruß

Das funktioniert nicht und sollte Dir der Compiler um die Ohren hauen.

Und hier sehe ich doch schon....

das nächste Problem auf Dich zu kommen.
Keine Zeitrechnung in die Zukunft!

Und dann finde ich da unendlich viele delays - die müssen da raus.
Wenn Du Pausen brauchst, brauchst Du eine StateMachine.

Moin

Ich habe es hinbekommen.

IR Sensor löst mein Lauflicht für 10 Sekunden aus :grinning:

Danke an alle die mir geholfen haben.

Ich hatte ein bisschen Hilfe. Chat GTP :face_with_monocle:

Hier mein Sketch. Vielleicht nicht der Beste aber er funktioniert.

#include <Adafruit_NeoPixel.h>

// Pin für WS2812-Streifen
#define LED_PIN 6
// Anzahl der LEDs im Streifen
#define NUM_LEDS 60
// Initialisierung des WS2812-Streifens
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

// Pin für TCRT5000-Sensor
#define SENSOR_PIN 2

// Variablen für Timing und Zustand
bool is_running = false;
unsigned long start_time = 0;
unsigned long duration = 10000; // 10 Sekunden !! GEÄNDERT //

void setup() {
  strip.begin();
  strip.show(); // Alle LEDs ausschalten
  pinMode(SENSOR_PIN, INPUT); // Sensor-Pin als Eingang setzen
}

void loop() {
  // Sensor lesen
  int sensor_value = digitalRead(SENSOR_PIN);

  // Lauflicht aktivieren, wenn der Sensor ausgelöst wird
  if (sensor_value == LOW && !is_running) {  // GEÄNDERT auf LOW statt HIGH
    is_running = true;
    start_time = millis(); // Zähler starten
  }

  // Wenn das Lauflicht aktiviert ist und die 10 Sekunden nicht überschritten sind
  if (is_running && millis() - start_time < duration) {
    runChaseLight(); // Lauflicht aktivieren
  } else if (is_running) {
    // Lauflicht stoppen
    strip.clear(); // Alle LEDs ausschalten
    strip.show();
    is_running = false; // Status zurücksetzen
  }
}

void runChaseLight() {
  // Anzahl der LED-Pixel
  static int pixel = 0;

  // LEDs ausschalten
  strip.clear();

  // Ein Lauflicht-Effekt
  for (int i = 0; i < 3; i++) {
    int led_pos = (pixel + i) % NUM_LEDS;
    strip.setPixelColor(led_pos, strip.Color(255, 0, 0)); // Rot als Beispiel
  }

  strip.show(); // Aktualisieren

  // Zur nächsten LED für das Lauflicht
  pixel = (pixel + 1) % NUM_LEDS;

  // Kurze Verzögerung, um das Lauflicht zu verlangsamen
  delay(20);
}

Sieht schon besser aus, als das erste Schnipsel.
Gibt aber noch das eine oder andere, was ich nicht so machen würde.
Aber nu - man kann nicht alles haben.

Oha das war ja der falsche Beitrag. Das hatte ich nebenbei gemacht.
Das mit der Startampel funktioniert leider immer noch nicht.

Hallo

Komisch ist wenn ich die LED Stripes nicht verwende, leuchtet die RX Lampe auf dem Board synchron zur Ampelanzeige wie auf dem Bildschirm.

Was denkst Du denn, was hier so passiert?

Bevor ich das jetzt aufdrösel und mir errate, erzähl doch mal, was Du willst und was der stripe wann machen soll...

Hi

Also die Software Z-Round bietet eine Startampel auf dem Monitor an. Diese kann wiederum auf ein Arduino übertragen werden. Soll heißen, das wenn der Countdown läuft ( 5 rote Lampen auf dem Monitor ) soll dieses zeitgleich mit dem Arduino gesteuert werden.

Das ist der originale Sketch dazu

// Program: ZRound.ino
// Author: Juan Pardo
// Target: UNO R3, IDE 1.0.5
// Date: 2013/08/12
// Time: 02:32
// Notes:
// Uses Serial I/O
// Reference:
//==============================================================================
#define VERSION 0.7

//=====[ INCLUDE ]==============================================================


//=====[ CONSTANTS ]============================================================
#define CMD_START "$START"
#define CMD_STOP "$STOP"
#define ANS_GO "$GO"
#define bSize 64
#define L_OFF HIGH
#define L_ON LOW

//=====[ PINS ]=================================================================
int DebugLed = 13;

//=====[ VARIABLES ]============================================================
char Buffer[bSize]; // Serial buffer
char ShadowBuffer[bSize]; // Serial buffer
char Command[10];
byte LightPort[]={4,5,6,7,8,9}; // Last port will be used as green light
byte LIGHTS;
byte GREENLIGHT;

//=====[ 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;
}

//=====[ LightsOFF ]=============================================================
void LightsOFF(void) {
for(int i=0;i<LIGHTS;i++){
digitalWrite(LightPort[i], L_OFF); //Switch off lights
}
}

//=====[ SETUP ]===============================================================
void setup() {
LIGHTS = sizeof(LightPort);
GREENLIGHT = LIGHTS-1;
for(int i=0;i<LIGHTS>0){

strcpy(ShadowBuffer,Buffer);
strcpy(Command,strtok(ShadowBuffer,","));

if(strcmp(Command, CMD_START)==0){
LightsOFF();
for(int i=0;i<LIGHTS-1;i++){
digitalWrite(LightPort[i], L_ON); //Switch on lights
delay(1000);
}
// Send GO to PC
Serial.print(ANS_GO);
Serial.print('\n');
Serial.flush();

LightsOFF();
digitalWrite(LightPort[GREENLIGHT], L_ON); //Switch on Green light
}
else{
if(strcmp(Command, CMD_STOP)==0){
LightsOFF();
// Red lights blinking during 1 minute
for(int i=0;i<60;i++){
for(int j=0;j<LIGHTS-1;j++){
digitalWrite(LightPort[j], L_ON);
}
delay(500);
for(int j=0;j<LIGHTS-1;j++){
digitalWrite(LightPort[j], L_OFF);
}
delay(500);
}
LightsOFF();
}
}
}
}

Dieser funktioniert leider nicht synchron. Bei diesem Sketch habe ich es mit einzelnen Dioden probiert.

Danach habe ich einen neuen Sketch bekommen. Dieser sollte mit LED Stripe funktionieren.

Das ist der neue Sketch

// 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];

uint16_t messintervall = 120000;
unsigned long nextmeasurement = 0;
unsigned long currentloop = 0;


#define PIN 6  // PIN DE CONEXION
#define VERSION  0.7
//=====[ CONSTANTS ]============================================================
#define CMD_START   "$START"
#define CMD_STOP    "$STOP"
#define ANS_GO      "$GO"
#define bSize       64
#define L_OFF       HIGH
#define L_ON        LOW

//=====[ PINS ]=================================================================
int 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 (nextmeasurement < currentloop) {
    digitalWrite(LED_BUILTIN, HIGH);

    temperature = bme.readTemperature();
    humidity = bme.readHumidity();

    dtostrf(temperature, 3, 2, Tstr);
    dtostrf(humidity, 3, 2, Hstr);

    sprintf(sendbuffer, "$HS,%s\n", Hstr);
    Serial.println(sendbuffer);
    delay(200);
    sprintf(sendbuffer, "$TS,%s\n", Tstr);
    Serial.println(sendbuffer);

    nextmeasurement = currentloop + messintervall;
    digitalWrite(LED_BUILTIN, LOW);
  }

  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();
    }
  }
}

Hier ist eigentlich das gleiche Problem. Die ersten 5 Dioden sind taktgleich mit der Anzeige am Monitor. Bis das Startsignal erklingt dauert es nochmal 3-4 Sekunden. Die LED‘s aber laufen einfach durch.

Wenn ich die LED‘s nicht anschließe, die Software Z-Round starte und die RX Diode am dem Arduino Board beobachte , läuft die Routine ( LED blinken zur Sequenz) richtig.

Ich hoffe es ist einigermaßen verständlich geschrieben.

Gruß Max

Hi

Hier mal ein Link wie es funktionieren sollte. Die Technik ist etwas anders.

Das Video soll nur die Funktionsweise darstellen.

Startampel mit ZRound und Arduino

So!
Also mal ausklabüstert bekommt der Arduino Drei Kommandos via Serieller:

Eine Startampel wäre IMHO: Die 5 roten Dinger gehen nacheinander an.
-> Wäre mein Kommando START
Wenn die alle an sind, kommt irgendwann das Signal, dass die ausgehen:
-> wäre mein Kommando GO
Was macht STOP?

Das verdammte delay da drin verhaut Dir Deine ganze Vorgabe, da Du während dem keine Zeichen auf der Seriellen lesen kannst.
Nix.
Niente.

Da Du nicht für jede LED-Anzeige eine Information bekommst, sondern nur den Auslöser für "Zaehlen" und "Aus", wirst Du nie 100% syncron sein, aber das reagieren auf jeden Eingang sollte definitiv machbar sein.

Hi

Ja wie oben beschrieben, die 5 roten LED‘s laufen an aber wen das verzögerte Startsignal kommt ( dann sollen alle auf grün umschalten) funktioniert das nicht synchron.

Ich habe eine funktionierende Anlage im Mini Z Forum gesehen. Leider ist der gute Mann nicht mehr aktiv.

Nachtrag

Stop ist wenn das Rennen zu Ende ist.
Dann blinken die LED‘s abwechselnd rot und grün.

Bau ich Dir zu morgen.
Mein Akku ist down und ich hab jetzt keine Zeit mehr.

Hi

Da wäre ja echt Mega wenn du das hinbekommen solltest. :+1::+1:

Mit freundlichen Grüßen

Gesendet mit der GMX iPhone App

HA!
Ich hab den Code mal angesehen.
Der macht was anderes als Du erwartest!

Soweit richtig.

Und das ist falsch!
Das $GO sendet der Arduino an das Z-Round!!!

Also muss das ganz anders aufgebaut werden.
Das Z-Round startet die Ampel und der Arduino startet das Rennen:

Wobei jetzt die Frage ist, warum da nicht Serial3 benutzt wird.

Moin

Ich verstehe da nicht Serial 3 ?

Wo trage ich jetzt was ein ?

Gruß

Sorry - war ja nen UNO - also alles richtig.

Damit musst Du jetzt aber dem Z mitteilen, dass es nicht von selbst starten soll, sondern auf das $GO warten muss.
(BItte frag mich nicht, wie das geht. Davon hab ich keine Ahnung)

Hi

Trotzdem danke für deine tolle Unterstützung.
Ich werde nochmals versuchen mit dem User aus dem Mini Z Forum Kontakt aufzunehmen.
Irgendwie muss es ja funktionieren.

Wie gesagt, danke für deine tolle Arbeit.

Gruß

1 Like