Jon Freeman / Mbed 2 deprecated Brushless_STM3_ESC_2019_10

Dependencies:   mbed BufferedSerial Servo PCT2075 FastPWM

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
 //    }
 }