Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef CmdMessenger_h
00026 #define CmdMessenger_h
00027
00028 #include <inttypes.h>
00029 #if ARDUINO >= 100
00030 #include <Arduino.h>
00031 #else
00032 #include <WProgram.h>
00033 #endif
00034
00035
00036
00037 extern "C"
00038 {
00039
00040 typedef void (*messengerCallbackFunction) (void);
00041 }
00042
00043 #define MAXCALLBACKS 50 // The maximum number of commands (default: 50)
00044 #define MESSENGERBUFFERSIZE 64 // The length of the commandbuffer (default: 64)
00045 #define MAXSTREAMBUFFERSIZE 512 // The length of the streambuffer (default: 64)
00046 #define DEFAULT_TIMEOUT 5000 // Time out on unanswered messages. (default: 5s)
00047
00048
00049 enum
00050 {
00051 kProccesingMessage,
00052 kEndOfMessage,
00053 kProcessingArguments,
00054 };
00055
00056 #define white_space(c) ((c) == ' ' || (c) == '\t')
00057 #define valid_digit(c) ((c) >= '0' && (c) <= '9')
00058
00059 class CmdMessenger
00060 {
00061 private:
00062
00063
00064
00065 bool startCommand;
00066 uint8_t lastCommandId;
00067 uint8_t bufferIndex;
00068 uint8_t bufferLength;
00069 uint8_t bufferLastIndex;
00070 char ArglastChar;
00071 char CmdlastChar;
00072 bool pauseProcessing;
00073 bool print_newlines;
00074 char commandBuffer[MESSENGERBUFFERSIZE];
00075 char streamBuffer[MAXSTREAMBUFFERSIZE];
00076 uint8_t messageState;
00077 bool dumped;
00078 bool ArgOk;
00079 char *current;
00080 char *last;
00081 char prevChar;
00082 Stream *comms;
00083
00084 char command_separator;
00085 char field_separator;
00086 char escape_character;
00087
00088 messengerCallbackFunction default_callback;
00089 messengerCallbackFunction callbackList[MAXCALLBACKS];
00090
00091
00092
00093
00094 void init (Stream & comms, const char fld_separator, const char cmd_separator, const char esc_character);
00095 void reset ();
00096
00097
00098
00099 inline uint8_t processLine (char serialChar) __attribute__((always_inline));
00100 inline void handleMessage() __attribute__((always_inline));
00101 inline bool blockedTillReply (unsigned long timeout = DEFAULT_TIMEOUT, int ackCmdId = 1) __attribute__((always_inline));
00102 inline bool CheckForAck (int AckCommand) __attribute__((always_inline));
00103
00104
00105
00109 template < class T >
00110 void writeBin (const T & value)
00111 {
00112 const byte *bytePointer = (const byte *) (const void *) &value;
00113 for (unsigned int i = 0; i < sizeof (value); i++)
00114 {
00115 printEsc (*bytePointer);
00116 bytePointer++;
00117 }
00118 }
00119
00120
00121
00122 int findNext (char *str, char delim);
00123
00127 template < class T >
00128 T readBin (char *str)
00129 {
00130 T value;
00131 unescape (str);
00132 byte *bytePointer = (byte *) (const void *) &value;
00133 for (unsigned int i = 0; i < sizeof (value); i++)
00134 {
00135 *bytePointer = str[i];
00136 bytePointer++;
00137 }
00138 return value;
00139 }
00140
00141 template < class T >
00142 T empty ()
00143 {
00144 T value;
00145 byte *bytePointer = (byte *) (const void *) &value;
00146 for (unsigned int i = 0; i < sizeof (value); i++)
00147 {
00148 *bytePointer = '\0';
00149 bytePointer++;
00150 }
00151 return value;
00152 }
00153
00154
00155
00156 char *split_r (char *str, const char delim, char **nextp);
00157 bool isEscaped (char *currChar, const char escapeChar, char *lastChar);
00158
00159 void printEsc (char *str);
00160 void printEsc (char str);
00161
00162 public:
00163
00164
00165
00166
00167
00168 CmdMessenger (Stream & comms, const char fld_separator = ',',
00169 const char cmd_separator = ';',
00170 const char esc_character = '/');
00171
00172 void printLfCr (bool addNewLine=true);
00173 void attach (messengerCallbackFunction newFunction);
00174 void attach (byte msgId, messengerCallbackFunction newFunction);
00175
00176
00177
00178 void feedinSerialData ();
00179 bool next ();
00180 bool available ();
00181 bool isArgOk ();
00182 uint8_t CommandID ();
00183
00184
00185
00190 template < class T >
00191 bool sendCmd (int cmdId, T arg, bool reqAc = false, int ackCmdId = 1,
00192 int timeout = DEFAULT_TIMEOUT)
00193 {
00194 if (!startCommand) {
00195 sendCmdStart (cmdId);
00196 sendCmdArg (arg);
00197 return sendCmdEnd (reqAc, ackCmdId, timeout);
00198 }
00199 return false;
00200 }
00201
00206 template < class T >
00207 bool sendBinCmd (int cmdId, T arg, bool reqAc = false, int ackCmdId = 1,
00208 int timeout = DEFAULT_TIMEOUT)
00209 {
00210 if (!startCommand) {
00211 sendCmdStart (cmdId);
00212 sendCmdBinArg (arg);
00213 return sendCmdEnd (reqAc, ackCmdId, timeout);
00214 }
00215 return false;
00216 }
00217
00218 bool sendCmd (int cmdId);
00219 bool sendCmd (int cmdId, bool reqAc, int ackCmdId );
00220
00221
00222 void sendCmdStart (int cmdId);
00223 void sendCmdEscArg (char *arg);
00224 void sendCmdfArg (char *fmt, ...);
00225 bool sendCmdEnd (bool reqAc = false, int ackCmdId = 1, int timeout = DEFAULT_TIMEOUT);
00226
00231 template < class T > void sendCmdArg (T arg)
00232 {
00233 if (startCommand) {
00234 comms->print (field_separator);
00235 comms->print (arg);
00236 }
00237 }
00238
00243 template < class T > void sendCmdArg (T arg, int n)
00244 {
00245 if (startCommand) {
00246 comms->print (field_separator);
00247 comms->print (arg, n);
00248 }
00249 }
00250
00255 void sendCmdSciArg(double arg, int n=6);
00256
00257
00262 template < class T > void sendCmdBinArg (T arg)
00263 {
00264 if (startCommand) {
00265 comms->print (field_separator);
00266 writeBin (arg);
00267 }
00268 }
00269
00270
00271 bool readBoolArg();
00272 int16_t readInt16Arg ();
00273 int32_t readInt32Arg ();
00274 char readCharArg ();
00275 float readFloatArg ();
00276 double readDoubleArg();
00277 char *readStringArg ();
00278 void copyStringArg (char *string, uint8_t size);
00279 uint8_t compareStringArg (char *string);
00280
00284 template < class T > T readBinArg ()
00285 {
00286 if (next ()) {
00287 dumped = true;
00288 return readBin < T > (current);
00289 } else {
00290 return empty < T > ();
00291 }
00292 }
00293
00294
00295
00296 void unescape (char *fromChar);
00297 void printSci(double f, unsigned int digits);
00298
00299
00300 };
00301 #endif