Electric Locomotive control system. Touch screen driver control, includes regenerative braking, drives 4 brushless motors, displays speed MPH, system volts and power
Dependencies: BSP_DISCO_F746NG FastPWM LCD_DISCO_F746NG SD_DISCO_F746NG TS_DISCO_F746NG mbed
graphics.cpp@1:8ef34deb5177, 2017-11-13 (annotated)
- Committer:
- JonFreeman
- Date:
- Mon Nov 13 09:53:00 2017 +0000
- Revision:
- 1:8ef34deb5177
- Parent:
- 0:23cc72b18e74
Brushless Motor electric locomotive congtrol system; Drives 4 motors using touch-screen control.; Displays speed MPH, system volts and power
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JonFreeman | 0:23cc72b18e74 | 1 | #include "mbed.h" |
JonFreeman | 0:23cc72b18e74 | 2 | #include "TS_DISCO_F746NG.h" |
JonFreeman | 0:23cc72b18e74 | 3 | #include "LCD_DISCO_F746NG.h" |
JonFreeman | 1:8ef34deb5177 | 4 | #include "Electric_Loco.h" |
JonFreeman | 0:23cc72b18e74 | 5 | |
JonFreeman | 0:23cc72b18e74 | 6 | #define VOLTMETER_X 68 // Voltmeter screen position |
JonFreeman | 0:23cc72b18e74 | 7 | #define VOLTMETER_Y 68 |
JonFreeman | 0:23cc72b18e74 | 8 | #define AMMETER_X 68 // Ammeter screen position - Now replaced by Power meter |
JonFreeman | 0:23cc72b18e74 | 9 | #define AMMETER_Y 202 |
JonFreeman | 0:23cc72b18e74 | 10 | #define SPEEDO_X 274 // Speedometer screen position |
JonFreeman | 0:23cc72b18e74 | 11 | #define SPEEDO_Y 135 |
JonFreeman | 0:23cc72b18e74 | 12 | #define V_A_SIZE 54 // Size of voltmeter and ammeter |
JonFreeman | 0:23cc72b18e74 | 13 | #define SPEEDO_SIZE 112 |
JonFreeman | 0:23cc72b18e74 | 14 | |
JonFreeman | 0:23cc72b18e74 | 15 | #define SPEEDO_BODY_COLOUR LCD_COLOR_BLACK |
JonFreeman | 0:23cc72b18e74 | 16 | #define SPEEDO_DIAL_COLOUR LCD_COLOR_WHITE |
JonFreeman | 0:23cc72b18e74 | 17 | #define SPEEDO_TEXT_COLOUR LCD_COLOR_BLUE |
JonFreeman | 0:23cc72b18e74 | 18 | |
JonFreeman | 0:23cc72b18e74 | 19 | #define VMETER_BODY_COLOUR LCD_COLOR_BLACK |
JonFreeman | 0:23cc72b18e74 | 20 | #define VMETER_DIAL_COLOUR LCD_COLOR_WHITE |
JonFreeman | 0:23cc72b18e74 | 21 | #define VMETER_TEXT_COLOUR LCD_COLOR_BLUE |
JonFreeman | 0:23cc72b18e74 | 22 | |
JonFreeman | 0:23cc72b18e74 | 23 | #define AMETER_BODY_COLOUR LCD_COLOR_BLACK |
JonFreeman | 0:23cc72b18e74 | 24 | #define AMETER_DIAL_COLOUR LCD_COLOR_WHITE |
JonFreeman | 0:23cc72b18e74 | 25 | #define AMETER_TEXT_COLOUR LCD_COLOR_BLUE |
JonFreeman | 0:23cc72b18e74 | 26 | |
JonFreeman | 0:23cc72b18e74 | 27 | extern LCD_DISCO_F746NG lcd; |
JonFreeman | 0:23cc72b18e74 | 28 | extern TS_DISCO_F746NG touch_screen; |
JonFreeman | 0:23cc72b18e74 | 29 | extern Serial pc; |
JonFreeman | 0:23cc72b18e74 | 30 | |
JonFreeman | 0:23cc72b18e74 | 31 | static const int char_widths[] = {5, 7, 11, 14, 17, 17} , |
JonFreeman | 0:23cc72b18e74 | 32 | meter_radius_min = 30, meter_radius_max = 120; |
JonFreeman | 0:23cc72b18e74 | 33 | |
JonFreeman | 0:23cc72b18e74 | 34 | |
JonFreeman | 0:23cc72b18e74 | 35 | // Uses our own generated sine and cosines from lookup table. For some unexplained reason, using inbuilt sin and cos fns cause display flicker ! |
JonFreeman | 0:23cc72b18e74 | 36 | extern double jcos (double angle); // Used in DrawNeedle, plain sin and cos functions cause display flicker !! |
JonFreeman | 0:23cc72b18e74 | 37 | extern double jsin (double angle); |
JonFreeman | 0:23cc72b18e74 | 38 | |
JonFreeman | 0:23cc72b18e74 | 39 | /*void costabgen (int points) { |
JonFreeman | 0:23cc72b18e74 | 40 | double angle = 0.0; |
JonFreeman | 0:23cc72b18e74 | 41 | while (angle < 2.1 * PI) { |
JonFreeman | 0:23cc72b18e74 | 42 | pc.printf ("Angle %f, my cos %+f, c cos %+f\r\n", angle, jcos(angle), cos(angle)); |
JonFreeman | 0:23cc72b18e74 | 43 | // pc.printf ("Angle %f, my sin %+f, c sin %+f\r\n", angle, jsin(angle), sin(angle)); |
JonFreeman | 0:23cc72b18e74 | 44 | angle += PI / 24; |
JonFreeman | 0:23cc72b18e74 | 45 | } |
JonFreeman | 0:23cc72b18e74 | 46 | // double angle; |
JonFreeman | 0:23cc72b18e74 | 47 | *//* int step, perline = 0; |
JonFreeman | 0:23cc72b18e74 | 48 | double interval = PI / 2.0 / (double)points; |
JonFreeman | 0:23cc72b18e74 | 49 | pc.printf ("//At costabgen with %d points\r\n", points); |
JonFreeman | 0:23cc72b18e74 | 50 | pc.printf ("static const double costab[] = {\r\n"); |
JonFreeman | 0:23cc72b18e74 | 51 | for (step = 0; step <= points; step++) { |
JonFreeman | 0:23cc72b18e74 | 52 | angle = interval * (double)step; |
JonFreeman | 0:23cc72b18e74 | 53 | // pc.printf ("cos %+.3f = %+.3f\r\n", angle, cos(angle)); |
JonFreeman | 0:23cc72b18e74 | 54 | if (++perline == 8) { |
JonFreeman | 0:23cc72b18e74 | 55 | pc.printf ("%+.6f,\r\n", cos(angle)); |
JonFreeman | 0:23cc72b18e74 | 56 | perline = 0; |
JonFreeman | 0:23cc72b18e74 | 57 | } |
JonFreeman | 0:23cc72b18e74 | 58 | else |
JonFreeman | 0:23cc72b18e74 | 59 | pc.printf ("%+.6f, ", cos(angle)); |
JonFreeman | 0:23cc72b18e74 | 60 | wait (0.025); |
JonFreeman | 0:23cc72b18e74 | 61 | } |
JonFreeman | 0:23cc72b18e74 | 62 | pc.printf ("0.0\t}\t;\r\n//End of costab\r\n"); |
JonFreeman | 0:23cc72b18e74 | 63 | */ |
JonFreeman | 0:23cc72b18e74 | 64 | //} |
JonFreeman | 0:23cc72b18e74 | 65 | |
JonFreeman | 0:23cc72b18e74 | 66 | /** |
JonFreeman | 0:23cc72b18e74 | 67 | * @brief Fills a triangle (between 3 points). |
JonFreeman | 0:23cc72b18e74 | 68 | * @param x1: Point 1 X position |
JonFreeman | 0:23cc72b18e74 | 69 | * @param y1: Point 1 Y position |
JonFreeman | 0:23cc72b18e74 | 70 | * @param x2: Point 2 X position |
JonFreeman | 0:23cc72b18e74 | 71 | * @param y2: Point 2 Y position |
JonFreeman | 0:23cc72b18e74 | 72 | * @param x3: Point 3 X position |
JonFreeman | 0:23cc72b18e74 | 73 | * @param y3: Point 3 Y position |
JonFreeman | 0:23cc72b18e74 | 74 | * @retval None |
JonFreeman | 0:23cc72b18e74 | 75 | */ |
JonFreeman | 0:23cc72b18e74 | 76 | static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3) |
JonFreeman | 0:23cc72b18e74 | 77 | { |
JonFreeman | 0:23cc72b18e74 | 78 | int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, |
JonFreeman | 0:23cc72b18e74 | 79 | yinc1 = 0, yinc2 = 0, den = 0, num = 0, num_add = 0, num_pixels = 0, |
JonFreeman | 0:23cc72b18e74 | 80 | curpixel = 0; |
JonFreeman | 0:23cc72b18e74 | 81 | |
JonFreeman | 0:23cc72b18e74 | 82 | deltax = abs(x2 - x1); /* The difference between the x's */ |
JonFreeman | 0:23cc72b18e74 | 83 | deltay = abs(y2 - y1); /* The difference between the y's */ |
JonFreeman | 0:23cc72b18e74 | 84 | x = x1; /* Start x off at the first pixel */ |
JonFreeman | 0:23cc72b18e74 | 85 | y = y1; /* Start y off at the first pixel */ |
JonFreeman | 0:23cc72b18e74 | 86 | |
JonFreeman | 0:23cc72b18e74 | 87 | if (x2 >= x1) { /* The x-values are increasing */ |
JonFreeman | 0:23cc72b18e74 | 88 | xinc1 = 1; |
JonFreeman | 0:23cc72b18e74 | 89 | xinc2 = 1; |
JonFreeman | 0:23cc72b18e74 | 90 | } else { /* The x-values are decreasing */ |
JonFreeman | 0:23cc72b18e74 | 91 | xinc1 = -1; |
JonFreeman | 0:23cc72b18e74 | 92 | xinc2 = -1; |
JonFreeman | 0:23cc72b18e74 | 93 | } |
JonFreeman | 0:23cc72b18e74 | 94 | |
JonFreeman | 0:23cc72b18e74 | 95 | if (y2 >= y1) { /* The y-values are increasing */ |
JonFreeman | 0:23cc72b18e74 | 96 | yinc1 = 1; |
JonFreeman | 0:23cc72b18e74 | 97 | yinc2 = 1; |
JonFreeman | 0:23cc72b18e74 | 98 | } else { /* The y-values are decreasing */ |
JonFreeman | 0:23cc72b18e74 | 99 | yinc1 = -1; |
JonFreeman | 0:23cc72b18e74 | 100 | yinc2 = -1; |
JonFreeman | 0:23cc72b18e74 | 101 | } |
JonFreeman | 0:23cc72b18e74 | 102 | |
JonFreeman | 0:23cc72b18e74 | 103 | if (deltax >= deltay) { /* There is at least one x-value for every y-value */ |
JonFreeman | 0:23cc72b18e74 | 104 | xinc1 = 0; /* Don't change the x when numerator >= denominator */ |
JonFreeman | 0:23cc72b18e74 | 105 | yinc2 = 0; /* Don't change the y for every iteration */ |
JonFreeman | 0:23cc72b18e74 | 106 | den = deltax; |
JonFreeman | 0:23cc72b18e74 | 107 | num = deltax / 2; |
JonFreeman | 0:23cc72b18e74 | 108 | num_add = deltay; |
JonFreeman | 0:23cc72b18e74 | 109 | num_pixels = deltax; /* There are more x-values than y-values */ |
JonFreeman | 0:23cc72b18e74 | 110 | } else { /* There is at least one y-value for every x-value */ |
JonFreeman | 0:23cc72b18e74 | 111 | xinc2 = 0; /* Don't change the x for every iteration */ |
JonFreeman | 0:23cc72b18e74 | 112 | yinc1 = 0; /* Don't change the y when numerator >= denominator */ |
JonFreeman | 0:23cc72b18e74 | 113 | den = deltay; |
JonFreeman | 0:23cc72b18e74 | 114 | num = deltay / 2; |
JonFreeman | 0:23cc72b18e74 | 115 | num_add = deltax; |
JonFreeman | 0:23cc72b18e74 | 116 | num_pixels = deltay; /* There are more y-values than x-values */ |
JonFreeman | 0:23cc72b18e74 | 117 | } |
JonFreeman | 0:23cc72b18e74 | 118 | |
JonFreeman | 0:23cc72b18e74 | 119 | for (curpixel = 0; curpixel <= num_pixels; curpixel++) { |
JonFreeman | 0:23cc72b18e74 | 120 | lcd.DrawLine(x, y, x3, y3); |
JonFreeman | 0:23cc72b18e74 | 121 | |
JonFreeman | 0:23cc72b18e74 | 122 | num += num_add; /* Increase the numerator by the top of the fraction */ |
JonFreeman | 0:23cc72b18e74 | 123 | if (num >= den) { /* Check if numerator >= denominator */ |
JonFreeman | 0:23cc72b18e74 | 124 | num -= den; /* Calculate the new numerator value */ |
JonFreeman | 0:23cc72b18e74 | 125 | x += xinc1; /* Change the x as appropriate */ |
JonFreeman | 0:23cc72b18e74 | 126 | y += yinc1; /* Change the y as appropriate */ |
JonFreeman | 0:23cc72b18e74 | 127 | } |
JonFreeman | 0:23cc72b18e74 | 128 | x += xinc2; /* Change the x as appropriate */ |
JonFreeman | 0:23cc72b18e74 | 129 | y += yinc2; /* Change the y as appropriate */ |
JonFreeman | 0:23cc72b18e74 | 130 | } |
JonFreeman | 0:23cc72b18e74 | 131 | } |
JonFreeman | 0:23cc72b18e74 | 132 | |
JonFreeman | 0:23cc72b18e74 | 133 | double anglefix (double a) { // Ensures 0.0 <= angle <= + two PI |
JonFreeman | 0:23cc72b18e74 | 134 | while (a > PI) a -= 2.0 * PI; |
JonFreeman | 0:23cc72b18e74 | 135 | while (a < 0.0) a += 2.0 * PI; |
JonFreeman | 0:23cc72b18e74 | 136 | return a; |
JonFreeman | 0:23cc72b18e74 | 137 | } |
JonFreeman | 0:23cc72b18e74 | 138 | |
JonFreeman | 0:23cc72b18e74 | 139 | class moving_coil_meter |
JonFreeman | 0:23cc72b18e74 | 140 | { |
JonFreeman | 0:23cc72b18e74 | 141 | int meter_radius, cent_x, cent_y, needle_len, scale_ticks, |
JonFreeman | 0:23cc72b18e74 | 142 | disc_colour, needle_colour, scale_colour, text_colour, body_colour, dec_places; |
JonFreeman | 0:23cc72b18e74 | 143 | double start_angle, end_angle, old_angle, value_min, value_max, rad_per_value, swept_angle, value_range; |
JonFreeman | 0:23cc72b18e74 | 144 | double Value; // This is the one that determines pointer angle |
JonFreeman | 0:23cc72b18e74 | 145 | |
JonFreeman | 0:23cc72b18e74 | 146 | void DrawNeedle (double alpha, int colour) ; |
JonFreeman | 0:23cc72b18e74 | 147 | void DrawScaleGraduations(int colour) ; |
JonFreeman | 0:23cc72b18e74 | 148 | double get_pointer_angle (double value) ; |
JonFreeman | 0:23cc72b18e74 | 149 | int get_font () ; |
JonFreeman | 0:23cc72b18e74 | 150 | |
JonFreeman | 0:23cc72b18e74 | 151 | public: |
JonFreeman | 0:23cc72b18e74 | 152 | |
JonFreeman | 0:23cc72b18e74 | 153 | moving_coil_meter () { // constructor |
JonFreeman | 0:23cc72b18e74 | 154 | meter_radius = 100; |
JonFreeman | 0:23cc72b18e74 | 155 | value_min = -1.0; |
JonFreeman | 0:23cc72b18e74 | 156 | value_max = 1.0; |
JonFreeman | 0:23cc72b18e74 | 157 | cent_x = cent_y = 150; |
JonFreeman | 0:23cc72b18e74 | 158 | disc_colour = LCD_COLOR_BLACK; |
JonFreeman | 0:23cc72b18e74 | 159 | needle_colour = LCD_COLOR_WHITE; |
JonFreeman | 0:23cc72b18e74 | 160 | scale_colour = LCD_COLOR_MAGENTA; |
JonFreeman | 0:23cc72b18e74 | 161 | text_colour = LCD_COLOR_RED; |
JonFreeman | 0:23cc72b18e74 | 162 | body_colour = LCD_COLOR_CYAN; |
JonFreeman | 0:23cc72b18e74 | 163 | old_angle = 0.0; |
JonFreeman | 0:23cc72b18e74 | 164 | } |
JonFreeman | 0:23cc72b18e74 | 165 | |
JonFreeman | 0:23cc72b18e74 | 166 | 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) ; |
JonFreeman | 0:23cc72b18e74 | 167 | void set_colours (int bod_colour, int bgcol, int needlecol, int textcolour, int scalecol) ; |
JonFreeman | 0:23cc72b18e74 | 168 | void set_value (double v) ; |
JonFreeman | 0:23cc72b18e74 | 169 | } Voltmeter, Powermeter, Speedo; // 3 instances of moving coil meter graphic |
JonFreeman | 0:23cc72b18e74 | 170 | |
JonFreeman | 0:23cc72b18e74 | 171 | void moving_coil_meter::set_colours (int bod_col, int bgcol, int needlecol, int textcol, int scalecol) { |
JonFreeman | 0:23cc72b18e74 | 172 | body_colour = bod_col; |
JonFreeman | 0:23cc72b18e74 | 173 | disc_colour = bgcol; |
JonFreeman | 0:23cc72b18e74 | 174 | needle_colour = needlecol; |
JonFreeman | 0:23cc72b18e74 | 175 | text_colour = textcol; |
JonFreeman | 0:23cc72b18e74 | 176 | scale_colour = scalecol; |
JonFreeman | 0:23cc72b18e74 | 177 | } |
JonFreeman | 0:23cc72b18e74 | 178 | |
JonFreeman | 0:23cc72b18e74 | 179 | void moving_coil_meter::DrawNeedle (double alpha, int colour) |
JonFreeman | 0:23cc72b18e74 | 180 | { |
JonFreeman | 0:23cc72b18e74 | 181 | point pixpts[4]; |
JonFreeman | 0:23cc72b18e74 | 182 | int save_colour, ssa, sca; |
JonFreeman | 0:23cc72b18e74 | 183 | alpha = anglefix (alpha); |
JonFreeman | 0:23cc72b18e74 | 184 | double shortln = (needle_len / 18.7), |
JonFreeman | 0:23cc72b18e74 | 185 | sina = jsin(alpha), |
JonFreeman | 0:23cc72b18e74 | 186 | cosa = jcos(alpha); |
JonFreeman | 0:23cc72b18e74 | 187 | |
JonFreeman | 0:23cc72b18e74 | 188 | save_colour = lcd.GetTextColor (); |
JonFreeman | 0:23cc72b18e74 | 189 | ssa = (int)(shortln * sina); |
JonFreeman | 0:23cc72b18e74 | 190 | sca = (int)(shortln * cosa); |
JonFreeman | 0:23cc72b18e74 | 191 | old_angle = alpha; |
JonFreeman | 0:23cc72b18e74 | 192 | pixpts[0].x = cent_x - ssa;//(int)(shortln * sin(alpha)); |
JonFreeman | 0:23cc72b18e74 | 193 | pixpts[0].y = cent_y - sca;//(int)(shortln * cos(alpha)); |
JonFreeman | 0:23cc72b18e74 | 194 | pixpts[1].x = cent_x + (int)(needle_len * cosa); |
JonFreeman | 0:23cc72b18e74 | 195 | pixpts[1].y = cent_y - (int)(needle_len * sina); // - as increasing y is downwards |
JonFreeman | 0:23cc72b18e74 | 196 | pixpts[2].x = cent_x + ssa;//(int)(shortln * sin(alpha)); |
JonFreeman | 0:23cc72b18e74 | 197 | pixpts[2].y = cent_y + sca;//(int)(shortln * cos(alpha)); |
JonFreeman | 0:23cc72b18e74 | 198 | lcd.SetTextColor (colour); |
JonFreeman | 0:23cc72b18e74 | 199 | lcd.FillCircle (cent_x, cent_y, (int)(needle_len / 15.0)); |
JonFreeman | 0:23cc72b18e74 | 200 | FillTriangle (pixpts[0].x, pixpts[1].x, pixpts[2].x, pixpts[0].y, pixpts[1].y, pixpts[2].y); |
JonFreeman | 0:23cc72b18e74 | 201 | lcd.SetTextColor (save_colour); |
JonFreeman | 0:23cc72b18e74 | 202 | } |
JonFreeman | 0:23cc72b18e74 | 203 | |
JonFreeman | 0:23cc72b18e74 | 204 | void moving_coil_meter::DrawScaleGraduations (int colour) |
JonFreeman | 0:23cc72b18e74 | 205 | { |
JonFreeman | 0:23cc72b18e74 | 206 | int save_colour = lcd.GetTextColor (); |
JonFreeman | 0:23cc72b18e74 | 207 | int i, radius_inner = (int) meter_radius - 2, radius_outer = (int) (meter_radius * 0.9); |
JonFreeman | 0:23cc72b18e74 | 208 | double ang, cosang, sinang, angle_step; |
JonFreeman | 0:23cc72b18e74 | 209 | lcd.SetTextColor (colour); |
JonFreeman | 0:23cc72b18e74 | 210 | ang = start_angle; |
JonFreeman | 0:23cc72b18e74 | 211 | angle_step = (start_angle - end_angle) / scale_ticks; |
JonFreeman | 0:23cc72b18e74 | 212 | for (i = 0; i <= scale_ticks; i++) { // |
JonFreeman | 0:23cc72b18e74 | 213 | cosang = cos(ang); |
JonFreeman | 0:23cc72b18e74 | 214 | sinang = sin(ang); |
JonFreeman | 0:23cc72b18e74 | 215 | lcd.DrawLine (cent_x + radius_outer * cosang, cent_y - radius_outer * sinang, cent_x + radius_inner * cosang, cent_y - radius_inner * sinang); |
JonFreeman | 0:23cc72b18e74 | 216 | ang -= angle_step; |
JonFreeman | 0:23cc72b18e74 | 217 | } |
JonFreeman | 0:23cc72b18e74 | 218 | lcd.SetTextColor (save_colour); |
JonFreeman | 0:23cc72b18e74 | 219 | } |
JonFreeman | 0:23cc72b18e74 | 220 | |
JonFreeman | 0:23cc72b18e74 | 221 | void displaytext (int x, int y, const int font, char * txt) ; |
JonFreeman | 0:23cc72b18e74 | 222 | |
JonFreeman | 0:23cc72b18e74 | 223 | 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) |
JonFreeman | 0:23cc72b18e74 | 224 | { |
JonFreeman | 0:23cc72b18e74 | 225 | bool retval = true; |
JonFreeman | 0:23cc72b18e74 | 226 | int font, charwid, x_offset; |
JonFreeman | 0:23cc72b18e74 | 227 | if (size < meter_radius_min || size > meter_radius_max) |
JonFreeman | 0:23cc72b18e74 | 228 | return false; |
JonFreeman | 0:23cc72b18e74 | 229 | meter_radius = size; |
JonFreeman | 0:23cc72b18e74 | 230 | if (meter_radius > cx || meter_radius > cy) |
JonFreeman | 0:23cc72b18e74 | 231 | return false; |
JonFreeman | 0:23cc72b18e74 | 232 | int corner_rad = meter_radius / 6, |
JonFreeman | 0:23cc72b18e74 | 233 | screw_hole_offset = meter_radius * 92 / 100, |
JonFreeman | 0:23cc72b18e74 | 234 | screw_rad = meter_radius / 13; |
JonFreeman | 0:23cc72b18e74 | 235 | cent_x = cx; |
JonFreeman | 0:23cc72b18e74 | 236 | cent_y = cy; |
JonFreeman | 0:23cc72b18e74 | 237 | |
JonFreeman | 0:23cc72b18e74 | 238 | start_angle = start_ang; |
JonFreeman | 0:23cc72b18e74 | 239 | end_angle = end_ang; |
JonFreeman | 0:23cc72b18e74 | 240 | value_min = lo; |
JonFreeman | 0:23cc72b18e74 | 241 | value_max = hi; |
JonFreeman | 0:23cc72b18e74 | 242 | scale_ticks = scaleticks; |
JonFreeman | 0:23cc72b18e74 | 243 | swept_angle = abs(start_angle - end_angle); |
JonFreeman | 0:23cc72b18e74 | 244 | value_range = (value_max - value_min); |
JonFreeman | 0:23cc72b18e74 | 245 | rad_per_value = swept_angle / value_range; |
JonFreeman | 0:23cc72b18e74 | 246 | dec_places = decimal_places; |
JonFreeman | 0:23cc72b18e74 | 247 | |
JonFreeman | 0:23cc72b18e74 | 248 | needle_len = (int)(0.87 * (double)meter_radius); |
JonFreeman | 0:23cc72b18e74 | 249 | int oldcolour1 = lcd.GetTextColor (); |
JonFreeman | 0:23cc72b18e74 | 250 | int oldcolour2 = lcd.GetBackColor (); |
JonFreeman | 0:23cc72b18e74 | 251 | lcd.SetTextColor (body_colour); |
JonFreeman | 0:23cc72b18e74 | 252 | // Draw meter body as solid square with rounded corners, complete with mounting screw holes ! |
JonFreeman | 0:23cc72b18e74 | 253 | lcd.FillRect (cent_x - meter_radius, cent_y - meter_radius - corner_rad, meter_radius * 2, corner_rad); |
JonFreeman | 0:23cc72b18e74 | 254 | lcd.FillRect (cent_x - meter_radius, cent_y + meter_radius, meter_radius * 2, corner_rad + 1); |
JonFreeman | 0:23cc72b18e74 | 255 | lcd.FillRect (cent_x - meter_radius - corner_rad, cent_y - meter_radius, 1 +(meter_radius + corner_rad) * 2, meter_radius * 2); |
JonFreeman | 0:23cc72b18e74 | 256 | lcd.FillCircle (cent_x - meter_radius, cent_y - meter_radius, corner_rad); // meter box has rounded corners |
JonFreeman | 0:23cc72b18e74 | 257 | lcd.FillCircle (cent_x - meter_radius, cent_y + meter_radius, corner_rad); |
JonFreeman | 0:23cc72b18e74 | 258 | lcd.FillCircle (cent_x + meter_radius, cent_y - meter_radius, corner_rad); |
JonFreeman | 0:23cc72b18e74 | 259 | lcd.FillCircle (cent_x + meter_radius, cent_y + meter_radius, corner_rad); |
JonFreeman | 0:23cc72b18e74 | 260 | lcd.SetTextColor (LCD_COLOR_DARKGRAY); |
JonFreeman | 0:23cc72b18e74 | 261 | lcd.FillCircle (cent_x - screw_hole_offset, cent_y - screw_hole_offset, screw_rad); // panel mounting screw holes near corners |
JonFreeman | 0:23cc72b18e74 | 262 | lcd.FillCircle (cent_x - screw_hole_offset, cent_y + screw_hole_offset, screw_rad); |
JonFreeman | 0:23cc72b18e74 | 263 | lcd.FillCircle (cent_x + screw_hole_offset, cent_y - screw_hole_offset, screw_rad); |
JonFreeman | 0:23cc72b18e74 | 264 | lcd.FillCircle (cent_x + screw_hole_offset, cent_y + screw_hole_offset, screw_rad); |
JonFreeman | 0:23cc72b18e74 | 265 | lcd.SetTextColor (disc_colour); |
JonFreeman | 0:23cc72b18e74 | 266 | lcd.FillCircle (cent_x, cent_y, meter_radius); |
JonFreeman | 0:23cc72b18e74 | 267 | DrawScaleGraduations (scale_colour); //drew the green trace around active needle-sweep angle |
JonFreeman | 0:23cc72b18e74 | 268 | |
JonFreeman | 0:23cc72b18e74 | 269 | font = get_font (); |
JonFreeman | 0:23cc72b18e74 | 270 | charwid = char_widths[font]; |
JonFreeman | 0:23cc72b18e74 | 271 | x_offset = charwid * strlen(units) / 2; |
JonFreeman | 0:23cc72b18e74 | 272 | lcd.SetTextColor (text_colour); |
JonFreeman | 0:23cc72b18e74 | 273 | lcd.SetBackColor (disc_colour); |
JonFreeman | 0:23cc72b18e74 | 274 | // displaytext (cent_x - x_offset, cent_y + (meter_radius * 7) / 19, font, units); |
JonFreeman | 0:23cc72b18e74 | 275 | displaytext (cent_x - x_offset, cent_y + (meter_radius * 6) / 19, font, units); |
JonFreeman | 0:23cc72b18e74 | 276 | lcd.SetBackColor (oldcolour2); |
JonFreeman | 0:23cc72b18e74 | 277 | lcd.SetTextColor (oldcolour1); |
JonFreeman | 0:23cc72b18e74 | 278 | return retval; |
JonFreeman | 0:23cc72b18e74 | 279 | } |
JonFreeman | 0:23cc72b18e74 | 280 | |
JonFreeman | 0:23cc72b18e74 | 281 | int moving_coil_meter::get_font () |
JonFreeman | 0:23cc72b18e74 | 282 | { |
JonFreeman | 0:23cc72b18e74 | 283 | int font = meter_radius - meter_radius_min; |
JonFreeman | 0:23cc72b18e74 | 284 | font /= 17; |
JonFreeman | 0:23cc72b18e74 | 285 | if (font > 4) |
JonFreeman | 0:23cc72b18e74 | 286 | font = 4; |
JonFreeman | 0:23cc72b18e74 | 287 | if (font < 2) |
JonFreeman | 0:23cc72b18e74 | 288 | font = 2; |
JonFreeman | 0:23cc72b18e74 | 289 | return font; |
JonFreeman | 0:23cc72b18e74 | 290 | } |
JonFreeman | 0:23cc72b18e74 | 291 | |
JonFreeman | 0:23cc72b18e74 | 292 | double moving_coil_meter::get_pointer_angle (double v) |
JonFreeman | 0:23cc72b18e74 | 293 | { |
JonFreeman | 0:23cc72b18e74 | 294 | double vabvmin, retval; |
JonFreeman | 0:23cc72b18e74 | 295 | if (v < value_min) v = value_min; |
JonFreeman | 0:23cc72b18e74 | 296 | if (v > value_max) v = value_max; |
JonFreeman | 0:23cc72b18e74 | 297 | Value = v; // clipped copy of supplied value |
JonFreeman | 0:23cc72b18e74 | 298 | vabvmin = v - value_min; |
JonFreeman | 0:23cc72b18e74 | 299 | retval = start_angle - (vabvmin * rad_per_value); |
JonFreeman | 0:23cc72b18e74 | 300 | return anglefix (retval); |
JonFreeman | 0:23cc72b18e74 | 301 | } |
JonFreeman | 0:23cc72b18e74 | 302 | |
JonFreeman | 0:23cc72b18e74 | 303 | void moving_coil_meter::set_value (double meter_read_value) |
JonFreeman | 0:23cc72b18e74 | 304 | { |
JonFreeman | 0:23cc72b18e74 | 305 | char txt[32]; |
JonFreeman | 0:23cc72b18e74 | 306 | int x_offset, font, charwid, lenchk;//, |
JonFreeman | 0:23cc72b18e74 | 307 | DrawNeedle (old_angle, disc_colour); // un-draw needle |
JonFreeman | 0:23cc72b18e74 | 308 | DrawNeedle (get_pointer_angle (meter_read_value), needle_colour) ; // re-draw needle |
JonFreeman | 0:23cc72b18e74 | 309 | if (dec_places == ONE_DP) |
JonFreeman | 0:23cc72b18e74 | 310 | sprintf (txt, " %+.1f \0", meter_read_value); |
JonFreeman | 0:23cc72b18e74 | 311 | else |
JonFreeman | 0:23cc72b18e74 | 312 | sprintf (txt, " %+.0f \0", meter_read_value); |
JonFreeman | 0:23cc72b18e74 | 313 | lenchk = strlen(txt); |
JonFreeman | 0:23cc72b18e74 | 314 | font = get_font(); |
JonFreeman | 0:23cc72b18e74 | 315 | charwid = char_widths[font]; |
JonFreeman | 0:23cc72b18e74 | 316 | x_offset = charwid * lenchk / 2; |
JonFreeman | 0:23cc72b18e74 | 317 | lcd.SetTextColor (text_colour); |
JonFreeman | 0:23cc72b18e74 | 318 | lcd.SetBackColor (disc_colour); |
JonFreeman | 0:23cc72b18e74 | 319 | if (lenchk > 0 && lenchk < 9) |
JonFreeman | 0:23cc72b18e74 | 320 | displaytext (cent_x - x_offset, cent_y + (meter_radius * 11) / 19, font, txt); |
JonFreeman | 0:23cc72b18e74 | 321 | } |
JonFreeman | 0:23cc72b18e74 | 322 | //bool moving_coil_meter::setup (int cx, int cy, int size, double lo, double hi, double start_ang, double end_ang, |
JonFreeman | 0:23cc72b18e74 | 323 | // int scale_ticks, char * units) |
JonFreeman | 0:23cc72b18e74 | 324 | void vm_set () //x y size minv maxv min angle max angle, |
JonFreeman | 0:23cc72b18e74 | 325 | { |
JonFreeman | 0:23cc72b18e74 | 326 | Speedo.set_colours (SPEEDO_BODY_COLOUR, SPEEDO_DIAL_COLOUR, LCD_COLOR_RED, SPEEDO_TEXT_COLOUR, LCD_COLOR_BLACK); |
JonFreeman | 0:23cc72b18e74 | 327 | Speedo.setup (SPEEDO_X, SPEEDO_Y, SPEEDO_SIZE, 0.0, 12.0, 1.25 * PI, -0.25 * PI , 12, "MPH", ONE_DP); |
JonFreeman | 0:23cc72b18e74 | 328 | Voltmeter.set_colours (LCD_COLOR_BLACK, LCD_COLOR_WHITE, LCD_COLOR_RED, LCD_COLOR_BLUE, LCD_COLOR_MAGENTA); |
JonFreeman | 0:23cc72b18e74 | 329 | Voltmeter.setup (VOLTMETER_X, VOLTMETER_Y, V_A_SIZE, 22.0, 59.0, 1.25 * PI, -0.25 * PI , 30, "V", ONE_DP); |
JonFreeman | 0:23cc72b18e74 | 330 | Powermeter.set_colours (LCD_COLOR_BLACK, LCD_COLOR_WHITE, LCD_COLOR_RED, LCD_COLOR_BLUE, LCD_COLOR_BLUE); |
JonFreeman | 0:23cc72b18e74 | 331 | Powermeter.setup (AMMETER_X, AMMETER_Y, V_A_SIZE, -1400.0, 1400.0, 1.25 * PI, -0.25 * PI , 14, "Watt", NO_DPS); |
JonFreeman | 0:23cc72b18e74 | 332 | } |
JonFreeman | 0:23cc72b18e74 | 333 | |
JonFreeman | 1:8ef34deb5177 | 334 | //void update_meters (double speed, double current, double voltage) |
JonFreeman | 1:8ef34deb5177 | 335 | void update_meters (double speed, double power, double voltage) |
JonFreeman | 0:23cc72b18e74 | 336 | { |
JonFreeman | 1:8ef34deb5177 | 337 | // Powermeter.set_value(voltage * current); |
JonFreeman | 1:8ef34deb5177 | 338 | Powermeter.set_value(power); |
JonFreeman | 0:23cc72b18e74 | 339 | Voltmeter.set_value (voltage); |
JonFreeman | 0:23cc72b18e74 | 340 | Speedo.set_value (speed); |
JonFreeman | 0:23cc72b18e74 | 341 | } |
JonFreeman | 0:23cc72b18e74 | 342 | |
JonFreeman | 0:23cc72b18e74 | 343 | |
JonFreeman | 0:23cc72b18e74 | 344 | |
JonFreeman | 0:23cc72b18e74 | 345 | struct rect { struct point a, b; } ; |
JonFreeman | 0:23cc72b18e74 | 346 | |
JonFreeman | 0:23cc72b18e74 | 347 | struct butt_on { |
JonFreeman | 0:23cc72b18e74 | 348 | struct rect area; |
JonFreeman | 0:23cc72b18e74 | 349 | int border_colour, body_colour; |
JonFreeman | 0:23cc72b18e74 | 350 | bool in_use, pressed;//, released; |
JonFreeman | 0:23cc72b18e74 | 351 | char txt1[12]; |
JonFreeman | 0:23cc72b18e74 | 352 | char txt2[12]; |
JonFreeman | 0:23cc72b18e74 | 353 | } ; |
JonFreeman | 0:23cc72b18e74 | 354 | |
JonFreeman | 0:23cc72b18e74 | 355 | struct butt_on button[NUMOF_BUTTONS]; |
JonFreeman | 0:23cc72b18e74 | 356 | |
JonFreeman | 0:23cc72b18e74 | 357 | int get_button_press (struct point & pt) ; |
JonFreeman | 0:23cc72b18e74 | 358 | int get_but_p (int x, int y) |
JonFreeman | 0:23cc72b18e74 | 359 | { |
JonFreeman | 0:23cc72b18e74 | 360 | struct point p; |
JonFreeman | 0:23cc72b18e74 | 361 | p.x = x; |
JonFreeman | 0:23cc72b18e74 | 362 | p.y = y; |
JonFreeman | 0:23cc72b18e74 | 363 | return get_button_press (p); |
JonFreeman | 0:23cc72b18e74 | 364 | } |
JonFreeman | 0:23cc72b18e74 | 365 | |
JonFreeman | 0:23cc72b18e74 | 366 | |
JonFreeman | 0:23cc72b18e74 | 367 | void read_keypresses (struct ky_bd & a) |
JonFreeman | 0:23cc72b18e74 | 368 | { |
JonFreeman | 0:23cc72b18e74 | 369 | int x; |
JonFreeman | 0:23cc72b18e74 | 370 | a.count = 0; |
JonFreeman | 0:23cc72b18e74 | 371 | a.sli = false; |
JonFreeman | 0:23cc72b18e74 | 372 | for (x = 0; x < MAX_TOUCHES; x++) |
JonFreeman | 0:23cc72b18e74 | 373 | a.ky[x].keynum = -1; |
JonFreeman | 0:23cc72b18e74 | 374 | int touches, but; |
JonFreeman | 0:23cc72b18e74 | 375 | TS_StateTypeDef TS_State; |
JonFreeman | 0:23cc72b18e74 | 376 | touch_screen.GetState(&TS_State); |
JonFreeman | 0:23cc72b18e74 | 377 | touches = TS_State.touchDetected; |
JonFreeman | 0:23cc72b18e74 | 378 | for (int h = 0; h < touches; h++) { |
JonFreeman | 0:23cc72b18e74 | 379 | but = get_but_p (TS_State.touchX[h], TS_State.touchY[h]); |
JonFreeman | 0:23cc72b18e74 | 380 | if (but > - 1) { |
JonFreeman | 0:23cc72b18e74 | 381 | a.ky[a.count].keynum = but; |
JonFreeman | 0:23cc72b18e74 | 382 | a.ky[a.count].x = TS_State.touchX[h]; |
JonFreeman | 0:23cc72b18e74 | 383 | a.ky[a.count].y = TS_State.touchY[h]; |
JonFreeman | 0:23cc72b18e74 | 384 | if (but == SLIDER) { |
JonFreeman | 0:23cc72b18e74 | 385 | a.sli = true; |
JonFreeman | 0:23cc72b18e74 | 386 | a.slider_y = a.ky[a.count].y; |
JonFreeman | 0:23cc72b18e74 | 387 | } |
JonFreeman | 0:23cc72b18e74 | 388 | a.count++; |
JonFreeman | 0:23cc72b18e74 | 389 | } |
JonFreeman | 0:23cc72b18e74 | 390 | } |
JonFreeman | 0:23cc72b18e74 | 391 | } |
JonFreeman | 0:23cc72b18e74 | 392 | |
JonFreeman | 0:23cc72b18e74 | 393 | |
JonFreeman | 0:23cc72b18e74 | 394 | void displaytext (int x, int y, char * txt) |
JonFreeman | 0:23cc72b18e74 | 395 | { |
JonFreeman | 0:23cc72b18e74 | 396 | lcd.DisplayStringAt(x, y, (uint8_t *)txt, LEFT_MODE); |
JonFreeman | 0:23cc72b18e74 | 397 | } |
JonFreeman | 0:23cc72b18e74 | 398 | |
JonFreeman | 0:23cc72b18e74 | 399 | void displaytext (int x, int y, const int font, char * txt) |
JonFreeman | 0:23cc72b18e74 | 400 | { |
JonFreeman | 0:23cc72b18e74 | 401 | sFONT * const fp[] = {&Font8, &Font12, &Font16, &Font20, &Font24}; |
JonFreeman | 0:23cc72b18e74 | 402 | lcd.SetFont(fp[font]); |
JonFreeman | 0:23cc72b18e74 | 403 | displaytext (x, y, txt); |
JonFreeman | 0:23cc72b18e74 | 404 | } |
JonFreeman | 0:23cc72b18e74 | 405 | |
JonFreeman | 0:23cc72b18e74 | 406 | void displaytext (int x, int y, const int font, uint32_t BCol, uint32_t TCol, char * txt) |
JonFreeman | 0:23cc72b18e74 | 407 | { |
JonFreeman | 0:23cc72b18e74 | 408 | uint32_t otc, obc; |
JonFreeman | 0:23cc72b18e74 | 409 | otc = lcd.GetTextColor(); |
JonFreeman | 0:23cc72b18e74 | 410 | obc = lcd.GetBackColor(); |
JonFreeman | 0:23cc72b18e74 | 411 | lcd.SetTextColor(TCol); |
JonFreeman | 0:23cc72b18e74 | 412 | lcd.SetBackColor(BCol); |
JonFreeman | 0:23cc72b18e74 | 413 | displaytext (x, y, font, txt); |
JonFreeman | 0:23cc72b18e74 | 414 | lcd.SetTextColor(otc); |
JonFreeman | 0:23cc72b18e74 | 415 | lcd.SetBackColor(obc); |
JonFreeman | 0:23cc72b18e74 | 416 | } |
JonFreeman | 0:23cc72b18e74 | 417 | |
JonFreeman | 0:23cc72b18e74 | 418 | void draw_button (struct butt_on & bu) |
JonFreeman | 0:23cc72b18e74 | 419 | { |
JonFreeman | 0:23cc72b18e74 | 420 | int oldbgcolour; |
JonFreeman | 0:23cc72b18e74 | 421 | lcd.SetTextColor (bu.body_colour); |
JonFreeman | 0:23cc72b18e74 | 422 | 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); |
JonFreeman | 0:23cc72b18e74 | 423 | oldbgcolour = lcd.GetBackColor(); |
JonFreeman | 0:23cc72b18e74 | 424 | lcd.SetBackColor(bu.body_colour); |
JonFreeman | 0:23cc72b18e74 | 425 | lcd.SetTextColor(LCD_COLOR_BLACK); |
JonFreeman | 0:23cc72b18e74 | 426 | if (strlen(bu.txt2) == 0) { |
JonFreeman | 0:23cc72b18e74 | 427 | displaytext (bu.area.a.x + 4, bu.area.a.y + 14, 4, bu.txt1); // largest font 4 |
JonFreeman | 0:23cc72b18e74 | 428 | } else { |
JonFreeman | 0:23cc72b18e74 | 429 | displaytext (bu.area.a.x + 4, bu.area.a.y + 4, 3, bu.txt1); // not so large font 3 |
JonFreeman | 0:23cc72b18e74 | 430 | displaytext (bu.area.a.x + 4, bu.area.a.y + 26, bu.txt2); |
JonFreeman | 0:23cc72b18e74 | 431 | } |
JonFreeman | 0:23cc72b18e74 | 432 | lcd.SetBackColor(LCD_COLOR_BLACK); |
JonFreeman | 0:23cc72b18e74 | 433 | lcd.SetTextColor(bu.border_colour); |
JonFreeman | 0:23cc72b18e74 | 434 | 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); |
JonFreeman | 0:23cc72b18e74 | 435 | 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); |
JonFreeman | 0:23cc72b18e74 | 436 | lcd.SetBackColor(oldbgcolour); |
JonFreeman | 0:23cc72b18e74 | 437 | } |
JonFreeman | 0:23cc72b18e74 | 438 | |
JonFreeman | 0:23cc72b18e74 | 439 | void draw_button_hilight (int but, int colour) |
JonFreeman | 0:23cc72b18e74 | 440 | { |
JonFreeman | 0:23cc72b18e74 | 441 | if (but < 0 || but > NUMOF_BUTTONS) { |
JonFreeman | 0:23cc72b18e74 | 442 | pc.printf ("Button out of range in draw_button_hilight %d\r\n", but) ; |
JonFreeman | 0:23cc72b18e74 | 443 | } else { |
JonFreeman | 0:23cc72b18e74 | 444 | struct butt_on * bu = &button[but]; |
JonFreeman | 0:23cc72b18e74 | 445 | int oldbgcolour = lcd.GetBackColor();//, minx, miny, maxx, maxy; |
JonFreeman | 0:23cc72b18e74 | 446 | lcd.SetTextColor(colour); |
JonFreeman | 0:23cc72b18e74 | 447 | 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); |
JonFreeman | 0:23cc72b18e74 | 448 | 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); |
JonFreeman | 0:23cc72b18e74 | 449 | 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); |
JonFreeman | 0:23cc72b18e74 | 450 | lcd.SetBackColor(oldbgcolour); |
JonFreeman | 0:23cc72b18e74 | 451 | } |
JonFreeman | 0:23cc72b18e74 | 452 | } |
JonFreeman | 0:23cc72b18e74 | 453 | |
JonFreeman | 0:23cc72b18e74 | 454 | void draw_button (struct butt_on & bu, int body_colour) |
JonFreeman | 0:23cc72b18e74 | 455 | { |
JonFreeman | 0:23cc72b18e74 | 456 | bu.body_colour = body_colour; |
JonFreeman | 0:23cc72b18e74 | 457 | draw_button (bu); |
JonFreeman | 0:23cc72b18e74 | 458 | } |
JonFreeman | 0:23cc72b18e74 | 459 | |
JonFreeman | 0:23cc72b18e74 | 460 | void setup_button (struct butt_on & bu, int x1, int y1, int dx, int dy, int bord, int body, char * txt1, char * txt2) |
JonFreeman | 0:23cc72b18e74 | 461 | { |
JonFreeman | 0:23cc72b18e74 | 462 | static const int margin = 3; |
JonFreeman | 0:23cc72b18e74 | 463 | int xsize = lcd.GetXSize(); |
JonFreeman | 0:23cc72b18e74 | 464 | int ysize = lcd.GetXSize(); |
JonFreeman | 0:23cc72b18e74 | 465 | int x2 = x1 + dx, y2 = y1 + dy; |
JonFreeman | 0:23cc72b18e74 | 466 | if (x1 < margin) x1 = margin; |
JonFreeman | 0:23cc72b18e74 | 467 | if (y1 < margin) y1 = margin; |
JonFreeman | 0:23cc72b18e74 | 468 | if (x2 > xsize - margin) x2 = xsize - margin; |
JonFreeman | 0:23cc72b18e74 | 469 | if (y2 > ysize - margin) y2 = ysize - margin; |
JonFreeman | 0:23cc72b18e74 | 470 | bu.area.a.x = x1; |
JonFreeman | 0:23cc72b18e74 | 471 | bu.area.a.y = y1; |
JonFreeman | 0:23cc72b18e74 | 472 | bu.area.b.x = x2; |
JonFreeman | 0:23cc72b18e74 | 473 | bu.area.b.y = y2; |
JonFreeman | 0:23cc72b18e74 | 474 | bu.border_colour = bord; |
JonFreeman | 0:23cc72b18e74 | 475 | bu.body_colour = body; |
JonFreeman | 0:23cc72b18e74 | 476 | strcpy (bu.txt1, txt1); |
JonFreeman | 0:23cc72b18e74 | 477 | strcpy (bu.txt2, txt2); |
JonFreeman | 0:23cc72b18e74 | 478 | bu.in_use = true; |
JonFreeman | 0:23cc72b18e74 | 479 | bu.pressed = false; |
JonFreeman | 0:23cc72b18e74 | 480 | draw_button(bu); |
JonFreeman | 0:23cc72b18e74 | 481 | } |
JonFreeman | 0:23cc72b18e74 | 482 | |
JonFreeman | 0:23cc72b18e74 | 483 | bool ifpressed (int key) |
JonFreeman | 0:23cc72b18e74 | 484 | { |
JonFreeman | 0:23cc72b18e74 | 485 | return button[key].pressed; |
JonFreeman | 0:23cc72b18e74 | 486 | } |
JonFreeman | 0:23cc72b18e74 | 487 | |
JonFreeman | 0:23cc72b18e74 | 488 | bool is_button_pressed (struct point & pt, struct butt_on & bu) |
JonFreeman | 0:23cc72b18e74 | 489 | { |
JonFreeman | 0:23cc72b18e74 | 490 | if (bu.in_use) { |
JonFreeman | 0:23cc72b18e74 | 491 | if (bu.area.a.x < pt.x && bu.area.b.x > pt.x |
JonFreeman | 0:23cc72b18e74 | 492 | && bu.area.a.y < pt.y && bu.area.b.y > pt.y) |
JonFreeman | 0:23cc72b18e74 | 493 | return true; |
JonFreeman | 0:23cc72b18e74 | 494 | } |
JonFreeman | 0:23cc72b18e74 | 495 | return false; |
JonFreeman | 0:23cc72b18e74 | 496 | } |
JonFreeman | 0:23cc72b18e74 | 497 | |
JonFreeman | 0:23cc72b18e74 | 498 | bool keyrelease (int key) |
JonFreeman | 0:23cc72b18e74 | 499 | { |
JonFreeman | 0:23cc72b18e74 | 500 | bool rv = false; |
JonFreeman | 0:23cc72b18e74 | 501 | if (button[key].pressed) { |
JonFreeman | 0:23cc72b18e74 | 502 | rv = true; |
JonFreeman | 0:23cc72b18e74 | 503 | button[key].pressed = false; |
JonFreeman | 0:23cc72b18e74 | 504 | } |
JonFreeman | 0:23cc72b18e74 | 505 | return rv; |
JonFreeman | 0:23cc72b18e74 | 506 | } |
JonFreeman | 0:23cc72b18e74 | 507 | void setpressed (int key, bool torf) |
JonFreeman | 0:23cc72b18e74 | 508 | { |
JonFreeman | 0:23cc72b18e74 | 509 | button[key].pressed = torf; |
JonFreeman | 0:23cc72b18e74 | 510 | } |
JonFreeman | 0:23cc72b18e74 | 511 | void setinuse (int key, bool torf) |
JonFreeman | 0:23cc72b18e74 | 512 | { |
JonFreeman | 0:23cc72b18e74 | 513 | button[key].in_use = torf; |
JonFreeman | 0:23cc72b18e74 | 514 | } |
JonFreeman | 0:23cc72b18e74 | 515 | |
JonFreeman | 0:23cc72b18e74 | 516 | |
JonFreeman | 0:23cc72b18e74 | 517 | int get_button_press (struct point & pt) |
JonFreeman | 0:23cc72b18e74 | 518 | { |
JonFreeman | 0:23cc72b18e74 | 519 | for (int j = 0; j < NUMOF_BUTTONS; j++) |
JonFreeman | 0:23cc72b18e74 | 520 | if (button[j].in_use && is_button_pressed (pt, button[j])) |
JonFreeman | 0:23cc72b18e74 | 521 | return j; |
JonFreeman | 0:23cc72b18e74 | 522 | return -1; |
JonFreeman | 0:23cc72b18e74 | 523 | } |
JonFreeman | 0:23cc72b18e74 | 524 | |
JonFreeman | 0:23cc72b18e74 | 525 | void setup_buttons () |
JonFreeman | 0:23cc72b18e74 | 526 | { |
JonFreeman | 0:23cc72b18e74 | 527 | setup_button (button[SPEEDO_BUT], |
JonFreeman | 0:23cc72b18e74 | 528 | SPEEDO_X - SPEEDO_SIZE, SPEEDO_Y - SPEEDO_SIZE, |
JonFreeman | 0:23cc72b18e74 | 529 | SPEEDO_SIZE * 2, SPEEDO_SIZE * 2, SPEEDO_BODY_COLOUR, LCD_COLOR_RED, " X", "") ; |
JonFreeman | 0:23cc72b18e74 | 530 | setup_button (button[VMETER_BUT], |
JonFreeman | 0:23cc72b18e74 | 531 | 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", "") ; |
JonFreeman | 0:23cc72b18e74 | 532 | setup_button (button[AMETER_BUT], |
JonFreeman | 0:23cc72b18e74 | 533 | 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", "") ; |
JonFreeman | 0:23cc72b18e74 | 534 | setup_button (button[SLIDER], SLIDERX, SLIDERY, SLIDERW, SLIDERH, LCD_COLOR_BLUE, LCD_COLOR_MAGENTA, "", "") ; |
JonFreeman | 0:23cc72b18e74 | 535 | } |
JonFreeman | 0:23cc72b18e74 | 536 | |
JonFreeman | 0:23cc72b18e74 | 537 | |
JonFreeman | 0:23cc72b18e74 | 538 | void SliderGraphic (struct slide & q) { |
JonFreeman | 0:23cc72b18e74 | 539 | int |
JonFreeman | 0:23cc72b18e74 | 540 | colr, |
JonFreeman | 0:23cc72b18e74 | 541 | oldbgcolr = lcd.GetBackColor (), |
JonFreeman | 0:23cc72b18e74 | 542 | oldtxtcolr = lcd.GetTextColor (); |
JonFreeman | 0:23cc72b18e74 | 543 | char txt[4]; |
JonFreeman | 0:23cc72b18e74 | 544 | txt[1] = 0; |
JonFreeman | 0:23cc72b18e74 | 545 | if (q.position > MAX_POS) |
JonFreeman | 0:23cc72b18e74 | 546 | q.position = MAX_POS; |
JonFreeman | 0:23cc72b18e74 | 547 | if (q.position < MIN_POS) |
JonFreeman | 0:23cc72b18e74 | 548 | q.position = MIN_POS; |
JonFreeman | 0:23cc72b18e74 | 549 | if (q.position == NEUTRAL_VAL) |
JonFreeman | 0:23cc72b18e74 | 550 | q.state = NEUTRAL_DRIFT; |
JonFreeman | 0:23cc72b18e74 | 551 | if (q.position > NEUTRAL_VAL) |
JonFreeman | 0:23cc72b18e74 | 552 | q.state = REGEN_BRAKE; |
JonFreeman | 0:23cc72b18e74 | 553 | if (q.position < NEUTRAL_VAL) |
JonFreeman | 0:23cc72b18e74 | 554 | if (q.state == REGEN_BRAKE) { // Ensure transition from BRAKE to RUN passes through NEUTRAL |
JonFreeman | 0:23cc72b18e74 | 555 | q.position = NEUTRAL_VAL; |
JonFreeman | 0:23cc72b18e74 | 556 | q.state = NEUTRAL_DRIFT; |
JonFreeman | 0:23cc72b18e74 | 557 | } |
JonFreeman | 0:23cc72b18e74 | 558 | else |
JonFreeman | 0:23cc72b18e74 | 559 | q.state = RUN; |
JonFreeman | 0:23cc72b18e74 | 560 | if (q.position == MAX_POS) { |
JonFreeman | 0:23cc72b18e74 | 561 | if (q.loco_speed < LOCO_HANDBRAKE_ESCAPE_SPEED) |
JonFreeman | 0:23cc72b18e74 | 562 | q.state = PARK; |
JonFreeman | 0:23cc72b18e74 | 563 | else { |
JonFreeman | 0:23cc72b18e74 | 564 | q.state = REGEN_BRAKE; |
JonFreeman | 0:23cc72b18e74 | 565 | q.position--; |
JonFreeman | 0:23cc72b18e74 | 566 | } |
JonFreeman | 0:23cc72b18e74 | 567 | } |
JonFreeman | 0:23cc72b18e74 | 568 | if (q.position != q.oldpos) { |
JonFreeman | 0:23cc72b18e74 | 569 | // Draw slider background colour rectangle overwriting previous circles |
JonFreeman | 0:23cc72b18e74 | 570 | // Redraw black vertical |
JonFreeman | 0:23cc72b18e74 | 571 | // Draw new circles |
JonFreeman | 0:23cc72b18e74 | 572 | // Write text char |
JonFreeman | 0:23cc72b18e74 | 573 | lcd.SetTextColor(LCD_COLOR_MAGENTA); |
JonFreeman | 0:23cc72b18e74 | 574 | lcd.FillRect (SLIDERX + 1, q.oldpos - BUTTON_RAD, SLIDERW - 2, SLIDERW); |
JonFreeman | 0:23cc72b18e74 | 575 | lcd.SetTextColor(LCD_COLOR_BLACK); |
JonFreeman | 0:23cc72b18e74 | 576 | lcd.FillRect (SLIDERX + (SLIDERW / 2) - 3, 6, 7, SLIDERH - 8); |
JonFreeman | 0:23cc72b18e74 | 577 | q.oldpos = q.position; |
JonFreeman | 0:23cc72b18e74 | 578 | lcd.SetTextColor(LCD_COLOR_WHITE); |
JonFreeman | 0:23cc72b18e74 | 579 | lcd.DrawCircle (CIRC_CTR, q.position, BUTTON_RAD); // seel also FillCircle |
JonFreeman | 0:23cc72b18e74 | 580 | lcd.DrawCircle (CIRC_CTR, q.position, BUTTON_RAD - 1); |
JonFreeman | 0:23cc72b18e74 | 581 | switch (q.state) { |
JonFreeman | 0:23cc72b18e74 | 582 | case RUN: |
JonFreeman | 0:23cc72b18e74 | 583 | txt[0] = 'R'; |
JonFreeman | 0:23cc72b18e74 | 584 | colr = LCD_COLOR_GREEN; |
JonFreeman | 0:23cc72b18e74 | 585 | break; |
JonFreeman | 0:23cc72b18e74 | 586 | case NEUTRAL_DRIFT: |
JonFreeman | 0:23cc72b18e74 | 587 | txt[0] = 'N'; |
JonFreeman | 0:23cc72b18e74 | 588 | colr = LCD_COLOR_BLUE; |
JonFreeman | 0:23cc72b18e74 | 589 | break; |
JonFreeman | 0:23cc72b18e74 | 590 | case REGEN_BRAKE: |
JonFreeman | 0:23cc72b18e74 | 591 | txt[0] = 'B'; |
JonFreeman | 0:23cc72b18e74 | 592 | colr = LCD_COLOR_ORANGE; |
JonFreeman | 0:23cc72b18e74 | 593 | break; |
JonFreeman | 0:23cc72b18e74 | 594 | case PARK: |
JonFreeman | 0:23cc72b18e74 | 595 | txt[0] = 'P'; |
JonFreeman | 0:23cc72b18e74 | 596 | colr = LCD_COLOR_RED; |
JonFreeman | 0:23cc72b18e74 | 597 | break; |
JonFreeman | 0:23cc72b18e74 | 598 | default: |
JonFreeman | 0:23cc72b18e74 | 599 | txt[0] = 'X'; |
JonFreeman | 0:23cc72b18e74 | 600 | colr = LCD_COLOR_CYAN; |
JonFreeman | 0:23cc72b18e74 | 601 | } // End of switch |
JonFreeman | 0:23cc72b18e74 | 602 | lcd.SetTextColor(colr); |
JonFreeman | 0:23cc72b18e74 | 603 | lcd.FillCircle (CIRC_CTR, q.position, BUTTON_RAD - 2); |
JonFreeman | 0:23cc72b18e74 | 604 | lcd.SetBackColor (colr); |
JonFreeman | 0:23cc72b18e74 | 605 | lcd.SetTextColor(LCD_COLOR_YELLOW); |
JonFreeman | 0:23cc72b18e74 | 606 | displaytext(SLIDERX + 17, q.position - 10, 4, txt); // largest font |
JonFreeman | 0:23cc72b18e74 | 607 | lcd.SetBackColor (LCD_COLOR_BLACK); |
JonFreeman | 0:23cc72b18e74 | 608 | } // End of else |
JonFreeman | 0:23cc72b18e74 | 609 | lcd.SetTextColor (oldtxtcolr); |
JonFreeman | 0:23cc72b18e74 | 610 | lcd.SetBackColor (oldbgcolr); |
JonFreeman | 0:23cc72b18e74 | 611 | // pc.printf ("SliderG %d, %d, %d\r\n", q.position, q.oldpos, q.state); |
JonFreeman | 0:23cc72b18e74 | 612 | } |
JonFreeman | 0:23cc72b18e74 | 613 | |
JonFreeman | 0:23cc72b18e74 | 614 | |
JonFreeman | 0:23cc72b18e74 | 615 | |
JonFreeman | 0:23cc72b18e74 | 616 |