Motorcycle Blinkers: Need some help with the code

Hello,

I am working on a project to use an arduino to control some WS2812 leds as blinkers (for the most part), I want to also be able to control the lights via bluetooth.

Right now I have an Uno with the BLE Shield (http://redbearlab.com/bleshield/) and I have modified the RGB Led example from Red Bear Lab that lets me change the color of an LED from my iphone. That part is working just fine… The part I am having a problem with is adding the code to read a pin connected to the flasher relay on the motorcycle and make the led’s blink yellow.

I have attached the code. Right now when I connect something to the input pin the leds go yellow and goes non-responisve… I am missing a way to have the blinkers have priority over the rest of the functions, so no matter what state the leds are in, when i hit the blinker they work, then return to whatever state they were in (if riding will be off).

I am still learning coding and really need some guidance to move forward. Help would be greatly appreciated!!

Cheers,
Mike

ZeroCTRL_v0_3.ino (2.52 KB)

OK I need to clarify the issue I think... When I supply a load to the pin the light's go yellow, but don't turn off when I kill the load. I can use the app to change the color or turn off. Before I wrote that the board is non-responsive, but that's not correct sorry.

I believe my problem is with this part of the code: if(lsiState == LOW) { strip_left.show();

Maybe I need a "then" statement instead of "if"? Also, I need help with using something return to last state instead of show().

Cheers

The part I am having a problem with is adding the code to read a pin connected to the flasher relay on the motorcycle and make the led's blink yellow.

What is the voltage on the relay? How are you getting it to a range that the Arduino can handle? In other words, where is your schematic?

    if(lsiState == LOW) {
   strip_left.show();

I would not expect the relay state to be low to indicate blinking.

  if(lsiState == HIGH) { 
    strip_left.setPixelColor(0, yellowl);
        strip_left.setPixelColor(1, yellowl);
        strip_left.setPixelColor(2, yellowl);
        strip_left.setPixelColor(3, yellowl);
          strip_left.show();
    }
    if(lsiState == LOW) { 
    strip_left.show();
    }

If the state id HIGH, set the colors and show those colors. If the pin is LOW, show the same colors. No wonder it's not blinking.

Use Tools + Auto Format before you post any more ugly code.

Hi Paul,

Thanks for your responses.

What is the voltage on the relay? How are you getting it to a range that the Arduino can handle? In other words, where is your schematic?

I am dropping the voltage from the relay to 3.3v, so when the flasher is activated it should fluctuate between 3.3v and 0v. But maybe my understating is not correct?

I would not expect the relay state to be low to indicate blinking.

From my understanding of the code, strip_left.show(); turns OFF the leds which is why i thought that command may work.

If the state id HIGH, set the colors and show those colors. If the pin is LOW, show the same colors. No wonder it's not blinking.

I explained this above...

Use Tools + Auto Format before you post any more ugly code.

OK.

Auto-formatted

#include "Adafruit_NeoPixel.h"
#include <SPI.h>
#include <boards.h>
#include <ble_shield.h>
#include <services.h>

//Control Pin(s)
#define Left_Blinkers 5
#define Right_Blinkers 6
#define Left_Signal_Input 7
#define Right_Signal_Input 8
int lsiState = 0;
int rsiState = 0;

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel strip_left = Adafruit_NeoPixel(4, Left_Blinkers, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip_right = Adafruit_NeoPixel(4, Right_Blinkers, NEO_GRB + NEO_KHZ800);

int R = 0;
int G = 0;
int B = 0;

void setup() 
{
  strip_left.begin();
  strip_left.show(); // Initialize all pixels to 'off'
  strip_right.begin();
  strip_right.show(); // Initialize all pixels to 'off'
  pinMode(Left_Signal_Input, INPUT);
  pinMode(Right_Signal_Input, INPUT);
  ble_begin();
}

void loop() 
{
  if(3 == ble_available())
  {
    R = ble_read();
    G = ble_read();
    B = ble_read();
    colorWipe( strip_left.Color(R, G, B) );
    colorWipe( strip_right.Color(R, G, B) );
  }
  ble_do_events();

  //simplify syntax for yellow color
  uint32_t yellowl = strip_left.Color(255, 255, 0);
  uint32_t yellowr = strip_right.Color(255, 255, 0);

  //Configure Input Pins
  lsiState = digitalRead(Left_Signal_Input);
  rsiState = digitalRead(Right_Signal_Input);

  //Actions for Blinkers 
  if(lsiState == HIGH) { 
    strip_left.setPixelColor(0, yellowl);
    strip_left.setPixelColor(1, yellowl);
    strip_left.setPixelColor(2, yellowl);
    strip_left.setPixelColor(3, yellowl);
    strip_left.show();
  }
  if(lsiState == LOW) { 
    strip_left.show();
  }
  if(rsiState == HIGH) { 
    strip_right.setPixelColor(0, yellowr);
    strip_right.setPixelColor(1, yellowr);
    strip_right.setPixelColor(2, yellowr);
    strip_right.setPixelColor(3, yellowr);
    strip_right.show();
  }
  if(rsiState == LOW) { 
    strip_right.show();
  }
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c) 
{
  for(uint16_t i=0; i<strip_left.numPixels(); i++) 
  {
    strip_left.setPixelColor(i, c);
    strip_left.show();
  }
  for(uint16_t i=0; i<strip_right.numPixels(); i++) 
  {
    strip_right.setPixelColor(i, c);
    strip_right.show();
  }
}

From my understanding of the code, strip_left.show(); turns OFF the leds which is why i thought that command may work.

I don't think your understanding is correct. If it were, there would be no reason to do anything when the state is low, because you have this for when the state is high:

  if(lsiState == HIGH) { 
    strip_left.setPixelColor(0, yellowl);
    strip_left.setPixelColor(1, yellowl);
    strip_left.setPixelColor(2, yellowl);
    strip_left.setPixelColor(3, yellowl);
    strip_left.show();
  }

If your understanding was correct, this would turn some pixels on, then no time later, turn everything off. Does that pass the sniff test? Not from here, it doesn't.

Of course my understanding is wrong, that's why I am asking for help.

Of course my understanding is wrong, that's why I am asking for help.

I thought I explained what you need to do. When the state goes LOW, you need to turn off the LEDs, then show the new state.

I thought I explained what you need to do. When the state goes LOW, you need to turn off the LEDs, then show the new state.

No I missed that, thank you for clarifying, the blinker part works now!

 //simplify syntax for yellow color
  uint32_t yellowl = strip_left.Color(255, 255, 0);
  uint32_t yellowr = strip_right.Color(255, 255, 0);
  uint32_t offl = strip_left.Color(0, 0, 0);
  uint32_t offr = strip_right.Color(0, 0, 0);

  //Configure Input Pins
  lsiState = digitalRead(Left_Signal_Input);
  rsiState = digitalRead(Right_Signal_Input);

  //Actions for Blinkers 
  if(lsiState == HIGH) { 
    strip_left.setPixelColor(0, yellowl);
    strip_left.setPixelColor(1, yellowl);
    strip_left.setPixelColor(2, yellowl);
    strip_left.setPixelColor(3, yellowl);
    strip_left.show();
  }
  if(lsiState == LOW) {
    strip_left.setPixelColor(0, offl);
    strip_left.setPixelColor(1, offl);
    strip_left.setPixelColor(2, offl);
    strip_left.setPixelColor(3, offl); 
    strip_left.show();
  }
  if(rsiState == HIGH) { 
    strip_right.setPixelColor(0, yellowr);
    strip_right.setPixelColor(1, yellowr);
    strip_right.setPixelColor(2, yellowr);
    strip_right.setPixelColor(3, yellowr);
    strip_right.show();
  }
  if(rsiState == LOW) {
    strip_right.setPixelColor(0, offr);
    strip_right.setPixelColor(1, offr);
    strip_right.setPixelColor(2, offr);
    strip_right.setPixelColor(3, offr); 
    strip_right.show();
  }

When I try to change colors with the app, the pixels will only quickly blink the desired color... I gather that's because there is no load on the input pin. Is there a away that I can have the blinkers revert to whatever color they were if it doesn't receive any load on the pin after 1 second after the load is detected?

I am not sure if that would be the correct way of doing it... I just want to be able to adjust the led colors with the app, then the blinker can override the color when activated and go back to whatever state it was in when the blinker is deactivated. I don't understand how I can have both functionality work.

Thank you for your help!

 //simplify syntax for yellow color
  uint32_t yellowl = strip_left.Color(255, 255, 0);
  uint32_t yellowr = strip_right.Color(255, 255, 0);
  uint32_t offl = strip_left.Color(0, 0, 0);
  uint32_t offr = strip_right.Color(0, 0, 0);

Aren’t yellowl and yellowr the same value?

Aren’t offl and offr the same value?

Aren’t you glad the functions aren’t called pinmode, digitalread, and digitalwrite?

Aren't yellowl and yellowr the same value?

Aren't offl and offr the same value?

Yes but I can't figure out how to declare that color for both strips.

Aren't you glad the functions aren't called pinmode, digitalread, and digitalwrite?

I don't understand.

Yes but I can't figure out how to declare that color for both strips.

Yellow is yellow. It doesn't matter which instance of the class converted the r, g, b values to an unsigned long.

I don't understand.

Function names and variable names need some way to distinguish the individual words. The two usual ways are underscores (pin_mode) which looks horrid, or camelCase (leftYellow, rightYellow).

Yellow is yellow. It doesn’t matter which instance of the class converted the r, g, b values to an unsigned long.

If I do this:

   uint32_t yellow = strip_left.Color(255, 255, 0);
  uint32_t yellow = strip_right.Color(255, 255, 0);

I get an error:
redclaration of ‘unit32_t yellow’

How can I just declare yellow globally?

Function names and variable names need some way to distinguish the individual words. The two usual ways are underscores (pin_mode) which looks horrid, or camelCase (leftYellow, rightYellow).

So you are saying that I am declaring my variables like strip_left incorrectly?

get an error: redclaration of 'unit32_t yellow'

Why does that surprise you? If you know two people with accurate watches, does it matter which one you ask for the time? Do you REALLY need to ask them both?

So you are saying that I am declaring my variables like strip_left incorrectly?

Declaring? No. Naming? Yes.

strip_left and strip_right are OK (though not what I like). yellowl and yellowr are not.

Why does that surprise you? If you know two people with accurate watches, does it matter which one you ask for the time? Do you REALLY need to ask them both?

Apparently I do... like I said, I don't know how. From the examples I am using to learn from, the color is set to the strip.

Thank you for your lessons in code structuring and syntax, but I don't feel I have made much progress learning what I am really doing wrong. I know "yellowr" is ugly, but it should still work. I think I may have posted this in the wrong place.

Thank you for your time.

Apparently I do... like I said, I don't know how.

No, you don't. The two instances will compute EXACTLY the same result given the same input.

uint32_t yellow = strip_left.Color(255, 255, 0);

You do NOT need to ask the other instance to also tell you what value to use for yellow.