DMX Controlled NeoPixels "Blinking"

Hello all,
I am trying to connect 1x UNO with 1x DMX Shield with a 5m strip of 12v NeoPixels.
I wrote the following test code:

#include <Conceptinetics.h>
#include <Adafruit_NeoPixel.h>

//define NeoPixel Pin and Number of LEDs
#define PIN 8
#define NUM_LEDS 46

//create a NeoPixel strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ400);

// The slave device will use a block of 16 channels counting from
// its start address.
#define DMX_SLAVE_CHANNELS   138

DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );

const int RED = 1;
const int GREEN = 2;
const int BLUE = 3;

void setup() {

  // start the strip and blank it out
  strip.begin();
  strip.show();

  dmx_slave.enable ();

  // Set start address to 1
  dmx_slave.setStartAddress (1);
}

void loop()
{
  strip.setPixelColor(0, dmx_slave.getChannelValue (RED), dmx_slave.getChannelValue (GREEN), dmx_slave.getChannelValue (BLUE));
  strip.show();
  delay(10);

}

This works well, responding to DMX and outputting the correctly colored LED at the correct brightness.
The problem is every few seconds the strip turns off for about a second and then back on; if I unplug the DMX input, the blinking stops and the strip remains on the last DMX value.

I tried using someone elses code but the result was the same.
I have a resistor on the data line (though I also tried without it) and a CAP on the strips input power. Testing code that just turns the strip on without DMX input does not have this issue.
My guess is this is a timing issue, but I am unsure how to rectify it - anyone have any ideas?
Thanks,
Ryan

Neopixels turn off the interrupts when sending data out to them. This means that things that use the interrupts like the servo library and the serial input can get screwed during the time the data is being sent to them.

It is possible that you are sending things too fast on the DMX interface and that is corrupting a message being sent. This could be causing your unit to think it is receiving a message or screwing up what that message is.

As your code is continuously sending out the same data to the LEDs for no great effect then you are "asking for it". Try only sending data to the LEDs when there is something new to send.

Thanks @Grumpy_Mike,

I tried increasing the delay from 10 to 1000; as I got larger, the frequency of the flashing deceased. I didn't see any flashing at 1000 but I suspect it was only a matter of time before it would. Also with a delay that large is simply too long, especially when trying to display animations.

Unfortunately I do not believe the library I am using has a way to determine when only new messages are received. I thought about writing each dmx channel to a variable and then checking for a change between that variable and the live data; is there a way to do that in a "for loop", or do I have to do each comparison individually?

I have tested 2 different DMX Output devicesdevices; with my DMXcat there is about a 4 second gap between the 1 second blackouts, and with my GMA2 the gaps are much shorter under a second but the blackout only lasts a few milliseconds (so more a flicker than aa blink).

While I was searching for a solution, I found another post suggesting that the blackouts are caused by receiving random "0's" in the DMX Stream. I made an if statement in the code that would ignore messages if the blue channel on the 1st pixel was under 1/255. This seems to work (albeit at lower brightness' the LEDs to flicker slightly), though i'd prefer an actual fix to a workaround.

Ryan

Unfortunately I do not believe the library I am using has a way to determine when only new messages are received.

That is not a function of thee library it should be what your code does and at the moment you are not doing it. Do not use delays, that is not what you want.

I thought about writing each dmx channel to a variable and then checking for a change between that variable and the live data;

Are you saying that your DMX system that turns the lights on and off sends repeated identical date sets? If so that is what you want to fix if it is.

Otherwise just set the LEDs when you receive a message, not all the time.

The other solution is to use the dot star LEDs, these use a clock and data system and so don’t have to turn the interrupts of to get precise timing.

Thanks for your reply Grumpy_Mike.
Unfortunately thats how the DMX Protocol operates. But checking to see if the new value is equal to the old value, and if not sending the new value should work.
I am however having trouble assigning the variable "NEW" to a full string

NEW = 0, dmx_slave.getChannelValue (RED), dmx_slave.getChannelValue (GREEN), dmx_slave.getChannelValue (BLUE);

Perhaps this isn't possible; what is the best way to do this?

#include <Conceptinetics.h>
#include <Adafruit_NeoPixel.h>

//define NeoPixel Pin and Number of LEDs
#define PIN 8
#define NUM_LEDS 46

//create a NeoPixel strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ400);

// The slave device will use a block of 16 channels counting from
// its start address.
#define DMX_SLAVE_CHANNELS   138

DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );

