emergency lights

Hello fellow nerds,

So i volunteer as a firefighter and on personal vehicles we are allowed to have emergency lights but the commercial ones are expensive($600 and up) so i figured i would build my own using the UNO board as the base, I was able to get all pieces to work individually but when i put everything together it, for lack of a better word, freezes/ lags. your help on this would be great.

basis for the project:

everything is controlled with a IR remote (most channels with least pins)

2 front lights(flash back and forth with a strobe)(using a state machines)

2 side lights(flash back and forth with a strobe) (using a state machine)

2 back lights(flash back and forth with a strobe) (using a state machine)

the front and back can be operated by themselves with button 1 and 2 respectively, and mode 3 turns on all 3 sets of lights.

8 lights in the back traffic director (controlled with a shift register 74HC595)

pause/ play button puts it into a wigwag pattern
rewind button puts it into a move left pattern
fast forward button puts it into a move right pattern
up button puts it into a center out pattern

once again all pieces work by themselves but as soon as i combine it freezes/lags.
any help will be greatly appreciated.

#define FRONT1 0x0
#define FRONT2 0x1
#define BACK1 0x0
#define BACK2 0x1

int clockPin = 2; //IC Pin 11, orange Jumper
int dataPin = 3; //IC Pin 14, yellow Jumper
int latchPin = 4; //IC Pin 12, black Jumper

byte wigwag[4] = {
B10101010, 200,
B01010101, 200
};

byte right[16] = {
B10000000, 200,
B11000000, 200,
B11100000, 200,
B11110000, 200,
B11111000, 200,
B11111100, 200,
B11111110, 200,
B11111111, 200
};

byte left[16] = {
B00000001, 200,
B00000011, 200,
B00000111, 200,
B00001111, 200,
B00011111, 200,
B00111111, 200,
B01111111, 200,
B11111111, 200
};

byte center[18] = {
B00011000, 255,
B00011000, 255,
B00111100, 255,
B00111100, 255,
B01111110, 255,
B01111110, 255,
B11111111, 255,
B11111111, 255,
B00000000, 255
};
 
// Variable to track which LED is on
byte whichLEDfront = FRONT1;
byte whichLEDback = BACK1;
 
// Where are the LEDs connected?
const int front1 = 6;
const int front2 = 7;
const int back1 = 10;
const int back2 = 11;
const int side1 = 8;
const int side2 = 9;
 
// State variables for the LEDs
byte front1_State = LOW;
byte front2_State = LOW;
byte back1_State = LOW;
byte back2_State = LOW;
 
// Some delay values to change flashing behavior
unsigned long switchDelay = 500;
unsigned long strobeDelay = 100;
 
// Seed the initial wait for the strobe effect
unsigned long strobeWait = strobeDelay;
 
// Variable to see when we should swtich LEDs
unsigned long waitUntilSwitch = switchDelay;  // seed initial wait

#include <IRremote.h>

int RECV_PIN = 13;
int index = 0;
int count = sizeof(wigwag) / 2;
int count2 = sizeof(right) / 2;
int count3 = sizeof(left) / 2;
int count4 = sizeof(center) / 2;

IRrecv irrecv(RECV_PIN);

decode_results results;
 
