Skip to content

Commit a8a72b2

Browse files
authored
Merge branch 'dev' into dev
2 parents d8011fc + 8246fe5 commit a8a72b2

File tree

2 files changed

+57
-38
lines changed

2 files changed

+57
-38
lines changed

src/communication/Commander.cpp

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
#include "Commander.h"
22

33

4-
Commander::Commander(Stream& serial){
4+
Commander::Commander(Stream& serial, char eol, bool echo){
55
com_port = &serial;
6+
this->eol = eol;
7+
this->echo = echo;
68
}
7-
Commander::Commander(){
8-
// do nothing
9+
Commander::Commander(char eol, bool echo){
10+
this->eol = eol;
11+
this->echo = echo;
912
}
1013

1114

@@ -19,52 +22,47 @@ void Commander::add(char id, CommandCallback onCommand, char* label ){
1922

2023
void Commander::run(){
2124
if(!com_port) return;
22-
// a string to hold incoming data
23-
while (com_port->available()) {
24-
// get the new byte:
25-
received_chars[rec_cnt] = (char)com_port->read();
26-
// end of user input
27-
if (received_chars[rec_cnt++] == '\n') {
28-
// execute the user command
29-
run(received_chars);
30-
31-
// reset the command buffer
32-
received_chars[0] = 0;
33-
rec_cnt=0;
34-
}
35-
if (rec_cnt>=MAX_COMMAND_LENGTH) { // prevent buffer overrun if message is too long
36-
received_chars[0] = 0;
37-
rec_cnt=0;
38-
}
39-
}
25+
run(*com_port, eol);
4026
}
4127

42-
void Commander::run(Stream& serial){
28+
void Commander::run(Stream& serial, char eol){
4329
Stream* tmp = com_port; // save the serial instance
44-
// use the new serial instance to output if not available the one linked in constructor
45-
if(!tmp) com_port = &serial;
30+
char eol_tmp = this->eol;
31+
this->eol = eol;
32+
com_port = &serial;
4633

4734
// a string to hold incoming data
4835
while (serial.available()) {
4936
// get the new byte:
50-
received_chars[rec_cnt] = (char)serial.read();
37+
int ch = serial.read();
38+
received_chars[rec_cnt++] = (char)ch;
5139
// end of user input
52-
if (received_chars[rec_cnt++] == '\n') {
40+
if(echo)
41+
print((char)ch);
42+
if (isSentinel(ch)) {
5343
// execute the user command
5444
run(received_chars);
5545

5646
// reset the command buffer
5747
received_chars[0] = 0;
5848
rec_cnt=0;
5949
}
50+
if (rec_cnt>=MAX_COMMAND_LENGTH) { // prevent buffer overrun if message is too long
51+
received_chars[0] = 0;
52+
rec_cnt=0;
53+
}
6054
}
6155

6256
com_port = tmp; // reset the instance to the internal value
57+
this->eol = eol_tmp;
6358
}
6459

6560
void Commander::run(char* user_input){
6661
// execute the user command
6762
char id = user_input[0];
63+
64+
65+
6866
switch(id){
6967
case CMD_SCAN:
7068
for(int i=0; i < call_count; i++){
@@ -75,7 +73,7 @@ void Commander::run(char* user_input){
7573
}
7674
break;
7775
case CMD_VERBOSE:
78-
if(user_input[1] != '\n') verbose = (VerboseMode)atoi(&user_input[1]);
76+
if(!isSentinel(user_input[1])) verbose = (VerboseMode)atoi(&user_input[1]);
7977
printVerbose(F("Verb:"));
8078
switch (verbose){
8179
case VerboseMode::nothing:
@@ -88,7 +86,7 @@ void Commander::run(char* user_input){
8886
}
8987
break;
9088
case CMD_DECIMAL:
91-
if(user_input[1] != '\n') decimal_places = atoi(&user_input[1]);
89+
if(!isSentinel(user_input[1])) decimal_places = atoi(&user_input[1]);
9290
printVerbose(F("Decimal:"));
9391
println(decimal_places);
9492
break;
@@ -109,7 +107,7 @@ void Commander::motor(FOCMotor* motor, char* user_command) {
109107
char sub_cmd = user_command[1];
110108
int value_index = (sub_cmd >= 'A' && sub_cmd <= 'Z') ? 2 : 1;
111109
// check if get command
112-
bool GET = user_command[value_index] == '\n';
110+
bool GET = isSentinel(user_command[value_index]);
113111
// parse command values
114112
float value = atof(&user_command[value_index]);
115113

@@ -358,7 +356,7 @@ void Commander::motor(FOCMotor* motor, char* user_command) {
358356
case SCMD_SET:
359357
if(!GET) motor->monitor_variables = (uint8_t) 0;
360358
for(int i = 0; i < 7; i++){
361-
if(user_command[value_index+i] == '\n') break;
359+
if(isSentinel(user_command[value_index+i])) break;
362360
if(!GET) motor->monitor_variables |= (user_command[value_index+i] - '0') << (6-i);
363361
print( (user_command[value_index+i] - '0') );
364362
}
@@ -378,7 +376,7 @@ void Commander::motor(FOCMotor* motor, char* user_command) {
378376

379377
void Commander::pid(PIDController* pid, char* user_cmd){
380378
char cmd = user_cmd[0];
381-
bool GET = user_cmd[1] == '\n';
379+
bool GET = isSentinel(user_cmd[1]);
382380
float value = atof(&user_cmd[1]);
383381

384382
switch (cmd){
@@ -415,7 +413,7 @@ void Commander::pid(PIDController* pid, char* user_cmd){
415413

416414
void Commander::lpf(LowPassFilter* lpf, char* user_cmd){
417415
char cmd = user_cmd[0];
418-
bool GET = user_cmd[1] == '\n';
416+
bool GET = isSentinel(user_cmd[1]);
419417
float value = atof(&user_cmd[1]);
420418

421419
switch (cmd){
@@ -431,11 +429,26 @@ void Commander::lpf(LowPassFilter* lpf, char* user_cmd){
431429
}
432430

433431
void Commander::scalar(float* value, char* user_cmd){
434-
bool GET = user_cmd[0] == '\n';
432+
bool GET = isSentinel(user_cmd[0]);
435433
if(!GET) *value = atof(user_cmd);
436434
println(*value);
437435
}
438436

437+
bool Commander::isSentinel(char ch)
438+
{
439+
if(ch == eol)
440+
return true;
441+
else if (ch == '\r')
442+
{
443+
if(verbose == VerboseMode::user_friendly)
444+
{
445+
print(F("Warning! \\r detected but is not configured as end of line sentinel, which is configured as ascii code '"));
446+
print(int(eol));
447+
print("'\n");
448+
}
449+
}
450+
return false;
451+
}
439452

440453
void Commander::print(const int number){
441454
if( !com_port || verbose == VerboseMode::nothing ) return;

src/communication/Commander.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@ class Commander
4242
* Also if the function run() is used it uses this serial instance to read the serial for user commands
4343
*
4444
* @param serial - Serial com port instance
45+
* @param eol - the end of line sentinel character
46+
* @param echo - echo last typed character (for command line feedback)
4547
*/
46-
Commander(Stream &serial);
47-
Commander();
48+
Commander(Stream &serial, char eol = '\n', bool echo = false);
49+
Commander(char eol = '\n', bool echo = false);
4850

4951
/**
5052
* Function reading the serial port and firing callbacks that have been added to the commander
@@ -65,9 +67,10 @@ class Commander
6567
* '#' - Number of decimal places
6668
* '?' - Scan command - displays all the labels of attached nodes
6769
*
68-
* @param reader - Stream to read user input
70+
* @param reader - temporary stream to read user input
71+
* @param eol - temporary end of line sentinel
6972
*/
70-
void run(Stream &reader);
73+
void run(Stream &reader, char eol = '\n');
7174
/**
7275
* Function reading the string of user input and firing callbacks that have been added to the commander
7376
* once the user has requested them - when he sends the command
@@ -95,7 +98,8 @@ class Commander
9598

9699
// monitoring functions
97100
Stream* com_port = nullptr; //!< Serial terminal variable if provided
98-
101+
char eol = '\n'; //!< end of line sentinel character
102+
bool echo = false; //!< echo last typed character (for command line feedback)
99103
/**
100104
*
101105
* FOC motor (StepperMotor and BLDCMotor) command interface
@@ -198,6 +202,7 @@ class Commander
198202
* @param message - number to be printed
199203
* @param newline - if needs lewline (1) otherwise (0)
200204
*/
205+
201206
void print(const float number);
202207
void print(const int number);
203208
void print(const char* message);
@@ -210,6 +215,7 @@ class Commander
210215
void println(const char message);
211216

212217
void printError();
218+
bool isSentinel(char ch);
213219
};
214220

215221

0 commit comments

Comments
 (0)