Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SLCD mbed-rtos mbed
Fork of Serial_parser_v2 by
Serial_parser_v1.cpp
- Committer:
- scohennm
- Date:
- 2015-03-23
- Revision:
- 4:31207d384db0
- Parent:
- serialO_v6.cpp@ 3:2266158bf72f
- Child:
- 5:76c73467ef1a
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);
}
}
