Yeah I know what you mean. I've got a bad back as well and just had an injection on Tuesday dealing with a herniated disk. Chiropractor every week keeps me going but man is it expensive.
In my arduino code I have banned delays. I only add them if it increases stability. Sometimes it good to pause for a millisecond. Other than that though I use the clock timer. Here's my bar graph code and main switch code. As I said I've been separating things out a bit preparing to get the 2 arduinos talking to each other. My bargraph has 2 animations right now. The on but idle sweep and the firing animation. I also want to add a firing done animation and a more interesting power on animation. Code is a mess as it's in transition but should give you an idea what I'm doing
Code: Select all#include <Wire.h> // Include the I2C library (required)
#include <SparkFunSX1509.h> // Include SX1509 library
#include <Adafruit_NeoPixel.h>
// for led triggers
#define HIGH 0x1
#define LOW 0x0
// neopixel pins
#define NEO_NOSE 9
Adafruit_NeoPixel noseJewel = Adafruit_NeoPixel(7, NEO_NOSE, NEO_GRB + NEO_KHZ800);
bool powerBooted = false; // has the pack booted up
// inputs
const int THEME_SWITCH = 5;
const int STARTUP_SWITCH = 6;
const int SAFETY_SWITCH = 7;
const int FIRE_BUTTON = 8;
// switch states
bool theme = false;
bool startup = false;
bool safety = false;
bool fire = false;
bool warning = false;
// dialog trigger times/states
unsigned long startDialogMillis;
const int numDialog = 3;
int currentDialog = 1;
const int dialogWaitTime = 5000;
const int warnWaitTime = 10000;
// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
SX1509 io; // Create an SX1509 object to be used throughout
int seq_1_current = 0; // current led in sequence 1
const int num_led = 15; // total number of leds in bar graph
// SX1509 pin definitions:
const byte SX1509_BAR_01 = 0;
const byte SX1509_BAR_02 = 1;
const byte SX1509_BAR_03 = 2;
const byte SX1509_BAR_04 = 3;
const byte SX1509_BAR_05 = 4;
const byte SX1509_BAR_06 = 5;
const byte SX1509_BAR_07 = 6;
const byte SX1509_BAR_08 = 7;
const byte SX1509_BAR_09 = 8;
const byte SX1509_BAR_10 = 9;
const byte SX1509_BAR_11 = 10;
const byte SX1509_BAR_12 = 11;
const byte SX1509_BAR_13 = 12;
const byte SX1509_BAR_14 = 13;
const byte SX1509_BAR_15 = 14;
void setup() {
// Call io.begin(<address>) to initialize the SX1509. If it
// successfully communicates, it'll return 1.
if (!io.begin(SX1509_ADDRESS)){
while (1) ; // If we fail to communicate, loop forever for now but lets warn the user somehow
}
noseJewel.begin();
noseJewel.show(); // Initialize all pixels to 'off'
pinMode(THEME_SWITCH, INPUT);
pinMode(STARTUP_SWITCH, INPUT);
pinMode(SAFETY_SWITCH, INPUT);
pinMode(FIRE_BUTTON, INPUT);
io.pinMode(SX1509_BAR_01, OUTPUT);
io.pinMode(SX1509_BAR_02, OUTPUT);
io.pinMode(SX1509_BAR_03, OUTPUT);
io.pinMode(SX1509_BAR_04, OUTPUT);
io.pinMode(SX1509_BAR_05, OUTPUT);
io.pinMode(SX1509_BAR_06, OUTPUT);
io.pinMode(SX1509_BAR_07, OUTPUT);
io.pinMode(SX1509_BAR_08, OUTPUT);
io.pinMode(SX1509_BAR_09, OUTPUT);
io.pinMode(SX1509_BAR_10, OUTPUT);
io.pinMode(SX1509_BAR_11, OUTPUT);
io.pinMode(SX1509_BAR_12, OUTPUT);
io.pinMode(SX1509_BAR_13, OUTPUT);
io.pinMode(SX1509_BAR_14, OUTPUT);
io.pinMode(SX1509_BAR_15, OUTPUT);
shutdown_leds();
digitalWrite(THEME_SWITCH, HIGH);
digitalWrite(STARTUP_SWITCH, HIGH);
digitalWrite(SAFETY_SWITCH, HIGH);
digitalWrite(FIRE_BUTTON, HIGH);
}
bool isFiring = false;
void loop() {
int currentMillis = millis();
int theme_switch = digitalRead(THEME_SWITCH);
//int playing = digitalRead(ACT);
int playing = 0;
if (theme_switch == 1) {
if (theme == false) {
//playTrack(themeTrack); // send message to other board to play track
theme = true;
}
} else {
theme = false;
}
int startup_switch = digitalRead(STARTUP_SWITCH);
int safety_switch = digitalRead(SAFETY_SWITCH);
int fire_button = digitalRead(FIRE_BUTTON);
if (startup_switch == 1) {
if (playing == 1) {
// playTrack(idleTrack); // send message to other board to play track
}
/*
if( powerBooted == true ){
powerSequenceOne(currentMillis);
}else{
powerSequenceBoot(currentMillis);
}
*/
if (startup == false) {
startup = true;
// playTrack(startupTrack); // send message to other board to play track
if (safety_switch == 1 && safety == false) {
safety = true;
}
}
if( safety_switch == 1 && fire_button == 0){
if( isFiring == false ){
shutdown_leds();
isFiring = true;
}
barGraphSequenceTwo(currentMillis);
}else{
if( isFiring == true ){
shutdown_leds();
isFiring = false;
}
barGraphSequenceOne(currentMillis);
}
// fire loop
if (startup == true && safety_switch == 1) {
if (safety == false) {
safety = true;
// playTrack(clickTrack); // send message to other board to play track
}
if (fire_button == 0) {
fireStrobe();
if (fire == false) {
fire = true;
//startDialogMillis = millis();
//playTrack(blastTrack); // send message to other board to play track
} else {
if (playing == 1) {
// playTrack(blastTrack); // send message to other board to play track
}
}
} else {
if (fire == true) {
clearFireStrobe();
fire = false;
// see if we've been firing long enough to get the dialog
long diff = millis() - startDialogMillis;
if( diff > warnWaitTime){
// playTrack(warnTrack); // send message to other board to play track
}else if( diff > dialogWaitTime){
switch(currentDialog){
case(1):
// playTrack(choreTrack); // send message to other board to play track
break;
case(2):
// playTrack(toolsTrack); // send message to other board to play track
break;
case(3):
// playTrack(texTrack); // send message to other board to play track
break;
}
if( currentDialog >= numDialog ){
currentDialog = 1;
}else{
currentDialog++;
}
}else{
// playTrack(endTrack); // send message to other board to play track
}
}
}
} else {
if (safety == true) {
safety = false;
// playTrack(clickTrack); // send message to other board to play track
}
}
} else {
// clearPowerStrip();
shutdown_leds();
if (startup == true) {
startup = false;
safety = false;
fire = false;
// playTrack(shutdownTrack); // send message to other board to play track
}
}
delay(1);
}
unsigned long prevFireMillis = 0;
const long fire_interval = 2; // interval at which to cycle lights (milliseconds).
int fireSeqNum = 0;
int fireSeqTotal = 3;
void clearFireStrobe(){
for( int i=0; i< 7; i++) {
noseJewel.setPixelColor(i, 0);
}
noseJewel.show();
fireSeqNum = 0;
}
void fireStrobe(){
switch( fireSeqNum ){
case 0:
noseJewel.setPixelColor(0, noseJewel.Color(255,255,255));
noseJewel.setPixelColor(1, noseJewel.Color(255,255,255));
noseJewel.setPixelColor(2, 0);
noseJewel.setPixelColor(3, noseJewel.Color(255,255,255));
noseJewel.setPixelColor(4, 0);
noseJewel.setPixelColor(5, noseJewel.Color(255,255,255));
noseJewel.setPixelColor(6, 0);
break;
case 1:
noseJewel.setPixelColor(0, noseJewel.Color(0,0,255));
noseJewel.setPixelColor(1, noseJewel.Color(255,0,0));
noseJewel.setPixelColor(2, noseJewel.Color(255,255,255));
noseJewel.setPixelColor(3, noseJewel.Color(255,0,0));
noseJewel.setPixelColor(4, noseJewel.Color(255,255,255));
noseJewel.setPixelColor(5, noseJewel.Color(255,0,0));
noseJewel.setPixelColor(6, noseJewel.Color(255,255,255));
break;
case 2:
noseJewel.setPixelColor(0, noseJewel.Color(255,0,0));
noseJewel.setPixelColor(1, 0);
noseJewel.setPixelColor(2, noseJewel.Color(0,0,255));
noseJewel.setPixelColor(3, 0);
noseJewel.setPixelColor(4, noseJewel.Color(0,0,255));
noseJewel.setPixelColor(5, 0);
noseJewel.setPixelColor(6, noseJewel.Color(0,0,255));
break;
case 3:
noseJewel.setPixelColor(0, noseJewel.Color(0,0,255));
noseJewel.setPixelColor(1, noseJewel.Color(255,0,0));
noseJewel.setPixelColor(2, noseJewel.Color(255,255,255));
noseJewel.setPixelColor(3, noseJewel.Color(255,0,0));
noseJewel.setPixelColor(4, noseJewel.Color(255,255,255));
noseJewel.setPixelColor(5, noseJewel.Color(255,0,0));
noseJewel.setPixelColor(6, noseJewel.Color(255,255,255));
break;
}
noseJewel.show();
fireSeqNum++;
if( fireSeqNum > fireSeqTotal ){
fireSeqNum = 0;
}
}
unsigned long prevBarMillis_on = 0; // bargraph on tracker
const long pwrcl_interval = 60; // interval at which to cycle lights (milliseconds).
bool reverseSequenceOne = false;
void barGraphSequenceOne(int currentMillis){
// normal sync animation on the bar graph
if (currentMillis - prevBarMillis_on > pwrcl_interval) {
// save the last time you blinked the LED
prevBarMillis_on = currentMillis;
if( reverseSequenceOne == false ){
switch_led(seq_1_current, HIGH);
seq_1_current++;
if( seq_1_current > num_led ) {
reverseSequenceOne = true;
}
}else{
switch_led(seq_1_current, LOW);
seq_1_current--;
if( seq_1_current < 0 ) {
reverseSequenceOne = false;
}
}
}
}
unsigned long prevBarMillis_fire = 0; // bargraph firing tracker
const long firing_interval = 40; // interval at which to cycle firing lights (milliseconds).
int fireSequenceNum = 1;
void barGraphSequenceTwo(int currentMillis){
// normal sync animation on the bar graph
if (currentMillis - prevBarMillis_fire > firing_interval) {
// save the last time you blinked the LED
prevBarMillis_fire = currentMillis;
switch (fireSequenceNum) {
case 1:
switch_led(2, LOW);
switch_led(14, LOW);
switch_led(1, HIGH);
switch_led(15, HIGH);
fireSequenceNum++;
break;
case 2:
switch_led(1, LOW);
switch_led(15, LOW);
switch_led(2, HIGH);
switch_led(14, HIGH);
fireSequenceNum++;
break;
case 3:
switch_led(2, LOW);
switch_led(14, LOW);
switch_led(3, HIGH);
switch_led(13, HIGH);
fireSequenceNum++;
break;
case 4:
switch_led(3, LOW);
switch_led(13, LOW);
switch_led(4, HIGH);
switch_led(12, HIGH);
fireSequenceNum++;
break;
case 5:
switch_led(4, LOW);
switch_led(12, LOW);
switch_led(5, HIGH);
switch_led(11, HIGH);
fireSequenceNum++;
break;
case 6:
switch_led(5, LOW);
switch_led(11, LOW);
switch_led(6, HIGH);
switch_led(10, HIGH);
fireSequenceNum++;
break;
case 7:
switch_led(6, LOW);
switch_led(10, LOW);
switch_led(7, HIGH);
switch_led(9, HIGH);
fireSequenceNum++;
break;
case 8:
switch_led(7, LOW);
switch_led(9, LOW);
switch_led(6, HIGH);
switch_led(10, HIGH);
fireSequenceNum++;
break;
case 9:
switch_led(6, LOW);
switch_led(10, LOW);
switch_led(5, HIGH);
switch_led(11, HIGH);
fireSequenceNum++;
break;
case 10:
switch_led(5, LOW);
switch_led(11, LOW);
switch_led(4, HIGH);
switch_led(12, HIGH);
fireSequenceNum++;
break;
case 11:
switch_led(4, LOW);
switch_led(12, LOW);
switch_led(3, HIGH);
switch_led(13, HIGH);
fireSequenceNum++;
break;
case 12:
switch_led(3, LOW);
switch_led(13, LOW);
switch_led(2, HIGH);
switch_led(14, HIGH);
fireSequenceNum = 1;
break;
}
}
}
void shutdown_leds(){
// reset the sequence
seq_1_current = 1;
fireSequenceNum = 1;
// shut all led's off
switch_led(1, LOW);
switch_led(2, LOW);
switch_led(3, LOW);
switch_led(4, LOW);
switch_led(5, LOW);
switch_led(6, LOW);
switch_led(7, LOW);
switch_led(8, LOW);
switch_led(9, LOW);
switch_led(10, LOW);
switch_led(11, LOW);
switch_led(12, LOW);
switch_led(13, LOW);
switch_led(14, LOW);
switch_led(15, LOW);
}
void switch_led(int num, int state){
switch (num) {
case 1:
io.digitalWrite(SX1509_BAR_01, state);
break;
case 2:
io.digitalWrite(SX1509_BAR_02, state);
break;
case 3:
io.digitalWrite(SX1509_BAR_03, state);
break;
case 4:
io.digitalWrite(SX1509_BAR_04, state);
break;
case 5:
io.digitalWrite(SX1509_BAR_05, state);
break;
case 6:
io.digitalWrite(SX1509_BAR_06, state);
break;
case 7:
io.digitalWrite(SX1509_BAR_07, state);
break;
case 8:
io.digitalWrite(SX1509_BAR_08, state);
break;
case 9:
io.digitalWrite(SX1509_BAR_09, state);
break;
case 10:
io.digitalWrite(SX1509_BAR_10, state);
break;
case 11:
io.digitalWrite(SX1509_BAR_11, state);
break;
case 12:
io.digitalWrite(SX1509_BAR_12, state);
break;
case 13:
io.digitalWrite(SX1509_BAR_13, state);
break;
case 14:
io.digitalWrite(SX1509_BAR_14, state);
break;
case 15:
io.digitalWrite(SX1509_BAR_15, state);
break;
}
}