I got this code from a guy at Instructables, but I can't seem to get the push button section working. I've looked around a bit on the forums, trying to figure out his logic, but I can't make sense of it. I was wondering if anyone could look at it and explain what's going on, and how to fix the problem.
The push button is supposed to select between four different modes, but when I push it, it just starts the first mode over again. I know the button is working, so I figure it must be some logic problem in the code. Either that, or the button I have wired up won't work the code. It's an SPST momentary contact push button, wired to digital pin 4 along GND and a 2.2K resistor to HOT. Any help is greatly appreciated, thanks.
//example use of LCD4Bit library with a 20x4 Display
#include <LCD4Bit.h>
LCD4Bit lcd = LCD4Bit(2);
char decBuffer[] = {0,0,0,0,0,0,0};
char decFill = '0';
int bootUp = 0;
//-- Variables-------------
float h;
int h_int;
int hVal=0;
int r=0, g=0, b=0;
int oldHue;
int newHue;
int glowHue;
int lcdRefreshRate=0;
//-- input Controls---------
int potPin = 2; // Switch connected to analog pin 2
int potVal =0;
//-- button pins-----------------
#define Sw0 4 /* digital line to read "Sw0"... "SWitch zero" Wire it for closed pulls line low (i.e. to 0v)*/
boolean boItWasOn;
boolean boItIsOn;
byte bCount=1; //btn count
int btnPin = 4; // choose the input pin (for a pushbutton)
//----------------------------------
//-- output controls -------
int rpin = 3;
int gpin = 5;
int bpin = 6;
//--lcd pins ---------------
// pins 7,8,9,10
//
//--------------------------
#define MODESPEED 0
#define MODEHUE 1
#define MODERANDHUE 2
#define MODEGLOW 3
void h2rgb(float h, int &R, int &G, int &B);
void setup() {
//pinMode(ledPin, OUTPUT); //we'll use the debug LED to output a heartbeat
lcd.init();
pinMode(btnPin, INPUT); // declare pushbutton as input
Serial.begin(9600); // set up Serial library at 9600 bps
h=0;
boItWasOn=boSw0();
}
void loop() {
do {
boItIsOn=boSw0();
selectMode(bCount);
if (bootUp == 0) { bootMsg(); bootUp++;}
}while (not(boItWasOn xor boItIsOn));
boItWasOn=boItIsOn;
delay(300);
bCount++;
if (bCount==6){bCount=0;};
}
void selectMode(byte bToWrite)
{
switch (bToWrite)
{
case 0:{}
case 1:{
modeSpeed();
lcdPrint(MODESPEED);
serialPrint(MODESPEED);
break;
}
case 2:{}
case 3:{
modeHue();
lcdPrint(MODEHUE);
serialPrint(MODEHUE);
break;
}
case 4:{}
case 5:{
modeRandomHue();
lcdPrint(MODERANDHUE);
serialPrint(MODERANDHUE);
break;
}
case 6:{}
case 7:{
modeGlowHue();
lcdPrint(MODEGLOW);
serialPrint(MODEGLOW);
break;
}
};
}
//----modeSpeed hue loop, control loop speed
void modeSpeed(){
potVal=analogRead(potPin); // Read the pin and display the value
//------------------------------
potVal = pow((potVal/100),1.25)+1;
hVal = hVal + potVal;
if (hVal >1024) { hVal=0;}
//---------------------------------
h = ((float)hVal)/1024;
h_int = (int) 360*h;
h2rgb(h,r,g,b);
analogWrite(rpin, r);
analogWrite(gpin, g);
analogWrite(bpin, b);
}
//----modeHue SELECT hUE
void modeHue(){
potVal=analogRead(potPin); // Read the pin and display the value
h = ((float)potVal)/1024;
h_int = (int) 360*h;
h2rgb(h,r,g,b);
analogWrite(rpin, r);
analogWrite(gpin, g);
analogWrite(bpin, b);
}
void modeRandomHue(){
potVal=analogRead(potPin)/102;
if (newHue >= oldHue) {
oldHue = oldHue + potVal;
if (oldHue >= newHue) { newHue=random(1,1024); } //if random hue from old to new are equal, pick new random hue
}
if (newHue <= oldHue) {
oldHue = oldHue - potVal;
if (oldHue <= newHue) { newHue=random(1,1024); } //if random hue from old to new are equal, pick new random hue
}
h = ((float)oldHue)/1024;
h_int = (int) 360*h;
h2rgb(h,r,g,b);
analogWrite(rpin, r);
analogWrite(gpin, g);
analogWrite(bpin, b);
}
void modeGlowHue(){
///---not worked on. don't know how i want to acheive this effect
modeRandomHue();
potVal=analogRead(potPin)/102;
analogWrite(rpin, r+ (r - potVal));
analogWrite(gpin, g+ (g - potVal));
analogWrite(bpin, b+ (b - potVal));
}
void serialPrint(int Mode){
switch (Mode)
{
case MODESPEED:{
Serial.print(" [ Speed : ");
Serial.print(potVal);
Serial.print(" ] ");
break;
}
case MODEHUE:{
Serial.print(" [ Hue : ");
Serial.print(h_int);
Serial.print(" ] ");
break;
}
case MODERANDHUE:{
Serial.print(" [ old Hue : ");
Serial.print(oldHue);
Serial.print(" ] ");
Serial.print(" [ new Hue : ");
Serial.print(newHue);
Serial.print(" ] ");
break;
}
/*
case MODEGLOW:{
Serial.print(" [ Glow Hue : ");
Serial.print(h_int);
Serial.print(" ] ");
break;
}
*/
};
Serial.print(" [ bCount : ");
Serial.print(bCount);
Serial.print(" ] ");
Serial.print(" [ rgb: ");
Serial.print(r);
Serial.print(",");
Serial.print(g);
Serial.print(",");
Serial.print(b);
Serial.print(" ] ");
Serial.println("");
}
void h2rgb(float H, int& R, int& G, int& B) {
int var_i;
float S=1, V=1, var_1, var_2, var_3, var_h, var_r, var_g, var_b;
if ( S == 0 ) //HSV values = 0 [ch65533] 1
{
R = V * 255;
G = V * 255;
B = V * 255;
}
else
{
var_h = H * 6;
if ( var_h == 6 ) var_h = 0; //H must be < 1
var_i = int( var_h ) ; //Or ... var_i = floor( var_h )
var_1 = V * ( 1 - S );
var_2 = V * ( 1 - S * ( var_h - var_i ) );
var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) );
if ( var_i == 0 ) {
var_r = V ;
var_g = var_3 ;
var_b = var_1 ;
}
else if ( var_i == 1 ) {
var_r = var_2 ;
var_g = V ;
var_b = var_1 ;
}
else if ( var_i == 2 ) {
var_r = var_1 ;
var_g = V ;
var_b = var_3 ;
}
else if ( var_i == 3 ) {
var_r = var_1 ;
var_g = var_2 ;
var_b = V ;
}
else if ( var_i == 4 ) {
var_r = var_3 ;
var_g = var_1 ;
var_b = V ;
}
else {
var_r = V ;
var_g = var_1 ;
var_b = var_2 ;
}
R = (1-var_r) * 255; //RGB results = 0 [ch65533] 255
G = (1-var_g) * 255;
B = (1-var_b) * 255;
}
}
boolean boSw0()
{
/* The remmed out material is equivalent to the remaining
single line... longer, but more clear! If you are happy taking
the obscure shortcut, there is no need to "package" it in the
function, of course.
boolean boReturn;
if (digitalRead(Sw0)==1)
{boReturn=true;}
else
{boReturn=false;};
return boReturn;*/
return digitalRead(Sw0);//More strictly typed languages wouldn't allow this.
}
void waitForChange()
{
//Bad programming... reference made to global variables.
//Especially bad: Changing their values.
do {
boItIsOn=boSw0();
}
while (not(boItWasOn xor boItIsOn));
boItWasOn=boItIsOn;
}
Note: I took out unnecessary functions pertaining to LCD display. Also, the WaitForChange() function at the the end there isn't called anywhere; maybe it should be?