I've never used the switch command before. The sketch below had many IF statements and I've tried to tidy up the code. But the sketch will not load. I will try to post the error message below the sketch.
Best,
Tony
// simple calculator sketch
int myNumber1; //first number variable
int myNumber2; //second number variable
int result; //result variable
String calc_operator; //operator
void setup() {
// put your setup code here, to run once:
Serial.begin(115200); // begin serial monitor
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print("Enter first number: "); //ask for first number
while (Serial.available()==0); //wait for the user
myNumber1=Serial.parseFloat(); //assign user entry to variable
Serial.println(myNumber1); //print user entry for reference
Serial.print("Enter second number: "); //ask for second number
while (Serial.available()==0); //wait for the user
myNumber2=Serial.parseFloat(); //assign user entry to variable
Serial.println(myNumber2); //print user entry for reference
Serial.print("Enter your operator (+,-,*,/): "); //ask user for operator
while (Serial.available()==0); //wait for the user
calc_operator=Serial.readString(); //assign user entry to string
Serial.println(calc_operator); //print user entry for reference
switch (calc_operator) {
case '+':
result = myNumber1 + myNumber2; //if addition then add
break;
case '-':
result = myNumber1 - myNumber2; //if subtraction then subtract
break;
case '*':
result = myNumber1 * myNumber2; //if multiplication then multiply
break;
case '/':
result = myNumber1 / myNumber2; //if division then divide
break;
default:
Serial.println("That was not a valid operator.");
}
Serial.print("Your answer is: "); //print message for result
Serial.println(result); //print result
Serial.println(); //tidy up with a print line
}
Arduino: 1.8.13 Hourly Build 2020/04/21 12:12 (Mac OS X), Board: "Arduino Uno"
/Users/tonyperry/Documents/Arduino/Serial_Monitor_Calculator-3/Serial_Monitor_Calculator-3.ino: In function 'void loop()':
Serial_Monitor_Calculator-3:33:22: error: switch quantity not an integer
switch (calc_operator) {
^
exit status 1
switch quantity not an integer
Ah Ha, the switch only accepts integer arguments (1, 2, 3, 4). The switch cases are numbered (integers) to match the user input (1 Addition, 2 Subtraction, 3 Multiplication, 4 Division) The calc_operator variable needs to be assigned an integer value. Currently it is assigned a character value from the String.
ZoolanderMicro, where small ideas are a big deal
Your code is definitely looking better. Your use of 'while' still baffles me. It is a loop structure. Procedural code inside the loop is executed on each iteration, while the conditional statement is true. Code within an 'if' statement is executed only if the conditional statement is true. Be sure to encapsulate the procedural code in curly braces '{ }'. Below is an example program using while loops.
/* Exercise_Chap05_KnightRider This is an exercise taken from the book: Beginning C for Arduino 2nd Ed (Jack Purdum) Knight Rider Kit car sweeping lights. This version uses 'while' loops to count through an array of digital output pins. Notice that the loop control variable is declared static and initialized with a value of 0. It is shared between the loops in the main body of the program like a game of hot potato. Also, the constant 'MAX_COUNT' is initialized in a way that scales to the index of the last array element. This works for different array sizes and variable types. Thnx Jack ;-) Written in Arduino C language @author Mike Tonge @date 11/26/2019 */ // Initialize aray with Arduino digital pin numbers int ledPins[] = {4, 5, 6, 7, 8, 9, 10}; const int DELAY_TIME = 100; // Time in milisedonds. Change to suit const int MIN_COUNT = 0; // First aray element is index 0 // Scale value to index of last aray element // MAX_COUNT is 6 const int MAX_COUNT = (sizeof(ledPins) / sizeof(ledPins[0])) - 1; void setup() { for (int pin = MIN_COUNT; pin <= MAX_COUNT; pin++) { pinMode(ledPins[pin], OUTPUT); // Initialize Arduino pins as output digitalWrite(ledPins[pin], LOW); // Turn digital outputs off } } void loop() { static int index = 0; // Initialize loop control variable. while (index < MAX_COUNT) { // Counts up from 0 to 5 digitalWrite(ledPins[index], HIGH); // Turn on led delay(DELAY_TIME); // Wait a tick digitalWrite(ledPins[index], LOW); // Turn off led index = index + 1; } while (index > MIN_COUNT) { // Counts down from 6 to 1 digitalWrite(ledPins[index], HIGH); // Turn on led delay(DELAY_TIME); // Wait a tick digitalWrite(ledPins[index], LOW); // Turn off led index = index - 1; } }
ZoolanderMicro, where small ideas are a big deal
Here is a sketch that uses 'if' statements nested in a 'for' loop. The 'if' statements are testing for ranges of values assigned to the 'for' loop control variable 'i'.
#include <avr/io.h> #include <util/delay.h> /** Scetch ColorFade_CommonAnode is a color fade/blend routine for a tri-color common anode LED connected to Arduino Uno digital pins 9, 10, and 11 as PWM outputs. Colors transition from blue through teal, green, yellow, orange, red, violet, purple, and back to blue. With common anode tri-colored LEDs, analogWrite() value of 0 results in a full 'on' state, and analogWrite() value of 255 results in a full 'off' state. @author Mike Tonge @date 041716 */ // Constants const uint8_t DELAY_TIME = 100; // Delay time (miliseconds) const uint8_t redLED = 9; // Red on digital pin 9 const uint8_t grnLED = 10; // Green on digital pin 10 const uint8_t bluLED = 11; // Blue on digital pin 11 const uint8_t OFF = 255; // Value used to turn off LED // Variables uint8_t redVal = 0; // Red value uint8_t grnVal = 0; // Green value uint8_t bluVal = 0; // Blue value // Run once void setup() { //Serial.begin(9600); // Serial monitor used for diagnostics pinMode(redLED, OUTPUT); // Set pin 9 as output pinMode(grnLED, OUTPUT); // Set pin 10 as output pinMode(bluLED, OUTPUT); // Set pin 11 as output } // End setup void loop() { // Begin 'main' loop for (int i = 0; i < 765; i++) { // Loop counter 'i' used to set RGB values // Red is off, Green gets brighter, Blue gets dimmer if (i <= 255) { // If 'i' is less than or equal to 255 redVal = OFF; // Red is off grnVal = 255 - i; // Green brightens as 'i' increases bluVal = i; // Blue dims as 'i' increases } // Red gets brighter, Green gets dimmer, Blue is off if ((i > 255) && (i <= 510)) { // If 'i' is greater than 255 and less than or equal to 510 redVal = 510 - i; // Red brightens as 'i' increases grnVal = i - 255; // Green dims as 'i' increases bluVal = OFF; // Blue is off } // Red gets dimmer, Green is off, Blue gets brighter if (i > 510) { // If 'i' is greater than 510 redVal = i - 510; // Red dims as 'i' increases grnVal = OFF; // Green is off bluVal = 765 - i; // Blue brightens as 'i' increases } // Set RGB color values analogWrite(redLED, redVal); analogWrite(grnLED, grnVal); analogWrite(bluLED, bluVal); delay(DELAY_TIME); // Loop delay interval // Diagnostic output to Serial Monitor /** Serial.print(i); Serial.print(" , "); Serial.print(redVal); Serial.print(" , "); Serial.print(grnVal); Serial.print(" , "); Serial.print(bluVal); Serial.println(); */ }// End 'for' loop }// End 'main' loop
ZoolanderMicro, where small ideas are a big deal
@zoolandermicro So the easiest way would be to just identify to the user the operator assigned to which number. They enter, for instance, 1 and the case for addition would take place. Am I understanding it correctly?
Using multiple 'if' statements can be inefficient. All of the 'if' statements must be tested. Using if, else if, else statements are more efficient because the statements are tested up to the first true statement. Subsequent 'else if' statements are not considered. The trailing 'else' is usually a default to be executed when all conditions fail.
if(test_expression) { //execute your code } else if(test_expression n) { //execute your code } else { //execute your code }
I could have used this to make the ColorFade sketch more efficient.
ZoolanderMicro, where small ideas are a big deal
I recently re-wrote the ColorFade sketch using a switch case. Switches only accept integer arguments, but they can test for ranges of numbers. This code compiled using less program memory than the previous version using 'if' statements.
#include <avr/io.h> #include <util/delay.h> /** Scetch ColorBlend_CommonAnode is a color fade/blend routine for a tri-color common anode led connected to Arduino Uno digital pins 9, 10, and 11 as PWM outputs. Colors transition from blue through teal, green, yellow, orange, red, violet, purple, and back to blue. With common anode tri-colored LEDs, analogWrite() value of 0 results in a full 'on' state, and analogWrite() value of 255 results in a full 'off' state. This scetch works with common cathode tri-colored leds, only the color blend runs in the opposite order. Written in Arduino C language. @author Mike Tonge @date 11/28/2019 */ // Constants const uint8_t DELAY_TIME = 100; // Delay time (miliseconds) const uint8_t redLED = 9; // Red on digital pin 9 const uint8_t grnLED = 10; // Green on digital pin 10 const uint8_t bluLED = 11; // Blue on digital pin 11 const uint8_t OFF = 255; // Value used to turn led off // Variables uint8_t redVal = 0; // Red value uint8_t grnVal = 0; // Green value uint8_t bluVal = 0; // Blue value void setup() { pinMode(redLED, OUTPUT); // Set pin 9 as output pinMode(grnLED, OUTPUT); // Set pin 10 as output pinMode(bluLED, OUTPUT); // Set pin 11 as output } void loop() { for (int count = 0; count <= 765; count++) { switch (count) { // Red is off, Green gets brighter, Blue gets dimmer case 0 ... 255: redVal = OFF; grnVal = 255 - count; bluVal = count; break; // Red gets brighter, Green gets dimmer, Blue is off case 256 ... 510: redVal = 510 - count; grnVal = count - 255; bluVal = OFF; break; // Red gets dimmer, Green is off, Blue gets brighter case 511 ... 765: redVal = count - 510; grnVal = OFF; bluVal = 765 - count; break; default: break; } // End switch analogWrite(redLED, redVal); analogWrite(grnLED, grnVal); analogWrite(bluLED, bluVal); delay(DELAY_TIME); } }
ZoolanderMicro, where small ideas are a big deal
Yes, the user enters a number for the intended operation. I'm trying to find a sketch that accepts user input as an example.
ZoolanderMicro, where small ideas are a big deal
@zoolandermicro - Thank you for all of your guidance. I'd like to build and try the color fad sketch in the near future.
// Change this variable to be of type "char" char calc_operator; // Change from "readString()" to "read()" a single character calc_operator = Serial.read();
You were trying to switch on a string data type instead of an int type, which char is.
Cheers.
Ah Ha, the switch only accepts integer arguments (1, 2, 3, 4). The switch cases are numbered (integers) to match the user input (1 Addition, 2 Subtraction, 3 Multiplication, 4 Division) The calc_operator variable needs to be assigned an integer value. Currently it is assigned a character value from the String.
I hope you don't mind me correcting you, but this needs a little clarification.
The data type char is also an integral type, which maps to associated ASCII characters, and that's why we can also switch on a character literal, as well as an explicit number.
For example:
int character = '+'; Serial.println(character); // Correctly prints ASCII integer 43 Serial.println(char(character)); // Convert from int back to char representation '+'
Cheers.
Excellent! Thanks FrogandToad, I have not tried that before. Could Tperry724 use this to accept user input of arithmetic symbols (+, -, *, /)?
switch (calc_operator) {
case '+':
result = myNumber1 + myNumber2; //if addition then add
break;
case '-':
result = myNumber1 - myNumber2; //if subtraction then subtract
break;
case '*':
result = myNumber1 * myNumber2; //if multiplication then multiply
break;
case '/':
result = myNumber1 / myNumber2; //if division then divide
break;
default:
Serial.println("That was not a valid operator.");
}
ZoolanderMicro, where small ideas are a big deal
For the case statements, should he still use single quotes for a character? I wouldn't think so.
ZoolanderMicro, where small ideas are a big deal
As in:
switch (calc_operator) { case 43: // ASCII for + symbol result = myNumber1 + myNumber2; //if addition then add break; case 45: // ASCII for - symbol result = myNumber1 - myNumber2; //if subtraction then subtract break; case 42: // ASCII for * symbol result = myNumber1 * myNumber2; //if multiplication then multiply break; case 47: //ASCII for / symbol result = myNumber1 / myNumber2; //if division then divide break; default: Serial.println("That was not a valid operator."); }
ZoolanderMicro, where small ideas are a big deal
When I reply with a preformatted code block, I don't seem to be able to add text afterward. Do I just add text after the closing </pre> tag in the code block dialog?
ZoolanderMicro, where small ideas are a big deal