Results 1 to 6 of 6

Thread: Using I2C with Vixen

  1. #1
    Join Date
    Nov 2018
    Posts
    9
    Post Thanks / Like

    Default Using I2C with Vixen

    I searched for I2C on this forum...no hits.

    Has anyone been able to use I2C devices, either directly (as an addressable controller) or indirectly (connected to an Arduino or similar).

    My current display which is running well uses an Arduino UNO, 7 I2C port expanders (7x16=112) to control 112 RGB LEDs (336 elements). I want to synchronize those lights with Vixen.

    Any ideas how to do this? I'm currently experimenting with Vixen with 4 RGB LEDs (12 elements), to an UNO, using 12 DIOs.

  2. #2
    Join Date
    Dec 2012
    Location
    Hudson MA
    Posts
    3,527
    Post Thanks / Like

    Default Re: Using I2C with Vixen

    As long as the I2C ports are connected to an external controller (like your arduino), Vixen will not know anything about them and does not need to know. You use one of the many protocol choices in the show player (Vixen, xLights, FPP) to transfer data to the controller and then the controller does whatever it takes to output that data to the lights.


    2019 - Going to visit my Daughter in New Zealand (again). I will be dark for the 2nd year in a row. Sigh..

  3. #3
    Join Date
    Dec 2011
    Location
    UK S80 postcode
    Posts
    1,386
    Post Thanks / Like

    Default Re: Using I2C with Vixen

    Hi, as Martin points out the show player (device that is sending the vixen data) has no idea what it is sending data to it just outputs in the format required. This could be:

    Normal TTL Serial, this can then be cabled or over a radio to your Uno.
    DMX, cabled to your Uno. Not a choice I would consider for this but it can be done.
    sCAN (E1.31), an Ethernet protocol that can be cabled or WiFi to your Uno.

    The first thing you need to decide is how far from the show player your Uno is going to be.

    The second thing is; do you want to have the ability to add additional Uno’s.

    Once you have decided those it is easier to select a data transmission format. That said if it’s something you want to experiment with this year then TTL Serial will get you up and running without any additional parts, Martin is very conversant with the process and I’m sure be happy to point you to posts.

    Which port expanders are you using?

    I have I2C devices in controllers as part of my display. They are coded in Arduino but use the ESP8266, data transmission over WiFi was important to me meaning that distance and expansion where not an issue.

  4. #4
    Join Date
    Nov 2018
    Posts
    9
    Post Thanks / Like

    Default Re: Using I2C with Vixen

    I'm using MCP23017 with Centipede library (handy commands)
    First I used Vixen with mono LEDs, then color LEDS, then color LEDS through a port expander. All worked okay. Now I want to try it with the system attached to 7 port expanders (112 LEDS/336 elements)...having some difficulty but it has to do with constants and variable names I used.

    BTW, can I use the serial pins on 1 and 2 (UNO) or do I have to use the USB serial connection for Vixen and for the Arduino. There's always a conflict when I have to download the Arduino (I have to disable the port connection in Vixen.)

    Thanks for the info Barnabybear, you too Martin.

    The result of my display (not sequenced, but to music) is here: https://youtu.be/CHqAdyED89s. Pretty good for an UNO I thought.

  5. #5
    Join Date
    Dec 2011
    Location
    UK S80 postcode
    Posts
    1,386
    Post Thanks / Like

    Default Re: Using I2C with Vixen

    Hi, the star looks great. The following code was written in 2016 and ran on an ESP2866 so it will need slight changes:
    Libraries - remove (#include <ESP8266WiFi.h>).
    Setup - remove (WiFi.mode(WIFI_OFF);).
    Wire.begin (needs changing to A4,A5) for the Uno – I think.

    Other than that you will need to setup a serial output in Vixen at 115200 baud with the header VIXEN. As you will probably gather this was written for 4x MSP's so the Vixen serial output will need to be setup for 64 channels (0 = OFF & 0< = ON).
    The important thing to note is that this code sits listening to the serial data until it sees V (126), I (111), X (130), E (105) & N (116). When you set up a serial header in Vixen it will add whatever you request to the start of the data stream. Once ‘VIXEN’ is received it thinks the next 64 bytes of data are outputs for the MCP's, if you only setup 16 outputs in Vixen it will use the 16 bytes of data (data count = 16) - then the VIXEN header – 126, 111, 130, 105 & 116 (data count = 21) – then the next 16 bytes of data (data count = 37). You get the idea, it is important to send at least the correct amount of data as it will read everything until it gets to 64 bytes..

    It doesn’t use the centipede library as it just became too complicated and used far too much memory. I’m guessing from comments you might not need the background but if you do have a look at this thread - https://www.diychristmas.org/vb1/sho...ll=1#post84495

    I’m not going to have access to my workshop for about 5 days (hence this post) but I will be able to check in if you have questions. I’m not sure it will be a straight forward answer as it looks like you’re doing some multiplexing, have a great Christmas.
    Code:
    #include <ESP8266WiFi.h>
    #include <Wire.h>
    
    unsigned int output_A;
    unsigned int output_B;
    unsigned int read_loop;
    unsigned int IC_loop;
    
    void setup() {
      WiFi.mode(WIFI_OFF);
      Serial.begin(115200);
      Wire.begin(2,0); //start Wire and set SDA - SCL
      
    /*  setup stuff for the MCP23017 IC - seems a bit of hastle but we get speed gains later
     *  Wire.beginTransmission(<IC address hex number>); selects which of the 4 / 8 ICs we wish to speek to
     *  the first Wire.write((byte)<register address hex number>); is the register we wish to speek to
     *  NOTE: after having spoken to a register we will be directed to the next register in the list
     *  the second Wire.write((byte)<value to put in the register hex>); puts the value in the register
     *  the third Wire.write((byte)<value to put in the register hex>); puts the value in the register after the one above
     *  we could continue like this through all the registers, but somethimes its quicker to stop and restart at another register
     *  Wire.endTransmission(); ends our current transmission and tells the IC to implement what we told it
     *  register address 0x00 holds the value that states whether the pins on bank A are an input or output
     *  register address 0x01 holds the value that states whether the pins on bank B are an input or output
     *  register address 0x12 holds the value that states whether the pins on bank A are high or low
     *  register address 0x13 holds the value that states whether the pins on bank B are high or low
    */
      for (IC_loop = 0; IC_loop < 4; IC_loop++) { // simple loop goes round 4 times
        switch (IC_loop) {                        // the value that selects which IC we write to
          case 0:
            Wire.beginTransmission(0x20);         // start transmission to IC 1
            break;
          case 1:
            Wire.beginTransmission(0x21);         // start transmission to IC 2
            break;
          case 2:
            Wire.beginTransmission(0x22);         // start transmission to IC 3
            break;
          case 3:
            Wire.beginTransmission(0x23);         // start transmission to IC 4
            break;
        }
        /* sets MCP23017 pins on both A & B banks as outputs -
        the same as pinMode(<pin>, OUTPUT); but does all 8 pins on that bank at the same time
        */
        Wire.write((byte)0x00);                   // address of register that sets as input or output
        Wire.write((byte)0x00);                   // bank A, set all as outputs (then increments to bank B)
        Wire.write((byte)0x00);                   // bank B, set all as outputs
        Wire.endTransmission();                   // ends current transmission
    
        switch (IC_loop) {
          case 0:
            Wire.beginTransmission(0x20);         // start transmission to IC 1
            break;
          case 1:
            Wire.beginTransmission(0x21);         // start transmission to IC 2
            break;
          case 2:
            Wire.beginTransmission(0x22);         // start transmission to IC 3
            break;
          case 3:
            Wire.beginTransmission(0x23);         // start transmission to IC 4
            break;
        }
        /* sets MCP23017 pins on both A & B banks as low -
        same as digitalWrite(LOW); but does all 8 pins on that bank at the same time
        */
        Wire.write(0x12);                         // address of register that sets bank A output value
        Wire.write((byte)0x00);                   // set bank A output to zero (then increments to bank B)
        Wire.write((byte)0x00);                   // set bank B output to zero
        Wire.endTransmission();                   // ends current transmission
      }
    }
    void loop() {
      for (;;) {
        while (!Serial.available());
        if (Serial.read() != 'V') {
          //    continue;
        }
        while (!Serial.available());
        if (Serial.read() != 'I') {
          continue;
        }
        while (!Serial.available());
        if (Serial.read() != 'X') {
          continue;
        }
        while (!Serial.available());
        if (Serial.read() != 'E') {
          continue;
        }
        while (!Serial.available());
        if (Serial.read() != 'N') {
          continue;
        }
        for (IC_loop = 0; IC_loop < 4; IC_loop++) {
          output_A = 0;
          for (read_loop = 0; read_loop < 8; read_loop++) {
            while (!Serial.available());
            if (Serial.read() != 0)
              bitSet(output_A, read_loop);
          }
          output_B = 0;
          for (read_loop = 0; read_loop < 8; read_loop++) {
            while (!Serial.available());
            if (Serial.read() != 0)
              bitSet(output_B, read_loop);
          }
          switch (IC_loop) {
            case 0:
              Wire.beginTransmission(0x20);
              break;
            case 1:
              Wire.beginTransmission(0x21);
              break;
            case 2:
              Wire.beginTransmission(0x22);
              break;
            case 3:
              Wire.beginTransmission(0x23);
              break;
          }
          Wire.write(0x12);
          Wire.write((byte)output_A);
    ///      Wire.write(0x13);
          Wire.write((byte)output_B);
          Wire.endTransmission();
    
          Serial.print(" : output_A ");
          Serial.print(output_A);
          Serial.print(" : output_B ");
          Serial.println(output_B);
        }
        Serial.println();
      }
    }
    Last edited by Barnabybear; 12-23-2018 at 06:11 AM.

  6. Thanks queenidog thanked for this post
  7. #6
    Join Date
    Nov 2018
    Posts
    9
    Post Thanks / Like

    Default Re: Using I2C with Vixen

    I see another problem with my current setup. I use I2C for all the individual LEDS but to get RGB, I wired the Star with 3 busses: red, green, and blue so that I have a matrix of 3 x 112. The RGB gets it's signal from DIO 9,10,11 of the UNO, and the 112 LEDS get the other side from the port expanders. This is where I ran into problems. Although I can access each individual LED by it's own unique address (from 0 to 111), some of those "pins" overlap the ones I use for the color busses, DIO 9, 10, 11. I realize that Vixen handles the color on it's own and of course that's how I want to do it.

    Ideas? To recap, my Arduino functions first select a color (DIO) or range of colors, then I decide what LEDS to light up. Repeat many times.

Tags for this Thread

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
  •