This probably won't be well accepted.. But how about callback that is called when a full c string has been read from the Serial port?
Like this..
#include "serialWatch.h"
serialWatch strReader;
void setup(void) {
Serial.begin(57600); // Fire up the serial stuff.
Serial.println(F("Enter something. I'll repeat it.")); // Tell Mrs user to start inputting numbers.
strReader.setCallback(haveStr); // Hook up our callback.
}
// Magically... Complete c strings show up here.
void haveStr(char* inStr) {
int i=0;
if (strReader.hadOverrun()) { // If we had an overrun..
Serial.println(F("Oh no! overrun! Lost data!")); // Tell the user.
}
Serial.print(F("Entered : ")); // Show what we got..
Serial.println(inStr);
Serial.print(F("Reply : ")); // Show our repy.
while(inStr[i]) {
Serial.print((char)toupper(inStr[i++]));
}
Serial.println();
}
void loop(void) {
idle();
// And whatever else you would like to do in loop.
}
Still interested?
Here's the .h bit..
#ifndef serialWatch_h
#define serialWatch_h
#include <idlers.h>
class serialWatch : public idler {
public:
serialWatch(char endChar='\n',int numBytes=64);
virtual ~serialWatch(void);
void setCallback(void(*funct)(char*)); // Use a callback for a complete string.
virtual void idle(void);
bool hadOverrun(void);
int index;
char EOL;
int bytes;
char* buff;
void (*callback)(char*);
bool overrun;
};
And the guts of the matter. The .cpp bit.
#include "serialWatch.h"
#include <resizeBuff.h>
serialWatch::serialWatch(char endChar,int numBytes) {
index = 0;
EOL = endChar;
bytes = numBytes;
overrun = false;
resizeBuff(numBytes,&buff);
}
serialWatch::~serialWatch(void) { resizeBuff(0,&buff); }
void serialWatch::setCallback(void(*funct)(char*)) {
callback = funct;
hookup();
}
void serialWatch::idle(void) {
char aChar;
if (Serial.available()) { // If there is a char in the waiting to be read..
aChar = Serial.read(); // Grab and save the char.
if (aChar==EOL) { // If its a newline char..
callback(buff); // call it.
overrun = false; // If set, cler the overrun flag.
buff[0] = '\0'; // Clear the inBuff string.
index = 0; // Reset the index to start a new number string.
} else { // Else, it wasn't a newline char..
if (index<bytes) {
buff[index++] = aChar; // So we save the char we got into the c string.
buff[index] = '\0'; // And pop an end of string after it.
} else {
overrun = true; // Just blew past the buffer.
}
}
}
}
bool serialWatch::hadOverrun(void) { return overrun; }
I think its pretty slick! Gets rid of all those pesky while(available()) and read until things. Does not block. And, what could be easier than suddenly having your string all ready to go? Every newbie's dream!
-jim lee