Help with some code, please.

Hi everyone,
I am working on a project that takes 7 leds, and with 2 push buttons to click up and down through the leds.

So it would start with led 2 and then click up one at a time to led 6. Then I also want have a button that will shift the lights down from 6 to 1.

Here is the code I have so far. It won't compile. But the last working version shifts the lights properly one way. Can I ask you guys for some help.

How would I get the second button to work to shuffle the lights down?
And can anyone tell why this won't compile. It was compiling, and now it won't.

Thanks,
Tim

int switchPin = 9; // switch is connected to pin 9
int led1Pin = 8;
int led2Pin = 7;
int led3Pin = 6;
int led4Pin = 5;
int led5Pin = 4;
int led6Pin = 3;
int led7Pin = 2;

int val; // variable for reading the pin status
int val2; // variable for reading the delayed status
int buttonState; // variable to hold the button state

int lightMode = 0; // What mode is the light in?

void setup() {
pinMode(switchPin, INPUT); // Set the switch pin as input

pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
pinMode(led3Pin, OUTPUT);
pinMode(led4Pin, OUTPUT);
pinMode(led5Pin, OUTPUT);
pinMode(led6Pin, OUTPUT);
pinMode(led7Pin, OUTPUT);

Serial.begin(9600); // Set up serial communication at 9600bps
buttonState = digitalRead(switchPin); // read the initial state
}

void loop(){
val = digitalRead(switchPin); // read input value and store it in val
delay(10); // 10 milliseconds is a good amount of time
val2 = digitalRead(switchPin); // read the input again to check for bounces
if (val == val2) { // make sure we got 2 consistant readings!
if (val != buttonState) { // the button state has changed!
if (val == LOW) { // check if the button is pressed
if (lightMode == 0) { // Reverse gear
lightMode = 1; // 1st gear
} else {
if (lightMode == 1) { // if its 1st gear
lightMode = 2; // make it 2nd gear
} else {
if (lightMode == 2) { // if 2nd gear
lightMode = 3; // make it 3rd gear
} else {
if (lightMode == 3) { // if its 3rd gear,
lightMode = 4; // turn to 4th gear!
} else {
if (lightMode == 4) { // if 4th gear
lightMode = 5; // make it 5th gear
} else {
if (lightMode == 5) { // if its 5th gear,
lightMode = 6; // turn to 6th gear!
}
}
}
}
}
}
buttonState = val; // save the new state in our variable
}

// Now do whatever the lightMode indicates
if (lightMode == 0) { // Reverse gear
digitalWrite(led1Pin, HIGH);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
digitalWrite(led4Pin, LOW);
digitalWrite(led5Pin, LOW);
digitalWrite(led6Pin, LOW);
digitalWrite(led7Pin, LOW);
}

if (lightMode == 1) { // 1 gear
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, HIGH);
digitalWrite(led3Pin, LOW);
digitalWrite(led4Pin, LOW);
digitalWrite(led5Pin, LOW);
digitalWrite(led6Pin, LOW);
digitalWrite(led7Pin, LOW);
}

if (lightMode == 2) { // 2 gear
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, HIGH);
digitalWrite(led4Pin, LOW);
digitalWrite(led5Pin, LOW);
digitalWrite(led6Pin, LOW);
digitalWrite(led7Pin, LOW);
}
if (lightMode == 3) { // "3 gear"
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
digitalWrite(led4Pin, HIGH);
digitalWrite(led5Pin, LOW);
digitalWrite(led6Pin, LOW);
digitalWrite(led7Pin, LOW);
}
if (lightMode == 4) { // "4 gear"
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
digitalWrite(led4Pin, LOW);
digitalWrite(led5Pin, HIGH);
digitalWrite(led6Pin, LOW);
digitalWrite(led7Pin, LOW);
}
if (lightMode == 5) { // "5 gear"
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
digitalWrite(led4Pin, LOW);
digitalWrite(led5Pin, LOW);
digitalWrite(led6Pin, HIGH);
digitalWrite(led7Pin, LOW);
}
if (lightMode == 6) { // "6 gear"
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
digitalWrite(led4Pin, LOW);
digitalWrite(led5Pin, LOW);
digitalWrite(led6Pin, LOW);
digitalWrite(led7Pin, HIGH);
}

I just had some fun with you concept in mind:

#define UP_BUTTON 7 // the number of the input pin
#define NUMBER_OF_LEDS 7
#define NUMBER_OF_SWITCHES 2

#define DECREASE 0
#define INCREASE 1

//set current led with rules
#define INCREASE_GEAR (currentGear<NUMBER_OF_LEDS ? currentGear++ : currentGear)
#define DECREASE_GEAR (currentGear>0 ? currentGear-- : currentGear)

byte ledPins[] = {7,8,9,10,11,12,13}; // the number of the output pin
byte switchPins[] = {5,6}; //5 decrease - 6 increase

byte currentGear = 1;

void setup(){
for (byte i=0; i<NUMBER_OF_SWITCHES; i++){
pinMode( switchPins , INPUT);

  • }*
  • for (byte i=0; i<NUMBER_OF_LEDS; i++){*
    _ pinMode( ledPins , OUTPUT);_
    * }*
    }
    void loop()
    {
    * //GET STATES*
    * for (byte i=0; i<NUMBER_OF_SWITCHES; i++){
    _ if ( digitalRead(switchPins) == HIGH ){
    if ( i == INCREASE ){_
    INCREASE_GEAR;
    _ } else {//( i == DECREASE ){_
    DECREASE_GEAR;
    _ }
    //delay(20); //debounce using delay*
    * }
    }
    //SET STATES*
    * for (byte i=0; i<NUMBER_OF_LEDS; i++){*
    digitalWrite(ledPins*,LOW);
    }
    digitalWrite(ledPins[currentGear], HIGH);
    }
    [/quote]*_

WOW! Thanks so much for that. You have set me a lot closer to getting this thing working. There is one issue that I am coming up with. The 1st light will work, the down shift button works to go down, but doesn't save its state. Then when you up shift, it flashes all of the leds and then nothing is lite. If I down shift it will go into the reverse gear, then pop back to the 1st gear (the not saving it's state thing) then sit in first gear as it should. ?

