0
votes

I am trying to use an arduino to take incoming data from vixen software through serial comm. and move the data to 12 other arduino it works if I keep the channel numbers from the vixen to 43 but I need to control 480 channels. so the first arduino controls 43 channels the next is 44-87 and so on.

this is my master code: `void setup() { Serial.begin(9600);

  Serial3.begin(9600); 
}

void loop()
{ 
   // read from port 0, send to port 1:
   if (Serial.available()) {
   int inByte = Serial.read();
   Serial3.write(inByte); 

} } this is the slave code: // Output

int cue1 = 3;
int cue2 = 4;
int cue3 = 5;
int cue4 = 6;
int cue5 = 7;
int cue6 = 8;
int cue7 = 9;
int cue8 = 10;
int cue9 = 11;
int cue10 = 12;
int cue11 = 13;
int cue12 = 22;
int cue13 = 23;
int cue14 = 24;
int cue15 = 25;
int cue16 = 26;
int cue17 = 27;
int cue18 = 28;
int cue19 = 29;
int cue20 = 30;
int cue21 = 31;
int cue22 = 32;
int cue23 = 33;
int cue24 = 34;
int cue25 = 35;
int cue26 = 36;
int cue27 = 37;
int cue28 = 38;
int cue29 = 39;
int cue30 = 40;
int cue31 = 41;
int cue32 = 42;
int cue33 = 43;
int cue34 = 44;
int cue35 = 45;
int cue36 = 46;
int cue37 = 47;
int cue38 = 48;
int cue39 = 49;
int cue40 = 50;
int cue41 = 51;
int cue42 = 52;
int cue43 = 53;


 int i = 0;
 int incomingByte[43];


  void setup() // run once, when the sketch starts

  {
     Serial3.begin(9600);
     pinMode(cue1, OUTPUT); // sets the digital pin as output
     pinMode(cue2, OUTPUT); // sets the digital pin as output
     pinMode(cue3, OUTPUT); // sets the digital pin as output
     pinMode(cue4, OUTPUT); // sets the digital pin as output
     pinMode(cue5, OUTPUT); // sets the digital pin as output
     pinMode(cue5, OUTPUT); // sets the digital pin as output
     pinMode(cue6, OUTPUT); // sets the digital pin as output
     pinMode(cue7, OUTPUT); // sets the digital pin as output
     pinMode(cue8, OUTPUT); // sets the digital pin as output
     pinMode(cue9, OUTPUT); // sets the digital pin as output
     pinMode(cue10, OUTPUT); // sets the digital pin as output
     pinMode(cue11, OUTPUT); // sets the digital pin as output
     pinMode(cue12, OUTPUT); // sets the digital pin as output
     pinMode(cue13, OUTPUT); // sets the digital pin as output
     pinMode(cue14, OUTPUT); // sets the digital pin as output
     pinMode(cue15, OUTPUT); // sets the digital pin as output
     pinMode(cue16, OUTPUT); // sets the digital pin as output
     pinMode(cue17, OUTPUT); // sets the digital pin as output
     pinMode(cue18, OUTPUT); // sets the digital pin as output
     pinMode(cue19, OUTPUT); // sets the digital pin as output
     pinMode(cue20, OUTPUT); // sets the digital pin as output
     pinMode(cue21, OUTPUT); // sets the digital pin as output
     pinMode(cue22, OUTPUT); // sets the digital pin as output
     pinMode(cue23, OUTPUT); // sets the digital pin as output
     pinMode(cue24, OUTPUT); // sets the digital pin as output
     pinMode(cue25, OUTPUT); // sets the digital pin as output
     pinMode(cue26, OUTPUT); // sets the digital pin as output
     pinMode(cue27, OUTPUT); // sets the digital pin as output
     pinMode(cue28, OUTPUT); // sets the digital pin as output
     pinMode(cue29, OUTPUT); // sets the digital pin as output
     pinMode(cue30, OUTPUT); // sets the digital pin as output
     pinMode(cue31, OUTPUT); // sets the digital pin as output
     pinMode(cue32, OUTPUT); // sets the digital pin as output
     pinMode(cue33, OUTPUT); // sets the digital pin as output
     pinMode(cue34, OUTPUT); // sets the digital pin as output
     pinMode(cue35, OUTPUT); // sets the digital pin as output
     pinMode(cue36, OUTPUT); // sets the digital pin as output
     pinMode(cue37, OUTPUT); // sets the digital pin as output
     pinMode(cue38, OUTPUT); // sets the digital pin as output
     pinMode(cue39, OUTPUT); // sets the digital pin as output
     pinMode(cue40, OUTPUT); // sets the digital pin as output
     pinMode(cue41, OUTPUT); // sets the digital pin as output
     pinMode(cue42, OUTPUT); // sets the digital pin as output
     pinMode(cue43, OUTPUT); // sets the digital pin as output

     }

      void loop()
    {
       if (Serial3.available() >=43)
    {
      for (int i=0; i<43;i++)
     {
       incomingByte[i] = Serial3.read();
        }                                      
     digitalWrite(cue1, incomingByte[0]);  
     digitalWrite(cue2, incomingByte[1]);  
     digitalWrite(cue3, incomingByte[2]);  
     digitalWrite(cue4, incomingByte[3]);  
     digitalWrite(cue5, incomingByte[4]);  
     digitalWrite(cue6, incomingByte[5]);  
     digitalWrite(cue7, incomingByte[6]);  
     digitalWrite(cue8, incomingByte[7]);  
     digitalWrite(cue9, incomingByte[8]);  
     digitalWrite(cue10, incomingByte[9]);  
     digitalWrite(cue11, incomingByte[10]); 
     digitalWrite(cue12, incomingByte[11]); 
     digitalWrite(cue13, incomingByte[12]); 
     digitalWrite(cue14, incomingByte[13]); 
     digitalWrite(cue15, incomingByte[14]); 
     digitalWrite(cue16, incomingByte[15]);  
     digitalWrite(cue17, incomingByte[16]);  
     digitalWrite(cue18, incomingByte[17]);  
     digitalWrite(cue19, incomingByte[18]);  
     digitalWrite(cue20, incomingByte[19]);  
     digitalWrite(cue21, incomingByte[20]);  
     digitalWrite(cue22, incomingByte[21]);  
     digitalWrite(cue23, incomingByte[22]);  
     digitalWrite(cue24, incomingByte[23]);  
     digitalWrite(cue25, incomingByte[24]);  
     digitalWrite(cue26, incomingByte[25]); 
     digitalWrite(cue27, incomingByte[26]); 
     digitalWrite(cue28, incomingByte[27]); 
     digitalWrite(cue29, incomingByte[28]); 
     digitalWrite(cue30, incomingByte[29]); 
     digitalWrite(cue31, incomingByte[30]);  
     digitalWrite(cue32, incomingByte[31]);  
     digitalWrite(cue33, incomingByte[32]);  
     digitalWrite(cue34, incomingByte[33]);  
     digitalWrite(cue35, incomingByte[34]);  
     digitalWrite(cue36, incomingByte[35]);  
     digitalWrite(cue37, incomingByte[36]);  
     digitalWrite(cue38, incomingByte[37]);  
     digitalWrite(cue39, incomingByte[38]);  
     digitalWrite(cue40, incomingByte[39]);  
     digitalWrite(cue41, incomingByte[40]); 
     digitalWrite(cue42, incomingByte[41]); 
     digitalWrite(cue43, incomingByte[42]); 

       }
      }`
