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: mbed BufferedSerial Servo PCT2075 FastPWM
Diff: cli_nortos.cpp
- Revision:
- 3:ecb00e0e8d68
- Parent:
- 2:04761b196473
- Child:
- 4:21d91465e4b1
--- a/cli_nortos.cpp Sat Mar 10 10:11:07 2018 +0000
+++ b/cli_nortos.cpp Sun Mar 18 08:17:56 2018 +0000
@@ -4,150 +4,153 @@
#include "DualBLS.h"
using namespace std;
-typedef double fl_typ; //
+extern int I_Am () ; // Returns boards id number as ASCII char '0', '1' etc. Code for Broadcast = '\r'
+//typedef double fl_typ; //
-const int MAX_PARAMS = 10;
+const int BROADCAST = '\r';
+const int MAX_PARAMS = 20;
struct parameters {
// int32_t times[numof_menu_items];
- int32_t times[50];
- int32_t position_in_list, last_time, numof_dbls;
+// int32_t times[50];
+ int32_t position_in_list, last_time, numof_dbls, target_unit;
double dbl[MAX_PARAMS];
+ bool respond;
} ;
// WithOUT RTOS
-extern BufferedSerial xb, pc;
-//extern BufferedSerial bt;
+extern BufferedSerial com2, pc;
//extern void set_I_limit (double p) ; // Sets max motor current
//extern void set_V_limit (double p) ; // Sets max motor voltage
extern void send_test () ;
-//extern void assemble_rx_frame () ;
-//extern void read_pulses (uint32_t * ) ;
-//extern void apply_brake (double b) ;
-//extern uint32_t Watch_Dog ;
extern void setVI (double v, double i) ;
-/*void pcp (char * toprint) {
- pc.printf (toprint);
- return;
-}*/
+BufferedSerial * com;
void null_cmd (struct parameters & a) {
- pc.printf ("At null_cmd, parameters : First %.3f, second %.3f\r\n", a.dbl[0], a.dbl[1]);
+ com->printf ("At null_cmd, parameters : First %.3f, second %.3f\r\n", a.dbl[0], a.dbl[1]);
}
-extern void tickle () ;
+/*extern void tickleboth () ;
void ti_cmd (struct parameters & a) {
- pc.printf ("At tickle\r\n");
- tickle ();
-}
+ com->printf ("At tickle\r\n");
+ tickleboth ();
+}*/
-void rd_cmd (struct parameters & a) { // Reading Hall pulse totals and clock() from bogie
- uint32_t rd[2];
- char t[36];
-// read_pulses (rd);
- sprintf (t, "P0=%d, P1=%d, clock=%d\n", rd[0], rd[1], clock());
- pc.printf (t);
-}
extern void mode_test (int mode, double val) ;
void fw_cmd (struct parameters & a) {
- pc.printf ("Forward : First %d, second %d\r\n", a.dbl[0], a.dbl[1]);
+ com->printf ("Forward : First %d, second %d\r\n", a.dbl[0], a.dbl[1]);
mode_test (FORWARD, 0.0);
}
void re_cmd (struct parameters & a) {
- pc.printf ("Reverse : First %d, second %d\r\n", a.dbl[0], a.dbl[1]);
+ com->printf ("Reverse : First %d, second %d\r\n", a.dbl[0], a.dbl[1]);
mode_test (REVERSE, 0.0);
}
void rb_cmd (struct parameters & a) { // Regen brake
double b = a.dbl[0] / 99.0;
- pc.printf ("Applying brake %.3f\r\n", b);
+ com->printf ("Applying brake %.3f\r\n", b);
mode_test (REGENBRAKE, b);
// apply_brake (b);
}
-/*void drive_cmd (struct parameters & a) { // Drive
- double drive = a.dbl[0] / 999.0;
+extern bool wr_24LC64 (int mem_start_addr, char * source, int length) ;
+extern bool rd_24LC64 (int mem_start_addr, char * dest, int length) ;
+void erase_cmd (struct parameters & a) { // Sets eeprom contents to all 0xff. 256 pages of 32 bytes to do
+ char t[36];
+ for (int i = 0; i < 32; i++)
+ t[i] = 0xff;
+ for (int i = 0; i < 8191; i += 32) {
+ com->printf (".");
+ if (!wr_24LC64 (i, t, 32))
+ com->printf ("eeprom write prob\r\n");
+ }
}
-void coast_cmd (struct parameters & a) { // Coast
+/*struct motorpairoptions { // This to be user settable in eeprom, 32 bytes
+ uint8_t MotA_dir, // 0 or 1
+ MotB_dir, // 0 or 1
+ gang, // 0 for separate control (robot mode), 1 for ganged loco bogie mode
+ serv1, // 0, 1, 2 = Not used, Input, Output
+ serv2, // 0, 1, 2 = Not used, Input, Output
+ cmd_source, // 0 Invalid, 1 COM1, 2 COM2, 3 Pot, 4 Servo1, 5 Servo2
+ last;
+} ;
+*/
+struct optpar {
+ int min, max, def;
+ const char * t;
+} ;
+struct optpar const option_list[] = {
+ {0, 1, 1, "MotorA direction 0 or 1"},
+ {0, 1, 0, "MotorB direction 0 or 1"},
+ {0, 1, 1, "gang 0 for separate control (robot mode), 1 for ganged loco bogie mode"},
+ {0, 2, 2, "Servo1 0, 1, 2 = Not used, Input, Output"},
+ {0, 2, 2, "Servo2 0, 1, 2 = Not used, Input, Output"},
+ {1, 5, 2, "Command source 0 Invalid, 1 COM1, 2 COM2, 3 Pot, 4 Servo1, 5 Servo2"},
+ {0, 9, 0, "Alternative ID 0 to 9"},
+} ;
+
+void mode_cmd (struct parameters & a) { // With no params, reads eeprom contents. With params sets eeprom contents
+ char t[36];
+ const int numofopts = sizeof(option_list) / sizeof(struct optpar);
+ rd_24LC64 (0, t, 32);
+ com->printf ("Numof params=%d\r\n", a.numof_dbls);
+ for (int i = 0; i < numofopts; i++)
+ com->printf ("%2x\t%s\r\n", t[i], option_list[i].t);
+ if (a.numof_dbls == 0) { // Read present contents, do not write
+ com->printf ("That's it\r\n");
+ }
+ else { // Write new shit to eeprom
+ com->printf ("\r\n");
+ if (a.numof_dbls != numofopts) {
+ com->printf ("params required = %d, you offered %d\r\n", numofopts, a.numof_dbls);
+ }
+ else { // Have been passed correct number of parameters
+ int b;
+ com->printf("Ready to write params to eeprom\r\n");
+ for (int i = 0; i < numofopts; i++) {
+ b = (int)a.dbl[i]; // parameter value to check against limits
+ if ((b < option_list[i].min) || (b > option_list[i].max)) { // if parameter out of range
+ com->printf("Warning - Parameter = %d, out of range, setting to default %d\r\n", b, option_list[i].def);
+ b = option_list[i].def;
+ }
+ com->printf ("%2x\t%s\r\n", (t[i] = b), option_list[i].t);
+ }
+ wr_24LC64 (0, t, numofopts);
+ com->printf("Parameters set in eeprom\r\n");
+ }
+ }
+}
+/*void coast_cmd (struct parameters & a) { // Coast
}
*/
void hb_cmd (struct parameters & a) {
- pc.printf ("numof params = %d\r\n", a.numof_dbls);
- pc.printf ("Hand Brake : First %.3f, second %.3f\r\n", a.dbl[0], a.dbl[1]);
+ com->printf ("numof params = %d\r\n", a.numof_dbls);
+ com->printf ("Hand Brake : First %.3f, second %.3f\r\n", a.dbl[0], a.dbl[1]);
mode_test (HANDBRAKE, 0.0);
}
-//void wd_cmd (struct parameters & a) {
-// pc.printf ("Reset Watch Dog timer, was %d\r\n", Watch_Dog);
-// Watch_Dog = 0;
-//}
-
-/*void hall_cmd (struct parameters * a) { // Report back pulse totals from Hall sensors for both motors
- char buff[30];
- sprintf (buff, "Halls 0x%08lx 0x%08lx\r\n", Halls_A_accum, Halls_B_accum); // doesn't need to be hex
- pc.printf (buff);
-
- Halls_A_accum += 1369;
- Halls_B_accum += 11369;
-}*/
-
-/*void setpwm_cmd (struct parameters * a) {
- double pw = ((double)a[1].i) / 1000.0;
- pc.printf ("Setting Volt limit %.3f, %d\r\n", pw, a[1].i);
- set_V_limit (pw);
-}
-
-void setvref_cmd (struct parameters * a) {
- double pw = ((double)a[1].i) / 1000.0;
- pc.printf ("Setting Current limit %.3f, %d\r\n", pw, a[1].i);
- set_I_limit (pw);
-}*/
-
-/*
-void setmotpwm_cmd (struct parameters * a) {
- //a[1].i // first param
- pc.printf ("First %d, second %d\r\n", a[1].i, a[2].i);
-// set_motor_pwm (a[1].i, a[2].i);
-}
-//extern void set_fwd_rev (int direction) ;
-void set_fwd_cmd (struct parameters * a) {
-// set_fwd_rev (FWD);
-}
-void set_rev_cmd (struct parameters * a) {
-// set_fwd_rev (REV);
-}
-
-void set_speed_cmd (struct parameters * a) {
- pc.printf ("Speed entered %d\r\n", a[1].i);
-}
-
-void read_current_cmd (struct parameters * a) {
- pc.printf ("Read current\r\n");
-}
-*/
void menucmd (struct parameters & a);
-//void xb_cmd (struct parameters & a)
-//{
-// send_test();
-//}
-
-//extern void set_api_mode (bool mode) ;
void vi_cmd (struct parameters & a)
{
- pc.printf ("In setVI, setting V to %.2f, I %.2f\r\n", a.dbl[0], a.dbl[1]);
+ com->printf ("In setVI, setting V to %.2f, I %.2f\r\n", a.dbl[0], a.dbl[1]);
setVI (a.dbl[0] / 100.0, a.dbl[1] / 100.0);
}
-/*void at_cmd (struct parameters & a)
+void kd_cmd (struct parameters & a) // kick the watchdog
{
- xb.printf ("AT\r");
-// pc.printf ("AT %d\r\n", a[1].i);
-}*/
+}
+
+void who_cmd (struct parameters & a)
+{
+ int i = I_Am ();
+ if (I_Am() == a.target_unit)
+ com->printf ("Hi there, I am %c\r\n", a.target_unit);
+}
struct kb_command {
const char * cmd_word; // points to text e.g. "menu"
@@ -156,36 +159,39 @@
} ;
struct kb_command const command_list[] = {
- {"menu", "Lists available commands, same as ls", menucmd},
- {"ls", "Lists available commands, same as menu", menucmd},
-// {"sv", "set Volts pwm 0 to 999", setpwm_cmd},
-// {"si", "set Amps pwm 0 to 999", setvref_cmd},
-// {"ha", "read Hall pulse totals", hall_cmd},
- {"ti", "tickle to try to get mosfet driver charge pump primed", ti_cmd},
+ {"ls", "Lists available commands", menucmd},
+ {"?", "Lists available commands, same as ls", menucmd},
+// {"ti", "tickle to try to get mosfet driver charge pump primed", ti_cmd},
{"fw", "forward", fw_cmd},
{"re", "reverse", re_cmd},
{"rb", "regen brake 0 to 99 %", rb_cmd},
-// {"dr", "drive", drive_cmd},
-// {"co", "coast", coast_cmd},
{"hb", "hand brake", hb_cmd},
-// {"at", "AT", at_cmd},
{"vi", "set motors V and I percent RANGE 0 to 100", vi_cmd},
+ {"who", "search for connected units, e.g. 3who returs 'Hi there' if found", who_cmd},
+ {"mode", "read or set params in eeprom", mode_cmd},
+ {"erase", "set eeprom contents to all 0xff", erase_cmd},
+ {"kd", "kick the dog", kd_cmd},
{"nu", "do nothing", null_cmd},
-
-// {"rev", "set motors in tother direction", set_rev_cmd},
-// {"s", "set speed", set_speed_cmd},
-// {"i", "Read motor currents", read_current_cmd},
};
const int numof_menu_items = sizeof(command_list) / sizeof(kb_command);
void menucmd (struct parameters & a)
{
- pc.printf("\r\n\nDouble Brushless Motor Driver 2018\r\nAt menucmd function - listing commands:-\r\n");
+ com->printf("\r\n\nDouble Brushless Motor Driver 2018\r\nAt menucmd function - listing commands:-\r\n");
for(int i = 0; i < numof_menu_items; i++)
- pc.printf("[%s]\t\t%s\r\n", command_list[i].cmd_word, command_list[i].explan);
- pc.printf("End of List of Commands\r\n");
+ com->printf("[%s]\t\t%s\r\n", command_list[i].cmd_word, command_list[i].explan);
+ com->printf("End of List of Commands\r\n");
}
+
+/*
+New - March 2018
+Using opto isolated serial port, paralleled up using same pair to multiple boards running this code.
+New feature - commands have optional prefix digit 0-9 indicating which unit message is addressed to.
+Commands without prefix digit - broadcast to all units, none to respond.
+Only units recognising its address from prefix digit may respond. This avoids bus contention.
+But for BROADCAST commands, '0' may respond on behalf of the group
+*/
//void command_line_interpreter (void const *argument)
void command_line_interpreter ()
{
@@ -193,67 +199,62 @@
static char cmd_line[MAX_CMD_LEN + 4];
static int cl_index = 0;
int ch;
-char * pEnd;
+char * pEnd, * cmd_line_ptr;
static struct parameters param_block ;
-// while (true) {
-// assemble_rx_frame () ; // check for anything coming from xbee
-// Watch_Dog++;
-/* while (bt.readable()) {
- ch = bt.getc();
-// bt.putc(ch);
- pc.printf ("%c", ch);
- }*/
- while (pc.readable()) {
- ch = tolower(pc.getc());
- // pc.printf("%c", ch);
+ com = &com2;
+// while (pc.readable()) {
+ while (com->readable()) {
+ ch = tolower(com->getc());
if (cl_index > MAX_CMD_LEN) { // trap out stupidly long command lines
- pc.printf ("Error!! Stupidly long cmd line\r\n");
+ com->printf ("Error!! Stupidly long cmd line\r\n");
cl_index = 0;
}
- if (ch == '\r' || ch >= ' ' && ch <= 'z')
- pc.printf("%c", ch);
- else { // Using <Ctrl>+ 'F', 'B' for Y, 'L', 'R' for X, 'U', 'D' for Z
- cl_index = 0; // 6 2 12 18 21 4
- pc.printf("[%d]", ch);
- //nudger (ch); // was used on cnc to nudge axes a tad
- }
if(ch != '\r') // was this the 'Enter' key?
cmd_line[cl_index++] = ch; // added char to command being assembled
else { // key was CR, may or may not be command to lookup
+ param_block.target_unit = BROADCAST; // Broadcast
+ cmd_line_ptr = cmd_line;
cmd_line[cl_index] = 0; // null terminate command string
if(cl_index) { // If have got some chars to lookup
int i, wrdlen;
+ if (isdigit(cmd_line[0])) { // Look for command with prefix digit
+ cmd_line_ptr++; // point past identified digit prefix
+ param_block.target_unit = cmd_line[0]; // '0' to '9'
+ //com->printf ("Got prefix %c\r\n", cmd_line[0]);
+ }
for (i = 0; i < numof_menu_items; i++) { // Look for input match in command list
wrdlen = strlen(command_list[i].cmd_word);
- if(strncmp(command_list[i].cmd_word, cmd_line, wrdlen) == 0 && !isalpha(cmd_line[wrdlen])) { // If match found
+ if(strncmp(command_list[i].cmd_word, cmd_line_ptr, wrdlen) == 0 && !isalpha(cmd_line_ptr[wrdlen])) { // If match found
for (int k = 0; k < MAX_PARAMS; k++) {
param_block.dbl[k] = 0.0;
}
param_block.position_in_list = i;
param_block.last_time = clock ();
param_block.numof_dbls = 0;
- pEnd = cmd_line + wrdlen;
+ pEnd = cmd_line_ptr + wrdlen;
while (*pEnd) { // Assemble all numerics as doubles
param_block.dbl[param_block.numof_dbls++] = strtod (pEnd, &pEnd);
while (*pEnd && !isdigit(*pEnd) && '-' != *pEnd && '+' != *pEnd) {
pEnd++;
}
}
- pc.printf ("\r\n");
- for (int k = 0; k < param_block.numof_dbls; k++)
- pc.printf ("Read %.3f\r\n", param_block.dbl[k]);
- param_block.times[i] = clock();
+ //com->printf ("\r\n"); // Not allowed as many may output this.
+ //for (int k = 0; k < param_block.numof_dbls; k++)
+ // com->printf ("Read %.3f\r\n", param_block.dbl[k]);
+// param_block.times[i] = clock();
+ if ((param_block.target_unit == BROADCAST) && (I_Am() == '0'))
+ param_block.respond = true;
command_list[i].f(param_block); // execute command
i = numof_menu_items + 1; // to exit for loop
} // end of match found
} // End of for numof_menu_items
if(i == numof_menu_items)
- pc.printf("No Match Found for CMD [%s]\r\n", cmd_line);
+ com->printf("No Match Found for CMD [%s]\r\n", cmd_line);
} // End of If have got some chars to lookup
- pc.printf("\r\n>");
+ //com->printf("\r\n>");
cl_index = 0;
} // End of else key was CR, may or may not be command to lookup
- } // End of while (pc.readable())
+ } // End of while (com->readable())
// Thread::wait(20); // Using RTOS on this project
// }
}