Here is my modified code to fit my board. Did I mess something up? Thanks again for all of your help.

#define UP_BUTTON 9 // the number of the input pin
#define NUMBER_OF_LEDS 7
#define NUMBER_OF_SWITCHES 2

#define DECREASE 0
#define INCREASE 1

//set current led with rules
#define INCREASE_GEAR (currentGear<NUMBER_OF_LEDS ? currentGear++ : currentGear)
#define DECREASE_GEAR (currentGear>0 ? currentGear-- : currentGear)

byte ledPins[] = {2,3,4,5,6,7,8}; // the number of the output pin
byte switchPins[] = {9,10}; //9 decrease - 10 increase

byte currentGear = 1;

void setup(){
for (byte i=0; i<NUMBER_OF_SWITCHES; i++){gy
pinMode( switchPins , INPUT);
}
for (byte i=0; i<NUMBER_OF_LEDS; i++){
_ pinMode( ledPins , OUTPUT);_
}
}
void loop()
{
//GET STATES
for (byte i=0; i<NUMBER_OF_SWITCHES; i++){
_ if ( digitalRead(switchPins*) == HIGH ){
if ( i == INCREASE ){_
INCREASE_GEAR;
_ } else {//( i == DECREASE ){_
DECREASE_GEAR;
_ }
//delay(20); //debounce using delay*
* }
}
//SET STATES*
for (byte i=0; i<NUMBER_OF_LEDS; i++){
digitalWrite(ledPins*,LOW);
}
digitalWrite(ledPins[currentGear], HIGH);
}*_

Hmm.

Try this code, turn on the serial monitor, and let me what happens :slight_smile:

Cool project BTW!

#define UP_BUTTON 7 // the number of the input pin
#define NUMBER_OF_LEDS 7
#define NUMBER_OF_SWITCHES 2

#define DEBUG true

#define MAX_GEARCHANGES_PER_SECOND 10 //you can not change gear more than 10 times a second
#define DEBOUNCE (1000/MAX_GEARCHANGES_PER_SECOND)

#define DECREASE 0
#define INCREASE 1

//set current led with rules
#define INCREASE_GEAR (currentGear<NUMBER_OF_LEDS ? currentGear++ : currentGear)
#define DECREASE_GEAR (currentGear>0 ? currentGear-- : currentGear)

byte ledPins[] = {2,3,4,5,6,7,8}; // the number of the output pin
byte switchPins[] = {9,10}; //9 decrease - 10 increase

byte currentGear = 0;
unsigned long gearTime = 0;

void setup(){
for (byte i=0; i<NUMBER_OF_SWITCHES; i++){
pinMode( switchPins , INPUT);

  • }*
  • for (byte i=0; i<NUMBER_OF_LEDS; i++){*
    _ pinMode( ledPins , OUTPUT);_
    * }*
    * if (DEBUG){Serial.begin(9600);}*
    }
    void loop()
    {
    * //GET STATES*
    * for (byte i=0; i<NUMBER_OF_SWITCHES; i++){
    _ if ( digitalRead(switchPins) == HIGH && millis()>gearTime+DEBOUNCE){
    if ( i == INCREASE ){_
    INCREASE_GEAR;
    _ } else {//( i == DECREASE ){_
    DECREASE_GEAR;
    _ }
    gearTime = millis();
    }
    }
    //SET STATES*
    * for (byte i=0; i<NUMBER_OF_LEDS; i++){*
    digitalWrite(ledPins*,LOW);
    }
    digitalWrite(ledPins[currentGear], HIGH);*_

* if (DEBUG){Serial.print("Current gear: ");Serial.println(currentGear,DEC);}*
}
[/quote]

