I'm trying to display individual lights on an led strip as they are created which animate down the length of the strip. I'm doing this by using a custom class "Creature" to hold a colour, speed and array position. I set up a Read function to monitor button presses which decide colour and speed, then I use the function MakeNewCreature to set an entry in an array of creatures to the chosen values. Then I have an Animate function run through the array of leds on the strip and determine which ones currently align with a creature's array position, and then set the colour of that led. At the end of each run through this loop the led states are displayed (FastLED.show()).
The expected result is to have multiple dots of light moving along the strip at a time. The result I'm getting is a single dot crawling along the strip. If another creature is created through button presses then the currently displaying creature seems to stop displaying until the new creature has run to the end of the strip, at which point the first creature continues from the position is stopped at.
I'm not sure why I'm getting this behavior, it's likely something funny I've done (misunderstanding of how the code works) but I can't reconcile my code with this result. If someone would help me understand why it's doing what it's doing I'd be grateful!
I'm working with an arduino uno
Here is the code I've written (except for the debounce piece taken from a tutorial):
#include <FastLED.h>
#define DATA_PIN 13
#define NUM_LEDS 60
#define BRIGHTNESS 64
#define MAX_CREATURES 10
#define LED_TYPE NEOPIXEL
#define COLOR_ORDER GRB
#define NUMBER_OF_BUTTONS 2
#define SPEED_MULTIPLIER 100
class Creature{
public:
int speedDelay;
int colour1,colour2;
int arrayPosition;
int counter;
bool alive;
Creature(){}
Creature(int newColour1,int newColour2, int newSpeed){
colour1 = newColour1;
colour2 = newColour2;
speedDelay = newSpeed;
arrayPosition = 0;
counter = 0;
alive = true;
}
int locomotion(){
if(counter>=speedDelay){
arrayPosition++;
counter = 0;
}
else
counter++;
return arrayPosition;
}
};
Creature creatures[MAX_CREATURES];
CRGB leds[NUM_LEDS];
int buttons[] = {
2,3,4,5
};
CRGB colours[] = {
CRGB::Red,CRGB::Blue,CRGB::Green,CRGB::Yellow
};
int buttonState=0;
int tempSpeed,tempColour1,tempColour2;
int buttonCounter;
int creatureCounter;
bool makeNewCreature;
int debounce(int pin)
{
int state, previous_state;
previous_state = digitalRead(pin);
for(int i = 0; i < 25; i++)
{
delay(3);
state = digitalRead(pin);
if( state != previous_state)
{
i = 0;
previous_state = state;
}
}
return state;
}
void setup() {
delay( 3000 ); // power-up safety delay
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
FastLED.setBrightness( BRIGHTNESS );
Serial.begin(9600);
for(int i = 0; i<NUMBER_OF_BUTTONS;i++){
pinMode(buttons[i],INPUT);
}
}
void loop() {
Read();
AnimateCreatures();
}
void AnimateCreatures(){
for(int led = 0; led<NUM_LEDS;led++){
for(int a = 0; a<MAX_CREATURES;a++){
if(creatures[a].alive){
if(creatures[a].locomotion() == led){
leds[led] += colours[creatures[a].colour1]+colours[creatures[a].colour2];
}
else{
leds[led] = CRGB::Black;
}
if (creatures[a].locomotion()>=60){
creatures[a].alive = false;
}
}
}
}
FastLED.show();
}
void MakeNewCreature(){
Creature newCreature(tempColour1,tempColour2,tempSpeed);
creatures[creatureCounter] = newCreature;
creatureCounter++;
if(creatureCounter>=MAX_CREATURES){
creatureCounter=0;
}
}
void Read(){
for(int i = 0; i<NUMBER_OF_BUTTONS;i++){
if(debounce(buttons[i])==HIGH){
Serial.println(String("Button Pressed: ")+i);
switch (buttonCounter){
case 0:
tempColour1 = i;
break;
case 1:
tempColour2=i;
break;
case 2:
tempSpeed=(i+1)*SPEED_MULTIPLIER;
break;
}
buttonCounter++;
if(buttonCounter>=3){
buttonCounter=0;
MakeNewCreature();
}
}
}
}