TL:DR - I’m having some issues trying to wrap my brain around how to build a visualization on an LED array using charlieplexing. I could use some help figuring out where my issues are.
I’ve had this OpenHeart for many years, but I’m just now getting around to putting it to some use. I’m having some issues getting it to interface with my arduino, and I’m not sure what is going on.
Here is the original code as provided by the designer.
This code doesn’t even compile for me. After a little bit of googling, I found that the likely culprit was the way the heart variable was assigned. So after a bit of fiddling I ended up changing this line:
byte heart[][27] PROGMEM ={
To this:
char heart[][27] ={
This lets it compile, but it still doesn’t run correctly. Even after changing the pinouts around to make things more obvious to me, it still doesn’t work. If I run the code posted below, I just get a single LED that lights up, LED22.
#include <avr/pgmspace.h> //This is in the Arduino library
int pin1 = 2;
int pin2 = 3;
int pin3 = 4;
int pin4 = 5;
int pin5 = 6;
int pin6 = 7;
const int pins[] = {
pin1,pin2,pin3,pin4,pin5,pin6};
const int heartpins[27][2] ={
{pin3,pin1}, {pin1,pin3}, {pin2,pin1}, {pin1,pin2},
{pin3,pin4}, {pin4,pin1}, {pin1,pin4}, {pin1,pin5}, {pin6,pin1}, {pin1,pin6}, {pin6,pin2},
{pin4,pin3}, {pin3,pin5}, {pin5,pin3}, {pin5,pin1}, {pin2,pin5}, {pin5,pin2}, {pin2,pin6},
{pin4,pin5}, {pin5,pin4}, {pin3,pin2}, {pin6,pin5}, {pin5,pin6},
{pin4,pin6}, {pin2,pin3}, {pin6,pin4},
{pin4,pin2}
};
int blinkdelay = 200; //This basically controls brightness. Lower is dimmer
int runspeed = 50; //smaller = faster
char heart[][27] ={ // This stores the array in Flash ROM. You can easily have 500+ frames.
//Blinks all on and off
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//Fills the heart up from the bottom
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,1,0,1,1,1,1},
{0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1},
{0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1},
{0,1,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
//Parts fall off the bottom
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1},
{1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,0,1,0,1,0,0,1,0,0},
{1,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1},
{1,1,1,1,0,0,1,0,1,0,0,0,1,0,1,0,1,0,0,1,0,1,0,0,1,0,0},
{0,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1},
{0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,0,1,0,1,0,0,1,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,1,0,1,1,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
//Fills up from the center
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,1,1,0,1,1,0,0,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0},
{1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,1,1,1},
{1,1,1,1,1,0,0,1,0,0,1,1,0,0,0,0,0,1,1,0,0,0,1,1,0,1,1},
{1,1,1,1,1,0,0,1,0,0,1,1,0,0,0,0,0,1,1,0,0,0,1,1,0,1,1},
//Kill line
{2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
};
void setup()
{
// blinkall(2); // useful for testing
}
void loop()
{
// sequenceon(); // useful for testing
play();
}
void turnon(int led)
{
int pospin = heartpins[led][0];
int negpin = heartpins[led][1];
pinMode (pospin, OUTPUT);
pinMode (negpin, OUTPUT);
digitalWrite (pospin, HIGH);
digitalWrite (negpin, LOW);
}
void alloff()
{
for(int i = 0; i < 6; i++)
{
pinMode (pins[i], INPUT);
}
}
void play()
{
boolean run = true;
byte k;
int t = 0;
while(run == true)
{
for(int i = 0; i < runspeed; i++)
{
for(int j = 0; j < 27; j++)
{
k = pgm_read_byte(&(heart[t][j]));
if (k == 2)
{
run = false;
}
else if(k == 1)
{
turnon(j);
delayMicroseconds(blinkdelay);
alloff();
}
else if(k == 0)
{
delayMicroseconds(blinkdelay);
}
}
}
t++;
}
}
void blinkall(int numblink)
{
alloff();
for(int n = 0; n < numblink; n++)
{
for(int i = 0; i < runspeed; i++)
{
for(int j = 0; j < 27; j++)
{
turnon(j);
delay(blinkdelay);
alloff();
}
}
delay(500);
}
}
void sequenceon()
{
for(int i = 0; i < 27; i++)
{
turnon(i);
delay(800);
alloff();
delay(800);
}
}
So I fiddled around even more, and finally got a piece of code that does something that makes sense. This piece of code just counts through the LEDs one at a time, in order. But even with this, I still haven’t been able to figure out how to get it to blink through the animations the original code contained.
#include <avr/pgmspace.h> //This is in the Arduino library
int pin1 = 2;
int pin2 = 3;
int pin3 = 4;
int pin4 = 5;
int pin5 = 6;
int pin6 = 7;
const int pins[] = {
pin1,pin2,pin3,pin4,pin5,pin6};
const int heartpins[27][2] ={
{pin3,pin1}, {pin1,pin3}, {pin2,pin1}, {pin1,pin2},
{pin3,pin4}, {pin4,pin1}, {pin1,pin4}, {pin1,pin5}, {pin6,pin1}, {pin1,pin6}, {pin6,pin2},
{pin4,pin3}, {pin3,pin5}, {pin5,pin3}, {pin5,pin1}, {pin2,pin5}, {pin5,pin2}, {pin2,pin6},
{pin4,pin5}, {pin5,pin4}, {pin3,pin2}, {pin6,pin5}, {pin5,pin6},
{pin4,pin6}, {pin2,pin3}, {pin6,pin4},
{pin4,pin2}
};
int blinkdelay = 200; //This basically controls brightness. Lower is dimmer
int runspeed = 500; //smaller = faster
char heart[][27] ={ // This stores the array in Flash ROM. You can easily have 500+ frames.
//Fills up from the center
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,1,1,0,1,1,0,0,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0},
{1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,1,1,1},
{1,1,1,1,1,0,0,1,0,0,1,1,0,0,0,0,0,1,1,0,0,0,1,1,0,1,1},
{1,1,1,1,1,0,0,1,0,0,1,1,0,0,0,0,0,1,1,0,0,0,1,1,0,1,1},
};
void setup()
{
// blinkall(2); // useful for testing
}
void loop()
{
sequenceon(); // useful for testing
// play();
}
void turnon(int led)
{
int pospin = heartpins[led][0];
int negpin = heartpins[led][1];
pinMode (pospin, OUTPUT);
pinMode (negpin, OUTPUT);
digitalWrite (pospin, HIGH);
digitalWrite (negpin, LOW);
}
void alloff()
{
for(int i = 0; i < 6; i++)
{
pinMode (pins[i], INPUT);
}
}
void play()
{
boolean run = true;
byte k;
int t = 0;
while(run == true)
{
for(int i = 0; i < runspeed; i++)
{
for(int j = 0; j < 27; j++)
{
k = pgm_read_byte(&(heart[t][j]));
if (k == 2)
{
run = false;
}
else if(k == 1)
{
turnon(j);
delayMicroseconds(blinkdelay);
alloff();
}
else if(k == 0)
{
delayMicroseconds(blinkdelay);
}
}
}
t++;
}
}
void blinkall(int numblink)
{
alloff();
for(int n = 0; n < numblink; n++)
{
for(int i = 0; i < runspeed; i++)
{
for(int j = 0; j < 27; j++)
{
turnon(j);
delay(blinkdelay);
alloff();
}
}
delay(500);
}
}
void sequenceon()
{
for(int i = 0; i < 27; i++)
{
turnon(i);
delay(800);
alloff();
delay(800);
}
}
Does anyone have any ideas what I can try? I’m sure I could eventually figure out how to make these animations work, but I I’m really not sure where to begin to figure out how to store them while working with charlieplexing, this is all a bit new to me.