Thank you so much for all of your help on this. We are getting really close. The serial output is awesome! So the leds, and the up shift process is almost working. If I hold the button, it will cycle up to the top gear, then pause until the button is released. Once released, the leds cycle down properly. But I am still not getting it to save it's state per button press.

Here are a few pictures of the rig. My phone isn't the best camera but it'll give you an idea.


Thank you so much for all of your help on this. We are getting really close. The serial output is awesome!

Fun to help!

Does the serial, print correct gear? I do not understand why the state is not stored.

Could you post a copypaste of the serial output?

I'm working on it right now. I have it now saving it's state. But it shifts super fast. I need to slow down the shift.

I am working on double checking my code because I messed with something and it messed things up a little. I will post new code changes, and a copy of the serial output in a few minutes. My arduino software is so slow, and it is always freezing up on me for long periods of time while it figures out where it's at. Is this normal?

Simple edit. I don't know what changing my max gearchanges per second did, but I changed that, and then I cut out the millis in this line
"if ( digitalRead(switchPins*) == HIGH>gearTime+DEBOUNCE){"*
#define UP_BUTTON 7 // the number of the input pin
#define NUMBER_OF_LEDS 7
#define NUMBER_OF_SWITCHES 2
#define DEBUG true
#define MAX_GEARCHANGES_PER_SECOND 1 //you can not change gear more than 1 times a second
#define DEBOUNCE (100/MAX_GEARCHANGES_PER_SECOND)
#define DECREASE 0
#define INCREASE 1
//set current led with rules
#define INCREASE_GEAR (currentGear<NUMBER_OF_LEDS ? currentGear++ : currentGear)
#define DECREASE_GEAR (currentGear>0 ? currentGear-- : currentGear)
byte ledPins[] = {2,3,4,5,6,7,8}; // the number of the output pin
byte switchPins[] = {9,10}; //9 decrease - 10 increase
byte currentGear = 0;
unsigned long gearTime = 0;
void setup(){
for (byte i=0; i<NUMBER_OF_SWITCHES; i++){
_ pinMode( switchPins , INPUT);_
}
for (byte i=0; i<NUMBER_OF_LEDS; i++){
_ pinMode( ledPins , OUTPUT);
}
if (DEBUG){Serial.begin(9600);}
}
void loop()
{
//GET STATES
for (byte i=0; i<NUMBER_OF_SWITCHES; i++){
if ( digitalRead(switchPins*) == HIGH>gearTime+DEBOUNCE){
if ( i == INCREASE ){_

INCREASE_GEAR;
_ } else {//( i == DECREASE ){_
DECREASE_GEAR;
_ }
gearTime = millis();
}
}
//SET STATES*

for (byte i=0; i<NUMBER_OF_LEDS; i++){
digitalWrite(ledPins*,LOW);
}*

digitalWrite(ledPins[currentGear], HIGH);_

if (DEBUG){Serial.print("Current gear: ");Serial.println(currentGear,DEC);}
}

Simple edit. I don't know what changing my max gearchanges per second did, but I changed that, and then I cut out the millis in this line
"if ( digitalRead(switchPins*) == HIGH>gearTime+DEBOUNCE){"*
[/quote]
You will need to keep the millis. Try THIS one more time, and change only 'MAX_GEARCHANGES_PER_SECOND' to desired number.
I can honestly do not see why it should not work. And maybe post serial copypaste :slight_smile:

I would like to copy the serial output for you, but I can't seem to get it to copy. Any suggestions. The output keeps scrolling, and it won't let me pause without loosing the info.

Hmmm.
I just drag to select then hit Ctrl+C and then Ctrl+V.

...strange...

Console Text Select

I have been working on my computer at the office. It has so many strange little issues. I will try this again at home on my Ibook. We will see how that goes. Sorry I am having so many issues. I really appreciate you helping me through this.

I'll be on standby in the meanwhile.

I really appreciate you helping me through this.

It's fun! I find it is very educating actually :slight_smile:

Alright so here is the deal. I still can't copy and paste from the serial monitor. But it looks something like this.

Current gear: 1
Current gear: 1
Current gear: 0
Current gear: 0
Current gear: 1
Current gear: 1
Current gear: 4
Current gear: 4
Current gear: 7
Current gear: 7
Current gear: 7
Current gear: 7
Current gear: 7
Current gear: 1
Current gear: 1
Current gear: 1
Current gear: 1

