Jon Freeman / Mbed 2 deprecated Brute_TS_Controller_2018_11

Dependencies:   TS_DISCO_F746NG mbed Servo LCD_DISCO_F746NG BSP_DISCO_F746NG QSPI_DISCO_F746NG AsyncSerial FastPWM

Revision:
12:a25bdf135348
Parent:
8:5945d506a872
diff -r a573664b1a59 -r a25bdf135348 graphics.cpp
--- a/graphics.cpp	Sat Jun 23 09:37:41 2018 +0000
+++ b/graphics.cpp	Mon Jan 14 16:39:41 2019 +0000
@@ -3,358 +3,53 @@
 #include "LCD_DISCO_F746NG.h"
 #include "Electric_Loco.h"
 
-#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 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
 
 extern  LCD_DISCO_F746NG    lcd;
 extern  TS_DISCO_F746NG     touch_screen;
 extern  Serial pc;
 
-static const int    char_widths[]   = {5, 7, 11, 14, 17, 17}    ,
-                    meter_radius_min = 30, meter_radius_max = 120;
+/*
+moving_coil_meter   Voltmeter   (   LCD_COLOR_BLACK,    //  Frame / body colour
+                                    LCD_COLOR_WHITE,    //  Dial face colour
+                                    LCD_COLOR_RED,      //  Moving needle colour
+                                    LCD_COLOR_BLUE,     //  Text colour for Units e.g. 'V' and e.g. '32.7'
+                                    LCD_COLOR_MAGENTA,  //  Scale graduations colour
+                                    VOLTMETER_X,        //  X co-ord, centre of meter
+                                    VOLTMETER_Y,        //  Y co-ord, centre of meter
+                                    V_A_SIZE,           //  Meter is square with rounded corners. This is meter dial face radius
+                                    22.0,               //  Scale not limited to e.g. 0 to 10. This is reading at anti-clock limit
+                                    59.0,               //  This is reading at full scale deflection
+                                    1.25 * PI,          //  Angle of needle at anti-clockwise limit
+                                    -0.25 * PI ,        //  Angle of needle at full scale deflection (clockwise max)
+                                    30,                 //  Number of scale graduation marks drwan
+                                    "V",                //  Text for Units, e.g. 'V' or 'MPH'
+                                    ONE_DP,             //  NO_DPS or ONE_DP - supports only no decimal places or one
+                                    false) ;            //  true to show '+' or '-', false to supress sign display
+*/
+/*moving_coil_meter   Voltmeter   (   LCD_COLOR_BLACK, LCD_COLOR_WHITE, LCD_COLOR_RED, LCD_COLOR_BLUE, LCD_COLOR_MAGENTA,
+                                    VOLTMETER_X, VOLTMETER_Y, V_A_SIZE, 22.0, 61.0, 1.25 * PI, -0.25 * PI , 20, "V", ONE_DP, false),  
+                    Powermeter  (   LCD_COLOR_BLACK, LCD_COLOR_WHITE, LCD_COLOR_RED, LCD_COLOR_BLUE, LCD_COLOR_BLUE,
+                                    AMMETER_X, AMMETER_Y, V_A_SIZE, -1400.0, 1400.0, 1.25 * PI, -0.25 * PI , 14, "Watt", NO_DPS, false),    
+                    Speedo      (   SPEEDO_BODY_COLOUR, SPEEDO_DIAL_COLOUR, LCD_COLOR_RED, SPEEDO_TEXT_COLOUR, LCD_COLOR_BLACK,
+                                    SPEEDO_X, SPEEDO_Y, SPEEDO_SIZE, 0.0, 12.0, 1.25 * PI, -0.25 * PI , 12, "MPH", ONE_DP, false);     //  3 instances of moving coil meter graphic
+
+*/
 
 
-//  Uses our own generated sine and cosines from lookup table.  For some unexplained reason, using inbuilt sin and cos fns cause display flicker !
-//extern double  jcos  (double angle);    //  Used in DrawNeedle, plain sin and cos functions cause display flicker !!
-//extern double  jsin  (double angle);
-#define jcos    cos
-#define jsin    sin
-/*void    costabgen  (int points)  {
-    double  angle = 0.0;
-    while   (angle < 2.1 * PI)  {
-        pc.printf   ("Angle %f, my cos %+f, c cos %+f\r\n", angle, jcos(angle), cos(angle));
-//        pc.printf   ("Angle %f, my sin %+f, c sin %+f\r\n", angle, jsin(angle), sin(angle));
-        angle += PI / 24;
-    }
-//    double  angle;
-*//*    int step, perline = 0;
-    double  interval = PI / 2.0 / (double)points;
-    pc.printf   ("//At costabgen with %d points\r\n", points);
-    pc.printf   ("static const double costab[] = {\r\n");
-    for (step = 0; step <= points; step++)  {
-        angle   = interval * (double)step;
-//        pc.printf   ("cos %+.3f = %+.3f\r\n", angle, cos(angle));
-        if  (++perline == 8)  {
-            pc.printf   ("%+.6f,\r\n", cos(angle));
-            perline = 0;
-        }
-        else
-            pc.printf   ("%+.6f, ", cos(angle));
-        wait    (0.025);
-    }
-    pc.printf   ("0.0\t}\t;\r\n//End of costab\r\n");
-*/
-//}
-
-/**
-  * @brief  Fills a triangle (between 3 points).
-  * @param  x1: Point 1 X position
-  * @param  y1: Point 1 Y position
-  * @param  x2: Point 2 X position
-  * @param  y2: Point 2 Y position
-  * @param  x3: Point 3 X position
-  * @param  y3: Point 3 Y position
-  * @retval None
-  */
-static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3)
-{
-    int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
-            yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0,
-            curpixel = 0;
-
-    deltax = abs(x2 - x1);        /* The difference between the x's */
-    deltay = abs(y2 - y1);        /* The difference between the y's */
-    x = x1;                       /* Start x off at the first pixel */
-    y = y1;                       /* Start y off at the first pixel */
-
-    if (x2 >= x1) {               /* The x-values are increasing */
-        xinc1 = 1;
-        xinc2 = 1;
-    } else {                      /* The x-values are decreasing */
-        xinc1 = -1;
-        xinc2 = -1;
-    }
-
-    if (y2 >= y1) {               /* The y-values are increasing */
-        yinc1 = 1;
-        yinc2 = 1;
-    } else {                      /* The y-values are decreasing */
-        yinc1 = -1;
-        yinc2 = -1;
-    }
-
-    if (deltax >= deltay) {       /* There is at least one x-value for every y-value */
-        xinc1 = 0;                  /* Don't change the x when numerator >= denominator */
-        yinc2 = 0;                  /* Don't change the y for every iteration */
-        den = deltax;
-        num = deltax / 2;
-        num_add = deltay;
-        num_pixels = deltax;         /* There are more x-values than y-values */
-    } else {                      /* There is at least one y-value for every x-value */
-        xinc2 = 0;                  /* Don't change the x for every iteration */
-        yinc1 = 0;                  /* Don't change the y when numerator >= denominator */
-        den = deltay;
-        num = deltay / 2;
-        num_add = deltax;
-        num_pixels = deltay;         /* There are more y-values than x-values */
-    }
-
-    for (curpixel = 0; curpixel <= num_pixels; curpixel++) {
-        lcd.DrawLine(x, y, x3, y3);
-
-        num += num_add;              /* Increase the numerator by the top of the fraction */
-        if (num >= den) {           /* Check if numerator >= denominator */
-            num -= den;               /* Calculate the new numerator value */
-            x += xinc1;               /* Change the x as appropriate */
-            y += yinc1;               /* Change the y as appropriate */
-        }
-        x += xinc2;                 /* Change the x as appropriate */
-        y += yinc2;                 /* Change the y as appropriate */
-    }
-}
-
-double  anglefix    (double a)  {       //  Ensures 0.0 <= angle <= + two PI
-    while   (a > PI) a   -= 2.0 * PI;
-    while   (a < 0.0) a   += 2.0 * PI;
-    return  a;
-}
-
-class    moving_coil_meter
-{
-    int     meter_radius, cent_x, cent_y, needle_len, scale_ticks,
-            disc_colour,    needle_colour,  scale_colour,   text_colour, body_colour, dec_places;
-    double  start_angle, end_angle, old_angle, value_min, value_max, rad_per_value, swept_angle, value_range;
-    double  Value;  //  This is the one that determines pointer angle
-    bool    draw_sign;
-
-    void    DrawNeedle          (double alpha, int colour)  ;
-    void    DrawScaleGraduations(int colour)  ;
-    double  get_pointer_angle   (double value)  ;
-    int     get_font            ()  ;
-
-public:
-
-    moving_coil_meter   ()  {   //  constructor
-        meter_radius = 100;
-        value_min = -1.0;
-        value_max = 1.0;
-        cent_x = cent_y = 150;
-        disc_colour     = LCD_COLOR_BLACK;
-        needle_colour   = LCD_COLOR_WHITE;
-        scale_colour    = LCD_COLOR_MAGENTA;
-        text_colour     = LCD_COLOR_RED;
-        body_colour     = LCD_COLOR_CYAN;
-        old_angle       = 0.0;
-    }
-
-    bool    setup   (int cx, int cy, int size, double lo, double hi, double start_ang, double end_ang, int scaleticks, char * units, int decimal_places, bool sign)  ;
-    void    set_colours   (int bod_colour, int bgcol, int needlecol, int textcolour, int scalecol)  ;
-    void    set_value   (double v)  ;
-}   Voltmeter,  Powermeter,    Speedo;     //  3 instances of moving coil meter graphic
-
-void    moving_coil_meter::set_colours   (int bod_col, int bgcol, int needlecol, int textcol, int scalecol)  {
-    body_colour = bod_col;
-    disc_colour = bgcol;
-    needle_colour   = needlecol;
-    text_colour = textcol;
-    scale_colour    = scalecol;
-}
-
-void    moving_coil_meter::DrawNeedle  (double alpha, int colour)
-{
-    point  pixpts[4];
-    int save_colour, ssa, sca;
-    alpha   = anglefix  (alpha);
-    double  shortln = (needle_len / 18.7),
-            sina    = jsin(alpha),
-            cosa    = jcos(alpha);
-
-    save_colour = lcd.GetTextColor  ();
-    ssa = (int)(shortln * sina);
-    sca = (int)(shortln * cosa);
-    old_angle = alpha;
-    pixpts[0].x = cent_x - ssa;//(int)(shortln * sin(alpha));
-    pixpts[0].y = cent_y - sca;//(int)(shortln * cos(alpha));
-    pixpts[1].x = cent_x + (int)(needle_len * cosa);
-    pixpts[1].y = cent_y - (int)(needle_len * sina);  //  - as increasing y is downwards
-    pixpts[2].x = cent_x + ssa;//(int)(shortln * sin(alpha));
-    pixpts[2].y = cent_y + sca;//(int)(shortln * cos(alpha));
-    lcd.SetTextColor    (colour);
-    lcd.FillCircle      (cent_x, cent_y, (int)(needle_len / 15.0));
-    FillTriangle    (pixpts[0].x, pixpts[1].x, pixpts[2].x, pixpts[0].y, pixpts[1].y, pixpts[2].y);
-    lcd.SetTextColor    (save_colour);
-}
-
-void    moving_coil_meter::DrawScaleGraduations (int colour)
-{
-    int save_colour = lcd.GetTextColor  ();
-    int i, radius_inner = (int) meter_radius - 2, radius_outer = (int) (meter_radius * 0.9);
-    double  ang, cosang, sinang, angle_step;
-    lcd.SetTextColor    (colour);
-    ang = start_angle;
-    angle_step  = (start_angle - end_angle) / scale_ticks;
-    for (i = 0; i <= scale_ticks; i++)   {   //
-        cosang  = cos(ang);
-        sinang  = sin(ang);
-        lcd.DrawLine    (cent_x + radius_outer * cosang, cent_y - radius_outer * sinang, cent_x + radius_inner * cosang, cent_y - radius_inner * sinang);
-        ang -= angle_step;
-    }
-    lcd.SetTextColor    (save_colour);
-}
 
 void    displaytext    (int x, int y, const int font, char * txt)   ;
 
