Touch screen drivers control dashboard for miniature locomotive. Features meters for speed, volts, power. Switches for lights, horns. Drives multiple STM3_ESC brushless motor controllers for complete brushless loco system as used in "The Brute" - www.jons-workshop.com

Dependencies:   TS_DISCO_F746NG mbed Servo LCD_DISCO_F746NG BSP_DISCO_F746NG QSPI_DISCO_F746NG AsyncSerial FastPWM

Revision:
12:a25bdf135348
Parent:
11:a573664b1a59
Child:
14:6bcec5ac21ca
--- a/Electric_Loco.h	Sat Jun 23 09:37:41 2018 +0000
+++ b/Electric_Loco.h	Mon Jan 14 16:39:41 2019 +0000
@@ -1,5 +1,7 @@
 #include "mbed.h"
-/*  Updated 9 May 2018
+#include "movingcoilmeter.h"
+#include <cctype>
+/*  Updated January 2019
     Jon Freeman
 
   5" and 7.25" gauge Electric Locomotive Controller - ST DISCO-F746NG
@@ -7,11 +9,11 @@
 
 Display shows 'analogue' moving coil meter movements for :
     Locomotive speed Miles per Hour
-    System voltage (range 20v - 90v or thereabouts)
-    Power Watts delivered to drive motors.
+    System voltage (range 10v - 63v or thereabouts)
+    Power Watts delivered to drive motors or dumped.
 
-Touch screen has three 'buttons', these are currently unused, and are where the meter movements show.
-Idea is to use two for two horns,
+Touch screen has three 'buttons', and are where the meter movements show.
+Two smaller meter buttons for two horns, larger speedo button currently unsused
 
 Display has 'slider' touch control. This drives the loco.
 Control in central position when not driving or drfting.
@@ -20,7 +22,6 @@
 Take finger off and control drifts down to central 'neutral' position.
 */
 
-#define QSPI
 
 #define MAX_TOUCHES 6       //  Touch screen can decode up to this many simultaneous finger press positions
 #define NEUTRAL_VAL   150   //  Number of pixels
@@ -30,78 +31,146 @@
 #define SLIDERW 50          //  pixel width of slider
 #define SLIDERH 268         //  pixel height of slider
 
-//  To get speedo reading correctly, need to use correct gear ratio and wheel size info
-//#define BOGIE_5_INCH
-#define BOGIE_7_and_a_quarter_INCH
+#define VOLTMETER_X 68      //  Voltmeter screen position
+#define VOLTMETER_Y 68
+#define AMMETER_X   68      //  Ammeter screen position - Now replaced by Power meter
+#define AMMETER_Y   202
+#define SPEEDO_X    274     //  Speedometer screen position
+#define SPEEDO_Y    135
+//#define V_A_SIZE    54      //  Size of voltmeter and ammeter
+//#define SPEEDO_SIZE 112
+
+#define V_A_SIZE    56      //  Size of voltmeter and ammeter
+#define SPEEDO_SIZE 114
 
+#define SPEEDO_BODY_COLOUR  LCD_COLOR_BLACK
+#define SPEEDO_DIAL_COLOUR  LCD_COLOR_WHITE
+#define SPEEDO_TEXT_COLOUR  LCD_COLOR_BLUE
+
+#define VMETER_BODY_COLOUR  LCD_COLOR_BLACK
+#define VMETER_DIAL_COLOUR  LCD_COLOR_WHITE
+#define VMETER_TEXT_COLOUR  LCD_COLOR_BLUE
+
+#define AMETER_BODY_COLOUR  LCD_COLOR_BLACK
+#define AMETER_DIAL_COLOUR  LCD_COLOR_WHITE
+#define AMETER_TEXT_COLOUR  LCD_COLOR_BLUE
 const   int
-
     BUTTON_RAD  = (SLIDERW / 2) - 4,    //  radius of circular 'knob' in slider control
     MIN_POS     = BUTTON_RAD + 5,               //  top of screen
     MAX_POS     = SLIDERH - (BUTTON_RAD + 1),   //  bottom of screen
-    CIRC_CTR = SLIDERX + BUTTON_RAD + 4;
+    CIRC_CTR    = SLIDERX + BUTTON_RAD + 4;
 
