Simple code for Arduino Uno/Mega. Up to 48 realy/SSR channels, with Random mode

We shall have our Christmas Extravaganza!!!!

2 incorrectly shipped relays later, we now have a matching set of High Level Trigger relays installed and working. Our many challenges included my ignorance and inventory but we have overcome using this community, Victor's original Code found on pg 1, and a whole lot of cheer.

Merry Christmas everyone and thank you to all.

*It turns out, the chaos I was experiencing earlier with the High I had installed, it was my own mistake from plugging lights into assigned outlets incorrectly. DOH!!*
 
Hi,

I am a newbie with a similar setup with Arduino and 4 Sainsmart High Trigger SSR and the Victors sketch on first page . I have 3 blocks of 16 switches (2 SSR) connected back to Arduino via CAT6 cables. I am driving each block with its on power (AC and DC) and did not ground the SSR to Arduino board. I have not had any issues with any of the sequences I play. Am I missing out on something or potentially risking something? If I power all the SSR from Arduino board would it risk the Arduino board drawing too much current? Just got my first show of the ground this year after 2 years of lurking and trying to learn. Thanks
 
I'm not asking for anybody to fix this, but could you possibly help me out with the direction to go? I've tried if/else and while, but I can't figure it out.
 
Re: Easy to use code for Arduino Uno/Mega. Up to 48 channels, with Random mode

