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

Electric_Loco.h

Committer:
JonFreeman
Date:
2019-03-04
Revision:
14:6bcec5ac21ca
Parent:
12:a25bdf135348

File content as of revision 14:6bcec5ac21ca:

#include "mbed.h"
#include "movingcoilmeter.h"
#include <cctype>
/*  Updated January 2019
    Jon Freeman

  5" and 7.25" gauge Electric Locomotive Controller - ST DISCO-F746NG
Uses built in display and touch screen.

Display shows 'analogue' moving coil meter movements for :
    Locomotive speed Miles per Hour
    System voltage (range 10v - 63v or thereabouts)
    Power Watts delivered to drive motors or dumped.

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.
Moving towards bottom of screen applies regenerative braking - move further down applies harder braking.
Moving towards top of screen powers drive motors, move further up applies more torque (current controller implemented)
Take finger off and control drifts down to central 'neutral' position.
*/


#define MAX_TOUCHES 6       //  Touch screen can decode up to this many simultaneous finger press positions
#define NEUTRAL_VAL   150   //  Number of pixels

#define SLIDERX 418         //  slider graphic x position
#define SLIDERY 2           //  slider graphic y position
#define SLIDERW 50          //  pixel width of slider
#define SLIDERH 268         //  pixel height of slider

#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    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;

static const double    PI       = 4.0 * atan(1.0);
static const double    TWO_PI   = 8.0 * atan(1.0);

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_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  point   {   int x;    int y;  }   ;
struct  keystr  {   int keynum; int x;  int y;  }   ;
struct  ky_bd   {   int count,  slider_y; keystr key[MAX_TOUCHES + 1];   bool  sli;   }  ;

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  {
    int32_t numof_menu_items, numof_cl_values_read;
    double  dbl[MAX_PARAMS];
}   ;

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:
    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  (bool)  ;
}   ;

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 MPH   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
}   ;