-static const double
-#ifdef  BOGIE_7_and_a_quarter_INCH
-    MOTOR_PINION_T  = 17.0, //  motor pinion teeth, wheel gear teeth and wheel dia required to calculate speed and distance.
-    WHEEL_GEAR_T    = 76.0,
-    WHEEL_DIA_MM    = 147.0,
-#endif
-#ifdef  BOGIE_5_INCH
-    MOTOR_PINION_T  = 27.0, //  motor pinion teeth, wheel gear teeth and wheel dia required to calculate speed and distance.
-    WHEEL_GEAR_T    = 85.0,
-    WHEEL_DIA_MM    = 98.0,
-#endif
-    PI = 4.0 * atan(1.0),
-    WHEEL_CIRCUMFERENCE_METRE = PI * WHEEL_DIA_MM / 1000.0,
-    PULSES_PER_WHEEL_REV    = 32.0 * WHEEL_GEAR_T / MOTOR_PINION_T,
-    PULSES_PER_METRE        = PULSES_PER_WHEEL_REV / WHEEL_CIRCUMFERENCE_METRE,
-    rpm2mph         = 60.0                                      //  = Motor Revs per hour;
-                  * (MOTOR_PINION_T / WHEEL_GEAR_T)   //  = Wheel rev per hour
-                  * WHEEL_CIRCUMFERENCE_METRE         //  = metres per hour
-                  * 39.37                             //  = inches per hour
-                  / (1760 * 36)                       //  = miles per hour
-                  ;
+static const double    PI       = 4.0 * atan(1.0);
+static const double    TWO_PI   = 8.0 * atan(1.0);
 
-const   double LOCO_HANDBRAKE_ESCAPE_SPEED = 0.5;
-
+enum    {HI_HORN, LO_HORN};
 enum    {NO_DPS, ONE_DP};
 //  Assign unique number to every button we may use, and keep count of total number of them
-enum        {
-            ENTER, SLIDER, SPEEDO_BUT, VMETER_BUT, AMETER_BUT,
-            NUMOF_BUTTONS}  ;   //  button names
-enum        {
-            STATES, INACTIVE, RUN, NEUTRAL_DRIFT, REGEN_BRAKE, PARK, HANDBRAKE_SLIPPING};
+enum    {ENTER, SLIDER_BUTTON, SPEEDO_BUTTON, VMETER_BUTTON, AMETER_BUTTON,NUMOF_BUTTONS}  ;   //  button names
+enum    {STATES, RUN, NEUTRAL_DRIFT, REGEN_BRAKE, RUN_DOWN, INTO_RUN, INTO_REGEN_BRAKE, INTO_NEUTRAL_DRIFT};
+enum    {SLIDER_PRESS, SLIDER_RELEASE, SLIDER_AUTOREP};
 
-struct  slide   {   int position;    int    oldpos; int state; int direction;   bool recalc_run;    bool handbrake_slipping;    
-                    double handbrake_effort;   double   loco_speed;  }   ;
 struct  point   {   int x;    int y;  }   ;
-struct  key     {   int keynum; int x;  int y;  bool pressed;  }   ;
-struct  ky_bd   {   int count,  slider_y; key ky[MAX_TOUCHES + 1];   bool  sli;   }  ;
+struct  keystr  {   int keynum; int x;  int y;  }   ;
+struct  ky_bd   {   int count,  slider_y; keystr key[MAX_TOUCHES + 1];   bool  sli;   }  ;
 
-const   int MAX_PARAMS = 20;
+class   screen_touch_handler
+    {   
+        ky_bd   kybd_a, kybd_b;                 //  alternating present - previous keyboard structures
+        ky_bd * present_kybd, * previous_kybd;  //  pointers
+        bool    in_list  (struct ky_bd & , int )    ;
+        void    motor_power ()   ;
+        void    flush   ()  ;
+        int     viscous_drag   (int, double, double)  ;
+        int     position;    
+        int     oldpos; 
+        int     next_state;
+    public:
+        int     direction;   
+        void    DrawSlider    ()  ;
+        void    HandleFingerInput   ()  ;
+        screen_touch_handler  ()  ;     //  default constructor
+    }   ;
+
+const   int MAX_PARAMS = 30;
+const   int MAX_CMD_LINE_LEN    = 180;
+const   int MAX_ESCS = 12;
+
 struct  parameters  {
-    struct kb_command const * clist;
-    char    cmd_line[120];
-    char    * cmd_line_ptr;
-    int32_t position_in_list, numof_dbls, target_unit, numof_menu_items, com_no, cl_index, gp_i;
+    int32_t numof_menu_items, numof_cl_values_read;
     double  dbl[MAX_PARAMS];
-    bool    respond;
 }   ;
 
