Arduino mathy situation

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:

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?

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 :slight_smile:

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.

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.

Something like this should work:

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

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.

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.

It’s standard C.

Leon

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?

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 ```
if (val1 == HIGH) {


with

if (val1 == LOW) {

Cool, thanks!

you may need to implement a debouncer for you switches states.

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.

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.

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]

Cool.

But when do you need the values to change? Or is it literally they “stay at -1” forever?

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.

OK sorry I guess I’m not getting you. I understand the math logic, but I guess it’s the “usage” part that I don’t understand…

are you wanting the values to change every second, or every time a button is pushed, or at some other event/interval

maybe it would help if you could say what its being used for - for example, I dunno, it’s to count eggs on a conveyor belt or something

Aaaaaand I’m back. Left on an extended business trip to an isolated location. Anyway, I’ve been thinking about what the root problem is. My code in void.loop loops(obviously) and so as it comes around the first time, it sees that switch one is high, and says “Ooh, x now equals x+a.” But each subsequent loops says the same thing, and adds another instance of a to x. If I put it in void.setup, then it would get rid of this problem, but not change dynamically. Maybe if I could make the arduino see that its the same as last time and not do it again. As for what this is counting, lets just say how many of a certain mystery* gadget get produced per hour.

*The mystery is because i’m not sure my boss would like me telling the internet what it is.

Yep that’s what I was saying - what should be the signal for it to “do the count now”.

You need some sort of “event” to happen to make the arduino perform the maths. This could be

[1] A button press

[2] a time period elapsing

[3] a siren sounding

[4] lights turning on

[5] etc…

Yes. What I need the trigger to be is a switch. It just occurred to me, I could use a computer as sort of a bridge to execute the more complicated code that I need. If I’m going to interface between the arduino and a computer, where’s a good starting point? What programming language should I use?

Dude it’s all built in!

There are arduino commands like Serial.print() that send whatever you want over the in-built serial port. The you just have whatever program you want on your PC listening for data over the serial port. You can sent it as ascii, decimal, hex, whatever you want. Heaps of examples out there too.

So by “switch” exactly what type of switch do you mean? On/off? Momentary?