void setup() {
  pinMode(front1, OUTPUT);
  pinMode(front2, OUTPUT);
  pinMode(back1, OUTPUT);
  pinMode(back2, OUTPUT);
  pinMode(side1, OUTPUT);
  pinMode(side2, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
   
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}
 
void loop() {
  if (irrecv.decode(&results)) {

    irrecv.resume();
  }
  delay(50);
  switch(results.value){
  case 0xFFA25D://power button
    digitalWrite(front1,LOW);
    digitalWrite(front2,LOW);
    digitalWrite(back1,LOW);
    digitalWrite(back2,LOW);
    
  case 0xFF30CF://1 button
    digitalWrite(back1,LOW);
    digitalWrite(back2,LOW);
    digitalWrite(side1,LOW);
    digitalWrite(side2,LOW);
    digitalWrite(front1, front1_State);     // each iteration of loop() will set the IO pins,
    digitalWrite(front2, front2_State);    // even if they don't change, that's okay

    // Toggle back and forth between the two LEDs
    if ((long)(millis() - waitUntilSwitch)>=0) {
        // time is up!
        front1_State = LOW;
        front2_State = LOW;
        whichLEDfront = !whichLEDfront;  // toggle LED to strobe
        waitUntilSwitch += switchDelay;
    }
 
    // Create the stobing effect
    if ((long)(millis() - strobeWait)>=0) {
        if (whichLEDfront == FRONT1)
            front1_State = !front1_State;
        if (whichLEDfront == FRONT2)
            front2_State = !front2_State;
        strobeWait += strobeDelay;
    }

    case 0xFF18E7://2 button
    digitalWrite(front1,LOW);
    digitalWrite(front2,LOW);
    digitalWrite(side1,LOW);
    digitalWrite(side2,LOW);
    digitalWrite(back1, back1_State);     // each iteration of loop() will set the IO pins,
    digitalWrite(back2, back2_State);    // even if they don't change, that's okay

    // Toggle back and forth between the two LEDs
    if ((long)(millis() - waitUntilSwitch)>=0) {
        // time is up!
        back1_State = LOW;
        back2_State = LOW;
        whichLEDback = !whichLEDback;  // toggle LED to strobe
        waitUntilSwitch += switchDelay;
    }
 
    // Create the stobing effect
    if ((long)(millis() - strobeWait)>=0) {
        if (whichLEDback == BACK1)
            back1_State = !back1_State;
        if (whichLEDback == BACK2)
            back2_State = !back2_State;
        strobeWait += strobeDelay;
    }

 case 0xFF7A85://3 button
    digitalWrite(front1, front1_State);     // each iteration of loop() will set the IO pins,
    digitalWrite(front2, front2_State);    // even if they don't change, that's okay
    digitalWrite(back1, front1_State);
    digitalWrite(back2, front2_State);
    digitalWrite(side1, front1_State);
    digitalWrite(side2, front2_State);

    // Toggle back and forth between the two LEDs
    if ((long)(millis() - waitUntilSwitch)>=0) {
        // time is up!
        front1_State = LOW;
        front2_State = LOW;
        whichLEDfront = !whichLEDfront;  // toggle LED to strobe
        waitUntilSwitch += switchDelay;
    }
 
    // Create the stobing effect
    if ((long)(millis() - strobeWait)>=0) {
        if (whichLEDfront == FRONT1)
            front1_State = !front1_State;
        if (whichLEDfront == FRONT2)
            front2_State = !front2_State;
        strobeWait += strobeDelay;
    }
case 0xFF02FD: // play pause
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, wigwag[index * 2]);
digitalWrite(latchPin, HIGH);
delay(wigwag[(index * 2) + 1]);
index++;
if (index >= count){
index = 0;

}
    case 0xFFC23D: // fast forward
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, right[index * 2]);
digitalWrite(latchPin, HIGH);
delay(right[(index * 2) + 1]);
index++;
if (index >= count2){
index = 0;
}
    case 0xFF22DD:// rewind
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, left[index * 2]);
digitalWrite(latchPin, HIGH);
delay(left[(index * 2) + 1]);
index++;
if (index >= count3){
index = 0;}

    case 0xFF906F:// up button
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, center[index * 2]);
digitalWrite(latchPin, HIGH);
delay(center[(index * 2) + 1]);
index++;
if (index >= count4){
index = 0;} 
}
}

complete_police_lights_with_director.ino (5.74 KB)

You need a "break" statement after each "case" so it doesn't just fall through to the next case.
https://www.arduino.cc/en/Reference/SwitchCase
Also check this on how to properly post code. :slight_smile:
http://forum.arduino.cc/index.php?topic=149014.0

i forgot about the break; line, thank you. that fixed 1 issue, now the other issue is how to get either the 1,2,or 3 function to work the same time as a play, fastforward, rewind, or up function.

OP: Changing the code you initially posted makes edgemoron look like an idiot for pointing out that you need break statements, when anyone that reads the code later sees that they are there. DO NOT DO THAT AGAIN!

the other issue is how to get either the 1,2,or 3 function

You don't HAVE any 1, 2, or 3 function in that poorly indented code. Use Tools + Auto Format to properly indent your code, put the original code back, post the properly indented code in a new reply, and talk about the problems in terms of what you DO have in the code.