-class   genio   {   //  23/06/2018  generic io handler
+enum    {
+    FAULT_0,
+    FAULT_BOARD_ID_IN_MSG,
+    FAULT_TS,
+    FAULT_PC,
+    FAULT_COM,
+    FAULT_COM_NO_MATCH,
+    FAULT_COM_LINE_LEN,
+    FAULT_QSPI,
+    FAULT_ODOMETER,
+    FAULT_MAX,
+    NUMOF_REPORTABLE_TS_ERRORS
+    }   ;
+
+class   error_handling_Jan_2019
+{
+    int32_t    TS_fault[NUMOF_REPORTABLE_TS_ERRORS]    ;   //  Some number of reportable error codes, accessible through set and read members
     public:
-    uint32_t    count;  //  Running total of times called
-    bool        available;  //  set true when number rec'd, set false by reading it
-    int         d_type;      //  loaded on setup indicating expected data type
-    int         d_len;       //  loaded on setup indicating expected num of parameters to handle
-    uint32_t    ui[MAX_PARAMS];
-    double      dbl[MAX_PARAMS];
-    genio   ()  {}   //  default constructor
-    genio   (int, int)  ;   //  more useful constructor
-    void    store   (struct parameters &)  ;   //
-    bool    read    (uint32_t **)  ;
-    bool    read    (double &)  ;
+    error_handling_Jan_2019 ()  {   //  default constructor
+        for (int i = 0; i < (sizeof(TS_fault) / sizeof(int32_t)); i++)
+            TS_fault[i] = 0;
+    }
+    void        set   (uint32_t, int32_t)   ;
+    void        clr   (uint32_t)   ;
+    uint32_t    read  (uint32_t)   ;
+    bool        all_good    ()  ;
+    void        report_any  ()  ;
+}   ;
+
+class   command_line_interpreter_core  {
+    parameters  a   ;   //  as opposed to clicore(&parameters)
+    struct kb_command const * clist;
+    int32_t portio, cl_index, target_unit;
+    char    cmd_line[MAX_CMD_LINE_LEN];
+    char    * cmd_line_ptr;
+    int clreadable    ();
+    int clgetc        ();
+    void clputc        (int);
+  public:
+    command_line_interpreter_core   ()  {};   //  default constructor
+    command_line_interpreter_core   (int, int, struct kb_command const * )  ;    //{   //  constructor including io port id value
+    void    sniff   ()  ;   //  The function to call often to sniff out commands from command line and act upon them
+}   ;
+
+class   STM3_ESC_Interface
+{
+    int         board_IDs   [MAX_ESCS],    //  allow up to 4 boards in practical system, size for 10+ as 10 discrete ID nums exist
+                board_count,
+                reqno;
+public:
+    double  last_V, last_I, mph, esc_speeds[MAX_ESCS];
+    STM3_ESC_Interface  ()  {   //  Constructor
+        board_count = 0;
+        reqno = 0;
+        last_V = last_I = mph = 0.0;
+        for (int i = 0; i < MAX_ESCS; i++)  {
+            board_IDs[i] = 0;
+            esc_speeds[i] = 0.0;
+        }
+    }
+    bool    request_mph     ()  ;       //  Issue "'n'mph\r" to one particular STM3_ESC board to request RPM   22/06/2018
+    void    mph_update      (double)  ; //  touched 08/01/2019
+    void    set_board_ID    (int)   ;   //  called in response to 'whon' coming back from a STM3_ESC
+    void    search_for_escs ()  ;       //  one-off call during startup to identify all connected STM3_ESCs
+    void    get_boards_list (int *) ;   //  copies board list
+    void    set_V_limit     (double)    ;   //  Set max motor voltage
+    void    set_I_limit     (double)    ;   //  Set max motor current
+    void    message         (char *)    ;   //  Broadcast message to all STM3_ESCs
+    void    message         (int, char *)    ;   //  Send message to one individual STM3_ESC
 }   ;
 
 
+