Dual CANbus monitor and instrumentation cluster supporting ILI9341 display controller
Dependencies: SPI_TFTx2_ILI9341 TOUCH_TFTx2_ILI9341 TFT_fonts mbed
Fork of CANary by
displayModes.cpp
- Committer:
- TickTock
- Date:
- 2013-06-15
- Revision:
- 97:a25940fd7b5b
- Parent:
- 96:a6c6a6fd1d28
- Child:
- 99:c05abf8e1cdc
File content as of revision 97:a25940fd7b5b:
//displayModes.cpp #include "displayModes.h" char sTemp1[40]; char sTemp2[16]; void printLast (bool force, bool showButtons){ CANMessage msg; tt.locate(0,6); tt.foreground(Red); tt.background(Yellow); if(force) tt.cls(); // Just clear screen if forced - always update display tt.set_font((unsigned char*) Arial12x12_prop); // select the font for(int i=0; i<19; i++){ msg = lastMsg[i+indexOffset]; printf("%03x : %02x %02x %02x %02x %02x %02x %02x %02x \n",msg.id,msg.data[0],msg.data[1],msg.data[2],msg.data[3],msg.data[4],msg.data[5],msg.data[6],msg.data[7]); } if((sMode==1)&&showButtons){ tt.foreground(Yellow); tt.background(DarkCyan); tt.set_font((unsigned char*) Arial12x12); showButton(0,0," <up>","",4,4); showButton(2,0,"<down>","",4,4); } } void printChanged (bool force, bool showButtons){ CANMessage msg; unsigned char i,j; tt.locate(0,6); tt.foreground(Red); tt.background(Yellow); if(force) tt.cls(); // Just clear screen if forced - always update display tt.set_font((unsigned char*) Arial12x12_prop); // select the font i=0; j=indexOffset; do{ j=j<99?j+1:j; if(msgChanged[j]>0){ msg = lastMsg[j]; printf("%03x : %02x %02x %02x %02x %02x %02x %02x %02x \n",msg.id,msg.data[0],msg.data[1],msg.data[2],msg.data[3],msg.data[4],msg.data[5],msg.data[6],msg.data[7]); i++; }// if changed }while(i<19&&j<99); if((sMode==1)&&showButtons){ tt.foreground(Yellow); tt.background(DarkCyan); tt.set_font((unsigned char*) Arial12x12); showButton(0,0," <up>","",4,4); showButton(2,0," <down>","",4,4); showButton(1,0," Reset","Baseline",4,4); } } void printLog (bool force, bool showButtons){ static unsigned char lastldl = 0; unsigned char ldl=displayLoc; if(force||ldl!=lastldl){ //only update if changed tt.foreground(Amber); tt.background(Black); tt.cls(); tt.locate(0,6); tt.set_font((unsigned char*) Arial12x12); for(int i=0; i<19; i++){ printf("%s",displayLog[ldl]); ldl=ldl>17?0:ldl+1; } } lastldl=ldl; } void mainDisplay (bool force, bool showButtons){ unsigned short gids, SOC, packV; static unsigned short lgids=0, lSOC=0, lpackV=0, maxPS=0; static unsigned char lbattTemp_x4=0; static float lkW=0, laccV=0, lmpkWh=0; CANMessage msg; msg = lastMsg[indexLastMsg[0x5bc]]; //Get gids gids = (msg.data[0]<<2)+(msg.data[1]>>6); msg = lastMsg[indexLastMsg[0x55b]]; //Get SOC SOC = (msg.data[0]<<2)+(msg.data[1]>>6); msg = lastMsg[indexLastMsg[0x1db]]; //Get pack volts packV = (msg.data[2]<<2)+(msg.data[3]>>6); tt.background(Navy); tt.foreground(Yellow); tt.set_font((unsigned char*) Arial28x28); if(force) tt.cls(); if(skin==ttSkin){ if(force||gids!=lgids||mpkWh[dtePeriod]!=lmpkWh){ tt.locate(10,10); printf("%4d gids \n",gids); if(debugMode){ if(pointerSep>maxPS){maxPS=pointerSep;} tt.locate(10,70); printf("%3d sep %3d max\n",pointerSep,maxPS); } tt.locate(10,40); printf("%4.1f kWh \n",(float)(gids-5)*0.075); tt.set_font((unsigned char*) SCProSB31x55); tt.foreground(Green); tt.locate(60,96); printf("%4.1f mi \n",mpkWh[dtePeriod]*((float)(gids-5)*.075)); lgids=gids; lmpkWh=mpkWh[dtePeriod]; tt.foreground(Yellow); tt.set_font((unsigned char*) Arial28x28); } if(force||SOC!=lSOC){ tt.locate(200,10); printf("%4.1f%s\n",(float)SOC/10,"% "); lSOC=SOC; } if(force||packV!=lpackV){ tt.locate(200,200); printf("%4.1fV \n",(float)packV/2); lpackV=packV; } if(force||battTemp_x4!=lbattTemp_x4){ tt.locate(200,170); printf("%4.1fF\n",(float)battTemp_x4*9/20+32); lbattTemp_x4=battTemp_x4; } if(force||accV!=laccV){ tt.locate(20,200); printf("%3.1fV \n",accV); laccV=accV; } if(force||kW[0]!=lkW){ tt.locate(180,40); printf("%3.2fkW \n",kW[0]); //printf("%3.1f mpkWh \n",mpkWh[0]); lkW=kW[0]; } }else {//if(skin==ggSkin){ if(force||gids!=lgids){ tt.locate(10,10); printf("%4d GIDs \n",gids); tt.locate(40,40); // gg - add GIDs Percent of 281 printf("%4.1f%s \n", (float)gids*0.355872, "% ") ; tt.locate(20,70); //printf("%4.1f kWh \n",(float)gids*0.08); // is input, not usable printf("%4.1f kwh \n",(float)gids*0.075); // gg - closer to usable tt.set_font((unsigned char*) SCProSB31x55); tt.foreground(Green); //tt.locate(60,96); tt.locate(60,116); // gg - move down a little printf("%4.1f mi \n",(float)(gids-5)*0.31); // Approx for now lgids=gids; tt.foreground(Yellow); tt.set_font((unsigned char*) Arial28x28); } if(force||SOC!=lSOC){ tt.locate(200,10); printf("%4.1f%s\n",(float)SOC/10,"% "); lSOC=SOC; } if(force||packV!=lpackV){ tt.locate(200,200); printf("%4.1fV \n",(float)packV/2); lpackV=packV; } if(force||accV!=laccV){ tt.locate(20,200); printf("%3.1fV \n",accV); laccV=accV; } if(force||kW[0]!=lkW){ tt.locate(160,40); // gg - move left to keep from wrap printf("%3.2fkw \n",kW[0]); // use small w to save space lkW=kW[0]; } } } void braking (bool force, bool showButtons, bool prdata=false){ unsigned long targetBraking, regenBraking; static unsigned long maxTarget = 1000, maxRegen = 1000, tardivreg_x1000 = 1000; unsigned long temp; static unsigned char lastPressure[4] = {200,200,200,200}; unsigned char i,r,t; static unsigned char lr=0, lt=0; signed short steering; unsigned short s; static unsigned short ls; unsigned char throttle; static unsigned char lthrottle; short steerOutBounds = 0 ; CANMessage msg; //--------------- msg = lastMsg[indexLastMsg[0x180]]; //Get Throttle position throttle = msg.data[5]; // ---- steering ---- msg = lastMsg[indexLastMsg[0x002]]; //Get Steering angle steering = (msg.data[1]<<8)+msg.data[0]; if(skin==ttSkin){ s= (unsigned short) ((steering/10)+155)%310; // this modulo wraps display }else{// if(skin==ggSkin){ // do not go off screen left or right. gg - steering short ss = (short) ((steering/15)+160); // less gain 10 -> 15 if(ss<0) { ss=0; steerOutBounds = 1; } if(ss>310) { ss=310; steerOutBounds = 1; } s = (unsigned short) ss; } //-------------- msg = lastMsg[indexLastMsg[0x1ca]]; //Get brake pressure tt.background(Navy); if (force) { tt.cls(); tt.rect(0,111,170,239,White); tt.line(0,207,170,207,White); tt.line(0,175,170,175,White); tt.line(0,143,170,143,White); lastPressure[0] = 200; lastPressure[1] = 200; lastPressure[2] = 200; lastPressure[3] = 200; } // display the steering position small square if (s!=ls){ // steering position has moved //tt.fillrect(ls,5,ls+9,14, Navy); // blank old position //---- gg - steering red // box is blanked by top of Braking bar, so move up 5 tt.fillrect(ls,0,ls+9,9, Navy); // blank old position if( steerOutBounds != 0 ) // draw out-of-bounds as a red box tt.fillrect(s,0,s+9,9, Red); // draw out-of-bounds position else tt.fillrect(s,0,s+9,9, White); // draw new in-bounds position //---- //tt.foreground(Yellow); //tt.set_font((unsigned char*) Arial28x28); //tt.locate(10,40); //printf("%d %d \n",s,ls); ls=s; } if (throttle!=lthrottle){ if (throttle>239) throttle=239; if(throttle<lthrottle){ tt.fillrect(280,239-lthrottle,310,239-throttle,Navy); }else{ tt.fillrect(280,239-throttle,310,239,Yellow); } lthrottle=throttle; } // plot bar graph for each wheel pressure for (i=0; i<4; i++){ if (msg.data[i]<239) { if (msg.data[i]>lastPressure[i]){ tt.fillrect(10+40*i,239-msg.data[i],40+40*i,239,Red); } else if (msg.data[i]<lastPressure[i]) { tt.fillrect(10+40*i,238-lastPressure[i],40+40*i,238-msg.data[i],Navy); } lastPressure[i]=msg.data[i]; } } msg = lastMsg[indexLastMsg[0x1cb]]; //Get Target and Regen regenBraking = (msg.data[0]<<3)+(msg.data[1]>>5); targetBraking = (msg.data[2]<<3)+(msg.data[3]>>5); if (targetBraking<2045){ if ((targetBraking>50)&&(regenBraking>50)){ temp = targetBraking; temp *= 1000; temp /= regenBraking; if (temp<tardivreg_x1000) tardivreg_x1000=temp; } if (targetBraking>maxTarget) maxTarget=targetBraking; if (regenBraking>maxRegen) maxRegen=regenBraking; temp = targetBraking; temp *=200; temp /= maxTarget; t = (char) temp; if (t>200) t=200; temp = regenBraking; temp *= tardivreg_x1000; temp /= maxTarget; temp /= 5; // 1000/200=5 r = (char) temp; if (r>200) r=200; if(lr!=r&&prdata){ tt.foreground(Yellow); tt.set_font((unsigned char*) Arial28x28); tt.locate(100,40); printf("%d %d \n",regenBraking,maxRegen); tt.locate(100,70); printf("%3.1f (%3.1f%s) \n",(float)tardivreg_x1000/10,(float)regenBraking*tardivreg_x1000/targetBraking/10,"%"); } if(lt!=t&&prdata){ tt.foreground(Yellow); tt.set_font((unsigned char*) Arial28x28); tt.locate(100,10); printf("%d %d \n",targetBraking,maxTarget); } if (r>t) t=r; //Should never happen if((lr!=r||lt!=t)&&!prdata){ tt.fillrect(190,10,260,239-t,Navy); tt.fillrect(190,239-t,260,239-r,Red); tt.fillrect(190,239-r,260,239,Green); } lt=t; lr=r; } } void cpData(bool force, bool showButtons){ short unsigned max, min, jv, i, bd; unsigned avg; static char step=0; // counter to allow incremental update if(force){ tt.foreground(White); tt.background(Navy); tt.set_font((unsigned char*) Arial12x12_prop); // select the font max=0; min=9999; avg=0; for(i=0; i<96; i++){ bd=(battData[i*2+3]<<8)+battData[i*2+4]; avg+=bd; if(bd>max) max=bd; if(bd<min) min=bd; } avg /= 96; if(min<3713) { jv=avg-(max-avg)*1.5; } else { // Only compute judgement value if min cellpair meets <= 3712mV requirement jv=0; } switch(step){ case 0: tt.cls(); showCP=true; break; case 1: tt.locate(0,6); // BatDataBaseG4 * 7 = 224 printf(" MAX MIN AVG CVLI T1 T2 T3 T4\n %04d %04d %04d %04d %02dC %02dC %02dC %02dC\n\n", max,min,avg,jv, battData[224+5],battData[224+8],battData[224+11],battData[224+14]); tt.rect(8+0*41,16,40+0*41,28,Green); tt.rect(8+1*41,16,40+1*41,28,Yellow); //tt.rect(8+2*41,16,40+2*41,28,White); tt.rect(8+3*41,16,40+3*41,28,Red); break; default: tt.locate(0,36+(step-2)*48); for(i=(step-2)*4; i<(step-1)*4; i++){ printf("%02d-%02d : %04d %04d %04d %04d %04d %04d\n", i*6+1,i*6+6, (battData[i*12+3]<<8)+battData[i*12+4],(battData[i*12+5]<<8)+battData[i*12+6], (battData[i*12+7]<<8)+battData[i*12+8],(battData[i*12+9]<<8)+battData[i*12+10], (battData[i*12+11]<<8)+battData[i*12+12],(battData[i*12+13]<<8)+battData[i*12+14]); } for(i=(step-2)*24; i<(step-1)*24; i++){ bd=(battData[i*2+3]<<8)+battData[i*2+4]; if(bd>0){ if(bd==max) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Green); //if(bd==avg) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,White); if(bd==min) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Yellow); if(bd<jv) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Red); } } } step=step<5?step+1:0; if(step==0){ showCP=false; } } if((sMode==1)&&showButtons){ tt.foreground(Yellow); tt.background(DarkCyan); tt.set_font((unsigned char*) Arial12x12); showButton(1,0,"Request","CP Data",4,4); } } //---------------- // gg - index void showIndex(bool force, bool showButtons){ if(force){ tt.foreground(White); tt.background(Navy); //tt.set_font((unsigned char*) Arial12x12_prop); // select the font tt.cls(); // add the buttons to GoTo to other screens tt.foreground(Yellow); tt.background(DarkCyan); tt.set_font((unsigned char*) Arial12x12); // top row showButton(0,0," GoTo"," Main",4,4); showButton(1,0," GoTo"," Brake",4,4); showButton(2,0," GoTo"," EFF",4,4); showButton(3,0," GoTo"," DTE",4,4); // middle row showButton(0,1," GoTo","CP Data",4,4); showButton(1,1," GoTo","CP Hist",4,4); showButton(2,1," GoTo","CP Bars",4,4); // bottom (not Nav) row showButton(0,2," GoTo"," Config",4,4); showButton(1,2," GoTo","Playback",4,4); showButton(2,2," GoTo","Set Time",4,4); showButton(3,2," GoTo"," Log",4,4); showCP=false; } if(sMode==1&&showButtons){ tt.foreground(Yellow); tt.background(DarkCyan); tt.set_font((unsigned char*) Arial12x12); // do nothing here? } } //---------------- // gg - cpbars void cpBarPlot(bool force, bool showButtons){ short unsigned max, min, jv, i, bd; unsigned avg; short unsigned nBar[96] ; // bar height over min if(force){ tt.foreground(White); tt.background(Navy); tt.set_font((unsigned char*) Arial12x12_prop); // select the font max=0; min=9999; avg=0; // calc each cell-pair voltage, find max and min for(i=0; i<96; i++){ bd=(battData[i*2+3]<<8)+battData[i*2+4]; nBar[i] = bd; // init to bar height avg+=bd; if(bd>max) max=bd; if(bd<min) min=bd; } avg /= 96; if(min<3713) { jv=avg-(max-avg)*1.5; } else { // Only compute judgement value if min cellpair meets <= 3712mV requirement jv=0; } //------------------ tt.cls(); // show as vertical bar plot int xWinMin = 26; int xWinMax = 316; int yWinMin = 50; int yWinMax = 150; // draw the Bar Graph Frame, 2 pixels wide tt.rect( xWinMin-1,yWinMin-1, xWinMax+1,yWinMax+1,Red); tt.rect( xWinMin-2,yWinMin-2, xWinMax+2,yWinMax+2,Green); // bar heights int height = yWinMax - yWinMin ; int iBarValMax = max - min ; // zero to N //---------------- if( iBarValMax == 0 ) { // for testing min = 3501 ; //max = min + 95*2 ; // for tall values max = min + 95/4 ; // for small values avg = ( max + min ) / 2; iBarValMax = max - min ; // zero to N for(int i=0; i<96; i++) { //nBar[i] = i*2 + min ; // test tall values nBar[i] = i/4 + min ; // test small values } } //--------------- float nBarScale = float(height) / iBarValMax ; if( nBarScale < 0.1 ) nBarScale = 0.1 ; // do the Bar-height scaling for(int i=0; i<96; i++){ nBar[i] -= min ; // now, 0 to N = iBinValMax nBar[i] *= nBarScale ; // scale, as needed } // values, for now // BatDataBaseG4 * 7 = 224 tt.locate( 0, yWinMax+40 ); printf(" MAX MIN AVG CVLI T1 T2 T3 T4\n %04d %04d %04d %04d %02dC %02dC %02dC %02dC\n\n", max,min,avg,jv, battData[224+5],battData[224+8], battData[224+11],battData[224+14]); // label the X axis (approximate) tt.locate( 2, yWinMax+5); printf("%04d", min ); //tt.locate( 2, yWinMin-14 ); printf("%04d = %04d from %1.4f", max, int( height / nBarScale ) + min, nBarScale ); tt.locate( 2, yWinMin-14 ); printf("%04d = (%d) mv range.", max , max - min ); //--------------- // show the bars int nBarWidth = 2 ; int nBarSpace = 1 ; // 1 for testing int xPos = xWinMin + 2 ; // start one from the left for( int i=0; i<96; i++) { height = nBar[i] ; if( height > 100 ) height = 100 ; // clip tops // draw the bar, is always inside x-window tt.fillrect( xPos,yWinMax-height, xPos+nBarWidth-1,yWinMax, Green); // tic mark the y axis each 5 if(i%5 == 4){ tt.line( xPos,yWinMax+2, xPos,yWinMax+5, White); // a white tick mark tt.line( xPos+1,yWinMax+2, xPos+1,yWinMax+5, White); // a white tick mark, to widen //tt.rect( xPos,yWinMax+2, xPos+1,yWinMax+5, White); // a white 2-wide tick mark is SLOW } // label the y axis each 10 if(i%10 == 9){ tt.locate( xPos-6, yWinMax+8 ); printf("%02d\n", i+1 ); } // step to the next bar position xPos += nBarWidth + nBarSpace ; } showCP=false; } // handle the button if(sMode==1&&showButtons){ tt.foreground(Yellow); tt.background(DarkCyan); tt.set_font((unsigned char*) Arial12x12); showButton(1,0,"Request","CP Data",4,4); } } //---------------- // gg - hist void cpHistogram(bool force, bool showButtons){ short unsigned max, min, jv, i, bd; unsigned avg; if(force){ tt.foreground(White); tt.background(Navy); tt.set_font((unsigned char*) Arial12x12_prop); // select the font max=0; min=9999; avg=0; for(i=0; i<96; i++){ bd=(battData[i*2+3]<<8)+battData[i*2+4]; avg+=bd; if(bd>max) max=bd; if(bd<min) min=bd; } avg /= 96; if(min<3713) { jv=avg-(max-avg)*1.5; } else { // Only compute judgement value if min cellpair meets <= 3712mV requirement jv=0; } //------------------ tt.cls(); // show as histogram int xWinMin = 20; int xWinMax = 300; int yWinMin = 50; int yWinMax = 150; // draw the Histogram Frame, 2 pixels wide tt.rect( xWinMin-1,yWinMin-1, xWinMax+1,yWinMax+1,Red); tt.rect( xWinMin-2,yWinMin-2, xWinMax+2,yWinMax+2,Green); // binning short nBin[301] ; // bins to count Min values in nBin[0], etc. int height ; int iBinIndxMax = 300 ; int iBinValMax = max - min ; // zero to N if( iBinValMax > iBinIndxMax ) iBinValMax = iBinIndxMax ; // clean the bins for(int i=0; i<=iBinIndxMax; i++) { nBin[i] = 0; } // do the bin counting for(int i=0; i<96; i++){ bd=(battData[i*2+3]<<8)+battData[i*2+4] - min ; if( bd > iBinValMax ) bd = iBinValMax ; nBin[bd] ++ ; } //---------------- if( iBinValMax == 0 ) { // for testing min = 10 ; max = 50 ; avg = ( max + min ) / 2; iBinValMax = max - min ; for(int i=0; i<=(iBinValMax/2); i++) { nBin[i] = i ; nBin[iBinValMax-i] = i ; } } // the values, for now // BatDataBaseG4 * 7 = 224 tt.locate( 0, yWinMax+40 ); printf(" MAX MIN AVG CVLI T1 T2 T3 T4\n %04d %04d %04d %04d %02dC %02dC %02dC %02dC\n\n", max,min,avg,jv, battData[224+5],battData[224+8], battData[224+11],battData[224+14]); //--------------- // show the bars int nBarWidth = 3 ; int nBarSpace = 1 ; // 1 for testing int xPos = (xWinMin + xWinMax) / 2 ; xPos -= (avg-min) * (nBarWidth + nBarSpace) ; for( int i=0; i<=iBinValMax; i++) { height = 4 * nBin[i] ; if( height > 100 ) height = 100 ; // clip tops // if inside the window, draw the bar if( ( xPos + nBarWidth < xWinMax ) && ( xPos > xWinMin ) ) tt.fillrect( xPos,yWinMax-height, xPos+nBarWidth-1,yWinMax, Green); // step to the next bar position xPos += nBarWidth + nBarSpace ; } showCP=false; } // handle the button if(sMode==1&&showButtons){ tt.foreground(Yellow); tt.background(DarkCyan); tt.set_font((unsigned char*) Arial12x12); showButton(1,0,"Request","CP Data",4,4); } } //--------------- void config1(bool force, bool showButtons){ if (force) { tt.background(Black); tt.cls(); } tt.foreground(Yellow); tt.background(DarkCyan); tt.set_font((unsigned char*) Arial12x12); //-------- top row -------- showButton(0,0,"Calibrate"," Touch",4,4); // gg - 4x4 showButton(1,0," Reset","",4,4); showButton(2,0," Save"," Config",4,4); // a button to step to the next skin unsigned int nextSkin = skin + 1 ; if( nextSkin > maxSkin ) nextSkin = 0 ; if( nextSkin == ttSkin ) sprintf(sTemp1,"Skin TT"); else if( nextSkin == ggSkin ) sprintf(sTemp1,"Skin GG"); else sprintf(sTemp1,"Skin %d",nextSkin); showButton(3,0," Use",sTemp1,4,4); //------- second row ----- if (logEn) { sprintf(sTemp1,"Disable"); } else { sprintf(sTemp1,"Enable"); } showButton(0,1,sTemp1,"Logging",4,4); if (repeatPoll) { sprintf(sTemp1,"Disable"); } else { sprintf(sTemp1,"Enable"); } showButton(1,1,sTemp1,"Auto CP",4,4); // add Enable/Disable Batt Log gg - yesBattLog if (yesBattLog) { sprintf(sTemp1,"Disable"); } else { sprintf(sTemp1,"Enable"); } showButton(2,1,sTemp1,"Batt Log",4,4); // add Enable/Disable Debug - debugMode if (debugMode) { sprintf(sTemp1,"Disable"); } else { sprintf(sTemp1,"Enable"); } showButton(3,1,sTemp1," Debug",4,4); } void pbScreen(bool force, bool showButtons){ if (force) { tt.background(Black); tt.cls(); } tt.foreground(Yellow); tt.background(DarkCyan); tt.set_font((unsigned char*) Arial12x12); if(playbackOpen){ showButton(0,0,"Slower"," <--",4,4); if(playbackEn){ sprintf(sTemp1,"Pause"); }else{ sprintf(sTemp1," Run"); } sprintf(sTemp2,"%4.3f ",playbackInt); showButton(1,0,sTemp1,sTemp2,4,4); showButton(2,0,"Faster"," -->",4,4); } if(playbackOpen){ sprintf(sTemp1," Stop"); }else{ sprintf(sTemp1,"Start"); } showButton(1,1,sTemp1,"Playback",4,4); } void showDateTime(bool force, bool showButtons){ struct tm t; // pointer to a static tm structure time_t seconds ; tt.foreground(Yellow); tt.background(Black); if (force) { tt.cls(); seconds = time(NULL); t = *localtime(&seconds) ; tt.locate(10,10); tt.set_font((unsigned char*) Arial12x12); strftime(sTemp1, 32, "%a %m/%d/%Y %X \n", &t); printf("%s",sTemp1); if((sMode==1)&&showButtons){ switch(dtMode){ case 0: sprintf(sTemp1,"Year"); break; case 1: sprintf(sTemp1,"Month"); break; case 2: sprintf(sTemp1,"Day"); break; case 3: sprintf(sTemp1,"Hour"); break; case 4: sprintf(sTemp1,"Minute"); break; case 5: sprintf(sTemp1,"Second"); break; case 6: sprintf(sTemp1,"Select"); break; default: break; } tt.background(DarkCyan); showButton(0,1,sTemp1,"",4,4); showButton(1,1," UP","",4,4); showButton(2,1," DOWN","",4,4); } } } void dteDisplay(bool force, bool showButtons, bool showMiles){ unsigned short i,x,y,lx,ly,gids,radius,color,r,t; unsigned char toVal; static unsigned short lgids=0; static unsigned char leff[39]={0}; CANMessage msg; unsigned long targetBraking, regenBraking, temp; static unsigned long maxTarget = 1000, maxRegen = 1000, tardivreg_x1000 = 1000; static unsigned char lr=0, lt=0; msg = lastMsg[indexLastMsg[0x5bc]]; //Get gids gids = (msg.data[0]<<2)+(msg.data[1]>>6); if(gids==0){ gids=281; // Display new, fully charged capacity until real data obtained } tt.background(Navy); tt.foreground(Yellow); if(force){ tt.set_font((unsigned char*) Arial12x12); tt.cls(); x=50+0*6; tt.locate(x-10,226); printf("sec\n"); tt.line(x,10,x,220,DarkGrey); x=50+9*6; tt.locate(x-10,226); printf("min\n"); tt.line(x,10,x,220,DarkGrey); x=50+18*6; tt.locate(x-10,226); printf("hour\n"); tt.line(x,10,x,220,DarkGrey); x=50+25*6; tt.locate(x-10,226); printf("day\n"); tt.line(x,10,x,220,DarkGrey); x=50+32*6; tt.locate(x-10,226); printf("mon\n"); tt.line(x,10,x,220,DarkGrey); x=50+38*6; //tt.locate(x-10,226); //printf("year\n"); //tt.line(x,10,x,220,DarkGrey); toVal=33; } else { toVal=24;// no need to constantly update the long tc values } if(force||lgids!=gids){ // update Y axis when kWh changes //tt.set_font((unsigned char*) Arial12x12); tt.set_font((unsigned char*) Arial24x23); //for(i=0;i<10;i++){ //y=200-i*20; for(i=3;i<8;i++){ y=200-(i-3)*40; tt.locate(0,y-8); if (showMiles){ printf("%2.0f \n",i*((float)(gids-5)*.075)); }else{ printf("%d.0\n",i); } tt.line(48,y,toVal*6+56,y,DarkGrey); } lgids=gids; } if(updateDTE||force){ for(i=3;i<8;i++){ y=200-(i-3)*40; tt.line(40,y,158,y,DarkGrey); } x=50+0*6; tt.line(x,10,x,220,DarkGrey); x=50+9*6; tt.line(x,10,x,220,DarkGrey); x=50+18*6; tt.line(x,10,x,220,DarkGrey); //x=50+25*6; //tt.line(x,60,x,220,DarkGrey); //x=50+32*6; //tt.line(x,60,x,220,DarkGrey); //x=50+38*6; //tt.line(x,60,x,220,DarkGrey); tt.set_font((unsigned char*) SCProSB31x55); tt.foreground(Green); if (showMiles){ float miles = mpkWh[dtePeriod]*((float)(gids-5)*.075); // Right justify if (miles>99.9){ //space=18; num=31; . = 23 tt.locate(161,8); printf("%4.1f\n",miles); } else if (miles>9.9){ tt.locate(156,8); printf(" %3.1f\n",miles); } else { tt.locate(151,8); printf(" %2.1f\n",miles); } tt.foreground(Cyan); tt.set_font((unsigned char*) Arial24x23); tt.locate(198,70); printf("%3.1f \n",mpkWh[dtePeriod]); } else { tt.locate(200,10); printf("%3.1f \n",mpkWh[dtePeriod]); } lx=50; ly=mpkWh[0]*40; if(dtePeriod==0){ radius=6; color=Yellow; }else{ radius=2; color=Green; } if(ly<100){ ly=220; color=Red; }else if(ly<320) { ly=320-ly; }else{ ly=0; } tt.fillcircle(lx,leff[0],radius,Navy); tt.fillcircle(lx,ly,radius,color); for(i=1;i<toVal;i++){ x=50+i*6; y=mpkWh[i]*40; if(i==dtePeriod){ radius=6; color=Yellow; }else{ radius=2; color=Green; } if(y<100){ y=220; color=Red; }else if(y<320) { y=320-y; }else{ y=0; } tt.fillcircle(x,leff[i],radius,Navy); tt.line(x-6,leff[i-1],x,leff[i],Navy); leff[i-1]=ly; if(y>0){ tt.fillcircle(x,y,radius,color); } tt.line(lx,ly,x,y,White); lx=x; ly=y; } leff[i-1]=y; updateDTE=false; } msg = lastMsg[indexLastMsg[0x1cb]]; //Get Target and Regen regenBraking = (msg.data[0]<<3)+(msg.data[1]>>5); targetBraking = (msg.data[2]<<3)+(msg.data[3]>>5); if (targetBraking<2045){ if ((targetBraking>50)&&(regenBraking>50)){ temp = targetBraking; temp *= 1000; temp /= regenBraking; if (temp<tardivreg_x1000) tardivreg_x1000=temp; } if (targetBraking>maxTarget) maxTarget=targetBraking; if (regenBraking>maxRegen) maxRegen=regenBraking; temp = targetBraking; temp *=200; temp /= maxTarget; t = (char) temp; if (t>175) t=175; temp = regenBraking; temp *= tardivreg_x1000; temp /= maxTarget; temp /= 5; // 1000/200=5 r = (char) temp; if (r>175) r=175; if (r>t) t=r; //Should never happen if(lr!=r||lt!=t){ tt.fillrect(264,64,310,239-t,Navy); tt.fillrect(264,239-t,310,239-r,Red); tt.fillrect(264,239-r,310,239,Green); } lt=t; lr=r; } } void updateDisplay(char display){ bool changed; changed = dMode[display]!=lastDMode[display]; tt.set_display(display); switch (dMode[display]) { case logScreen: printLog(changed,(display==whichTouched)); break; case mainScreen: mainDisplay(changed,(display==whichTouched)); break; case brakeScreen: braking(changed,(display==whichTouched)); break; case dteScreen: dteDisplay(changed,(display==whichTouched),true); break; case effScreen: dteDisplay(changed,(display==whichTouched),false); break; case monitorScreen: printLast(changed,(display==whichTouched)); break; case changedScreen: printChanged(changed,(display==whichTouched)); break; case cpScreen: cpData(changed||showCP,(display==whichTouched)); break; case config1Screen: config1(changed,(display==whichTouched)); break; case playbackScreen: pbScreen(changed,(display==whichTouched)); break; case dateScreen: showDateTime(changed,(display==whichTouched)); break; case cpHistScreen: // gg - hist cpHistogram(changed||showCP,(display==whichTouched)); break; case cpBarScreen: // gg - cpbars cpBarPlot(changed||showCP,(display==whichTouched)); break; case indexScreen: showIndex(changed,(display==whichTouched)); break; default: if (changed){ tt.background(Black); tt.cls(); } break; } lastDMode[display]=dMode[display]; if(display==whichTouched){ switch (sMode) { case 1: // Select screens tt.foreground(Yellow); tt.background(DarkCyan); tt.set_font((unsigned char*) Arial12x12); showButton(0,tNavRow," <-Prev","",4,4); // gg - 4x4 // col 1 see below showButton(2,tNavRow," Go To"," Index",4,4); // gg - index showButton(3,tNavRow," Next->","",4,4); // gg - move next // col 1 in Nav row switch (dMode[display]) { case offScreen: sprintf(sTemp2," Off"); break; case logScreen: sprintf(sTemp2," Log"); break; case mainScreen: sprintf(sTemp2," Main"); break; case brakeScreen: sprintf(sTemp2,"Braking"); break; case dteScreen: sprintf(sTemp2," DTE"); break; case effScreen: sprintf(sTemp2," Eff"); break; case monitorScreen: sprintf(sTemp2," Monitor"); break; case changedScreen: sprintf(sTemp2,"DeltaMon"); break; case cpScreen: sprintf(sTemp2,"CP Data"); break; case config1Screen: sprintf(sTemp2," Config"); break; case playbackScreen: sprintf(sTemp2,"Playback"); break; case dateScreen: sprintf(sTemp2,"Set Time"); break; case cpHistScreen: // gg - hist sprintf(sTemp2,"CP Hist"); break; case cpBarScreen: // gg - cpbars sprintf(sTemp2,"CP Bars"); break; case indexScreen: // gg - index sprintf(sTemp2," Index"); break; } showButton(1,tNavRow," Select",sTemp2,4,4); wait_ms(100); // pause a moment to reduce flicker break; case 2: // numpad tt.foreground(Yellow); tt.background(DarkCyan); tt.set_font((unsigned char*) Arial24x23); sprintf(sTemp2,""); showButton(0,0," 1",sTemp2,4,4); showButton(1,0," 2",sTemp2,4,4); showButton(2,0," 3",sTemp2,4,4); showButton(0,1," 4",sTemp2,4,4); showButton(1,1," 5",sTemp2,4,4); showButton(2,1," 6",sTemp2,4,4); showButton(0,2," 7",sTemp2,4,4); showButton(1,2," 8",sTemp2,4,4); showButton(2,2," 9",sTemp2,4,4); showButton(1,3," 0",sTemp2,4,4); showButton(0,3,"<--",sTemp2,4,4); showButton(2,3,"-->",sTemp2,4,4); showButton(3,3,"return",sTemp2,4,4); case 3: break; default: break; } } } //--------------------- // gg - highlight void highlightButton(unsigned char column, unsigned char row, unsigned char tScn, unsigned char columns, unsigned char rows){ unsigned short x1,x2,y1,y2; x1=column*(320/columns)+btnGap/2; x2=(column+1)*(320/columns)-btnGap/2; y1=row*(240/rows)+btnGap/2; y2=(row+1)*(240/rows)-btnGap/2; tt.set_display(tScn); if( skin == ggSkin ){ // paint the whole button box, for a better visual effect // especially on a screen with a yellow background if( tScn == 0 ) tt.fillrect(x1,y1,x2,y2,White); // DarkCyan); else tt.fillrect(x1,y1,x2,y2,Green); // DarkCyan); } else { tt.fillrect(x1,y1,x2,y2,Green); // DarkCyan); } // paint the outer pixel as a yellow frame tt.rect(x1,y1,x2,y2,Yellow) ; // DarkCyan); } //--------------------- void showButton(unsigned char column, unsigned char row, char * text1, char * text2, unsigned char columns, unsigned char rows){ unsigned short x1,x2,y1,y2; x1=column*(320/columns)+btnGap/2; x2=(column+1)*(320/columns)-btnGap/2; y1=row*(240/rows)+btnGap/2; y2=(row+1)*(240/rows)-btnGap/2; tt.fillrect(x1,y1,x2,y2,DarkCyan); // adapt formatting of text to the smaller 4x4 box tt.locate(x1+btnGap/2,y1+btnGap); // gg - 4x4 printf("%s\n",text1); tt.locate(x1+btnGap/2,y1+btnGap+20); printf("%s\n",text2); } //------------- // below is braking screen normalized to power rather than force // changed to force since power had too large a dynamic range /*void braking (bool force, bool showButtons, bool prdata=false){ unsigned long targetBraking, regenBraking, speed; static unsigned long maxTarget = 20000, maxRegen = 20000, tardivreg_x1000 = 1000; short rpm; unsigned long temp; static unsigned char lastPressure[4] = {200,200,200,200}; unsigned char i,r,t; static unsigned char lr, lt; CANMessage msg; msg = lastMsg[indexLastMsg[0x1cb]]; //Get Target and Regen regenBraking = (msg.data[0]<<3)+(msg.data[1]>>5); targetBraking = (msg.data[2]<<3)+(msg.data[3]>>5); msg = lastMsg[indexLastMsg[0x176]]; //Get rpms - not sure what this is but scales to mph with .0725 rpm = ((short)msg.data[0]<<8)+msg.data[1]; speed =rpm>0?rpm>>3:-rpm>>3; //Take absolute to get speed; div8 if ((targetBraking>2039)||(speed>200)) { //Filter weird messages targetBraking = 0; regenBraking = 0; } else { if ((targetBraking>50)&&(regenBraking>50)){ temp = targetBraking; temp *= 1000; temp /= regenBraking; if (temp<tardivreg_x1000) tardivreg_x1000=temp; } targetBraking *= speed; regenBraking *= speed; if (targetBraking>maxTarget) maxTarget=targetBraking; if (regenBraking>maxRegen) maxRegen=regenBraking; } msg = lastMsg[indexLastMsg[0x1ca]]; //Get brake pressure tt.background(Navy); if (force) { tt.cls(); tt.rect(0,111,170,239,White); tt.line(0,207,170,207,White); tt.line(0,175,170,175,White); tt.line(0,143,170,143,White); lastPressure[0] = 200; lastPressure[1] = 200; lastPressure[2] = 200; lastPressure[3] = 200; } // plot bar graph for each wheel pressure for (i=0; i<4; i++){ if (msg.data[i]<239) { if (msg.data[i]>lastPressure[i]){ tt.fillrect(10+40*i,239-msg.data[i],40+40*i,239,Red); } else if (msg.data[i]<lastPressure[i]) { tt.fillrect(10+40*i,238-lastPressure[i],40+40*i,238-msg.data[i],Navy); } lastPressure[i]=msg.data[i]; } } temp = targetBraking; temp *=200; temp /= maxTarget; t = (char) temp; if (t>200) t=200; temp = regenBraking; temp *= tardivreg_x1000; temp /= maxTarget; temp /= 5; r = (char) temp; if (r>200) r=200; if(lr!=r&&prdata){ tt.foreground(Yellow); tt.set_font((unsigned char*) Arial28x28); tt.locate(100,40); printf("%d %d \n",regenBraking,maxRegen); tt.locate(100,70); printf("%3.1f (%3.1f%s) \n",(float)tardivreg_x1000/10,(float)regenBraking*tardivreg_x1000/targetBraking/10,"%"); } if(lt!=t&&prdata){ tt.foreground(Yellow); tt.set_font((unsigned char*) Arial28x28); tt.locate(100,10); printf("%d %d \n",targetBraking,maxTarget); } if (r>t) t=r; //Should never happen if((lr!=r||lt!=t)&&!prdata){ tt.fillrect(200,10,300,239-t,Navy); tt.fillrect(200,239-t,300,239-r,Red); tt.fillrect(200,239-r,300,239,Green); } lt=t; lr=r; }*/