More generic and scalable parser
Dependencies: SLCD mbed-rtos mbed
Fork of Serial_IO_test_v6 by
Revision 4:31207d384db0, committed 2015-03-23
- Comitter:
- scohennm
- Date:
- Mon Mar 23 16:37:23 2015 +0000
- Parent:
- 3:2266158bf72f
- Commit message:
- NMHU serial command parser program - more generic and scalable
Changed in this revision
Serial_parser_v1.cpp | Show annotated file Show diff for this revision Revisions of this file |
serialO_v6.cpp | Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Serial_parser_v1.cpp Mon Mar 23 16:37:23 2015 +0000 @@ -0,0 +1,201 @@ +#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); + } +} \ No newline at end of file
--- a/serialO_v6.cpp Wed Mar 18 19:08:22 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -#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 "SerialIO v6\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 NUMTONES 10 -#define NONOTE 8 -#define NOTEOFFSET 1 - - - -float diatonicScale[NUMTONES] = {246.94, 261.63,293.66,329.63,349.23,392.00,440.00,493.88,523.25,587.33}; - -DigitalOut rLed(LED_RED); - - -Serial pc(USBTX, USBRX); // tx, rx -SLCD slcd; //define LCD display -char rxChar; -char rxString[LCDLEN]; -string rxRealString; - -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); -} - - -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; - int noteOK; - 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(); -#ifdef PRINTDBUG - pc.printf("%s - StringLen = %d OK \n\r", rxString, rxStringLen); -#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 - if(noteOK != NONOTE){ - pc.printf("%s - IsNote - %4.2f\n\r", rxString, diatonicScale[noteOK + NOTEOFFSET]); - } else { - pc.printf("%s - Not a Note\n\r", rxString); - } -#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); - } -} \ No newline at end of file