sorry about that, im super new to all of this. I was not aware of the auto format tool. and the 1,2, and 3 functions are the 1,2,and 3 buttons on the IR remote. this is what ive corrected to and played around with since my first post.

1 button turns on the front pattern (state machine)
2 button turns on the back pattern (state machine)
3 button turns on the front, back and sides pattern. (state machine)

play button turns on a wigwag pattern of the traffic director (shift register)
rewind turns on the right to left pattern of the traffic director (shift register)
fast forward turns on the left to right pattern of the traffic director (shift register)
up button turn on the center out pattern of the traffic director (shift register)

all functions work perfect on their own.

when i add the case statement for the IR remote and combine it all into 1 sketch the 1,2,and 3 functions ocassionally freeze (like its not syncing with the clock properly)

none of the shift register patterns are correct. ( they all do something, just not what they are supposed to do).

and i cannot get a lights pattern and a traffic director pattern going at the same time.

here is the most recent version of the code:

#define FRONT1 0x0
#define FRONT2 0x1
#define BACK1 0x0
#define BACK2 0x1

int clockPin = 2; //IC Pin 11, orange Jumper
int dataPin = 3; //IC Pin 14, yellow Jumper
int latchPin = 4; //IC Pin 12, black Jumper

byte wigwag[4] = {
  B10101010, 200,
  B01010101, 200
};

byte right[18] = {
  B10000000, 200,
  B11000000, 200,
  B11100000, 200,
  B11110000, 200,
  B11111000, 200,
  B11111100, 200,
  B11111110, 200,
  B11111111, 200,
  B00000000, 200
};

byte left[18] = {
  B00000001, 200,
  B00000011, 200,
  B00000111, 200,
  B00001111, 200,
  B00011111, 200,
  B00111111, 200,
  B01111111, 200,
  B11111111, 200,
  B00000000, 200
};

byte center[18] = {
  B00011000, 255,
  B00011000, 255,
  B00111100, 255,
  B00111100, 255,
  B01111110, 255,
  B01111110, 255,
  B11111111, 255,
  B11111111, 255,
  B00000000, 255
};

// Variable to track which LED is on
byte whichLEDfront = FRONT1;
byte whichLEDback = BACK1;

// Where are the LEDs connected?
const int front1 = 6;
const int front2 = 7;
const int back1 = 10;
const int back2 = 11;
const int side1 = 8;
const int side2 = 9;

// State variables for the LEDs
byte front1_State = LOW;
byte front2_State = LOW;
byte back1_State = LOW;
byte back2_State = LOW;

// Some delay values to change flashing behavior
unsigned long switchDelay = 600;
unsigned long strobeDelay = 100;

// Seed the initial wait for the strobe effect
unsigned long strobeWait = strobeDelay;

// Variable to see when we should swtich LEDs
unsigned long waitUntilSwitch = switchDelay;  // seed initial wait

#include <IRremote.h>