Now I still modified the code a little. I cut out the millis on the
"if ( digitalRead(switchPins*) == HIGH>gearTime+DEBOUNCE){"*
line. It is the only way that I have found to save the current gear selected.
The serial output is controlled by my press. So that isn't a sporadic output. But it doesn't click one gear at a time. It just goes up through the gears till you let off the button. If your quick you can get it to stop about every 3rd gear.
I hope this helps. I have been hacking away at your code trying to see what I can come up with, but it doesn't seem to change anything.

if ( digitalRead(switchPins[i]) == HIGH>gearTime+DEBOUNCE)

That looks like unintended nonsense to me. Let's break down what is being calculated.

Replace macros with their equivalent. (That's what #define does.)

if ( digitalRead(switchPins[i]) == [glow]1[/glow]>gearTime+[glow](100/1)[/glow])

According to the order of precedence, calculate the expression. We will assume a gearTime of 3757 (the last reading from a hypothetical millis() call), and an i of 1.

100/1 is 1:

if ( digitalRead(switchPins[i]) == 1>gearTime+[glow]1[/glow])

gearTime + 1 is 3758:

if ( digitalRead(switchPins[i]) == 1>[glow]3758[/glow])

1 > 3758 is false, so 0:

if ( digitalRead(switchPins[i]) == [glow]0[/glow])

i is 1:

if ( digitalRead([glow]10[/glow]) == 0)

digitalRead(10) returns HIGH (1) or LOW (0):

if ([glow]1[/glow] == 0)

1 == 0 is false, so the if block doesn't run.

Now, I'm just guessing, but if you're trying to count HOW LONG HAS INPUT PIN BEEN HIGH, you're going to have to do that in a different way. You're going to have to notice when it goes high, and then watch the time go by until it goes low again or it's been high long enough to count as a trigger.

Could you post some close-ups of you wiring. :slight_smile:

This is tested, and works for me:

#define UP_BUTTON 7 // the number of the input pin
#define NUMBER_OF_LEDS 7
#define NUMBER_OF_SWITCHES 2

#define DEBUG true

#define DECREASE 0
#define INCREASE 1

#define PULLUP_RESISTOR 1 //set to 0 if pulldown is used
#define BUTTON_PRESSED (!PULLUP_RESISTOR)

#define MAX_GEARCHANGES_PER_SECOND 1 //you can not change gear more than 10 times a second
#define DEBOUNCE (1000/MAX_GEARCHANGES_PER_SECOND)

byte ledPins[] = {2,3,4,5,6,7,8}; // the number of the output pin
byte switchPins[] = {9,10}; //9 decrease - 10 increase

byte currentGear = 1;
unsigned long gearTime = 0;

void setup(){
for (byte i=0; i<NUMBER_OF_SWITCHES; i++){
pinMode( switchPins , INPUT);
if (PULLUP_RESISTOR) { digitalWrite(switchPins*,HIGH); }
_
}_
for (byte i=0; i<NUMBER_OF_LEDS; i++){
_ pinMode( ledPins , OUTPUT);
}
if (DEBUG){Serial.begin(9600);}
}
void loop()
{
//GET STATES*
for (byte i=0; i<NUMBER_OF_SWITCHES; i++){
if ( digitalRead(switchPins*) == BUTTON_PRESSED && millis()>gearTime+DEBOUNCE){*
* if ( i == INCREASE ){_
if(currentGear<NUMBER_OF_LEDS){currentGear++;}
_ } else {//( i == DECREASE ){
if(currentGear>0){currentGear--;}
}
if (DEBUG){Serial.print("After detected press, currentGear: ");Serial.println(currentGear,DEC);}
gearTime = millis();
}
}
//SET STATES*

for (byte i=0; i<NUMBER_OF_LEDS; i++){
digitalWrite(ledPins*,LOW);
}*

digitalWrite(ledPins[currentGear], HIGH);_

if (DEBUG){Serial.print("Current gear: ");Serial.println(currentGear,DEC);}
}
[/quote]

THATS IT! I have never been so happy to push a button! AlphaBeta's newest code is the working code.

Thank you so much for working with me on this. I will take photos, and maybe video later once I am home, and have a good camera.

Thanks again!!

THATS IT! I have never been so happy to push a button! AlphaBeta's newest code is the working code.

Thank you so much for working with me on this. I will take photos, and maybe video later once I am home, and have a good camera.

Thanks again!!

I am glad it's finally working! :smiley:

I do think that you had a case of floating I/O pins.
That phenomena is actually often used to simulate randomness: Random using floating pins

It could be floating I/O. But once you added in the

"#define PULLUP_RESISTOR 1 //set to 0 if pulldown is used"
& "if (PULLUP_RESISTOR) { digitalWrite(switchPins*,HIGH); }"*
it seemed to fix everything. That is the piece I kept trying to add. But I was not sure what I needed to add for it to work.
It was ST. Patty's day, so I didn't get pictures yet. Probably tonight. thanks again