-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSerialCmd.cpp
242 lines (196 loc) · 6.35 KB
/
SerialCmd.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// This is: D:\Russ\0000\Arduino\TestTerminal\Ver4\TestTerminal\TestTerminal.ino or a copy of it
// convertered from my old pic routines, this uses the normal arduino libe.
// Purpose:
// Recive a command string untill an end of command ( usually end of line, see .h file ) is recieved
// and return the command
// TestTerminal is a program showing its use.
// Some add ons include
// parsing out a number from the command
// parsing out a series of numbers
#if defined(ARDUINO) && ARDUINO >= 100 // # https://github.com/adafruit/DHT-sensor-library/issues/1 changed 2015 Feb 21
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "SerialCmd.h"
// ---------- begin constructor ----------
SerialCmd::SerialCmd( )
{
//pinMode(pin, OUTPUT);
//_pin = pin;
}
// ---------- begin subroutine ----------
// add a char to the string
// not really a string until it has been ended with a 0
//
void SerialCmd::buildCmd( unsigned char aNewChar ) {
_cmd[ _cmdIx ] = aNewChar;
_cmdIx ++;
if ( _cmdIx >= CMD_MAX ) {
_cmdIx = CMD_MAX;
}
}
// ---------- begin subroutine ----------
// backspace the command
void SerialCmd::backCmd( ) {
if ( _cmdIx > 0 ) {
_cmdIx --;
}
return;
}
// ---------- begin subroutine ----------
// reset the command to null, inline function good?
void SerialCmd::resetCmd( ) {
_cmdIx = 0;
gotCmd = 0;
_cmdStatus = CMD_STATUS_ADD;
}
//// ---------- begin subroutine ----------
//// Function: converts characters following one char command to signed long
//// todo* hardcode cmdprior?
//// does not skip spaces
//// manages leading +- start 1 char in, no spaces at the end
//long SerialCmd::parseCmdNbr( const char* text ) {
//
// long Nbr = 0;
// char next;
// char ix;
// char ix_lo = 1;
// bool neg_flag = false;
// // skipping spaces would not be too hard if we did not care where they occured
// if ( text[1] == 45 ) {
// neg_flag = true;
// ix_lo = 2;
// } else if ( text[1] == 43 ) { // 43 = +
// ix_lo = 2;
// }
// // minus sign is 45
// for( ix = ix_lo; ix < 16; ix++ ) {
// next = text[ix];
// if( next == 0 ) {
// if ( neg_flag ) {
// return -Nbr;
// } else {
// return Nbr;
// }
// }
// Nbr = ( Nbr * 10 ) + ( next - 48 ); // 48 = '0'
// }
// return 0; // it is an error to have more than n char
//}
// ---------- begin subroutine ----------
long SerialCmd::parseCmdNbr( const char* text ) {
long Nbr = 0;
char next;
char ix;
int sign = 1;
for( ix = 1; ix < 16; ix++ ) {
next = text[ix];
switch ( next ) {
case 0: // end of string
return Nbr * sign;
break;
case ' ': // skip space
break;
case '+': // skip +
break;
case '-': // flip sign
sign = -1 * sign;
break;
default:
Nbr = ( Nbr * 10 ) + ( next - 48 );
//Serial.print( "\n\r" );
//Serial.println( F("") );
}
}
return Nbr * sign;
}
// ---------- begin subroutine ----------
bool SerialCmd::doneNext( ) {
return done_getNext;
}
// ---------- begin subroutine ----------
// get next numeric value for now only pos ints, could peel off a string value and use libe to convert
// x11 22 333 4 5######
// x11 22 333 4 5 ######
// x 11 22 333 4 5###### ... are all valid note problems at begin and end
// x with no numbers ???
// for now do not allow trailing blanks which would require look ahead which we could do
int SerialCmd::getNext( ) {
int val;
char a_char;
val = 0;
done_getNext = false;
while ( true ) {
// do deal with 2 blanks need to know if we have started converting val == 0 not a good test add a flag??
ix_getNext ++;
a_char = cmdPrior[ ix_getNext ];
if( a_char == 0 ) { // null we are done
done_getNext = true;
//Serial.print( "done at ix_getNext = " );
//Serial.println( ix_getNext );
return val;
}
else if ( a_char == CHAR_SP ) {
// if ( val != 0 ) {
// and go ahead then back up one
return val;
}
else {
val = ( val * 10 ) + ( a_char - 48 );
}
}
return val;
}
// ---------- begin subroutine ----------
// try to recieve some data
// may use as interrupt service routine in which case serial peek test not required
// for arduino call frequently
void SerialCmd::tryRecCmd ( ) {
char dataIn;
while ( Serial.available() > 0 ) {
dataIn = Serial.read();
if ( dataIn == CHAR_LF ) {
// ignore this char
continue;
}
// if ( data_in == CHAR_CR ) {
// ignore this char
// continue;
// }
if ( dataIn == STOP_CHAR ) {
// stop no matter what else we are in the process of
// do not log as command
stopFlag = 1;
// resetCmd( ); // this resets the falg -- this is wrong, comment out may not fix -- still does not work at all
continue;
}
if ( dataIn == CHAR_CMD_TERM ) {
//if ( data_in == CHAR_CR ) {
// marks end of command execute the command ( or set flag for same )
// may want to save so can begin to build a new command
// void strcpy( char *dst, const char *src )
buildCmd( 0 ); // terminate the string
strcpy( cmdPrior, _cmd );
//serial.print( "cmdPrior" );
//serial.print( cmdPrior );
resetCmd( );
gotCmd = 1;
done_getNext = false;
ix_getNext = 0; // this will skip the first char the command
continue;
}
if ( dataIn == CHAR_BS ) {
//if (( data_in == CHAR_BS ) || ( data_in == CHAR_DEL )) {
backCmd();
continue;
}
if ( _cmdStatus == CMD_STATUS_ADD ) {
buildCmd( dataIn );
}
// if here just drop the recieved char
// are we too long in the interrup think not
}
return;
}
// ============ eof =============