I went ahead and wrote a sketch with pieces of code from Zparticle and Si_champion/Neil Tapp.
It should work fine for up to 18 channels in Arduino Uno, and up to 48 in Arduino Mega (could be coded for more, but I don't know if anyone needs more than that).

There are a few #define lines on top to set the serial speed, the number of channels to use, and whether the relays activate with a high or low signal:
-Set the number of channels that you will use with the line #define CHANNEL_COUNT 16

-Set the mode line to "#define MODE INVERTED" or "#define MODE NOT_INVERTED" as needed. If your channels are doing the opposite than expected, change it to the other mode.

-Set the com port speed (currently to 57600) #define VIXEN_COM_SPEED 57600

-Set the timeout (in milliseconds) for Random mode with #define TIME_OUT 1000

It only uses 1 library for the watchdog timer, included in the arduino IDE, so just copy the code to a new sketch, change the channels, speed, and relay mode settings, and upload to your Arduino.

NOTE: If you use an Arduino Uno, remove all the #define lines for channels after 18, and remove those channels from the line with "int channels[] = {CH01..." as all those pins are only valid in the Arduino Mega and would give a compilation error in an Arduino Uno.

It works in the following way:

-Vixen needs to be setup to use a header of: ~!
-Sets all the channels to off in startup.
-Wait for up to 2 seconds (can be changed for longer) and if there is no valid input, it goes into random mode, blinking some lights on and off every second.
-If it detects valid input (with ~! header), it writes to the relays, as long as Vixen is working.
-If Vixen goes off for more than 2 seconds, back to random mode.

Here is the code:

Code:
 // This code was written by Victor Perez for doityourselfchristmas.com based on the code from Zparticle, Si_champion and Neil Tapp.
 // To adapt the code to your case, just change this top section, with the #define lines.
 
 // Includes the watchdog timer library
 #include <avr/wdt.h>
 
 // This sets how many channels will vixen be sending. Can be set to any number from 1 to 48 for Arduino Mega, and 1 to 18 for Arduino Uno.
 #define CHANNEL_COUNT 16

 // speed for the com port for talking with vixen. From 9600 to 115200. Use the same speed as set in Vixen.
 #define VIXEN_COM_SPEED 57600
 
 // Timeout waiting for serial input before going to random mode (in milliseconds).
 #define TIME_OUT 1000
 
 // If the relays turn On and Off opposite to Vixen sequence, change "#define MODE NOT_INVERTED" for "#define MODE INVERTED"
 #define NOT_INVERTED 0
 #define INVERTED 1
 #define MODE NOT_INVERTED

 // which pins control which channels
 // You can change these assignment to use different pins, but be very careful to not repeat the same pin number for 2 channels. 
 // DO NOT use pings 0 and 1, as those are for the serial port to talk to the computer.
 #define CH01 2
 #define CH02 3
 #define CH03 4
 #define CH04 5
 #define CH05 6
 #define CH06 7
 #define CH07 8
 #define CH08 9
 #define CH09 10
 #define CH10 11
 #define CH11 12
 #define CH12 13
 #define CH13 A0
 #define CH14 A1
 #define CH15 A2
 #define CH16 A3
 #define CH17 A4
 #define CH18 A5
// Up to here for Arduino uno.
 #define CH19 A6
 #define CH20 A7
 #define CH21 A8
 #define CH22 A9
 #define CH23 A10
 #define CH24 A11
 #define CH25 A12
 #define CH26 A13
 #define CH27 A14
 #define CH28 A15
 #define CH29 22
 #define CH30 23
 #define CH31 24
 #define CH32 25
 #define CH33 26
 #define CH34 27
 #define CH35 28
 #define CH36 29
 #define CH37 30
 #define CH38 31
 #define CH39 32
 #define CH40 33
 #define CH41 34
 #define CH42 35
 #define CH43 36
 #define CH44 37
 #define CH45 38
 #define CH46 39
 #define CH47 40
 #define CH48 41
 
 int channels[] = {CH01,CH02,CH03,CH04,CH05 ,CH06,CH07,CH08,CH09,
 CH10,CH11,CH12,CH13,CH14,CH15,CH16,CH17,CH18,CH19,CH20,CH21,CH22,
 CH23,CH24,CH25,CH26,CH27,CH28,CH29,CH30,CH31,CH32,CH33,CH34,CH35,
 CH36,CH37,CH38,CH39,CH40,CH41,CH42,CH43,CH44,CH45,CH46,CH47,CH48};

 int incomingByte[CHANNEL_COUNT];

int i = 0;     // Loop counter
volatile unsigned long  timer_a = 0; // new line

//setup the pins/ inputs & outputs
void setup(){

  // enable the watchdog timer with a time of 1 second. If the board freezes, it will reset itself after 1 second.
  wdt_enable(WDTO_1S);
  
  // specifically for the UNO
  sei();  

// initalize PWM Channels / Pins
 for (i=0; i < CHANNEL_COUNT; i++){
    pinMode(channels[i], OUTPUT);
  }

// set all the realys to off to start with
if (MODE == NOT_INVERTED) {
 for (i=0; i < CHANNEL_COUNT; i++){
     digitalWrite(channels[i], LOW);

 }
}

else {
 for (i=0; i < CHANNEL_COUNT; i++){
     digitalWrite(channels[i], HIGH);
 }
}

 testSequence();
 
// set up Serial according to the speed defined above.
  Serial.begin(VIXEN_COM_SPEED);
}

void loop()
{
   if (Serial.available() >= (CHANNEL_COUNT+2)) {
     wdt_reset(); // resets the watchdog
     timer_a = millis (); // new line
     int uno = Serial.read();
     if (uno == 126){
       
       int dos = Serial.read();
       if (dos == 33){
   
         for (i=0; i < CHANNEL_COUNT; i++) {
             // read each byte
          incomingByte[i] = Serial.read();
         }
		 if (MODE == NOT_INVERTED) {
			for (i=0; i < CHANNEL_COUNT; i++){
			int value = incomingByte[i];
			if (value <= 127) {
				digitalWrite(channels[i], LOW);
			}
			else {
				digitalWrite(channels[i], HIGH);
			}
			}
		 }
		 else {
		 for (i=0; i < CHANNEL_COUNT; i++){
			int value = incomingByte[i];
			if (value < 127) {
				digitalWrite(channels[i], HIGH);
			}
			else {
				digitalWrite(channels[i], LOW);
			}
			}
		 }

       }
     }
   }
// Random mode code. Random mode starts if no serial input has been received in TIME_OUT millisenconds
   else {
     wdt_reset(); // resets the watchdog
     unsigned long diff = millis() - timer_a;
     if (diff >= TIME_OUT) {
       timer_a = millis ();
       int random_a = 0;
       for (i=0; i < CHANNEL_COUNT; i++){
         random_a = random(0, 2);
         if (random_a == 0) {
           digitalWrite(channels[i], LOW);
         }
         else {
           digitalWrite(channels[i], HIGH);
         }
       }
     }
   }
}

void testSequence(){

if (MODE == NOT_INVERTED) {
 for (i=0; i < CHANNEL_COUNT; i++){
   wdt_reset(); // resets the watchdog
   digitalWrite(channels[i], HIGH);
   delay (500);
   digitalWrite(channels[i], LOW);
 }
}

else {
 for (i=0; i < CHANNEL_COUNT; i++){
   wdt_reset(); // resets the watchdog
   digitalWrite(channels[i], LOW);
   delay (500);
   digitalWrite(channels[i], HIGH);
   }
 }
}

Hi,

I have this code and it works in randon mode and when I start vixen it stops and I can see the coms chatter on the light on the board, but it does not trip any relays when I start the basic sequence I have programmed, the issue appears to be the effect selected is gray / dark on the screen and not an indication of which effect is in play.

Any Ideas ?
 
That's going to be a Vixen configuration issue. Best to post the question in the Vixen forum. But somewhere in Vixen you don't have the elements defined or mapped correctly.
Dis you add the header information in the Vixen controller config screen?
 
Re: Easy to use code for Arduino Uno/Mega. Up to 48 channels, with Random mode

Hi,

I have this code and it works in randon mode and when I start vixen it stops and I can see the coms chatter on the light on the board, but it does not trip any relays when I start the basic sequence I have programmed, the issue appears to be the effect selected is gray / dark on the screen and not an indication of which effect is in play.

Any Ideas ?
If the effect is grey or transparent then you are applying colors not supported by the color filters you are using for your props. An effect will only work if there is a 100% color match.
 
Re: Easy to use code for Arduino Uno/Mega. Up to 48 channels, with Random mode

That makes sense :)
I have used the generic serial for the setup to a bank of relays, which effects should I be using to trigger ?
I really appreciate your answers.. i have been getting no where for hours.
Cheers
 
Re: Easy to use code for Arduino Uno/Mega. Up to 48 channels, with Random mode

That makes sense :)
I have used the generic serial for the setup to a bank of relays, which effects should I be using to trigger ?
I really appreciate your answers.. i have been getting no where for hours.
Cheers
Set Level makes the most sense for on/off devices. You can also use many of the other effects as long as you get the colors to match the color filters. Dimming effects will not work for you with mechanical relays.
 
Back
Top