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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers graphics.cpp Source File

graphics.cpp

00001 #include "mbed.h"
00002 #include "TS_DISCO_F746NG.h"
00003 #include "LCD_DISCO_F746NG.h"
00004 #include "Electric_Loco.h"
00005 
00006 
00007 extern  LCD_DISCO_F746NG    lcd;
00008 extern  TS_DISCO_F746NG     touch_screen;
00009 extern  Serial pc;
00010 
00011 /*
00012 moving_coil_meter   Voltmeter   (   LCD_COLOR_BLACK,    //  Frame / body colour
00013                                     LCD_COLOR_WHITE,    //  Dial face colour
00014                                     LCD_COLOR_RED,      //  Moving needle colour
00015                                     LCD_COLOR_BLUE,     //  Text colour for Units e.g. 'V' and e.g. '32.7'
00016                                     LCD_COLOR_MAGENTA,  //  Scale graduations colour
00017                                     VOLTMETER_X,        //  X co-ord, centre of meter
00018                                     VOLTMETER_Y,        //  Y co-ord, centre of meter
00019                                     V_A_SIZE,           //  Meter is square with rounded corners. This is meter dial face radius
00020                                     22.0,               //  Scale not limited to e.g. 0 to 10. This is reading at anti-clock limit
00021                                     59.0,               //  This is reading at full scale deflection
00022                                     1.25 * PI,          //  Angle of needle at anti-clockwise limit
00023                                     -0.25 * PI ,        //  Angle of needle at full scale deflection (clockwise max)
00024                                     30,                 //  Number of scale graduation marks drwan
00025                                     "V",                //  Text for Units, e.g. 'V' or 'MPH'
00026                                     ONE_DP,             //  NO_DPS or ONE_DP - supports only no decimal places or one
00027                                     false) ;            //  true to show '+' or '-', false to supress sign display
00028 */
00029 /*moving_coil_meter   Voltmeter   (   LCD_COLOR_BLACK, LCD_COLOR_WHITE, LCD_COLOR_RED, LCD_COLOR_BLUE, LCD_COLOR_MAGENTA,
00030                                     VOLTMETER_X, VOLTMETER_Y, V_A_SIZE, 22.0, 61.0, 1.25 * PI, -0.25 * PI , 20, "V", ONE_DP, false),  
00031                     Powermeter  (   LCD_COLOR_BLACK, LCD_COLOR_WHITE, LCD_COLOR_RED, LCD_COLOR_BLUE, LCD_COLOR_BLUE,
00032                                     AMMETER_X, AMMETER_Y, V_A_SIZE, -1400.0, 1400.0, 1.25 * PI, -0.25 * PI , 14, "Watt", NO_DPS, false),    
00033                     Speedo      (   SPEEDO_BODY_COLOUR, SPEEDO_DIAL_COLOUR, LCD_COLOR_RED, SPEEDO_TEXT_COLOUR, LCD_COLOR_BLACK,
00034                                     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
00035 
00036 */
00037 
00038 
00039 
00040 void    displaytext    (int x, int y, const int font, char * txt)   ;
00041 
00042 extern  uint32_t    odometer_out  ()    ;
00043 void    rewrite_odometer    ()  {
00044     char    dist[20];
00045     sprintf (dist, "%06dm", odometer_out());   //  12th June 2018 changed 05 to 06 to allow correct display of tot distance > 99999 metres
00046     lcd.SetTextColor    (LCD_COLOR_BLACK);
00047     displaytext (241, 224, 2, dist);
00048 }
00049 
00050 struct  rect    {   struct point a, b; }   ;
00051 
00052 struct  button_specs  {
00053     struct  rect    area;
00054     int border_colour,  body_colour;
00055     bool    in_use, pressed;//, released;
00056     char txt1[12];
00057     char txt2[12];
00058 }   ;
00059 
00060 struct  button_specs   button[NUMOF_BUTTONS];
00061 
00062 int get_button_press    (struct point & pt) ;
00063 int get_but_p   (int x, int y)
00064 {
00065     struct  point   p;
00066     p.x = x;
00067     p.y = y;
00068     return  get_button_press    (p);
00069 }
00070 
00071 /**
00072 void    read_keypresses    (struct ky_bd & a)
00073 Sets values in struct ky_bd, containing :
00074         struct  ky_bd   {   int count,  slider_y; keystr key[MAX_TOUCHES + 1];   bool  sli;   }  ;
00075             struct  keystr  {   int keynum; int x;  int y;  }   ;
00076     sets a.count to number of fingers found pressing buttons
00077     fills a.key[].keynum with list of 'a.count' button return codes
00078     fills corresponding a.key[].x and a.key[].y with finger coordinates
00079     if button is SLIDER_BUTTON
00080         sets a.sli true else sets false
00081         sets a.slider_y with new slider y coordinate - 0 at top
00082 */
00083 void    read_keypresses    (struct ky_bd & a)
00084 {
00085     int x;
00086     a.count = 0;
00087     a.sli   = false;
00088     for (x = 0; x < MAX_TOUCHES; x++)
00089         a.key[x].keynum = -1;
00090     int touches, but;
00091     TS_StateTypeDef TS_State;
00092     touch_screen.GetState(&TS_State);
00093     touches = TS_State.touchDetected;
00094     for (int h = 0; h < touches; h++)   {
00095         but = get_but_p  (TS_State.touchX[h], TS_State.touchY[h]);
00096         if  (but > - 1) {
00097             a.key[a.count].keynum = but;
00098             a.key[a.count].x     = TS_State.touchX[h];
00099             a.key[a.count].y     = TS_State.touchY[h];
00100             if  (but == SLIDER_BUTTON) {
00101                 a.sli   = true;
00102                 a.slider_y  = a.key[a.count].y;
00103             }
00104             a.count++;
00105         }
00106     }
00107 }
00108 
00109 
00110 void    displaytext    (int x, int y, char * txt)
00111 {
00112     lcd.DisplayStringAt(x, y, (uint8_t *)txt, LEFT_MODE);
00113 }
00114 
00115 void    displaytext    (int x, int y, const int font, char * txt)
00116 {
00117     sFONT * const fp[] = {&Font8, &Font12, &Font16, &Font20, &Font24};
00118     lcd.SetFont(fp[font]);
00119     displaytext (x, y, txt);
00120 }
00121 
00122 void    displaytext    (int x, int y, const int font, uint32_t BCol, uint32_t TCol, char * txt)
00123 {
00124     uint32_t otc, obc;
00125     otc = lcd.GetTextColor();
00126     obc = lcd.GetBackColor();
00127     lcd.SetTextColor(TCol);
00128     lcd.SetBackColor(BCol);
00129     displaytext (x, y, font, txt);
00130     lcd.SetTextColor(otc);
00131     lcd.SetBackColor(obc);
00132 }
00133 
00134 void    draw_button (struct button_specs & bu)
00135 {
00136     int oldbgcolour;
00137     lcd.SetTextColor    (bu.body_colour);
00138     lcd.FillRect(bu.area.a.x + 2, bu.area.a.y + 2, bu.area.b.x - bu.area.a.x - 2, bu.area.b.y - bu.area.a.y - 2);   //, bu.body_colour);
00139     oldbgcolour = lcd.GetBackColor();
00140     lcd.SetBackColor(bu.body_colour);
00141     lcd.SetTextColor(LCD_COLOR_BLACK);
00142     if  (strlen(bu.txt2) == 0)   {
00143         displaytext     (bu.area.a.x + 4, bu.area.a.y + 14, 4, bu.txt1); //  largest font 4
00144     } else    {
00145         displaytext     (bu.area.a.x + 4, bu.area.a.y + 4, 3, bu.txt1); //  not so large font 3
00146         displaytext     (bu.area.a.x + 4, bu.area.a.y + 26, bu.txt2);
00147     }
00148     lcd.SetBackColor(LCD_COLOR_BLACK);
00149     lcd.SetTextColor(bu.border_colour);
00150     lcd.DrawRect(bu.area.a.x, bu.area.a.y, bu.area.b.x - bu.area.a.x, bu.area.b.y - bu.area.a.y);   //, bu.border_colour);
00151     lcd.DrawRect(bu.area.a.x + 1, bu.area.a.y + 1, bu.area.b.x - bu.area.a.x - 1, bu.area.b.y - bu.area.a.y - 1);   //, bu.border_colour);
00152     lcd.SetBackColor(oldbgcolour);
00153 }
00154 
00155 void    draw_button_hilight     (int but, int colour)
00156 {
00157     if  (but < 0 || but > NUMOF_BUTTONS)    {
00158         pc.printf   ("Button out of range in draw_button_hilight %d\r\n", but)  ;
00159     } else    {
00160         struct   button_specs * bu = &button[but];
00161         int oldbgcolour = lcd.GetBackColor();//, minx, miny, maxx, maxy;
00162         lcd.SetTextColor(colour);
00163         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);
00164         lcd.DrawRect(bu->area.a.x - 2, bu->area.a.y - 2, bu->area.b.x - bu->area.a.x + 4, bu->area.b.y - bu->area.a.y + 4);
00165         lcd.DrawRect(bu->area.a.x - 2, bu->area.a.y - 3, bu->area.b.x - bu->area.a.x + 5, bu->area.b.y - bu->area.a.y + 6);
00166         lcd.SetBackColor(oldbgcolour);
00167     }
00168 }
00169 
00170 void    draw_button (struct button_specs & bu, int body_colour)
00171 {
00172     bu.body_colour = body_colour;
00173     draw_button (bu);
00174 }
00175 
00176 void    setup_button    (struct button_specs & bu, int x1, int y1, int dx, int dy, int bord, int body, char * txt1, char * txt2)
00177 {
00178     static const int margin = 3;
00179     int xsize = lcd.GetXSize();
00180     int ysize = lcd.GetXSize();
00181     int x2 = x1 + dx, y2 = y1 + dy;
00182     if  (x1 < margin) x1 = margin;
00183     if  (y1 < margin) y1 = margin;
00184     if  (x2 > xsize - margin)    x2 = xsize - margin;
00185     if  (y2 > ysize - margin)    y2 = ysize - margin;
00186     bu.area.a.x = x1;
00187     bu.area.a.y = y1;
00188     bu.area.b.x = x2;
00189     bu.area.b.y = y2;
00190     bu.border_colour = bord;
00191     bu.body_colour = body;
00192     strcpy  (bu.txt1, txt1);
00193     strcpy  (bu.txt2, txt2);
00194     bu.in_use = true;
00195     bu.pressed = false;
00196     draw_button(bu);
00197 }
00198 
00199 /*bool    ifpressed   (int key)
00200 {
00201     return  button[key].pressed;
00202 }
00203 */
00204 bool    is_button_pressed   (struct point & pt, struct button_specs & bu)
00205 {
00206     if  (bu.in_use)  {
00207         if  (   bu.area.a.x < pt.x 
00208                 && bu.area.b.x > pt.x
00209                 && bu.area.a.y < pt.y 
00210                 && bu.area.b.y > pt.y)
00211             return  true;
00212     }
00213     return  false;
00214 }
00215 
00216 int get_button_press    (struct point & pt)
00217 {
00218     for (int j = 0; j < NUMOF_BUTTONS; j++)
00219         if  (button[j].in_use && is_button_pressed   (pt, button[j]))
00220             return  j;
00221     return  -1;
00222 }
00223 
00224 void    setup_buttons   ()
00225 {
00226     setup_button    (button[SPEEDO_BUTTON],
00227                     SPEEDO_X - SPEEDO_SIZE, SPEEDO_Y - SPEEDO_SIZE,
00228                     SPEEDO_SIZE * 2, SPEEDO_SIZE * 2, SPEEDO_BODY_COLOUR,   LCD_COLOR_RED,   " X", "")  ;
00229     setup_button    (button[VMETER_BUTTON],
00230                     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", "")  ;
00231     setup_button    (button[AMETER_BUTTON],
00232                     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", "")  ;
00233     setup_button    (button[SLIDER_BUTTON],   SLIDERX, SLIDERY, SLIDERW, SLIDERH, LCD_COLOR_BLUE,   LCD_COLOR_MAGENTA,   "", "")  ;
00234 }
00235 
00236 void    screen_touch_handler::DrawSlider    ()  {
00237     uint32_t
00238         colr,
00239         oldbgcolr   = lcd.GetBackColor   (),
00240         oldtxtcolr  = lcd.GetTextColor   ();
00241     char    txt[4];
00242     txt[1] = 0;
00243     if  (position > MAX_POS)
00244         position = MAX_POS;
00245     if  (position < MIN_POS)
00246         position = MIN_POS;
00247     if  (position != oldpos)    {
00248         //  Draw slider background colour rectangle overwriting previous circles
00249         //  Redraw black vertical
00250         //  Draw new circles
00251         //  Write text char
00252         lcd.SetTextColor(LCD_COLOR_MAGENTA);
00253         lcd.FillRect    (SLIDERX + 1, oldpos - BUTTON_RAD, SLIDERW - 2, SLIDERW);
00254         lcd.SetTextColor(LCD_COLOR_BLACK);
00255         lcd.FillRect    (SLIDERX + (SLIDERW / 2) - 3, 6, 7, SLIDERH - 8);
00256         oldpos = position;
00257         lcd.SetTextColor(LCD_COLOR_WHITE);
00258         lcd.DrawCircle  (CIRC_CTR, position, BUTTON_RAD);  //  seel also FillCircle
00259         lcd.DrawCircle  (CIRC_CTR, position, BUTTON_RAD - 1);
00260         switch  (next_state)  {
00261             case    RUN_DOWN:
00262             case    RUN:
00263                 txt[0] = 'R';
00264                 colr = LCD_COLOR_GREEN;
00265                 break;
00266             case    INTO_NEUTRAL_DRIFT:
00267             case    NEUTRAL_DRIFT:
00268             case    INTO_RUN:
00269                 txt[0] = 'N';
00270                 colr = LCD_COLOR_BLUE;
00271                 break;
00272             case    REGEN_BRAKE:
00273             case    INTO_REGEN_BRAKE:
00274                 txt[0] = 'B';
00275                 colr = LCD_COLOR_ORANGE;
00276                 break;
00277             default:
00278                 txt[0] = 'X';
00279                 colr = LCD_COLOR_CYAN;
00280 //                pc.printf   ("State %d\r\n", next_state);
00281         }   //  End of switch
00282         lcd.SetTextColor(colr);
00283         lcd.FillCircle  (CIRC_CTR, position, BUTTON_RAD - 2);
00284         lcd.SetBackColor  (colr);
00285         lcd.SetTextColor(LCD_COLOR_YELLOW);
00286         displaytext(SLIDERX + 17, position - 10, 4, txt);   //  largest font
00287         lcd.SetBackColor  (LCD_COLOR_BLACK);
00288     }           //  End of else
00289     lcd.SetTextColor (oldtxtcolr);
00290     lcd.SetBackColor (oldbgcolr);
00291 }
00292 
00293 
00294 
00295