const int LED = 13;
const int RED = 1;
const int GREEN = 2;
const int BLUE = 3;
int OLD = 0;
int NEW = 0;

void setup() {

  // start the strip and blank it out
  strip.begin();
  strip.show();

  dmx_slave.enable ();

  // Set start address to 1
  dmx_slave.setStartAddress (1);

  pinMode(LED, OUTPUT);
}

void loop()
{

  NEW = 0, dmx_slave.getChannelValue (RED), dmx_slave.getChannelValue (GREEN), dmx_slave.getChannelValue (BLUE);

if (NEW != OLD) // && (dmx_slave.getChannelValue (2) > 0)
  {

    strip.setPixelColor(NEW);

    strip.show();

    OLD = NEW

          digitalWrite(LED, HIGH);

  }

  else {
    digitalWrite(LED, LOW);
  }

  delay(0)

}

Otherwise, I think I would need to create a variable for each color:

#include <Conceptinetics.h>
#include <Adafruit_NeoPixel.h>

//define NeoPixel Pin and Number of LEDs
#define PIN 8
#define NUM_LEDS 46

//create a NeoPixel strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ400);

// The slave device will use a block of 16 channels counting from
// its start address.
#define DMX_SLAVE_CHANNELS   138

DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );

const int LED = 13;
const int RED = 1;
const int GREEN = 2;
const int BLUE = 3;
int OLDR = 0;
int OLDG = 0;
int OLDB = 0;
int NEWR = 0;
int NEWG = 0;
int NEWB = 0;

void setup() {

  // start the strip and blank it out
  strip.begin();
  strip.show();

  dmx_slave.enable ();

  // Set start address to 1
  dmx_slave.setStartAddress (1);

  pinMode(LED, OUTPUT);
}

void loop()
{

NEWR = dmx_slave.getChannelValue (RED);
NEWG = dmx_slave.getChannelValue (GREEN);
NEWB = dmx_slave.getChannelValue (BLUE);

if ((NEWR != OLDR) ||  (NEWG != OLDG) ||  (NEWB != OLDB)){

// if ((dmx_slave.getChannelValue (2) > 0)) {
  

    strip.setPixelColor(0, NEWR, NEWG, NEWB);

    strip.show();

    OLDR = NEWR;
    OLDG = NEWG;
    OLDB = NEWB;

          digitalWrite(LED, HIGH);

  }

  else {
    digitalWrite(LED, LOW);
  }

  delay(0);

}

Unfortunately thats how the DMX Protocol operates.

You sure of that? What exactly do the messages consist of?

I am however having trouble assigning the variable "NEW" to a full string

Is this variable supposed to be a string?
The code you are trying makes no sense at all. You can’t put comers in a variable assignment. An int variable type will store only four bytes.

You have 46 LEDs so you need to store 46 * 3 bytes to define what you have. These are stored in the strip variable you build up before you send them into the LEDs.

Are all the LEDs supposed to be the same colour or are these messages telling you exactly what LEDs in the strip are supposed to be on?

If the latter then perhaps the best solution is to compare each byte to what is already in the strip array before you put it into the strip array. If you find it the same do not put it into the strip array. If you find it differs then put it into the strip array but also mark it as it as needs displaying. Then only call a show method if the strip needs displaying.

Once you have displayed your LEDs you need to ignore the compleat set of the next message sent by DMX.

As far as my research states,

It sends channel one, followed by two, then three, all the way to channel 512, and then starts all over again constantly looping through all 512 channels

Sorry, I am very new to Arduino programming. I was hoping to have that entire "equation" saved as a variable to use later in the code; if commas cannot be used then this won't work, so thanks for that information.
Each LED will be displaying something different (to simplify things on the forum I kept it to the first LED).
So then the second code I put in my previous post should work, as it is only putting the pixels that have changed into the strip array.
I'll give it a try and report my results...

So then the second code I put in my previous post should work, as it is only putting the pixels that have changed into the strip array.

Yes but it doesn’t do the missing out of the next message after the show. You need that as well.

Why would I need to skip the next message? If the DMX Stream has changed I would still need to show it...

I wrote the following for using more LEDs than just the first one, but am getting an error...

//LIBRARY INCLUSIONS
#include <Conceptinetics.h> //DMX Shield Library
#include <Adafruit_NeoPixel.h> //NeoPixel Library

//USER ENTRY
#define PIN 8 //Data pin for NeoPixel
#define NUM_LEDS 46 //Number of LEDs in strip
#define TYPE NEO_GRB + NEO_KHZ400 //Type of NeoPixels
const int LED = 13; //Pin for Status LED
const int START = 1; //DMX Start Address

int DMX[NUM_LEDS];
int NEWR[NUM_LEDS];
int NEWG[NUM_LEDS];
int NEWB[NUM_LEDS];
int OLDR[NUM_LEDS];
int OLDG[NUM_LEDS];
int OLDB[NUM_LEDS];
int NEW = 0;
int count = 0;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, TYPE);

#define DMX_SLAVE_CHANNELS (NUM_LEDS * 3)
DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );

void setup() {

  strip.begin();
  strip.show(); //Blackout LED Strip

  dmx_slave.enable ();
  dmx_slave.setStartAddress (START);

  pinMode(LED, OUTPUT);

  for (count = 0; count < (NUM_LEDS - 1); count++) {
    int DMX[count] = ((count * 3) - 1)
  }
  for (count = (NUM_LEDS - 2); count >= 0; count--) {
    int DMX[count] = ((count * 3) - 1)
  }

}

void loop() {

  for (count = 0; count < (NUM_LEDS - 1 ); count++) {
    int NEWR[count] = dmx_slave.getChannelValue (count);
    int NEWG[count] = dmx_slave.getChannelValue (count + 1);
    int NEWB[count] = dmx_slave.getChannelValue (count + 2);

  }
  for (count = (NUM_LEDS - 2); count >= 0; count--) {
    int NEWR[count] = dmx_slave.getChannelValue (count);
    int NEWG[count] = dmx_slave.getChannelValue (count + 1);
    int NEWB[count] = dmx_slave.getChannelValue (count + 2);
  }

  if ((NEWR[count] != OLDR[count]) ||  (NEWG[count] != OLDG[count]) ||  (NEWB[count] != OLDB[count])) {

    strip.setPixelColor(DMX[count], NEWR[count], NEWG[count], NEWB[count]);

    NEW = 1;

    OLDR[count] = NEWR[count];
    OLDG[count] = NEWG[count];
    OLDB[count] = NEWB[count];

    digitalWrite(LED, HIGH);

  }

  else {

    NEW = 0;

          digitalWrite(LED, LOW);
  }


  if (NEW = 1) {
    strip.show();
  }

  delay(0);

}

Why would I need to skip the next message? If the DMX Stream has changed I would still need to show it.

Because the next message will be corrupted by the time out sending the led data, that is what is giving you the odd flashing.

I wrote the following for using more LEDs than just the first one, but am getting an error...

Which is?
Please copy and paste the error as well as the code that caused it.

What did I tell you about not defining variables inside functions?

 int NEWR[count] = dmx_slave.getChannelValue (count);
    int NEWG[count] = dmx_slave.getChannelValue (count + 1);
    int NEWB[count] = dmx_slave.getChannelValue (count + 2)

I think you are not understanding what the contents of these DMX messages are.

If something simple is not working it makes little sense trying something more complicated, fix the simple stuff first.

Ah, I understand; luckily that seems pretty simple to do with a variable and if statement so I'll fix that up this evening.

I managed to fix the "array must be initialized with a brace-enclosed initializer" error from the line "int NEWB[count] = dmx_slave.getChannelValue (count +2);" as follows:

//LIBRARY INCLUSIONS
#include <Conceptinetics.h> //DMX Shield Library
#include <Adafruit_NeoPixel.h> //NeoPixel Library

//USER ENTRY
#define PIN 8 //Data pin for NeoPixel
#define NUM_LEDS 46 //Number of LEDs in strip
#define TYPE NEO_GRB + NEO_KHZ400 //Type of NeoPixels
const int LED = 13; //Pin for Status LED
const int START = 1; //DMX Start Address

int DMX[NUM_LEDS];
int NEWR[NUM_LEDS];
int NEWG[NUM_LEDS];
int NEWB[NUM_LEDS];
int OLDR[NUM_LEDS];
int OLDG[NUM_LEDS];
int OLDB[NUM_LEDS];
int NEW = 0;
int count = 0;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, TYPE);

#define DMX_SLAVE_CHANNELS (NUM_LEDS * 3)
DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );

void setup() {

  strip.begin();
  strip.show(); //Blackout LED Strip

  dmx_slave.enable ();
  dmx_slave.setStartAddress (START);

  pinMode(LED, OUTPUT);

  for (count = 0; count < (NUM_LEDS - 1); count++) {
    int DMX[count] = {((count * 3) - 1)};
  }
  for (count = (NUM_LEDS - 2); count >= 0; count--) {
    int DMX[count] = {((count * 3) - 1)};
  }

}

void loop() {

  for (count = 0; count < (NUM_LEDS - 1 ); count++) {
    int NEWR[count] = {dmx_slave.getChannelValue (count)};
    int NEWG[count] = {dmx_slave.getChannelValue (count + 1)};
    int NEWB[count] = {dmx_slave.getChannelValue (count + 2)};

  }
  for (count = (NUM_LEDS - 2); count >= 0; count--) {
    int NEWR[count] = {dmx_slave.getChannelValue (count)};
    int NEWG[count] = {dmx_slave.getChannelValue (count + 1)};
    int NEWB[count] = {dmx_slave.getChannelValue (count + 2)};
  }

  if ((NEWR[count] != OLDR[count]) ||  (NEWG[count] != OLDG[count]) ||  (NEWB[count] != OLDB[count])) {

    strip.setPixelColor(DMX[count], NEWR[count], NEWG[count], NEWB[count]);

    NEW = 1;

    OLDR[count] = NEWR[count];
    OLDG[count] = NEWG[count];
    OLDB[count] = NEWB[count];

    digitalWrite(LED, HIGH);

  }

  else {

    NEW = 0;

          digitalWrite(LED, LOW);
  }


  if (NEW = 1) {
    strip.show();
  }

  delay(0);

}

All the DMX messages consist of is a channel number (1-512) and a value (0-255), followed by the next channel.
I am trying to put this information into the appropriate section of the LED Strip.
I have this code working already without the "comparison" of the new and previous strip data, so I am trying to update the code to include this.

I believe this new code should work (I still haven't updated the code to miss the next DMX Message; I will hopefully do this over the weekend).

Sorry, I thought you meant only commas cannot be used

No my bad, it must be some other user I was telling this too. Sorry.

NEWR = dmx_slave.getChannelValue (RED); --- this is OK
int NEWR[count] = dmx_slave.getChannelValue (count); -- this is not

Every time you use a declaration like 'int' you create a new variable. If you use it in a function it totally replaces the variable used last time in the function, and also as soon as that function has finished that variable gets totally forgotten.
You are getting an error because this line is declaring an array of length count, and you don't declare arrays like this.
Also as a style thing you never use all uppercase letters in a variable name unless it is a constant.

All the DMX messages consist of is a channel number (1-512) and a value (0-255), followed by the next channel.

So you are relying on three such messages defining the R, G & B values? If so that will not work because those messages will get out of sync with the results you are seeing. What is generating these DMX messages to begin with?

No problems, thank you for clarifying. Also, thanks for the tip regarding uppercase in variables!

As far as my reading went, int NEWR[count] is a variable array, where count is defined in the "for loop". I would therefore be adding the current value of the red channel in the corresponding LED (1st LED 1st channel, 2nd LED 4th channel and so on). This array of all new red values would then be compared to the previous array of red values, and if there is a difference the result would be sent.

Adding {} to all the array sets fixed the errors. I haven't uploaded it to the UNO yet so I'm not sure if it works; I will do this ASAP and report my results.

Yes:
1(255),2(255),3(255),4(255)...
would be
LED1Red (100%),LED1Green(100%),LED1Blue(100%),LED2Red(100%)...

I know as the Arduino has to decipher all of these it won't be perfectly instantaneous, but in my tests it's close enough.

For testing purposes I am using a DMXCat.
For programming purposes I am using a GrandMA2.
For playback purposes I will be using a DMX-RT.
These are common devices used in professional theatrical lighting; I use them for the rest of the lighting fixtures in my setup (incluing an Arduino with a DMX Shield and 2x 8 pack relays) which is why I want to integrate this Arduino/Neopixel strip.

int NEWR[count] is a variable array, where count is defined in the "for loop". I would therefore be adding the current value of the red channel in the corresponding LED (1st LED 1st channel, 2nd LED 4th channel and so on).

No. that would just be:-
NEWR[count]
Putting the 'int' in fact says I want to declare a new variable called NEWR that has "count" number of elements. In C you can't have a variable array, the array size is fixed when you declare it. Where you have this every time round the for statement you declare a new array of a different size depending what the current value of count is.

If you want to put values into the NEWR array at the position pointed at by the count variable you have to not use "int" before the variable name. The array should be declared outside any function.

Adding {} to all the array sets fixed the errors.

But in no way does it fix the fault. An error message is generated only when the compiler can not make sense of the source code. The fact that the source code is not doing what you want it to do is irrelevant.

I know as the Arduino has to decipher all of these it won't be perfectly instantaneous, but in my tests it's close enough.

Yes but as a long term stratagy this is not going to work.
You are best just getting one number and using a look up table to decipher what colours you want the lights.
Or use the number to trigger a pattern you have programmed in the Arduino.

Thank you for your reply, Grumpy_Mike.
I agree; I'm actually just going to get a DMX NeoPixel Controller specifically built for this.

But as a learning experience in Arduino I did continue tinkering with this project, and implemented the fixes you mentioned in your last post. Working with only one LED, the code (shown below) works well:

#include <Conceptinetics.h>
#include <Adafruit_NeoPixel.h>

//define NeoPixel Pin and Number of LEDs
#define PIN 8
#define NUM_LEDS 1

//create a NeoPixel strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

// The slave device will use a block of 3 channels counting from
// its start address.
#define DMX_SLAVE_CHANNELS   3

DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );

int oldDMX1 = 0;
int oldDMX2 = 0;
int oldDMX3 = 0;

int NEW = 0;

const int LED = 13;

void setup() {

  // start the strip and blank it out
  strip.begin();
  strip.show();

  dmx_slave.enable ();

  // Set start address to 1
  dmx_slave.setStartAddress (1);

  pinMode (LED, OUTPUT );
}

void loop()
{

  if (dmx_slave.getChannelValue (1) != oldDMX1 || dmx_slave.getChannelValue (2) != oldDMX2 || dmx_slave.getChannelValue (3) != oldDMX3) {

    oldDMX1 = dmx_slave.getChannelValue (1);
    oldDMX2 = dmx_slave.getChannelValue (2);
    oldDMX3 = dmx_slave.getChannelValue (3);

    strip.setPixelColor(0, dmx_slave.getChannelValue (1), dmx_slave.getChannelValue (2), dmx_slave.getChannelValue (3));

    NEW = 1;

    digitalWrite(LED, HIGH);

  }

  else {

    digitalWrite(LED, LOW);
  }


  if (NEW = 1) {
    strip.show();
    NEW = 0;
  }

  delay(10);

}

However when I try to expand the code (shown below) for the entire strip it seems that the Arduino thinks the values are different, even when theyre not (the Status LED I programmed in to turn on with a change and turn off if there is not a change stays on constantly)...

#include <Conceptinetics.h>
#include <Adafruit_NeoPixel.h>

//define NeoPixel Pin and Number of LEDs
#define PIN 8
#define NUM_LEDS 46

//create a NeoPixel strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

// The slave device will use a block of 138 channels counting from
// its start address.
#define DMX_SLAVE_CHANNELS   138

DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );

const int FIX[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45
                  };
const int DMX[] = {1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70, 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127, 130, 133, 136
                  };

int oldR[] = {
};
int oldG[] = {
};
int oldB[] = {
};

int New = 0;
int count = 0;

const int LED = 13;

void setup() {

  // start the strip and blank it out
  strip.begin();
  strip.show();

  dmx_slave.enable ();

  // Set start address to 1
  dmx_slave.setStartAddress (1);

  pinMode (LED, OUTPUT );
}

void loop()
{

  for (count = 0; count < 46; count++) {

    if (dmx_slave.getChannelValue (DMX[count]) != OldR[count] || dmx_slave.getChannelValue (DMX[count] + 1) != OldG[count] || dmx_slave.getChannelValue (DMX[count] + 2) != (OldB[count])) {

      OldR[count] = dmx_slave.getChannelValue (DMX[count]);
      OldG[count] = dmx_slave.getChannelValue (DMX[count] + 1);
      OldB[count] = dmx_slave.getChannelValue (DMX[count] + 2);

      strip.setPixelColor(FIX[count], dmx_slave.getChannelValue (DMX[count]), dmx_slave.getChannelValue (DMX[count] + 1), dmx_slave.getChannelValue (DMX[count] + 2));

      New = 1;

    }
  }

  for (count = 45; count >= 0; count--) {

    if (dmx_slave.getChannelValue (DMX[count]) != OldR[count] || dmx_slave.getChannelValue (DMX[count] + 1) != OldG[count] || dmx_slave.getChannelValue (DMX[count] + 2) != (OldB[count])) {

      OldR[count] = dmx_slave.getChannelValue (DMX[count]);
      OldG[count] = dmx_slave.getChannelValue (DMX[count] + 1);
      OldB[count] = dmx_slave.getChannelValue (DMX[count] + 2);

      strip.setPixelColor(FIX[count], dmx_slave.getChannelValue (DMX[count]), dmx_slave.getChannelValue (DMX[count] + 1), dmx_slave.getChannelValue (DMX[count] + 2));

      New = 1;

    }
  }

  if (New = 1) {
    strip.show();
    digitalWrite(LED, HIGH);
    New = 0;
  }
  else {
    digitalWrite(LED, LOW);
  }

  delay(10);

}

When you do this:-

int oldR[] = {
};
int oldG[] = {
};
int oldB[] = {
};

You create three arrays with zero length. In the C language you can't change the length of an array once it is set.

So later on when you do this:-

OldR[count] = dmx_slave.getChannelValue (DMX[count]);
      OldG[count] = dmx_slave.getChannelValue (DMX[count] + 1);
      OldB[count] = dmx_slave.getChannelValue (DMX[count] + 2);

Those values are going somewhere but you can be sure they are not being put in the Oldx array. In an interpreted language this would give you a run time error of "index outside array bounds" but as C is a compiled language there is nothing to give the error message to, so it does what you tell it. It takes the base address given to Oldx and adds the value of count to it, which gives a memory location to store the variable. The big problem is that that memory at best has not been allocated and at worse has been allocated to some other variable. In short you code is screwed.

The other thing is your test to see if anything has changed is wrong.

for (count = 45; count >= 0; count--) {

    if (dmx_slave.getChannelValue (DMX[count]) != OldR[count] || dmx_slave.getChannelValue (DMX[count] + 1) != OldG[count] || dmx_slave.getChannelValue (DMX[count] + 2) != (OldB[count])) {

For that to work you would have to check all 45 * 3 values which you don't. A check like that should be in a for loop. Before the loop starts you set a changed variable to false. Then check the old and the new one at a time. Then if any one element is not the same as the last time you set that change variable to true. The after that you use the change variable to see if you need to pump out new values. Finally you should copy all the new values into the old values, don't bother checking just which you need to change, just copy them all.

Thanks again @Grumpy_Mike,
I have updated the code as below, but the "flashing" is still present; TBH I think that is the end of me working on this project. At least I learnt a lot in the process!

#include <Conceptinetics.h>
#include <Adafruit_NeoPixel.h>

//define NeoPixel Pin and Number of LEDs
#define PIN 8
#define NUM_LEDS 46

//create a NeoPixel strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

// The slave device will use a block of 138 channels counting from
// its start address.
#define DMX_SLAVE_CHANNELS   138

DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );

const int FIX[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45
                  };
const int DMX[] = {1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70, 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127, 130, 133, 136
                  };

int OldR[46] = {
};
int OldG[46] = {
};
int OldB[46] = {
};

int New1 = 0;
int count = 0;

const int LED = 13;

void setup() {

  // start the strip and blank it out
  strip.begin();
  strip.show();

  dmx_slave.enable ();

  // Set start address to 1
  dmx_slave.setStartAddress (1);

  pinMode (LED, OUTPUT );
}

void loop()
{

  for (count = 0; count < 46; count++) {

    New1 = 0;

    if (dmx_slave.getChannelValue (DMX[count]) != OldR[count]) {
      New1 = 1;
    }
    if (dmx_slave.getChannelValue (DMX[count] + 1) != OldG[count]) {
      New1 = 1;
    }
    if (dmx_slave.getChannelValue (DMX[count] + 2) != OldB[count]) {
      New1 = 1;
    }
    if (New1 = 1) {
      strip.setPixelColor(FIX[count], dmx_slave.getChannelValue (DMX[count]), dmx_slave.getChannelValue (DMX[count] + 1), dmx_slave.getChannelValue (DMX[count] + 2));
      digitalWrite(LED, HIGH);
    }
  }

  for (count = 45; count >= 0; count--) {

    New1 = 0;

    if (dmx_slave.getChannelValue (DMX[count]) != OldR[count]) {
      New1 = 1;
    }
    if (dmx_slave.getChannelValue (DMX[count] + 1) != OldG[count]) {
      New1 = 1;
    }
    if (dmx_slave.getChannelValue (DMX[count] + 2) != OldB[count]) {
      New1 = 1;
    }
    if (New1 = 1) {
      strip.setPixelColor(FIX[count], dmx_slave.getChannelValue (DMX[count]), dmx_slave.getChannelValue (DMX[count] + 1), dmx_slave.getChannelValue (DMX[count] + 2));
      digitalWrite(LED, HIGH);
    }
  }
  strip.show();
  digitalWrite(LED, LOW);
  delay(10);
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.