A simple meter using Adafruit 2.8 TFT with touch v2

Dependencies:   SPI_STMPE610 UniGraphic mbed vt100

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers meter.cpp Source File

meter.cpp

00001 #include "mbed.h"
00002 #include <math.h>
00003 #include <string.h>
00004 #include "ILI9341.h"
00005 #include "Arial28x28.h"
00006 #include "meter.h"
00007 #include "main.h"
00008 
00009 #ifndef M_PI
00010 #define M_PI 3.141593
00011 #endif
00012 
00013 extern ILI9341      *tft ;
00014 extern meter        *tacho ;
00015 double SIN[451] ; /* sin table for 45 to 90 degrees in 0.1 deg step */
00016 double COS[451] ; /* cos table for 45 to 90 degrees in 0.1 deg step */
00017 
00018 static void fillTriTable(void)
00019 {
00020     double theta ;
00021     int i ;
00022     for (i = 0 ; i <= 450 ; i++ ) {
00023         theta = M_PI * (((double)(i + 450))/1800.0) ;
00024         SIN[i] = sin( theta ) ;
00025         COS[i] = cos( theta ) ;
00026     }
00027 }
00028 
00029 meter::meter(int x, int y, int width, int height, float min, float max) 
00030 {
00031     _x = x ;
00032     _y = y ;
00033     _w = width ;
00034     _h = height ;
00035     _min = min ;
00036     _max = max ;
00037     _center_x = _x + _w / 2 ;
00038     _center_y = _y + (2 * _h) / 3 ;
00039     fillTriTable() ;
00040 }
00041 
00042 meter::~meter(void) 
00043 {
00044 }
00045 
00046 void meter::drawFrame(void)
00047 {
00048     tft->BusEnable(true) ;
00049     tft->fillrect(_x, _y, _x+ _w - 1, _y+(2 * _h)/3 - 1, White) ;
00050     tft->fillrect(_x, _y+(2 * _h)/3 - 1, _x + _w - 1, _y + _h - 1, Black) ;
00051     tft->rect(_x, _y, _x + _w - 1, _y + _h - 1, Green) ;
00052     tft->BusEnable(false) ;
00053 }
00054 
00055 void meter::drawScale(void)
00056 {
00057     int x1, x2, y1, y2 ;
00058     double radius ;
00059     double append ;
00060     radius = _w / 2.0 ;
00061     tft->BusEnable(true) ;
00062     for (int i = 0 ; i < 450 ; i += 45 ) {
00063         x1 = (radius * COS[i] + 0.5) ;
00064         y1 = (radius * SIN[i] + 0.5) ;
00065         if ((i % 10) == 5) {
00066             append = 5 ;
00067         } else {
00068             append = 10 ;
00069         }
00070         x2 = ((radius + append) * COS[i] + 0.5) ;
00071         y2 = ((radius + append) * SIN[i] + 0.5) ;
00072         tft->line(_center_x + x1, _center_y - y1, _center_x + x2, _center_y - y2, Black) ;
00073         tft->line(_center_x - x1, _center_y - y1, _center_x - x2, _center_y - y2, Black) ;
00074     }
00075     tft->line(_center_x, _center_y - radius, _center_x, _center_y - (radius + 10), Black) ;
00076     tft->BusEnable(false) ;
00077 }
00078 
00079 void meter::drawHand(float value)
00080 {
00081     static int prev_x1 = 0, prev_x2 = 0, prev_y1 = 0, prev_y2 = 0 ;
00082     int x1, x2, y1, y2 ;
00083     double theta ;
00084     double radius = _w / 20.0 ;
00085     double append = 8.0 * (_w / 20.0)  ;
00086     int i ;
00087     
00088     theta = 90.0 - (90.0 * (value / _max)) ;
00089     if (theta < 0.0) { theta = 0.0 ; }
00090     if (theta > 90.0) { theta = 90.0 ; }
00091     if (theta > 45.0) {
00092         i = (10.0 * (90.0 - theta) + 0.5) ; 
00093         x1 = _center_x - (radius * COS[i] + 0.5) ;
00094         x2 = _center_x - ((radius + append) * COS[i] + 0.5) ;
00095     } else {
00096         i = (10.0 * theta + 0.5) ;
00097         x1 = _center_x + (radius * COS[i] + 0.5) ;
00098         x2 = _center_x + ((radius + append) * COS[i] + 0.5) ;
00099     }
00100 
00101     y1 = _center_y - (radius * SIN[i] + 0.5) ;
00102     y2 = _center_y - ((radius + append) * SIN[i] + 0.5) ;
00103     tft->BusEnable(true) ;
00104     tft->line(prev_x1, prev_y1, prev_x2, prev_y2, White) ; /* erase prev */
00105     tft->line(x1, y1, x2, y2, Black) ;                     /* draw current */
00106     tft->BusEnable(false) ;
00107     prev_x1 = x1 ;
00108     prev_x2 = x2 ;
00109     prev_y1 = y1 ;
00110     prev_y2 = y2 ;
00111 }
00112 
00113 void meter::draw(float value) 
00114 {
00115     tft->BusEnable(true) ;
00116     drawFrame() ;
00117     drawScale() ;
00118     drawHand(value) ;
00119     drawValue(value) ;
00120     tft->BusEnable(false) ;
00121 }
00122 
00123 void meter::drawValue(float value)
00124 {
00125     char str[32] ;
00126     int v1, v2 ;
00127     v1 = (int)value ;
00128     v2 = ((int)(1000.0 * value) % 1000) ;
00129     sprintf(str, "%d.%03d V", v1, v2) ;
00130     tft->BusEnable(true) ;
00131     tft->locate(80, 190) ;
00132     tft->printf(str) ;
00133     wait(0.01) ;
00134     tft->BusEnable(false) ;
00135 }
00136 
00137 void meter::update(float value) 
00138 {
00139     tft->BusEnable(true) ;
00140     drawHand(value) ;
00141     drawValue(value) ;
00142     tft->BusEnable(false) ;
00143 }