Hi all,
My 1st post here. I'm running into this crazy weird issue - any help would be appreciated!!!
My ProjectI'm building this 20-LEDs project, I wrote a small software for editing the LED patterns and animation. The frames are uploaded to the EEPROM with a 1st sketch and then read by a 2nd sketch that turns on each LED and controls the timing, loops, etc.
The IssueHere's my problem: each individual LED turns on/off nicely (see video below) but when 2 or more LEDs are lit, I get some weird patterns.
This simple video summarizes it well:
https://www.youtube.com/watch?v=XLDbFfPZhLcThe simplest case is when I turn LEDs 1+2+3 at once, I get 1+3. When I turn 6+7+8 I get 3+8... This is driving me nuts!
What Could Be Wrong?!1. Software?
I checked the code and I'm 99% confident it is not the problem (I output the DigitalWrite calls and I get the expected result). Is it possible the chip gets desynchronized and executes instructions in the wrong order?
2. Hardware?
I initially suspected I created a soldering bridge in the MUX but I checked carefully and is doesn't seem to be the case. My only hypethesis at this stage is that the MUX is somehow not working as it should.
Or maybe the MUX doesn't support multiple simultaneout output signals? the documentation (
Mux_Shield_II_User_Guide) says it does.
3. Next Steps?
I'm thinking I should try to remove the MUX and see if I can get LEDs 1+2+3 using the Arduino directly. This would tell me if the MUX is the problem...
SpecsHere're the specs:
- Arduino UNO R3
- MUX Shield II with first 2 rows attached to individual LEDs
- The code looks like this (this is a small snippets, as I'm pretty sure it's a hardware issue)
Code (extract)
// example of EEPROM value, starting at 32:
// 0x4, 0x0, 0xe8, 0x3, 0x1, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x3, 0x80, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0
#include <MuxShield.h>
#include <EEPROM.h>
# define EEPROM_START 32 // start address of structure in EEPROM
//Initialize the Mux Shield
MuxShield muxShield;
static byte bit_io_mapping[20][2] = {\
{1, 0}, // left, tile 00 -> IO1 PIN0
{1, 1}, // left, tile 01 -> IO1 PIN1
{1, 2}, // left, tile 02 -> IO1 PIN2
{1, 3}, // left, tile 03 -> IO1 PIN3
{1, 4}, // left, tile 04 -> IO1 PIN4
{1, 5}, // left, tile 05 -> IO1 PIN5
{1, 6}, // left, tile 06 -> IO1 PIN6
{1, 7}, // left, tile 07 -> IO1 PIN7
{2, 0}, // left, tile 08 -> IO2 PIN0
{2, 1}, // left, tile 09 -> IO2 PIN1
{1, 10}, // right, tile 00 -> IO1 PIN10
{2, 3}, // right, tile 01 -> IO1 PIN11
{1, 12}, // right, tile 02 -> IO1 PIN12
{1, 13}, // right, tile 03 -> IO1 PIN13
{1, 14}, // right, tile 04 -> IO1 PIN14
{1, 15}, // right, tile 05 -> IO1 PIN15
{1, 11}, // right, tile 06 -> IO2 PIN3
{2, 2}, // right, tile 07 -> IO2 PIN2
{1, 8}, // right, tile 08 -> IO1 PIN8
{1, 9}}; // right, tile 09 -> IO1 PIN9
// set the state of the relays
void set_relays(unsigned long relay_state)
{
// Turn off all relay gates by toggling all IO 1 and 2 outputs
for (int j = 1 ; j < 4 ; j++)
for (int i = 0 ; i < 16 ; i++)
muxShield.digitalWriteMS(j, i, HIGH);
// read the 20 first bits and active the correct LED
bool is_active = false;
for (int i = 0 ; i < 20; i++)
{
is_active = bitRead(relay_state, i);
if (is_active)
{
muxShield.digitalWriteMS(bit_io_mapping[i][0], bit_io_mapping[i][1], is_active ? LOW : HIGH);
Serial.println(" led #" + String(i) + " IO" + String(bit_io_mapping[i][0]) + "PORT" + String(bit_io_mapping[i][1]));
}
}
}
// load an animation stored in the Arduino's EEPROM
bool run_animation(unsigned int &eeprom_address)
{
unsigned int nb_frames = 0;
unsigned int speed = 0;
unsigned long frame = 0;
unsigned long f[4];
byte nb_loops = 0;
Serial.println("loading animation from EEPROM " + String(eeprom_address));
// nb frames (2 bytes = Arduino's unsigned int)
byte b1 = EEPROM.read(eeprom_address++); // Reads a byte from the EEPROM
byte b2 = EEPROM.read(eeprom_address++);
nb_frames = (b2 << 8) | b1;
Serial.println(" nb_frames = " + String(nb_frames));
// speed (2 bytes = Arduino's unsigned int)
b1 = EEPROM.read(eeprom_address++); // Reads a byte from the EEPROM
b2 = EEPROM.read(eeprom_address++);
speed = (b2 << 8) | b1;
Serial.println(" speed = " + String(speed));
// nb loops (1 byte = BYTE)
nb_loops = EEPROM.read(eeprom_address++);
Serial.println(" nb_loops = " + String(nb_loops));
unsigned int start_address = eeprom_address;
for (int loop_idx = 0 ; loop_idx < nb_loops ; loop_idx++)
{
eeprom_address = start_address; // reset the read address for the next loop
// animation frame #
for (int frame_idx = 0 ; frame_idx < nb_frames ; frame_idx++)
{
// tiles (20 bits encoded on 4 bytes)
for (int i = 0 ; i<4 ; i++)
f[i] = EEPROM.read(eeprom_address++);
frame = (unsigned long)((f[0] << 24) | (f[1] << 16) | (f[2] << 8) | f[3]);
set_relays(frame);
delay(speed);
}
}
}
void setup()
{
Serial.begin(9600);
// Set I/O 1, I/O 2, and I/O 3 as digital outputs
muxShield.setMode(1, DIGITAL_OUT);
muxShield.setMode(2, DIGITAL_OUT);
muxShield.setMode(3, DIGITAL_OUT);
// Turn off all relay gates by toggling all IO 1 and 2 outputs
for (int j = 1 ; j < 4 ; j++)
for (int i=0 ; i<16 ; i++)
muxShield.digitalWriteMS(j, i, HIGH);
}
void loop()
{
unsigned int eeprom_address = EEPROM_START;
run_animation(eeprom_address);
}
Here're some pictures of the setup (my friends are laughing at it but I built it to be robust and flexible)
Any help would be welcome! I'm getting a bit desperate now!

Thanks
-Romain