Page 1 of 29 12311 ... LastLast
Results 1 to 10 of 287

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

  1. #1
    Join Date
    Nov 2014
    Location
    Austin, TX
    Posts
    164
    Post Thanks / Like

    Default 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);
       }
     }
    }
    Last edited by victor_pv; 12-04-2014 at 11:35 AM. Reason: Edited to add watchdog timer as per Simmonwood recommendations in page 4

  2. Thanks smcq64, imeagle, GSPFilmworks, oldcaptainrusty thanked for this post
    Likes smcq64 liked this post
  3. #2
    Join Date
    Nov 2009
    Location
    Morrisburg, On, Canada
    Posts
    2,541
    Post Thanks / Like

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

    May I suggest you enclose code in code tags? Without using code tags there is a possibility that spaces are inserted and then the code will not compile.

    example;
    Code:
    void loop()
     {
     if (Serial.available() >= (CHANNEL_COUNT+2)) {
     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();
     }

  4. #3
    Join Date
    Nov 2014
    Location
    Austin, TX
    Posts
    164
    Post Thanks / Like

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

    Nice, didn't know you could do that
    Done now
    Last edited by victor_pv; 11-21-2014 at 04:24 PM.

  5. #4
    Join Date
    Nov 2014
    Location
    Destin, Fl
    Posts
    157
    Post Thanks / Like

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

    Ok, I've just started my Vixen/Arduino Mega combo about 2 weeks ago - until then, I had not even touched an Aruduino. I've played around with a bunch of sketches, some worked, some I got to work, and some I gave up on. This one works GREAT, and I appreciate all of the work that went into it. I plan on using it, however with one small (or so I thought) modification. When Vixen 3 isn't running, I would like all of the relays to be on - and all off right before the show starts. I know it has to be possible, but I can't figure it out for the life of me!

    I have: Arduino Mega R3, Vixen 3, 24 channels and the header works!

    Sorry for the sloppy code...

    Thanks for your time!

    Code:
    // Copy from this line down to your new sketch
    // 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.
    // 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 24
    
    // 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 2000
    
    // 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. 
    // which pins control which channels
    #define CHANNEL01 2
    #define CHANNEL02 3
    #define CHANNEL03 4
    #define CHANNEL04 5
    #define CHANNEL05 6
    #define CHANNEL06 7
    #define CHANNEL07 8
    #define CHANNEL08 9
    #define CHANNEL09 45
    #define CHANNEL10 44
    #define CHANNEL11 43
    #define CHANNEL12 42
    #define CHANNEL13 41
    #define CHANNEL14 40
    #define CHANNEL15 39
    #define CHANNEL16 38
    #define CHANNEL17 29
    #define CHANNEL18 28
    #define CHANNEL19 27
    #define CHANNEL20 26
    #define CHANNEL21 25
    #define CHANNEL22 24
    #define CHANNEL23 23
    #define CHANNEL24 22
    
    int channels[] = { CHANNEL01, CHANNEL02, CHANNEL03, CHANNEL04, CHANNEL05,
    		CHANNEL06, CHANNEL07, CHANNEL08, CHANNEL09,
    		CHANNEL10, CHANNEL11, CHANNEL12, CHANNEL13, CHANNEL14, CHANNEL15,
    		CHANNEL16, CHANNEL17, CHANNEL18, CHANNEL19, CHANNEL20,
    		CHANNEL21, CHANNEL22, CHANNEL23, CHANNEL24 };
    
    int incomingByte[CHANNEL_COUNT];
    
    int i = 0;     // Loop counter
    
    volatile unsigned long timer_a = 0; // new line
    
    //setup the pins/ inputs & outputs
    void setup() {
    
    	// 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)) {
    		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 {
    	//turn them all on
    			turnLightsOn();
    	}
    }
    
    void testSequence() {
    
    	if (MODE == NOT_INVERTED) {
    		for (i = 0; i < CHANNEL_COUNT; i++) {
    			digitalWrite(channels[i], HIGH);
    			delay(120);
    			digitalWrite(channels[i], LOW);
    			
    		}
    	}
    
    	else {
    		for (i = 0; i < CHANNEL_COUNT; i++) {
    			digitalWrite(channels[i], LOW);
    			delay(500);
    			digitalWrite(channels[i], HIGH);
    			delay(500);
    		}
    	}
    }
    
    void turnLightsOn()
    {
    	int n = 0;	   // On counter
    	for (n = 0; n < CHANNEL_COUNT; n++) {
    		digitalWrite(channels[n], HIGH);
    	}
    			
    }
    
    void turnLightsOff()
    {
    	//turn them all off
    	int f = 0;	   // Off counter
    	for (f = 0; f < CHANNEL_COUNT; f++) {
    		digitalWrite(channels[f], LOW);
    	}
    }
    Last edited by outbreak; 11-21-2014 at 11:36 PM. Reason: Added "and all off right before the show starts"

  6. #5
    Join Date
    Nov 2014
    Location
    Austin, TX
    Posts
    164
    Post Thanks / Like

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

    You took a bit too much away in the part that checks if it is waiting for serial input and nothing comes, you still need to have some timeout there.
    Try like this, it will turn on all the lights if nothing is coming from Vixen for 20 seconds, so it gives you 20 seconds of lights off. If nothing comes, then turns all the lights ON and keeps them that way until Vixen starts sending data or you reset the arduino.

    Code:
    // Copy from this line down to your new sketch
    // 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.
    // 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 24
    
    // 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 20000
    
    // 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. 
    // which pins control which channels
    #define CHANNEL01 2
    #define CHANNEL02 3
    #define CHANNEL03 4
    #define CHANNEL04 5
    #define CHANNEL05 6
    #define CHANNEL06 7
    #define CHANNEL07 8
    #define CHANNEL08 9
    #define CHANNEL09 45
    #define CHANNEL10 44
    #define CHANNEL11 43
    #define CHANNEL12 42
    #define CHANNEL13 41
    #define CHANNEL14 40
    #define CHANNEL15 39
    #define CHANNEL16 38
    #define CHANNEL17 29
    #define CHANNEL18 28
    #define CHANNEL19 27
    #define CHANNEL20 26
    #define CHANNEL21 25
    #define CHANNEL22 24
    #define CHANNEL23 23
    #define CHANNEL24 22
    
    int channels[] = { CHANNEL01, CHANNEL02, CHANNEL03, CHANNEL04, CHANNEL05,
    		CHANNEL06, CHANNEL07, CHANNEL08, CHANNEL09,
    		CHANNEL10, CHANNEL11, CHANNEL12, CHANNEL13, CHANNEL14, CHANNEL15,
    		CHANNEL16, CHANNEL17, CHANNEL18, CHANNEL19, CHANNEL20,
    		CHANNEL21, CHANNEL22, CHANNEL23, CHANNEL24 };
    
    int incomingByte[CHANNEL_COUNT];
    
    int i = 0;     // Loop counter
    
    volatile unsigned long timer_a = 0; // new line
    
    //setup the pins/ inputs & outputs
    void setup() {
    
    	// specifically for the UNO
    	//sei();  
    
    // initalize PWM Channels / Pins
    	for (i = 0; i < CHANNEL_COUNT; i++) {
    		pinMode(channels[i], OUTPUT);
    	}
    
    // set all the relays 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)) {
    		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 {
      //turn them all on
            unsigned long diff = millis() - timer_a;
            if (diff >= TIME_OUT) {
             timer_a = millis ();
             turnLightsOn();
    	}
    }
    }
    
    void testSequence() {
    
    	if (MODE == NOT_INVERTED) {
    		for (i = 0; i < CHANNEL_COUNT; i++) {
    			digitalWrite(channels[i], HIGH);
    			delay(120);
    			digitalWrite(channels[i], LOW);
    			
    		}
    	}
    
    	else {
    		for (i = 0; i < CHANNEL_COUNT; i++) {
    			digitalWrite(channels[i], LOW);
    			delay(500);
    			digitalWrite(channels[i], HIGH);
    		}
    	}
    }
    
    void turnLightsOn()
    {
      for (i = 0; i < CHANNEL_COUNT; i++) {
      digitalWrite(channels[i], HIGH);
      }
    }

  7. #6
    Join Date
    Nov 2014
    Location
    Destin, Fl
    Posts
    157
    Post Thanks / Like

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

    You're the HEAT!!! Thank you!!!

    One more question. The way I understand it, is that if there is a Vixen schedule waiting to be run, that would cause all of these lights to be off until the actual show ran. Would it be possible to use a PININ and PINOUT to open the relays if the PININ was set to "HIGH" during the entire show - therefore allowing the relays to be switched on?

    This may not make sense, I'm INCREDIBLY tired...I can try to re-attack in the morning.

    Again, THANK YOU!!!

  8. #7
    Join Date
    Nov 2014
    Location
    Austin, TX
    Posts
    164
    Post Thanks / Like

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

    You mean like using a pin in the arduino as input, like a switch to set the lights to stay off forever until the shows start?

  9. #8
    Join Date
    Nov 2014
    Location
    Austin, TX
    Posts
    164
    Post Thanks / Like

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

    Quote Originally Posted by outbreak View Post
    You're the HEAT!!! Thank you!!!

    One more question. The way I understand it, is that if there is a Vixen schedule waiting to be run, that would cause all of these lights to be off until the actual show ran. Would it be possible to use a PININ and PINOUT to open the relays if the PININ was set to "HIGH" during the entire show - therefore allowing the relays to be switched on?

    This may not make sense, I'm INCREDIBLY tired...I can try to re-attack in the morning.

    Again, THANK YOU!!!
    By the way, the way it is set, doesn't matter if Vixen is open or not, as long as it is not sending data for more than 20 seconds (in your new sketch), it will go in random mode. So when the show finishes, after 20 seconds it goes to random mode.

  10. #9
    Join Date
    Nov 2014
    Location
    Destin, Fl
    Posts
    157
    Post Thanks / Like

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

    Quote Originally Posted by victor_pv View Post
    You mean like using a pin in the arduino as input, like a switch to set the lights to stay off forever until the shows start?
    Yes, that's what I meant!

  11. #10
    Join Date
    Nov 2014
    Location
    Destin, Fl
    Posts
    157
    Post Thanks / Like

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

    Quote Originally Posted by victor_pv View Post
    By the way, the way it is set, doesn't matter if Vixen is open or not, as long as it is not sending data for more than 20 seconds (in your new sketch), it will go in random mode. So when the show finishes, after 20 seconds it goes to random mode.
    That's what I originally thought would happen, however as soon as I start Vixen, data is sent to my Arduino and opens the relays.

Page 1 of 29 12311 ... LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •