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
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
Generated on Thu Jul 14 2022 06:50:34 by 1.7.2