int RECV_PIN = 13;
int index = 0;
int count = sizeof(wigwag) / 2;
int count2 = sizeof(right) / 2;
int count3 = sizeof(left) / 2;
int count4 = sizeof(center) / 2;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup() {

  pinMode(front1, OUTPUT);
  pinMode(front2, OUTPUT);
  pinMode(back1, OUTPUT);
  pinMode(back2, OUTPUT);
  pinMode(side1, OUTPUT);
  pinMode(side2, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    irrecv.resume();
  }
  delay(50);
  switch (results.value) {

    case 0xFF02FD: // play pause
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, MSBFIRST, wigwag[index * 2]);
      digitalWrite(latchPin, HIGH);
      delay(wigwag[(index * 2) + 1]);
      index++;
      if (index >= count) {
        index = 0;
        break;
      }
    case 0xFFC23D: // fast forward
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, MSBFIRST, right[index * 2]);
      digitalWrite(latchPin, HIGH);
      delay(right[(index * 2) + 1]);
      index++;
      if (index >= count2) {
        index = 0;
        break;
      }
    case 0xFF22DD:// rewind
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, MSBFIRST, left[index * 2]);
      digitalWrite(latchPin, HIGH);
      delay(left[(index * 2) + 1]);
      index++;
      if (index >= count3) {
        index = 0;
      }
      break;

    case 0xFF906F:// up button
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, MSBFIRST, center[index * 2]);
      digitalWrite(latchPin, HIGH);
      delay(center[(index * 2) + 1]);
      index++;
      if (index >= count4) {
        index = 0;
      }
      break;
    case 0xFFA25D://power button
      digitalWrite(front1, LOW);
      digitalWrite(front2, LOW);
      digitalWrite(back1, LOW);
      digitalWrite(back2, LOW);
      break;

    case 0xFF30CF://1 button
      digitalWrite(back1, LOW);
      digitalWrite(back2, LOW);
      digitalWrite(side1, LOW);
      digitalWrite(side2, LOW);
      digitalWrite(front1, front1_State);     // each iteration of loop() will set the IO pins,
      digitalWrite(front2, front2_State);    // even if they don't change, that's okay

      // Toggle back and forth between the two LEDs
      if ((long)(millis() - waitUntilSwitch) >= 0) {
        // time is up!
        front1_State = LOW;
        front2_State = LOW;
        whichLEDfront = !whichLEDfront;  // toggle LED to strobe
        waitUntilSwitch += switchDelay;
      }

      // Create the stobing effect
      if ((long)(millis() - strobeWait) >= 0) {
        if (whichLEDfront == FRONT1)
          front1_State = !front1_State;
        if (whichLEDfront == FRONT2)
          front2_State = !front2_State;
        strobeWait += strobeDelay;
      }
      break;

    case 0xFF18E7://2 button
      digitalWrite(front1, LOW);
      digitalWrite(front2, LOW);
      digitalWrite(side1, LOW);
      digitalWrite(side2, LOW);
      digitalWrite(back1, back1_State);     // each iteration of loop() will set the IO pins,
      digitalWrite(back2, back2_State);    // even if they don't change, that's okay

      // Toggle back and forth between the two LEDs
      if ((long)(millis() - waitUntilSwitch) >= 0) {
        // time is up!
        back1_State = LOW;
        back2_State = LOW;
        whichLEDback = !whichLEDback;  // toggle LED to strobe
        waitUntilSwitch += switchDelay;
      }

      // Create the stobing effect
      if ((long)(millis() - strobeWait) >= 0) {
        if (whichLEDback == BACK1)
          back1_State = !back1_State;
        if (whichLEDback == BACK2)
          back2_State = !back2_State;
        strobeWait += strobeDelay;
      }
      break;

    case 0xFF7A85://3 button
      digitalWrite(front1, front1_State);     // each iteration of loop() will set the IO pins,
      digitalWrite(front2, front2_State);    // even if they don't change, that's okay
      digitalWrite(back1, front1_State);
      digitalWrite(back2, front2_State);
      digitalWrite(side1, front1_State);
      digitalWrite(side2, front2_State);

      // Toggle back and forth between the two LEDs
      if ((long)(millis() - waitUntilSwitch) >= 0) {
        // time is up!
        front1_State = LOW;
        front2_State = LOW;
        whichLEDfront = !whichLEDfront;  // toggle LED to strobe
        waitUntilSwitch += switchDelay;
      }

      // Create the stobing effect
      if ((long)(millis() - strobeWait) >= 0) {
        if (whichLEDfront == FRONT1)
          front1_State = !front1_State;
        if (whichLEDfront == FRONT2)
          front2_State = !front2_State;
        strobeWait += strobeDelay;
      }
      break;
  }
}
int count = sizeof(wigwag) / 2;
int count2 = sizeof(right) / 2;
int count3 = sizeof(left) / 2;
int count4 = sizeof(center) / 2;

How about meaningful names?

     delay(wigwag[(index * 2) + 1]);
      index++;
      if (index >= count) {
        index = 0;
        break;
      }

Why is the break in the if block?

not sure, just bad placement. i will get that changed. but that still doesnt solve the other problems.

Hi,
Why do you need IR remote, just switches would make life easier and safer.
Pressing a switch on a panel is better than locating the remote and pressing the button while driving.

Tom… :slight_smile:

because the IR remote gives me the most amount of channels with the least amount of pins. and the plan was to Velcro the remote to the dash pointed at the receiver.

but that still doesnt solve the other problems.

How do you know? You won't KNOW that until you fix the code.

i did, didnt change anything.

You changed your code. We don’t know how.

It still doesn’t work. We are expected to know why?

same issues as previously stated, but thats fine, ive decided to go a different route and use 2 separate controllers. thank you all for your help.