More generic and scalable parser
Dependencies: SLCD mbed-rtos mbed
Fork of Serial_IO_test_v6 by
Serial_parser_v1.cpp
- Committer:
- scohennm
- Date:
- 2015-03-23
- Revision:
- 4:31207d384db0
- Parent:
- serialO_v6.cpp@ 3:2266158bf72f
File content as of revision 4:31207d384db0:
#include "mbed.h" #include <iostream> #include <stdio.h> #include <ctype.h> #include <string.h> #include <locale.h> #include "rtos.h" #include "SLCD.h" // Debug printout control #define PRINTDBUG #define PROGNAME "Serial_parser_v1 - sc\n\r" #define LCDLEN 10 #define MAXCHAR 4 #define ALL8 "8888" #define LCDUPDATE 100 //ms #define LEDBLINKTIME 300 // ms *** NOTE Change of units *** #define SERIALREADTIME 50 //ms // ASCII constants #define CR '\r' #define ALLNOTES "CDEFGAB" // Note only 7 unique notes. #define NONOTE 7 #define OCTAVELLEN 7 #define VALIDOCTAVES "45" #define NOOCTAVE 2 #define NUMTONES 14 // length of two octaves #define COMMANDLEN 2 //Max characters in the command #define NOTOK "NOK" #define NOTEOFFSET 1 #define NOTEINVALID 20 // length of float diatonicScale[NUMTONES] = {261.63,293.66,329.63,349.23,392.00,440.00,493.88,523.25,587.33,659.25,698.46,783.99,880.00,987.77}; DigitalOut rLed(LED_RED); Serial pc(USBTX, USBRX); // tx, rx SLCD slcd; //define LCD display char rxChar; char rxString[LCDLEN]; string rxRealString; bool commandReady = false; // This is the flag to even look at the command string void clearString (char * aString){ int i; int sSize = sizeof(aString); for (i=0; i< sSize; i++){ aString[i] = NULL; } return; } int isNote(char theNote){ //check for valid onte int noteListLen = sizeof(ALLNOTES); int pos = NONOTE; int i; for (i=0; i<noteListLen; i++){ if (ALLNOTES[i] == theNote){ pos = i; break; } } return (pos); } int isOctave(char theOct){ //check for valid onte int noteListLen = sizeof(VALIDOCTAVES); int pos = NOOCTAVE; int i; for (i=0; i<noteListLen; i++){ if (VALIDOCTAVES[i] == theOct){ pos = i; break; } } return (pos); } /* one way to do the parsing ************** void parseCommand (char * commandChars){ int charPos = 0; int noteIndex = 0; // this is the length into the diatonic scale array bool validCommand = false; noteIndex = isNote(commandChars[charPos]); validCommand = (noteIndex != NONOTE); // First test for a good command string if (validCommand) { charPos++; noteIndex = noteIndex + OCTAVELLEN * isOctave(commandChars[charPos]); validCommand = (noteIndex < NUMTONES); // Final test for a good string } #ifdef PRINTDBUG if (validCommand) { pc.printf("%s - IsNote - %4.2f OK\n\r", rxString, diatonicScale[noteIndex]); sprintf(rxString,"%4.1f", diatonicScale[noteIndex]); // show frequency on LCD } else { pc.printf("%s - Not a Note NOK\n\r", rxString); sprintf(rxString,"%s", NOTOK ); } #endif return; } **************** */ // calculating the valid command void parseCommand (char * commandChars){ #define NOTEPOS 0 // index of note and octive tokens #define OCTPOS 1 int noteIndex; int octaveIndex; int diatonicArrayIndex = 0; // this is the length into the diatonic scale array bool validCommand = false; noteIndex = isNote(commandChars[NOTEPOS]); octaveIndex = isOctave(commandChars[OCTPOS]); validCommand = ((noteIndex != NONOTE)&&(octaveIndex != NOOCTAVE)); // test for good command string #ifdef PRINTDBUG if (validCommand) { diatonicArrayIndex = noteIndex + (OCTAVELLEN * octaveIndex); pc.printf("%s - IsNote - %4.2f OK\n\r", rxString, diatonicScale[diatonicArrayIndex]); sprintf(rxString,"%4.1f", diatonicScale[diatonicArrayIndex]); // show frequency on LCD } else { pc.printf("%s - Not a Note NOK\n\r", rxString); sprintf(rxString,"%s", NOTOK ); } #endif return; } void LCDMessNoDwell(char *lMess){ slcd.Home(); slcd.clear(); slcd.printf(lMess); } // use "thread" in the name to keep things straight // note the use of void constant * args - understand memory resources // Thes are "forever loops" void LCDdis_thread(void const *args){ while(true) { LCDMessNoDwell(rxString); Thread::wait(LCDUPDATE); } } void serial_thread(void const *args){ static int charIndex =0; int rxStringLen; while(true) { if (pc.readable()) { // only read from the serial port if there is a character rxChar= toupper(pc.getc()); // reading clears the buffer // noteOK = isNote(rxChar); // construct a 4-digit string for the LCD // check for carriage return if (rxChar == CR) { rxRealString.assign(rxString); rxStringLen = rxRealString.length(); if(rxStringLen == COMMANDLEN) { // if the input string does not equal the expected parseCommand(rxString); // command length it's not a good command } else { #ifdef PRINTDBUG pc.printf("%s NOK\n\r", rxString); sprintf(rxString,"%s", NOTOK ); #endif } charIndex = 0; // start building string from position zero next time around } else { if(charIndex == 0) clearString(rxString); rxString[charIndex] = rxChar; rxRealString.assign(rxString); #ifdef PRINTDBUG pc.printf("%s\n\r", rxString); // This echo's the new char and prevous up to 4 chars #endif charIndex = (charIndex + 1)% (MAXCHAR); // Only allow 4 characters then roll over } } Thread::wait(SERIALREADTIME); } } int main() { Thread lthread(LCDdis_thread); Thread serthread(serial_thread); sprintf(rxString,"%s",ALL8); // just put something on the LCD to show it's working #ifdef PRINTDBUG pc.printf(PROGNAME); #endif while (true) { rLed = !rLed; // toggle led Thread::wait(LEDBLINKTIME); } }