SparkFun Forums 

Where electronics enthusiasts find answers.

Your source for all things Atmel.
By username
#69671
Ok, I'm very new at c/c++ with arduino, but maybe you guys could help with this. Basically what I need is a way for 3 switches to change a variable, sort of like this pseudocode:
Code: Select all
if switch1 is on, add "a" to "x"

else subtract "a" from "x"

if switch2 is on, add "b" to "x"

else subtract "b" from "x"

if switch3 is on, add "c" to "x"

else subtract "c" from "x"


Serial.print( "amount used: "x")
How would I go about doing this?
By trialex
#69674
I'd suggest that if you had a go at it and post your code, you'll get more responses, but I'm bored and looking for distractions :-)

There is the arduino code way and the c++ code way - do you mean you can do this in Aduino code but want to do it in c++?

I'll make aboslutely no claim to now much about c++, so if that's what you are looking for I'll let someone else help you. I'm sure I could have a crack at the arduino code version though.
By username
#69733
The arduino way would be preferred, and the code that I do have is just crap copied and pasted from the "button" example, because I don't know enough about arduino programming to do much more.
User avatar
By leon_heller
#69734
Something like this should work:
Code: Select all
switch (sw)
{
	case Switch1: x += a; break;
	case SWitch2: x += b; break;
	case Switch3: x += c; break;
	default: x -= c; break;
}

printf("Amount used: %d", x);
Leon
By trialex
#69743
Well Leon's provided the c++ way, maybe I should have a go at the arduino way.


This is assuming you have used an external PULL-DOWN resistor in combination with your button - do some research on this and the arduino forum to learn why you need one and how to set it up.

Note that I don't have my arduino in front of me, and nothing I do works first time, so take this as a starting point.
Code: Select all

int switch1_pin = 2;  // Which pin is switch1 connected to?
int switch2_pin = 3;  // Which pin is switch2 connected to?
int switch3_pin = 4;  // Which pin is switch3 connected to?

int x = 8;                    // initial value for x

int val1 = 0;                  // dummy variables to hold botton states
int val2 = 0;
int val3 = 0;

int a = 3;
int b = 5;                    // values for a, b, c 
int c = 1;

void setup(){
  pinMode(switch1_pin, INPUT);   // Make button pins inputs
  pinMode(switch2_pin, INPUT); 
  pinMode(switch3_pin, INPUT); 

  Serial.begin(9600);           // Create a serial connection at 9600bps
}

void loop(){

  val1 = digitalRead(switch1_pin);  // read input value
  if (val1 == HIGH) {            // check if the input is HIGH
    x = x + a;  
  } 

  else {                            // Otherwise
    x = x - a; 
  }


  val2 = digitalRead(switch2_pin);    // read state of button 2
  if (val2 == HIGH){                //if button is pushed
    x = x + b;
  }
  else {                         // Otherwise
    x = x - b;
  }

  val3 = digitalRead(switch3_pin);    // read state of button 3
  if (val3 == HIGH){                //if button is pushed
    x = x + c;
  }
  else {                          // Otherwise
    x = x - c;
  }

  Serial.print("Amount used:");  // Print the string
  Serial.println(x);             // Print value and go to new line


  delay(1000);                   // Wait 1 second so it doesn't happen too quickly 

}

 
So obviously the code is longer, but it is much easier to understand as a beginner.
User avatar
By leon_heller
#69746
It's standard C.

Leon
By username
#69756
Wow, that's awesome guys. I feel like a moron looking at this code and going "ohhhhh..." but I guess I still have a lot to learn. As for the pull down resistors, I have 20k pull UP resistors in place, does that accomplish the same function as pull down?
By trialex
#69757
Yep, they serve the same purpose, but obviously work slightly differently in that now your button pins will read high when the button is not pushed, so you need to check for a LOW when you want to know if the switch is pushed.

Just replace the
Code: Select all
if (val1 == HIGH) { 
with
Code: Select all
if (val1 == LOW) { 
By username
#69759
Cool, thanks!
By sharkbits
#69779
you may need to implement a debouncer for you switches states.
By username
#69894
Okay, I'm not really sure how to implement a debouncer, but I have a different problem. First of all, here is my current clumsy mess of code in its entirety:


#include <stdio.h>

// ------------------------------------------------------------
// SparkFun LCD display API
// ------------------------------------------------------------


extern void LCDOpen (); // open the LCD interface
extern void LCDClear (); // clear the screen
extern void LCDText ( int xPos , int yPos , char * message ); // write text at a location

extern void LCDSetSplash (); // save current screen as the splash screen
extern void LDCSetBright ( int perCent ); // set the display brightness in percent


// ------------------------------------------------------------
// LCDopen - open the LCD display on the serial interface
// ------------------------------------------------------------

void LCDOpen()
{
// open the serial connection

Serial.begin ( 9600 );

// clear the screen

LCDClear();
}


// ------------------------------------------------------------
// LCDclear- clear the LCD display
// ------------------------------------------------------------

void LCDClear()
{
// send the screen clear command

Serial.print ( 0xFE , BYTE ); // special display command
Serial.print ( 0x01 , BYTE ); // clear screen
}

// ------------------------------------------------------------
// LCDText - draw a text message to the display at specified position
// ------------------------------------------------------------

void LCDText ( int xPos , int yPos , char * message )
{
int crsPos;

// compute the cursor position for the device

switch ( yPos )
{
case 0 : crsPos = 0x00; break;
case 1 : crsPos = 0x40; break;
case 2 : crsPos = 0x10; break;
case 3 : crsPos = 0x50; break;
default : crsPos = 0x0; break;
}

crsPos += xPos; crsPos |= 0x80;


// position the cursor

Serial.print ( 0xFE , BYTE ); // special display command
Serial.print ( crsPos , BYTE ); // set the cursor position


// print the message

Serial.print ( message );
}

// ------------------------------------------------------------
// LCDSetSplash - save the current screen as the splash screen to EEPROM
// ------------------------------------------------------------

void LCDSetSplash()
{

// send commands to save the current

Serial.print ( 0x7C , BYTE ); // special EEPROM command
Serial.print ( 0x0A , BYTE ); // save screen as splash


// confirm to the display

delay ( 3000 ); // give the EEPROM time to write
LCDClear(); // clear the display
LCDText ( 0 , 0 , "splash set" ); // confirmation message
delay ( 3000 ); // let the user see it

}

// ------------------------------------------------------------
// LDCSetBright - set the display brightness in percent
// ------------------------------------------------------------

void LCDSetBright ( int perCent )
{
// compute backlight code from percentage

int blCode = 128 + ( 157 - 128 ) * perCent / 100;

// send command

Serial.print ( 0x7C , BYTE ); // special EEPROM command
Serial.print ( blCode , BYTE ); // send the brightness value


// confirm to the display

char msg[40];
sprintf ( msg , "brt %d%%" , perCent , blCode );

delay ( 3000 ); // give the EEPROM time to write
LCDClear(); // clear the display
LCDText ( 0 , 0 , msg ); // confirmation message
delay ( 3000 ); // let the user see it
}



// ------------------------------------------------------------
//
// ------------------------------------------------------------

int a = 300;
int b = 400;
int c = 600;

int x = 0;

int switch1 = 3;
int switch2 = 4;
int switch3 = 5;
int led1 = 13;
int led2 = 14;
int led3 = 15;

int val1 = 0; // variable for reading the pin status
int val2 = 0; // variable for reading the pin status
int val3 = 0; // variable for reading the pin status


void setup ()
{
pinMode(switch1, INPUT);
pinMode(switch2, INPUT);
pinMode(switch3, INPUT);

digitalWrite(switch1, LOW);
digitalWrite(switch2, LOW);
digitalWrite(switch3, LOW);

pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);

// open the display

LCDOpen();

// set the splash screen and brigthness ( need this only once to configure )
// LCDText ( 0 , 0 , "in case of fire" );
// LCDText ( 0 , 1 , " break glass " );
// delay (300);
// LCDSetSplash();
// LCDSetBright ( 80 );



}

void loop ()
{

val1 = digitalRead(switch1); // read input value
if (val1 == HIGH) { // check if the input is HIGH
digitalWrite(led1, LOW); // turn LED OFF
x = x + a;
delay (1000);
}
else {
digitalWrite(led1, HIGH); // turn LED ON
x = x - a;
delay (1000);
}


val2 = digitalRead(switch2); // read input value
if (val2 == HIGH) { // check if the input is HIGH
digitalWrite(led2, LOW); // turn LED OFF
x = x + b;
}
else {
digitalWrite(led2, HIGH); // turn LED ON
x = x - b;
}


val3 = digitalRead(switch3); // read input value
if (val3 == HIGH) { // check if the input is HIGH
digitalWrite(led3, LOW); // turn LED OFF
x = x + c;
}
else {
digitalWrite(led3, HIGH); // turn LED ON
x = x - c;
}




// clear the screen

LCDClear();


// draw message to the display


LCDText ( 0 , 0 , "X used: " );
Serial.print (x);

// don't overrun the display

delay ( 100 );
}

Okay, as you can see, the pull up/down resistors are the ones built in to the atmega644p that I am using on a breadboard. My problem is that as it loops again and again, it adds and subtracts and adds over and over again, as it sees each switch on and off. How would I go about fixing this? Also, I apparently need a debouncer or something.
By trialex
#69898
My problem is that as it loops again and again, it adds and subtracts and adds over and over again, as it sees each switch on and off.
Ok well you'll need to define what the problem is better - at the moment you have describe what the actual behaviour is, but you haven't described what the desired behaviour is.
By username
#69900
Ohh sorry. Basically, if switch 1 is on, switch 2 is off and switch 3 is on, x = x + a - b + c.

So for that example if x is 0, a is 4, b is 7, and c is 2, the screen would say -1, and stay at -1 [edit] until a switch is flipped. [/edit]
Last edited by username on Thu Apr 02, 2009 7:59 pm, edited 1 time in total.
By trialex
#69901
Cool.

But when do you need the values to change? Or is it literally they "stay at -1" forever?
By username
#69903
Ok, so if switch 1, 2, and 3 are off, x = 0. but for example if switch 1 is turned on, and a = 9, then x = 9. So, switch 1 adds and subtracts a from x. Same with 2 and 3, except they control b and c, respectively.