-bool    moving_coil_meter::setup   (int cx, int cy, int size, double lo, double hi, double start_ang, double end_ang, int scaleticks, char * units, int decimal_places, bool sign)
-{
-    bool    retval = true;
-    int font, charwid, x_offset;
-    if  (size < meter_radius_min || size > meter_radius_max)
-        return  false;
-    meter_radius = size;
-    if  (meter_radius > cx || meter_radius > cy)
-        return  false;
-    int corner_rad          = meter_radius / 6,
-        screw_hole_offset   = meter_radius * 92 / 100,
-        screw_rad           = meter_radius / 13;
-    cent_x = cx;
-    cent_y = cy;
-
-    start_angle = start_ang;
-    end_angle = end_ang;
-    value_min = lo;
-    value_max = hi;
-    scale_ticks = scaleticks;
-    swept_angle = abs(start_angle - end_angle);
-    value_range = (value_max - value_min);
-    rad_per_value = swept_angle / value_range;
-    dec_places  = decimal_places;
-    draw_sign   = sign;
-
-    needle_len = (int)(0.87 * (double)meter_radius);
-    int oldcolour1 = lcd.GetTextColor   ();
-    int oldcolour2 = lcd.GetBackColor   ();
-    lcd.SetTextColor    (body_colour);
-    //  Draw meter body as solid square with rounded corners, complete with mounting screw holes !
-    lcd.FillRect    (cent_x - meter_radius, cent_y - meter_radius - corner_rad, meter_radius * 2, corner_rad);
-    lcd.FillRect    (cent_x - meter_radius, cent_y + meter_radius, meter_radius * 2, corner_rad + 1);
-    lcd.FillRect    (cent_x - meter_radius - corner_rad, cent_y - meter_radius, 1 +(meter_radius + corner_rad) * 2, meter_radius * 2);
-    lcd.FillCircle  (cent_x - meter_radius, cent_y - meter_radius, corner_rad);  //  meter box has rounded corners
-    lcd.FillCircle  (cent_x - meter_radius, cent_y + meter_radius, corner_rad);
-    lcd.FillCircle  (cent_x + meter_radius, cent_y - meter_radius, corner_rad);
-    lcd.FillCircle  (cent_x + meter_radius, cent_y + meter_radius, corner_rad);
-    lcd.SetTextColor    (LCD_COLOR_DARKGRAY);
-    lcd.FillCircle  (cent_x - screw_hole_offset, cent_y - screw_hole_offset, screw_rad);  //  panel mounting screw holes near corners
-    lcd.FillCircle  (cent_x - screw_hole_offset, cent_y + screw_hole_offset, screw_rad);
-    lcd.FillCircle  (cent_x + screw_hole_offset, cent_y - screw_hole_offset, screw_rad);
-    lcd.FillCircle  (cent_x + screw_hole_offset, cent_y + screw_hole_offset, screw_rad);
-    lcd.SetTextColor    (disc_colour);
-    lcd.FillCircle      (cent_x, cent_y, meter_radius);
-    DrawScaleGraduations (scale_colour);   //drew the green trace around active needle-sweep angle
-
-    font = get_font ();
-    charwid = char_widths[font];
-    x_offset = charwid * strlen(units) / 2;
-    lcd.SetTextColor    (text_colour);
-    lcd.SetBackColor    (disc_colour);
-//    displaytext (cent_x - x_offset, cent_y + (meter_radius * 7) / 19, font, units);
-    displaytext (cent_x - x_offset, cent_y + (meter_radius * 6) / 19, font, units);
-    lcd.SetBackColor    (oldcolour2);
-    lcd.SetTextColor    (oldcolour1);
-    return  retval;
+extern  uint32_t    odometer_out  ()    ;
+void    rewrite_odometer    ()  {
+    char    dist[20];
+    sprintf (dist, "%06dm", odometer_out());   //  12th June 2018 changed 05 to 06 to allow correct display of tot distance > 99999 metres
+    lcd.SetTextColor    (LCD_COLOR_BLACK);
+    displaytext (241, 224, 2, dist);
 }
 
-int     moving_coil_meter::get_font ()
-{
-    int font = meter_radius - meter_radius_min;
-    font /= 17;
-    if  (font > 4)
-        font = 4;
-    if  (font < 2)
-        font = 2;
-    return  font;
-}
-
-double  moving_coil_meter::get_pointer_angle    (double v)
-{
-    double   vabvmin, retval;
-    if   (v < value_min) v = value_min;
-    if   (v > value_max) v = value_max;
-    Value = v;   //  clipped copy of supplied value
-    vabvmin = v - value_min;
-    retval   = start_angle - (vabvmin * rad_per_value);
-    return   anglefix   (retval);
-}
-
-void    moving_coil_meter::set_value   (double meter_read_value)
-{
-    char    txt[32];
-    int x_offset, font, charwid, lenchk;//,
-    DrawNeedle  (old_angle, disc_colour);                   //  un-draw needle
-    DrawNeedle  (get_pointer_angle   (meter_read_value), needle_colour)  ; //  re-draw needle
- //   if  (draw_sign) {
-    if  (dec_places == ONE_DP)
-        sprintf (txt, " %+.1f \0", meter_read_value);
-    else
-        sprintf (txt, " %+.0f \0", meter_read_value);
-    lenchk = strlen(txt);
-    if  (!draw_sign)    {
-        for (int i = 1; i < lenchk; i++)
-            txt[i] = txt[i + 1];
-//        lenchk--;     //  Stupidly, this gives the display flicker blight
-    }
-    lenchk = strlen(txt);//  Stupidly, repeating this instead does NOT give the display flicker blight
-    font = get_font();
-    charwid = char_widths[font];
-    x_offset = charwid * lenchk / 2;
-    lcd.SetTextColor    (text_colour);
-    lcd.SetBackColor    (disc_colour);
-    if  (lenchk > 0 && lenchk < 9)
-        displaytext (cent_x - x_offset, cent_y + (meter_radius * 11) / 19, font, txt);
-}
-//bool    moving_coil_meter::setup   (int cx, int cy, int size, double lo, double hi, double start_ang, double end_ang,
-//                                    int scale_ticks, char * units)
-void    vm_set  ()   //x   y  size minv  maxv  min angle   max angle,
-{
-    Speedo.set_colours  (SPEEDO_BODY_COLOUR, SPEEDO_DIAL_COLOUR, LCD_COLOR_RED, SPEEDO_TEXT_COLOUR, LCD_COLOR_BLACK);
-    Speedo.setup    (SPEEDO_X, SPEEDO_Y, SPEEDO_SIZE, 0.0, 12.0, 1.25 * PI, -0.25 * PI , 12, "MPH", ONE_DP, false);
-    Voltmeter.set_colours  (LCD_COLOR_BLACK, LCD_COLOR_WHITE, LCD_COLOR_RED, LCD_COLOR_BLUE, LCD_COLOR_MAGENTA);
-    Voltmeter.setup (VOLTMETER_X, VOLTMETER_Y, V_A_SIZE, 22.0, 59.0, 1.25 * PI, -0.25 * PI , 30, "V", ONE_DP, false);
-    Powermeter.set_colours  (LCD_COLOR_BLACK, LCD_COLOR_WHITE, LCD_COLOR_RED, LCD_COLOR_BLUE, LCD_COLOR_BLUE);
-    Powermeter.setup   (AMMETER_X, AMMETER_Y, V_A_SIZE, -1400.0, 1400.0, 1.25 * PI, -0.25 * PI , 14, "Watt", NO_DPS, false);
-}
-
-//void    update_meters  (double speed, double current, double voltage)
-void    update_meters  (double speed, double power, double voltage)
-{
-//    Powermeter.set_value(voltage * current);
-    Powermeter.set_value(power);
-    Voltmeter.set_value (voltage);
-    Speedo.set_value    (speed);
-}
-
-
-
 struct  rect    {   struct point a, b; }   ;
 
-struct  butt_on  {
+struct  button_specs  {
     struct  rect    area;
     int border_colour,  body_colour;
     bool    in_use, pressed;//, released;
@@ -362,7 +57,7 @@
     char txt2[12];
 }   ;
 
-struct  butt_on   button[NUMOF_BUTTONS];
+struct  button_specs   button[NUMOF_BUTTONS];
 
 int get_button_press    (struct point & pt) ;
 int get_but_p   (int x, int y)
@@ -373,14 +68,25 @@
     return  get_button_press    (p);
 }
 
-
+/**
+void    read_keypresses    (struct ky_bd & a)
+Sets values in struct ky_bd, containing :
+        struct  ky_bd   {   int count,  slider_y; keystr key[MAX_TOUCHES + 1];   bool  sli;   }  ;
+            struct  keystr  {   int keynum; int x;  int y;  }   ;
+    sets a.count to number of fingers found pressing buttons
+    fills a.key[].keynum with list of 'a.count' button return codes
+    fills corresponding a.key[].x and a.key[].y with finger coordinates
+    if button is SLIDER_BUTTON
+        sets a.sli true else sets false
+        sets a.slider_y with new slider y coordinate - 0 at top
+*/
 void    read_keypresses    (struct ky_bd & a)
 {
     int x;
     a.count = 0;
     a.sli   = false;
     for (x = 0; x < MAX_TOUCHES; x++)
-        a.ky[x].keynum = -1;
+        a.key[x].keynum = -1;
     int touches, but;
     TS_StateTypeDef TS_State;
     touch_screen.GetState(&TS_State);
@@ -388,12 +94,12 @@
     for (int h = 0; h < touches; h++)   {
         but = get_but_p  (TS_State.touchX[h], TS_State.touchY[h]);
         if  (but > - 1) {
-            a.ky[a.count].keynum = but;
-            a.ky[a.count].x     = TS_State.touchX[h];
-            a.ky[a.count].y     = TS_State.touchY[h];
-            if  (but == SLIDER) {
+            a.key[a.count].keynum = but;
+            a.key[a.count].x     = TS_State.touchX[h];
+            a.key[a.count].y     = TS_State.touchY[h];
+            if  (but == SLIDER_BUTTON) {
                 a.sli   = true;
-                a.slider_y  = a.ky[a.count].y;
+                a.slider_y  = a.key[a.count].y;
             }
             a.count++;
         }
@@ -425,7 +131,7 @@
     lcd.SetBackColor(obc);
 }
 
-void    draw_button (struct butt_on & bu)
+void    draw_button (struct button_specs & bu)
 {
     int oldbgcolour;
     lcd.SetTextColor    (bu.body_colour);
@@ -451,7 +157,7 @@
     if  (but < 0 || but > NUMOF_BUTTONS)    {
         pc.printf   ("Button out of range in draw_button_hilight %d\r\n", but)  ;
     } else    {
-        struct   butt_on * bu = &button[but];
+        struct   button_specs * bu = &button[but];
         int oldbgcolour = lcd.GetBackColor();//, minx, miny, maxx, maxy;
         lcd.SetTextColor(colour);
         lcd.DrawRect(bu->area.a.x - 1, bu->area.a.y - 1, bu->area.b.x - bu->area.a.x + 2, bu->area.b.y - bu->area.a.y + 2);
@@ -461,13 +167,13 @@
     }
 }
 
-void    draw_button (struct butt_on & bu, int body_colour)
+void    draw_button (struct button_specs & bu, int body_colour)
 {
     bu.body_colour = body_colour;
     draw_button (bu);
 }
 
-void    setup_button    (struct butt_on & bu, int x1, int y1, int dx, int dy, int bord, int body, char * txt1, char * txt2)
+void    setup_button    (struct button_specs & bu, int x1, int y1, int dx, int dy, int bord, int body, char * txt1, char * txt2)
 {
     static const int margin = 3;
     int xsize = lcd.GetXSize();
@@ -490,40 +196,23 @@
     draw_button(bu);
 }
 
-bool    ifpressed   (int key)
+/*bool    ifpressed   (int key)
 {
     return  button[key].pressed;
 }
-
-bool    is_button_pressed   (struct point & pt, struct butt_on & bu)
+*/
+bool    is_button_pressed   (struct point & pt, struct button_specs & bu)
 {
     if  (bu.in_use)  {
-        if  (bu.area.a.x < pt.x && bu.area.b.x > pt.x
-                && bu.area.a.y < pt.y && bu.area.b.y > pt.y)
+        if  (   bu.area.a.x < pt.x 
+                && bu.area.b.x > pt.x
+                && bu.area.a.y < pt.y 
+                && bu.area.b.y > pt.y)
             return  true;
     }
     return  false;
 }
 
-bool    keyrelease  (int key)
-{
-    bool    rv = false;
-    if  (button[key].pressed)   {
-        rv = true;
-        button[key].pressed = false;
-    }
-    return  rv;
-}
-void    setpressed  (int key, bool torf)
-{
-    button[key].pressed = torf;
-}
-void    setinuse    (int key, bool torf)
-{
-    button[key].in_use = torf;
-}
-
-
 int get_button_press    (struct point & pt)
 {
     for (int j = 0; j < NUMOF_BUTTONS; j++)
@@ -534,91 +223,71 @@
 
 void    setup_buttons   ()
 {
-    setup_button    (button[SPEEDO_BUT],
+    setup_button    (button[SPEEDO_BUTTON],
                     SPEEDO_X - SPEEDO_SIZE, SPEEDO_Y - SPEEDO_SIZE,
                     SPEEDO_SIZE * 2, SPEEDO_SIZE * 2, SPEEDO_BODY_COLOUR,   LCD_COLOR_RED,   " X", "")  ;
-    setup_button    (button[VMETER_BUT],
+    setup_button    (button[VMETER_BUTTON],
                     VOLTMETER_X - V_A_SIZE, VOLTMETER_Y - V_A_SIZE, V_A_SIZE * 2, V_A_SIZE * 2, VMETER_BODY_COLOUR,   LCD_COLOR_RED,   " Y", "")  ;
-    setup_button    (button[AMETER_BUT],
+    setup_button    (button[AMETER_BUTTON],
                     AMMETER_X - V_A_SIZE, AMMETER_Y - V_A_SIZE, V_A_SIZE * 2, V_A_SIZE * 2, AMETER_BODY_COLOUR,   LCD_COLOR_RED,   " Z", "")  ;
-    setup_button    (button[SLIDER],   SLIDERX, SLIDERY, SLIDERW, SLIDERH, LCD_COLOR_BLUE,   LCD_COLOR_MAGENTA,   "", "")  ;
+    setup_button    (button[SLIDER_BUTTON],   SLIDERX, SLIDERY, SLIDERW, SLIDERH, LCD_COLOR_BLUE,   LCD_COLOR_MAGENTA,   "", "")  ;
 }
 
-
-void SliderGraphic (struct slide & q)   {
-    int
-    colr,
-    oldbgcolr   = lcd.GetBackColor   (),
-    oldtxtcolr  = lcd.GetTextColor   ();
+void    screen_touch_handler::DrawSlider    ()  {
+    uint32_t
+        colr,
+        oldbgcolr   = lcd.GetBackColor   (),
+        oldtxtcolr  = lcd.GetTextColor   ();
     char    txt[4];
     txt[1] = 0;
-    if  (q.position > MAX_POS)
-        q.position = MAX_POS;
-    if  (q.position < MIN_POS)
-        q.position = MIN_POS;
-    if  (q.position == NEUTRAL_VAL)
-        q.state = NEUTRAL_DRIFT;
-    if  (q.position > NEUTRAL_VAL)
-        q.state = REGEN_BRAKE;
-    if  (q.position < NEUTRAL_VAL)
-        if  (q.state == REGEN_BRAKE)    {   //  Ensure transition from BRAKE to RUN passes through NEUTRAL
-            q.position = NEUTRAL_VAL;
-            q.state = NEUTRAL_DRIFT;
-        }
-        else
-            q.state = RUN;
-    if  (q.position == MAX_POS) {
-        if  (q.loco_speed < LOCO_HANDBRAKE_ESCAPE_SPEED)
-            q.state = PARK;
-        else    {
-            q.state = REGEN_BRAKE;
-            q.position--;
-        }
-    }
-    if  (q.position != q.oldpos)    {
+    if  (position > MAX_POS)
+        position = MAX_POS;
+    if  (position < MIN_POS)
+        position = MIN_POS;
+    if  (position != oldpos)    {
         //  Draw slider background colour rectangle overwriting previous circles
         //  Redraw black vertical
         //  Draw new circles
         //  Write text char
         lcd.SetTextColor(LCD_COLOR_MAGENTA);
-        lcd.FillRect    (SLIDERX + 1, q.oldpos - BUTTON_RAD, SLIDERW - 2, SLIDERW);
+        lcd.FillRect    (SLIDERX + 1, oldpos - BUTTON_RAD, SLIDERW - 2, SLIDERW);
         lcd.SetTextColor(LCD_COLOR_BLACK);
         lcd.FillRect    (SLIDERX + (SLIDERW / 2) - 3, 6, 7, SLIDERH - 8);
-        q.oldpos = q.position;
+        oldpos = position;
         lcd.SetTextColor(LCD_COLOR_WHITE);
-        lcd.DrawCircle  (CIRC_CTR, q.position, BUTTON_RAD);  //  seel also FillCircle
-        lcd.DrawCircle  (CIRC_CTR, q.position, BUTTON_RAD - 1);
-        switch  (q.state)  {
+        lcd.DrawCircle  (CIRC_CTR, position, BUTTON_RAD);  //  seel also FillCircle
+        lcd.DrawCircle  (CIRC_CTR, position, BUTTON_RAD - 1);
+        switch  (next_state)  {
+            case    RUN_DOWN:
             case    RUN:
                 txt[0] = 'R';
                 colr = LCD_COLOR_GREEN;
                 break;
+            case    INTO_NEUTRAL_DRIFT:
             case    NEUTRAL_DRIFT:
+            case    INTO_RUN:
                 txt[0] = 'N';
                 colr = LCD_COLOR_BLUE;
                 break;
             case    REGEN_BRAKE:
+            case    INTO_REGEN_BRAKE:
                 txt[0] = 'B';
                 colr = LCD_COLOR_ORANGE;
                 break;
-            case    PARK:
-                txt[0] = 'P';
-                colr = LCD_COLOR_RED;
-                break;
             default:
                 txt[0] = 'X';
                 colr = LCD_COLOR_CYAN;
+//                pc.printf   ("State %d\r\n", next_state);
         }   //  End of switch
         lcd.SetTextColor(colr);
-        lcd.FillCircle  (CIRC_CTR, q.position, BUTTON_RAD - 2);
+        lcd.FillCircle  (CIRC_CTR, position, BUTTON_RAD - 2);
         lcd.SetBackColor  (colr);
         lcd.SetTextColor(LCD_COLOR_YELLOW);
-        displaytext(SLIDERX + 17, q.position - 10, 4, txt);   //  largest font
+        displaytext(SLIDERX + 17, position - 10, 4, txt);   //  largest font
         lcd.SetBackColor  (LCD_COLOR_BLACK);
     }           //  End of else
     lcd.SetTextColor (oldtxtcolr);
     lcd.SetBackColor (oldbgcolr);
-//    pc.printf   ("SliderG %d, %d, %d\r\n", q.position, q.oldpos, q.state);
 }