1

1 Answers

0
votes

First you did not actually ask a question. Which is bad form for this forum.

Seeing you have basically copied the typical Vixen code and added to it on top of a Mega, I can see several areas that need addressing. How to expand to multiple units, Framing and buffer size.

The typical example that appears to be proliferated for Arduino's receiving from Vixen. Is scary in that it does not frame the Start or End of the stream of cues. Rather it requires the stream to be and stay synchronized, being dependent upon the length. This will work until ONE byte is lost. Then everything will be out of sync until each component is reset and restarted. Something you will not want to do with multiple Arduino's.

The following code enhances this with the configuring the Vixen's General Serial Port setup to enable the "Send a Text Footer" sending the single letter "E".

Vixen General Port Set Up 2.0

Taking advantage that in this implementation the output cues are only boolean. Being ON or OFF. Where the Vixen will send either 0x00 or 0xFF for each cue in the sequence. So with the above footer enabled Vixen will terminate each sequence with the byte 'E' or 0x45 (hex). Normally the cues are a range from 0x00 through 0xFF for intensity. If this were the case, then a more complex Footer would be needed, as 0x45 may be legitimate value. Whereas in this case 'E' will work nicely.

#define FIRST_IN_CHAIN 1 // set this to 1 for the first in Chain
#define SIZE_OF_ARRAY(X) (sizeof(X)/sizeof(X[0])) //total length divided by length of one element

