Don't Cross The Streams (FP scientific calculator serial co-processor)

This thread started as as fun project of building a floating point calculator that could be "called over RS232" via the main uC processor. Results would be sent back to the requesting processor via RS232. The idea is that the small investment in a ATmel328 (or other) Arduino on a breadboard would provide an inexpensive (approx. $3) capability by offloading the rather large IEEE floating point library (32-bit) to a second Arduino chip on a board-duino.

However, even with all the code for parsing and calculating a variety of scientific calculations and handshaking with the main uC, there is still some flash left over. Worst, nearly an entire 328 I/O is left over! Clearly, this presents an opportunity to extend the instruction set of the coprocessor to incorporate manipulation of the digital IO lines (same can be done with Analog readings.) As a proof, I extended the current calculator repertoire with a single new instruction, "DPR" Digital Pin Read, and the instruction takes a single integer argument value of 2 through 13. The syntax then is: DPR n where n is 2-13. Attempting to read outside the allowed range will be indicated as an Error if in Verbose mode and as a "2" if in processor to processor mode.

Another command could be constructed for Digital Pin Write, DPW, and another for Analog Pin Read, APR. As you can see from the snipplets of code below, the implementation is very easy. While manipulating a remote uC's state over RS232 may seem completely insane, not every design requires near instanteous control; sometimes, the external signals only need to be monitored occasionally and RS232 is a nearly 'free' resource in the Arduino world.

Ray

Here are the changes to implement the new functionality:

#define Err 2
#define operations 23
byte DigPinNo;
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"};
...
void setup()
  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
...
    case 22:    //DPR DigitalPin Read # valid 2 - 13  Return 0, 1 for state or 2 for Error
            if (verbose) {Serial.print(F("Prompting for Digital Pin Number 2 - 13: ")); }
            DigPinNo = Serial.parseInt(); 
            if (DigPinNo <2 || DigPinNo > 13) {
              if (verbose) { Serial.print(DigPinNo);
                Serial.print(" Pin# Error"); break; }
                Serial << Err; break; }
            if (verbose) { Serial.print(DigPinNo); }
            if (verbose) {Serial.print(F(" Logic State = ")); }
            Serial << digitalRead(DigPinNo);
            if (verbose) {Serial.println(); }
            break;

Calculator.ino (12.1 KB)