A simple oscilloscope using Adafruit 2.8" TFT with touch. Runs on FRDM-KL25Z, FRDM-K22F, FRDM-K64F, NUCLEO-F411RE. 2 channel analog inputs with 4 trigger modes and time division.

Dependencies:   SPI_STMPE610 UniGraphic mbed vt100

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers view.cpp Source File

view.cpp

00001 /** mbed oscilloscope my implementation of a oscillo scope
00002  * Copyright (c) 2014, 2015 Motoo Tanaka @ Design Methodology Lab
00003  *
00004  * view.cpp
00005  *
00006  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00007  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00008  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00009  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00010  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00011  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00012  * THE SOFTWARE.
00013  */
00014 #include "mbed.h"
00015 #include <ILI9341.h>
00016 #include "SPI_STMPE610.h"
00017 #include "Arial12x12.h"
00018 #include "Arial24x23.h"
00019 #include "Arial28x28.h"
00020 #include "Arial43x48_numb.h"
00021 #include "vt100.h"
00022 #include "TFTMenu.h"
00023 #include "main.h"
00024 #include "trig.h"
00025 #include "view.h"
00026 
00027 int pane_w = 200 ;
00028 int pane_h = 70 ; // height per channel
00029 int head_h = 20 ; // header height
00030 int foot_h = 20 ; // footer height
00031 int right_margin = 10 ;
00032 int left_margin = 30 ;
00033 
00034 void initTFT(void)
00035 {
00036     //Configure the display driver
00037     TFT.BusEnable(true) ;
00038     TFT.FastWindow(true) ;
00039     TFT.background(Black);
00040     TFT.foreground(White);
00041     wait(0.01) ;
00042     TFT.cls();
00043     TFT.BusEnable(false) ;
00044 }
00045 
00046 
00047 void eraseChFrame(int ch)
00048 {
00049     int x1, x2, y1, y2 ;
00050     x1 = left_margin ;
00051     x2 = left_margin + pane_w ;
00052     y1 = head_h + (pane_h + 5) * ch ;
00053     y2 = y1 + pane_h ;
00054     TFT.BusEnable(true) ;
00055     TFT.fillrect(x1,y1,x2, y2, Black) ;
00056     TFT.BusEnable(false) ;
00057 }
00058 
00059 void eraseGraphFrames(void)
00060 {
00061     int ch ;
00062     TFT.BusEnable(true) ;
00063     for (ch = 0 ; ch < numAnalogIn ; ch++) {
00064         eraseChFrame(ch) ;
00065     }
00066     TFT.BusEnable(false) ;
00067 }
00068 
00069 void drawChFrame(int ch)
00070 {
00071     int x1, x2, y1, y2,y_offset ;
00072     x1 = left_margin ;
00073     x2 = left_margin + pane_w ;
00074     y1 = head_h + (pane_h + 5) * ch ;
00075     y2 = y1 + pane_h ;
00076     TFT.BusEnable(true) ;
00077     TFT.set_font((unsigned char*) Arial12x12);
00078     TFT.background(Black) ;
00079     TFT.foreground(White) ;
00080     TFT.locate(5, y1+5) ;
00081     TFT.printf("3.0") ;
00082     TFT.locate(15, (y1+y2)/2) ;
00083     TFT.printf("V") ;
00084     TFT.locate(5, y2-10) ;
00085     TFT.printf("0.0") ;
00086     TFT.rect(x1,y1,x2,y2,Blue) ;
00087     y_offset = head_h + 1;
00088  
00089     for (int i = 0 ; i < pane_w ; i += 10) {
00090         x1 = left_margin + i ;
00091         x2 = x1 ;
00092         if ((i % 100) == 0) {
00093             y1 = head_h - 5 ;
00094         } else {
00095             y1 = head_h - 2 ;
00096         }
00097         y2 = head_h ;
00098         TFT.line(x1, y1, x2, y2, Blue) ;
00099         y1 = head_h + (pane_h + 5) * 2 - 5 ;
00100         if ((i % 100) == 0) {
00101             y2 = y1 + 5 ;
00102         } else {
00103             y2 = y1 + 2 ;
00104         }
00105         TFT.line(x1, y1, x2, y2, Blue) ;
00106     }
00107 
00108     for (float f = 0.0 ; f < vref ; f += 1.0) {
00109         y_offset = head_h + 1;
00110         y1 = ((pane_h - 2) * (1.0 - f/vref)) + y_offset ;
00111         y2 = y1 ;
00112         x1 = left_margin - 3 ;
00113         x2 = left_margin ;
00114         TFT.line(x1, y1, x2, y2, Blue) ;
00115         y_offset = head_h + (pane_h + 5) + 1;
00116         y1 = ((pane_h - 2) * (1.0 - f/vref)) + y_offset  ;
00117         y2 = y1 ;
00118         TFT.line(x1, y1, x2, y2, Blue) ;
00119     }
00120     TFT.BusEnable(false) ;
00121 }
00122 
00123 bool inChFrame(int ch, int x, int y)
00124 {
00125     bool result = false ;
00126     int x1, x2, y1, y2 ;
00127     x1 = left_margin ;
00128     x2 = left_margin + pane_w ;
00129     y1 = head_h + (pane_h + 5) * ch ;
00130     y2 = y1 + pane_h ;
00131     if ((x1 < x)&&(x < x2)&&(y1 < y)&&(y < y2)) { // on 5-Mar-2015 '=' removed
00132         result = true ;
00133     }
00134     return( result ) ;
00135 }
00136 
00137 void plotCh_line(int turn, int ch, int index, int color)
00138 {
00139     int x[2], y[2] ;
00140     int y_offset, data_pos, prev_pos ;
00141     
00142     y_offset = head_h + (pane_h + 5) * ch + 1;
00143     data_pos = (bor[turn] + index) % memLength ;
00144     prev_pos = (memLength + bor[turn] + index - 1) % memLength ;
00145     
00146     x[1] = left_margin + index + 1; 
00147     y[1] = ((pane_h - 2) * (1.0 - u2f(udata[turn][ch][data_pos]))) + y_offset ;
00148 
00149     if (index == 0) {
00150         x[0] = x[1] ;
00151         y[0] = y[1] ;
00152     } else {
00153         x[0] = left_margin + index ;
00154         y[0] = ((pane_h - 2) * (1.0 - u2f(udata[turn][ch][prev_pos]))) + y_offset ;
00155     }
00156     TFT.line(x[0],y[0],x[1],y[1], color) ;
00157 }
00158 
00159 void drawGraphFrames(void)
00160 {
00161     TFT.BusEnable(true) ;
00162     for (int i = 0 ; i < numAnalogIn ; i++ ) {
00163         drawChFrame(i) ;
00164     }
00165     TFT.BusEnable(false) ;
00166 }
00167 
00168 void drawChart(void)
00169 {
00170     int i, ch ;
00171     if (!frame_full) {
00172         return ;
00173     }
00174     if (mode == MODE_RUN) {
00175         timer.detach() ;
00176     }
00177 
00178     TFT.BusEnable(true) ;
00179     for (i = 0 ; i < memLength ; i++ ) {
00180         for (ch = 0 ; ch < numAnalogIn ; ch++ ) {
00181             plotCh_line(prev_page, ch, i, Black) ; // erase prev
00182             plotCh_line(page, ch, i, White) ;
00183         }
00184     }
00185     TFT.BusEnable(false) ;
00186     prev_page = page ;
00187     page = (page + 1)%2 ;
00188     sampling_status = ST_PRE_TRIG ;
00189     frame_full = false ;
00190     trig_index = 0 ;
00191     data_index = 0 ;
00192     if (mode == MODE_RUN) {
00193         timer.attach_us(&sampleAD, us_interval) ;
00194     }
00195 }
00196 
00197 void printMode(void)
00198 {
00199     TFT.BusEnable(true) ;
00200     TFT.locate(80, 200) ;
00201     TFT.background(Black) ;
00202 
00203     if (mode == MODE_STOP) {
00204         TFT.foreground(Yellow) ;
00205         TFT.printf(" Stopped") ;
00206     } else if (mode == MODE_RUN) {
00207         TFT.foreground(White) ;
00208         TFT.printf(" Running") ;
00209     }
00210     TFT.BusEnable(false) ;
00211 }
00212 
00213 void printTimeDiv(void)
00214 {
00215     char str[32] ;
00216     int ival, dotval ;
00217     if (us_interval < 100) { // 10 * us_interval < 1ms
00218         sprintf(str, " %3d us/div", 10 *us_interval) ;
00219     } else if (us_interval < 100000) { // 10 * us_interval >= 1ms
00220         ival = us_interval / 100 ;
00221         dotval = us_interval % 100 ;
00222         sprintf(str, " %3d.%0d ms/div", ival, dotval) ;
00223     }
00224     TFT.BusEnable(true) ;
00225     TFT.fillrect(65, 240, 175, 260, Black) ;
00226         
00227     TFT.background(Black) ;
00228     TFT.foreground(White) ;
00229 
00230     TFT.locate(65, 240) ;
00231     TFT.printf(str) ;
00232     TFT.BusEnable(false) ;
00233 }
00234 
00235 void printTrigMode(void)
00236 {
00237     char str[60] ;
00238     TFT.BusEnable(true) ;
00239     TFT.fillrect(65, 280, 235, 310, Black) ;
00240  
00241     TFT.background(Black) ;
00242     TFT.foreground(White) ;
00243 
00244     if (trig_mode == TRIG_MODE_NONE) {
00245         sprintf(str, "%6s",
00246         trig_name[trig_mode]) ;
00247     } else {
00248         sprintf(str, "%6s ch%1d (%d, %.1f)",
00249         trig_name[trig_mode], trig_ch+1, trig_pos, trig_level) ;
00250     }
00251     TFT.locate(65, 280) ;
00252     TFT.printf(str) ;
00253     TFT.BusEnable(false) ;
00254 }
00255 
00256 void printTrigLevel(void)
00257 {
00258     char str[16] ;
00259     sprintf(str, " %.1f", trig_level) ;
00260     TFT.BusEnable(true) ;
00261     TFT.locate(140, 280) ;
00262     TFT.background(Black) ;
00263     TFT.foreground(White) ;
00264     TFT.printf(str) ;
00265     TFT.BusEnable(false) ;
00266 }
00267 
00268 void eraseTrigMark(void)
00269 {
00270     int x1, x2, y1, y2 ;
00271     TFT.BusEnable(true) ;
00272     x1 = left_margin - 3 ;
00273     x2 = left_margin + pane_w + 3 ;
00274     y1 = 1 ;
00275     y2 = head_h - 5 ;
00276     TFT.fillrect(x1,y1,x2, y2, Black) ;
00277     y1 = (head_h + (pane_h + 5)*2) + 5  ;
00278     y2 = y1 + 13 ;
00279     TFT.fillrect(x1,y1,x2, y2, Black) ;
00280     x1 = left_margin + pane_w + 1 ;
00281     x2 = x1 + 10 ;
00282     y1 = 0 ;
00283     y2 = head_h + (pane_h + 5) * (2) + 1;
00284     TFT.fillrect(x1, y1, x2, y2, Black) ;
00285     TFT.BusEnable(false) ;
00286 }
00287 
00288 void drawTrigPos()
00289 {
00290     uint16_t color = Green ;
00291     int x1, x2, y1, y2 ;
00292     int y_offset ;
00293 // draw down arrow
00294     TFT.BusEnable(true) ;
00295     x1 = left_margin + trig_pos + 1 ;
00296     x2 = x1 ;
00297     y1 = 5 ;
00298     y2 = head_h - 8 ;
00299     TFT.line(x1, y1, x2, y2, color) ;
00300     x1 = x2 - 3 ;
00301     y1 = y2 - 4 ;
00302     TFT.line(x1, y1, x2, y2, color) ;
00303     x1 = x2 + 3 ;
00304     TFT.line(x1, y1, x2, y2, color) ;
00305 // draw up arrow
00306     x1 = x2 ;
00307     y1 = (head_h + (pane_h + 5)*2) + 5  ;
00308     y2 = y1 + 7 ;
00309     TFT.line(x1, y1, x2, y2, color) ;
00310     x2 = x1 - 3 ;
00311     y2 = y1 + 3 ;
00312     TFT.line(x1, y1, x2, y2, color) ;
00313     x2 = x1 + 3 ;
00314     TFT.line(x1, y1, x2, y2, color) ;
00315 // draw level mark
00316     x1 = left_margin + pane_w + 3 ;
00317     x2 = x1 + 7 ;
00318     y_offset = head_h + (pane_h * (trig_ch+1)) +  (5 * trig_ch) - 1;
00319     y1 = y_offset - ((pane_h - 2) * (trig_level/vref)) ;
00320     y2 = y1 ;
00321     TFT.line(x1, y1, x2, y2, color) ;
00322     x2 = x1 + 3 ;
00323     y2 = y1 - 3 ;
00324     TFT.line(x1, y1, x2, y2, color) ;
00325     y2 = y1 + 3 ;
00326     TFT.line(x1, y1, x2, y2, color) ;
00327     TFT.BusEnable(false) ;
00328 // printf("trig_ch = %d, trig level = %.2f, y1 = %d yoffset = %d\n", 
00329 //         trig_ch, trig_level, y1, y_offset) ;
00330 }
00331 
00332 void drawTrigMark(void)
00333 {
00334     eraseTrigMark() ;
00335     switch(trig_mode) {
00336     case TRIG_MODE_NONE:
00337         break ;
00338     case TRIG_MODE_RISE:
00339     case TRIG_MODE_FALL:   
00340     case TRIG_MODE_LEVEL:
00341         drawTrigPos() ;
00342         break ;
00343     default:
00344         printf("Unkown trigger mode %d\n\r",trig_mode) ;
00345         break ;
00346     }
00347 }