Maybe a different example that has character matching, numerics, and subsequent cases that can easily be extended.
The example below is for the Uno/Nano AVR boards and implements a terminal-based calculator. It shows many useful concepts.
// Extensible calculator by M. Ray Burnette 20130906
// Nano: Binary sketch size: 12056 bytes (of a 30,720 byte maximum)
#include <Streaming.h>
#define BAUD 9600
#define Err 2
#define timeoutPeriod 2147483647// Long var... about 25 days
//#define timeoutPeriod 10000 // 10 seconds
#define operations 27 // 1-27 not 0-26
byte j;
byte decimals = 7;
byte DigPinNo;
byte AnaPinNo;
boolean Degrees = true; // Trig input is in degrees
float a;
float b;
float Pi = 3.141592654;
float LastX;
unsigned long temp; // factorials
unsigned long T0; // timing
unsigned long T1; // timing
String Operation;
float* Mem[43] = {}; // memory registers 0-9, :-@, A-Z == 10 + 7 + 26
char* Inst = "XYZ\n";
char* sStack[ ] = {
"DIV","MUL","ADD","SUB","Y^X","LOG","NLG","10X","1/X","e^X",
"SQR","X^2","SIN","COS","TAN","ASN","ACS","ATN","DEG","RAD",
"DEC","RTT","DPR","APR","LTX","FN!","MEM"};
void setup()
{
Serial.begin(BAUD);
Serial.setTimeout(timeoutPeriod); // default is 1 second
// 20130208 Added Command DRP to read digital pin state
pinMode(3, INPUT); // sets the digital pin 3 as input
pinMode(6, INPUT); // sets the digital pin 6 as input
pinMode(7, INPUT); // sets the digital pin 7 as input
pinMode(8, INPUT); // sets the digital pin 8 as input
pinMode(9, INPUT); // sets the digital pin 9 as input
pinMode(10, INPUT); // sets the digital pin 10 as input
pinMode(11, INPUT); // sets the digital pin 11 as input
pinMode(12, INPUT); // sets the digital pin 12 as input
}
void loop()
{
Serial.readBytes( Inst, 4);
Operation = Inst; Operation.trim();
for ( j= 0; j<operations; j++) {
if (Operation.equalsIgnoreCase(sStack[j])) {
T0 = millis();
break;
}
}
switch (j)
{
case 0: // DIVide
a = Serial.parseFloat();
b = Serial.parseFloat();
LastX = a / b;
Serial << _FLOAT(LastX , decimals);
break;
case 1: // MULtiply
a = Serial.parseFloat();
b = Serial.parseFloat();
LastX = a * b;
Serial << _FLOAT(LastX, decimals);
break;
case 2: // ADD
a = Serial.parseFloat();
b = Serial.parseFloat();
LastX = a + b;
Serial << _FLOAT(LastX, decimals);
break;
case 3: // SUBstract
a = Serial.parseFloat();
b = Serial.parseFloat();
LastX = a - b;
Serial << _FLOAT(LastX, decimals);
break;
case 4: // Y ^ X : Y to the X power
b = Serial.parseFloat();
a = Serial.parseFloat();
LastX = pow(b, a);
Serial << _FLOAT(LastX, decimals);
break;
case 5: // LOGrithm of X
b = Serial.parseFloat();
LastX = log10(b);
Serial << _FLOAT(LastX, decimals);
break;
case 6: // Natural LOGrithm of X
b = Serial.parseFloat();
LastX = log(b);
Serial << _FLOAT(LastX, decimals);
break;
case 7: // 10 ^ X : 10 raised to X power
b = Serial.parseFloat();
LastX = pow(10.00, b);
Serial << _FLOAT(LastX, decimals);
break;
case 8: // 1/X : reciprocal of X
b = Serial.parseFloat();
LastX = 1.00 / b;
Serial << _FLOAT(LastX, decimals);
break;
case 9: // e ^ X : e = 2.718281828459045 raised to X
b = Serial.parseFloat();
LastX = pow(2.718281828459045, b);
Serial << _FLOAT(LastX, decimals);
break;
case 10: // SQRoot X
b = Serial.parseFloat();
LastX = sqrt(b);
Serial << _FLOAT(LastX, decimals);
break ;
case 11: // x^2
b = Serial.parseFloat();
LastX = b * b;
Serial << _FLOAT(LastX, decimals);
break;
case 12: // SIN
b = Serial.parseFloat();
if (Degrees){b = b * Pi / 180.0; }
LastX = sin(b);
Serial << _FLOAT(LastX, decimals);
break;
case 13: // COS
b = Serial.parseFloat();
if (Degrees){b = b * Pi / 180.0; }
LastX = cos(b);
Serial << _FLOAT(LastX, decimals);
break;
case 14: // TAN
b = Serial.parseFloat();
if (Degrees){b = b * Pi / 180.0; }
LastX = tan(b);
Serial << _FLOAT(LastX, decimals);
break;
case 15: // ASN ArcSin
b = Serial.parseFloat();
if (Degrees) {LastX = asin(b) * 180.0 / Pi;
} else {LastX = asin(b); }
Serial << _FLOAT(LastX, decimals);
break;
case 16: // ACS ArcCos
b = Serial.parseFloat();
if (Degrees) {LastX = acos(b) * 180.0 / Pi;
} else {LastX = acos(b); }
Serial << _FLOAT(LastX, decimals);
break;
case 17: // ATN ArcTan
b = Serial.parseFloat();
if (Degrees) {LastX = atan(b) * 180.0 / Pi;
} else {LastX = atan(b); }
Serial << _FLOAT(LastX, decimals);
break;
case 18: // DEG (normal startup)
Degrees = true;
break;
case 19: // RAD (alterate input in radians)
Degrees = false;
break;
case 20: // DEC set decimal places
b = Serial.parseInt();
if (b>10) {b = 10; }
decimals = b;
break;
case 21: // RTT calculate the Hypotenuse of a right triangle from sides a and b
a = Serial.parseFloat();
b = Serial.parseFloat();
LastX = sqrt(a*a + b*b);
Serial << _FLOAT(LastX, decimals);
break;
case 22: //DPR DigitalPin Read # valid 3, 6 - 12 (Nano) Returns: 0, 1 for state or 2 for Error
DigPinNo = Serial.parseInt();
if (DigPinNo < 3 || DigPinNo > 12) {
Serial << Err; break; }
if (DigPinNo == 4 || DigPinNo == 5) {
Serial << Err; break; }
Serial << digitalRead(DigPinNo);
break;
case 23: //APR Analog Pin Read - A0 through A7 (Nano) Return 0 - 1024 value for 10-bit A/D or "Err" for Error
AnaPinNo = Serial.parseInt();
if (AnaPinNo < 0 || AnaPinNo > 7) {
if (AnaPinNo == 255) {
for (byte q = 0; q < 8; q++) {
Serial << analogRead(q) << " " ; }
break; }
Serial << "Err\n"; break; }
Serial << analogRead(AnaPinNo);
break;
case 24: //LTX send value of LTX
Serial << _FLOAT(LastX, decimals);
break;
case 25: // Factorial FN! Max value of x! is 12 for Arduino== 479,001,600
a = Serial.parseFloat();
temp = a; // need an unsigned double here
if ( a > 12 ) {
Serial << "Err\n" ; break ; }
for ( j= 1; j < int (a); j++) {
temp = temp * byte (j); }
if (a == 0) temp = 1; // special by definition
LastX = float (temp);
Serial << temp;
break;
default:
Serial << "?\n" ;
break;
}
Serial.println(); // cr lf Adjust if receiver expects different termination
T1 = millis();
// Serial.print(F("Milliseconds = ")); Serial.print( T1 - T0);
// un-remark the next line and recompile if you want to see RAM usage
// Serial.print(F(" Free RAM = ")); Serial.println(freeRam()); Serial.println();
}
From an ancient forum post here