Control LED stripe via master/slave communication

Hi,

I am really going crazy because I cannot make my setup work. I am working with arduinos for the first time in my masters thesis.

I have read a lot about the interrupt problem, but I don´t know a solution for my project.

I am using 2 Arduino Uno.
Arduino 1 contains a rf module to communicate with a control unit. The received data (only one char; “0”,“1” or “2”) will be transmitted to the Arduino 2 as a slave. Arduino 2 should trigger the right LED scene. I have build this master/slave setup as I found out that the rf communication is blocked by the LEDs…finding out that I2C communication doesn´t work any better :frowning:

So the communication setup is working, but the LED problem still exist. As soon as the LEDs enlighten, no communication is possible. I am using 3 striped LEDs which I have read are bad for my purpose. I have access to a 4 striped LED, but I cannot use a additional power supply in my prototype. I also tried FastLED as I thought only Neopixel could be the problem. Both, the same problem.

Is there ANY chance to make this work? (we are talking about 12 LEDs which are everytime in the same color (yellow, green,red)).

//#include <Adafruit_NeoPixel.h>
#define FASTLED_ALLOW_INTERRUPTS 0
#include <FastLED.h>
#include <Wire.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define DATA_PIN 2 // connected PIN for LEDs
#define NUM_LEDS 12 // 12 LEDs on roof
//Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

//variables for connection
char x;  //transmitted char via I2C
char oldX; //save current state

CRGB leds[NUM_LEDS];

void setup()
{
  //pixels.begin(); // Initialisierung der NeoPixel
  Serial.begin(9600);      
  //setup for communication to master arduino via I2C
  Wire.begin(9); //listen to "channel" 9
  Wire.onReceive(receiveEvent); /// Attach a function to trigger when something is received.
  pinMode(13, OUTPUT);

  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);

  //test output
  Serial.println("System rdy");
}

// Function for wired connection
void receiveEvent(int bytes) {
  x = Wire.read();    // read one character from the I2C
  Serial.println(x);
}

void loop()
{

if(x != oldX){
        //change current state
        oldX = x;

        //start output
        switch(x){
          case '0': //Serial.print((char)buf[0]);
                    //LEDs power off
                    for (int i = 0; i < NUM_LEDS; i++) {
                      leds[i] = CRGB::Black; 
                      FastLED.show();
                    } 
                    //display power off

                    //stop engine
                    Serial.println("Szenario beendet");   
            break;
          case '1': //Serial.print((char)buf[0]);
                    // start servos to move vehicle
                    //TODO
          
                     //call function LEDblink(), execute 1 time
                    for(int c=0; c<2;c++){
                      if (c==0) {
                        LedBlink();
                      } else {
                        //start communication output
                        //LEDs are green, pedestrian has right of way
                        for (int i = 0; i < NUM_LEDS; i++) {
                          leds[i] = CRGB::Green; 
                          FastLED.show();
                        }
                        //display sign "green arrow" simultanous to green LEDs
                        //TODO
                      }
                    }
                    Serial.println("Szenario 1 gestartet");
            break;
          case '2': //Serial.print((char)buf[0]);
                    // start servos to move vehicle
                    //TODO


                     //call function LEDblink(), execute 1 time
                    for(int c=0; c<2;c++){
                      if (c==0) {
                        LedBlink();
                      } else {
                        //start communication output
                        //LEDs are red, vehicle has right of way
                        for (int i = 0; i < NUM_LEDS; i++) {
                          leds[i] = CRGB::Red; 
                          FastLED.show();
                        }
                        //display sign "red cross" simultanous to red LEDs
                        //TODO
                      }
                    } 
                    Serial.println("Szenario 2 gestartet");
            break;
                  
          }//end switch-case       
}//end if

}//end loop function


/////////////////////////////////////////////////////////////
//       FUNKTION LEDs blinken gelb                       //
///////////////////////////////////////////////////////////
void LedBlink() {
  //j = LED blink sequence 
  for (int j = 0; j < 3; j++) {
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Yellow;
      FastLED.show();
    }
    delay(300);
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CRGB::Black;
      FastLED.show();
    }
    delay(300);
  }
}

You are sending the LED’s data far too often, move the show method call to outside the for loop and use it only when all the LEDs have had their colour set.

Also have you got the large capacitor across the strip’s power and out the resistor in the data line?

 // start servos to move vehicle
                    //TODO

You will find you can’t use addressable LEDs and use servos at the same time one or other function has to be driven by external hardware driver chips.

Hi,

thanks for your help. I´ve put the FastLED.show() function outside the for loop - makes sense. But it doesn´t make it work.

The servo comments are old - this was the second reason for a master/slave communication, so I can put these functions on different devices. But thanks for the comment as well :slight_smile:

You didn't answer about

Also have you got the large capacitor across the strip's power and out the resistor in the data line?

Hi,

sorry. No I don´t. The stripe is directly wired to 5V, GND and PIN2 of the arduino.

I have found a solution for my prototype, which is definitly not nice but it works.

//call function LEDblink(), execute 1 time
                    for(int c=0; c<2;c++){
                      if (c==0) {
                        LedBlink();
                      } else {
                        //start communication output
                        //LEDs are green, pedestrian has right of way
                        for (int i = 0; i < NUM_LEDS; i++) {
                          leds[i] = CRGB::Green; 
                        }
                        FastLED.show();
                        //display sign "green arrow" simultanous to green LEDs
                        //TODO
                      }
                    }
                    Serial.println("Szenario 1 gestartet");
                    delay(2000);  //Scenario is running
                    resetFunc(); //reset arduino

So i reset the arduino after starting the LEDs, so it will enable the interrupt and start listening to the master arduino again

Rubbish.