// As specified in Vixen's General Serial Port Setup "Send a Text Footer"
#define VIXEN_END_OF_TEXT 'E'

#if (FIRST_IN_CHAIN == 1)
  #define SERIALIN Serial
#else
  #define SERIALIN Serial2
#endif

// General GPIO used to output Cues
uint8_t pins[] = {3,4,5,6,7,8,9,10,11,12,13,\
  // not used SerialX ports
  // 14,15, \ // TXD3/RXD3
  // 16,17, \ // TXD2/RXD2
  // 18,19, \ // TXD1/RXD1
  // 20,21, \ // SDA/SCL
  22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53};

void setup() {
  SERIALIN.begin(9600);
  Serial3.begin(9600);

  // initialize cue pins OFF and Output
  for (uint8_t pin = 0; pin < SIZE_OF_ARRAY(pins); pin++) {
    digitalWrite(pins[pin], LOW);
    pinMode(pins[pin], OUTPUT);
  }
}

void loop()
{
  // get first 43 cues for this Arduino
  for (uint8_t pin = 0; pin < SIZE_OF_ARRAY(pins); pin++) {
    while(!SERIALIN.available()); // wait for some data.
    char c = SERIALIN.read();
    if(c == VIXEN_END_OF_TEXT) {
      return;
    }
    else if(c > 0) {
      digitalWrite(pins[pin], HIGH);
    } 
    else {
      digitalWrite(pins[pin], LOW);
    }
  }

  // read from port 0, send to port 1:
  while(1) {
    while(!SERIALIN.available()) ; // wait for next data.
   // echo byte on to the next stage
    char c = SERIALIN.read();
    Serial3.write(c); 
    if(c == VIXEN_END_OF_TEXT) {
      // when Carriage Return is received Exit while and wait for new frame 
      break;
    }
  }
}

Now this is not perfect and since I don't have a Vixen and such set up it has not been proven. However, it does compile and appears it should work fine.

Configured with a footer of 'E' Vixen sends out the stream of bytes representing each Cue terminating the frame with a 'E'. So the above sketch listens for the first 43 cues and applies them to the local pins. If by chance the script gets out of sequence and a Footer of 'E' is inadvertently detected the loop() is returned to start a-new. If successfully recieves all the cues to be locally applied it then moves onto echo the remaining in cues out Serial3 (TXD3) to the next Arduino's Serial2 (RXD2), until a footer 'E" is received denoting the end of the sequence. At which point it starts over. Note the cue's locally applied are not echo'ed, this means the next Arduino will again act on the next 43 or first 43 cues it receives and echo the remainder on until the chain is exhausted.

enter image description here


Few points of interest:

Note the use of

    while(!SERIALIN.available()); // wait for some data.

Which is effectively "wait while there is no data to be read" or wait until there is something. These are Blocking (meaning the code is stuck) until something is received. Whereas it is expected that Vixen will periodically be sending the stream of cues. And even if ONE 'E' is missed the next frame will contain it, so that the code will autonomously re-synchronize.

Also worth noting the pins to cue definition is more flexible. If you want to possible use 47 cues, un-comment:

  // 18,19, \ // TXD1/RXD1
  // 20,21, \ // SDA/SCL

the code will automatically resize. Or comment out other pins if used for other purposes.

It is worth noting that 9600 baud is approximately 960 bytes per second. which means the sequence can only update just less then twice a second or approximately 2 Hz. And the daisy chaining would add noticeable propagation delays and difference between Arduino's. Vixen 2 can be configured with a maximum rate of 57600 baud which can yield approximately 12 Hz. Hence I would recommend configuring both Vixen and the Arduino's to at least 57600 Baud. As to minimize these affects. Vixen 3 can actually go faster. Where I would recommend 115200 Baud or 24 Hz.

To summarize The first unit is compiled with FIRST_IN_CHAIN defined as 1. This causes the lead ArduinoMega to receive the data from Serial port attached to the PC running Vixen. The remaining Mega's are compiled with FIRST_IN_CHAIN defined as 0. Where the Serial3 of the preceding unit is connected to the next units Serial2. It is possible to drive into Serial. Where it is simpler to reserve Serial for debugging and such. Vixen is configured with a Foot of 'E'.

Where buffer size is not an issue in this solution as each byte is handled individually. Not waiting for them all to build up in the Arduino's Serial.read() buffer. Which would over fill beyond 62.