Due to the 9000 char limit I've attached my .ino file to this post.
My current project is an led strip with three push buttons. One for changing the effect, color, and brightness. I'm using pin change interrupts to do this on pins 3,4,5.
Here is the first section of my code:
#include <EEPROM.h>
#include "FastLED.h"
#include "EnableInterrupt.h"
#define NUM_LEDS 20
#define PIN 7
#define EFFECT_BUTTON 3
#define COLOR_BUTTON 4
#define BRIGHTNESS_BUTTON 5
CRGB leds[NUM_LEDS];
CRGB row1[NUM_LEDS]; // array used by colorWheel function
// Color (HEX Code) Array Position
// gGreen (0x00, 0xFF, 0x00) 0,1,2
// gGreenCyan (0x00, OxFF, 0x7F) 3,4,5
// Cyan (0x00, 0xFF, 0xFF) 6,7,8
// gBlueCyan (0x00, 0x7F, 0xFF) 9,10,11
// gBlue (0x00, 0x00, 0xFF) 12,13,14
// gBlueMagenta (0x7F, 0x00, 0xFF) 15,16,17
// Magenta (0xFF, 0x00, 0xFF) 18,19,20
// gRedMagenta (0xFF, 0x00, 0x7F) 21,22,23
// gRed (0xFF, 0x00, 0x00) 24,25,26
// Orange (0xFF, 0x7F, 0x00) 27,28,29
// Yellow (0xFF, 0xFF, 0x00) 30,31,32
// gGreenYellow (0x7F, 0xFF, 0x00) 33,34,35
// White (0xFF, 0xFF, 0xFF) 36,37,38
byte ColorArray[] = {0x00, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0xFF, 0xFF, 0xFF};
byte gRed = ColorArray[0];
byte gGreen = ColorArray[1];
byte gBlue = ColorArray[2];
volatile byte selectedEffect = 0;
volatile byte selectedColor = 0;
volatile byte selectedBrightness = 0;
void setup() {
FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
pinMode (EFFECT_BUTTON, INPUT_PULLUP); // internal pull-up resistor
pinMode (COLOR_BUTTON, INPUT_PULLUP);
pinMode (BRIGHTNESS_BUTTON, INPUT_PULLUP);
enableInterrupt(EFFECT_BUTTON, changeEffect, CHANGE); // EFFECT_BUTTON pressed
enableInterrupt(COLOR_BUTTON, changeColor, CHANGE); // COLOR_BUTTON pressed
enableInterrupt(BRIGHTNESS_BUTTON, changeBrightness, CHANGE); // BRIGHTNESS_BUTTON pressed
EEPROM.get(0, selectedEffect);
EEPROM.get(1, selectedColor);
EEPROM.get(2, selectedBrightness);
Serial.begin(9600);
if (selectedEffect > 14) {
selectedEffect = 0;
EEPROM.put(0, 0);
}
if (selectedColor > 12) {
selectedColor = 0;
EEPROM.put(1, 0);
}
if (selectedBrightness > 4) {
selectedBrightness = 0;
EEPROM.put(2, 0);
}
}
I'm utilizing EEPROM.put and EEPROM.get to keep track of button presses, in conjunction with three different switches in the main loop to determine the action and then calling a particular function, or passing color variables from the predefined array, or setting brightness. "asm volatile (" jmp 0");" forces the board to reset once the value is stored in EEPROM.
void changeEffect() {
if (digitalRead (EFFECT_BUTTON) == HIGH) {
selectedEffect++;
EEPROM.put(0, selectedEffect);
asm volatile (" jmp 0");
}
}
void changeColor() {
if (digitalRead (COLOR_BUTTON) == HIGH) {
selectedColor++;
EEPROM.put(1, selectedColor);
asm volatile (" jmp 0");
}
}
void changeBrightness() {
if (digitalRead (BRIGHTNESS_BUTTON) == HIGH) {
selectedBrightness++;
EEPROM.put(2, selectedBrightness);
asm volatile (" jmp 0");
}
}
I've ran into a number of rather strange issues and I was hoping someone in the forums could help explain. The first issue is that this code only seems to work when only one interrupt is enabled. For example, the functions in the code (please see attached .ino file) work perfectly fine when the enableInterrupt function is enabled for the EFFECT_BUTTON, but as soon as I add the second or third line of code several of the effect functions either only run once, or freeze the entire program to where button presses have no effect. Even the serial port freezes. If I remove the offending line of code, it works as before, switching between functions seamlessly. Even if I have only two buttons set up for external interrupts on pins 2 and 3, and call them using attachInterrupt, it doesn't appear to matter, the effect is the same. I'm at a total loss as to how/why this is happening. Below is the code i'm referring to
enableInterrupt(EFFECT_BUTTON, changeEffect, CHANGE); // EFFECT_BUTTON pressed
enableInterrupt(COLOR_BUTTON, changeColor, CHANGE); // COLOR_BUTTON pressed
enableInterrupt(BRIGHTNESS_BUTTON, changeBrightness, CHANGE); // BRIGHTNESS_BUTTON
The second major issue I've ran into while attempt to debug is that EEPROM.put appears to be clearing all three values stored at addresses 0,1, and 2 (effect, color, and brightness variables)when the following code is ran
if (selectedEffect > 14) {
selectedEffect = 0;
EEPROM.put(0, 0);
}
Watching the serial port shows that when selectedEffect reaches a value of 1, it sets selectedColor & selectedBrightness to 0. My understanding of the .put function is that it only replaces values at the 0 address if they are different, it shouldn't be affecting the 1 and 2 address values. Although this is rather new to me, I'm hoping someone can help me understand what exactly is going on so I can hopefully get the desired result.
The last issue has briefly been mentioned but I wanted to provide an example. When the colorWipe function is called from the selectedEffect switch it will only run once (its suppose to loop) if I have anything more than one interrupt enabled. Yet if I only have the interrupt for the effects button it loops perfectly fine....I don't understand why this would affect the function in this way, does anyone have any idea why this would happen?
void colorWipe(byte gRed, byte gGreen, byte gBlue, int SpeedDelay) {
for (uint16_t i = 0; i < NUM_LEDS; i++) {
setPixel(i, gRed, gGreen, gBlue);
showStrip();
delay(SpeedDelay);
}
}
I'm hoping someone can help me debug/learn from this. Any help is greatly appreciated!
Goggle_Code_FinalVersion.ino (20.9 KB)