Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SPI_TFTx2_ILI9341 TOUCH_TFTx2_ILI9341 TFT_fonts mbed
Fork of CANary by
displayModes.cpp
- Committer:
- TickTock
- Date:
- 2014-03-06
- Revision:
- 177:6fda79c2fda1
- Parent:
- 175:0357b4159b40
- Child:
- 178:bf6404312c45
File content as of revision 177:6fda79c2fda1:
//displayModes.cpp
#include "displayModes.h"
char sTemp1[40];
char sTemp2[16];
void mainDisplay (bool force, bool showButtons){
unsigned short gids, SOC_x10, packV_x2, tireP;
float dte,total_kW;
unsigned char aTemp;
static unsigned short lgids=0, lSOC=0, lpackV_x2=0, ltireP=0;
static unsigned char laTemp=0;
static float lmaxTemp=0, lkW=0, laccV=0, lmpkWh=0, useable_kWh=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_x10 = (msg.data[0]<<2)+(msg.data[1]>>6);
msg = lastMsg[indexLastMsg[0x1db]]; //Get pack volts
packV_x2 = (msg.data[2]<<2)+(msg.data[3]>>6);
msg = lastMsg[indexLastMsg[0x54c]]; //Get ambient
aTemp = msg.data[6]-56;
msg = lastMsg[indexLastMsg[0x385]]; //Get tire pressure
tireP = msg.data[2]+msg.data[3]+msg.data[4]+msg.data[5];
tt.background(Navy);
tt.set_font((unsigned char*) Arial28x28);
if(force) tt.cls();
if(skin==ttSkin){
if(force||gids!=lgids){
tt.locate(10,4);
tt.foreground(White);
printf("%dgids \n",gids);
useable_kWh = (float)(gids-5)*kWperGid;
if (useable_kWh<0){
useable_kWh=0;
}
tt.locate(181,4);
if (useable_kWh<9.95){
printf("%3.2fkWh\n",useable_kWh);
} else {
printf("%3.1fkWh\n",useable_kWh);
}
}
if(force||SOC_x10!=lSOC){
tt.locate(10,34);//216,10
tt.foreground(LightGrey);
printf("%2.1f%s\n",(float)SOC_x10/10,"%");
lSOC=SOC_x10;
}
total_kW=kW[0]+CCkW;
if(force||total_kW!=lkW){
tt.foreground(Yellow);
if(total_kW<=-9.95){ //Right justify
tt.locate(186,34);
printf("%3.1fkW\n",total_kW);
} else if (total_kW<0){
tt.locate(186,34);
printf("%3.2fkW\n",total_kW);
} else if (total_kW<9.95){
tt.locate(180,34);
printf(" %3.2fkW\n",total_kW);
} else {
tt.locate(180,34);
printf(" %3.1fkW\n",total_kW);
}
lkW=total_kW;
if(CCon){
tt.set_font((unsigned char*) Arial12x12);
tt.locate(228,64);
tt.foreground(GreenYellow);
printf(" -%3.2fkW\n",CCkW);
tt.set_font((unsigned char*) Arial28x28);
}
}
if(force||gids!=lgids||mpkWh[dtePeriod]!=lmpkWh){
// Display DTE
// worst-case DTE
// Compute DTE based on worst saved trip efficiency (without climate control) and adding the impact
// of the current climate control power relative to the last 10 minutes of driving
if(maxTripEff>0){// Skip if no data available
dte=convertDistance((minTripEff-mpkWh_noCC+mpkWh[dtePeriod])*useable_kWh); //LM - add metric conversion
tt.foreground(Green);
tt.locate(10,84);
if(dte>=9.5){
printf("%2.0f \n",dte);
}else{
printf("%2.1f \n",dte);
}
}
// 10-minute DTE
tt.set_font((unsigned char*) SCProSB31x55);
tt.foreground(Yellow);
dte=convertDistance(mpkWh[dtePeriod]*useable_kWh); //LM - add metric conversion
if(dte>199){
dte=199;
}
// " "=0x10, "."=0x15, #=0x1D
if(dte>=99.5){
tt.locate(70,85);
printf(" %3.0f\n",dte);
}else if(dte>=9.5){
tt.locate(84,85);
printf(" %2.0f\n",dte);
}else{
tt.locate(79,85);
printf(" %2.1f\n",dte);
}
tt.set_font((unsigned char*) Arial28x28);
tt.locate(185,106);
printf("%s\n",distanceUnit());
// No Climate Control DTE
tt.set_font((unsigned char*) Arial24x23);
if(CCon) {
dte=convertDistance((mpkWh_noCC-mpkWh[dtePeriod])*useable_kWh); //LM - add metric conversion
if(dte>199){
dte=199;
}
tt.foreground(GreenYellow);
if(dte>=9.5){
tt.locate(130,134);
printf("+%2.0f \n",dte);
}else{
tt.locate(130,134);
printf("+%2.1f \n",dte);
}
lmaxTemp=0; //force battery termperature refresh (sometimes overlaps)
}
// best-case DTE
tt.set_font((unsigned char*) Arial28x28);
// Compute DTE based on best saved trip efficiency (without climate control) and adding the impact
// of the current climate control power relative to the last 10 minutes of driving
if(maxTripEff>0){// Skip if no data available
dte=convertDistance((maxTripEff-mpkWh_noCC+mpkWh[dtePeriod])*useable_kWh); //LM - add metric conversion
tt.foreground(Orange);
if(dte>=99.5){
tt.locate(255,84);
printf("%3.0f \n",dte);
}else if(dte>=9.5){
tt.locate(270,84);
printf("%2.0f \n",dte);
}else{
tt.locate(265,84);
printf("%2.1f \n",dte);
}
}
lmpkWh=mpkWh[dtePeriod];
} //!(force||gids!=lgids||mpkWh[dtePeriod]!=lmpkWh)
lgids=gids;
if(force||packV_x2!=lpackV_x2){
tt.locate(210,176);
tt.foreground(Yellow);
printf("%4.1fV\n",(float)packV_x2/2);
lpackV_x2=packV_x2;
ltireP=0;//Force tire pressure redraw, too
}
if(force||aTemp!=laTemp){
tt.foreground(Cyan);
tt.locate(10,146);
printf("%2.0f%s\n",convertF(aTemp),temperatureUnit());
laTemp=aTemp;
}
if(force||maxTemp!=lmaxTemp){
tt.foreground(Cyan);
tt.locate(210,146);
if (convertC(maxTemp)<99.5){
printf(" %3.1f%s\n",convertC(maxTemp),temperatureUnit());
}else{
printf("%4.1f%s\n",convertC(maxTemp),temperatureUnit());
}
lmaxTemp=maxTemp;
}
if(force||accV!=laccV){
tt.locate(10,176);
tt.foreground(Yellow);
printf("%3.1fV \n",accV);
laccV=accV;
}
if(force||tireP!=ltireP){
if(msg.data[2]<minTirePressure){
tt.foreground(Orange); // Hi-light if any are low (<35psi)
}else{
tt.foreground(LightGrey);
}
if(msg.data[6]&0x80){
if(msg.data[2]<minTirePressure){
tt.foreground(Orange); // Hi-light if any are low (<35psi)
}else{
tt.foreground(LightGrey);
}
tt.locate(10,206);
printf("%3.1f\n",(float)msg.data[2]/4);
}
if(msg.data[6]&0x40){
if(msg.data[3]<minTirePressure){
tt.foreground(Orange); // Hi-light if any are low (<35psi)
}else{
tt.foreground(LightGrey);
}
tt.locate(90,206);
printf("%3.1f\n",(float)msg.data[3]/4);
}
if(msg.data[6]&0x20){
if(msg.data[4]<minTirePressure){
tt.foreground(Orange); // Hi-light if any are low (<35psi)
}else{
tt.foreground(LightGrey);
}
tt.locate(170,206);
printf("%3.1f\n",(float)msg.data[4]/4);
}
if(msg.data[6]&0x10){
if(msg.data[5]<minTirePressure){
tt.foreground(Orange); // Hi-light if any are low (<35psi)
}else{
tt.foreground(LightGrey);
}
tt.locate(250,206);
printf("%3.1f\n",(float)msg.data[5]/4);
}
ltireP=tireP;
}
}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*kWperGid); // 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 %s \n",convertDistance((float)(gids-5)*0.31),distanceUnit()); // Approx for now - LM added metric
lgids=gids;
tt.foreground(Yellow);
tt.set_font((unsigned char*) Arial28x28);
}
if(force||SOC_x10!=lSOC){
tt.locate(200,10);
printf("%4.1f%s\n",(float)SOC_x10/10,"% ");
lSOC=SOC_x10;
}
if(force||packV_x2!=lpackV_x2){
tt.locate(200,200);
printf("%4.1fV \n",(float)packV_x2/2);
lpackV_x2=packV_x2;
}
if(force||accV!=laccV){
tt.locate(20,200);
printf("%3.1fV \n",accV);
laccV=accV;
}
total_kW=kW[0]+CCkW;
if(force||total_kW!=lkW){
tt.locate(160,40); // gg - move left to keep from wrap
printf("%3.2fkw \n",total_kW); // use small w to save space
lkW=total_kW;
}
}
if(led4){
tt.fillcircle(310,10,6,Red);
}else{
tt.fillcircle(310,10,6,Navy);
}
}
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(showButtons){
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(showButtons){
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 tripDisplay (bool force, bool showButtons, bool inclCC){
static int lkWh=0;
float mpkWh_f, kWh_f;
tt.background(White);
if(force){
tt.cls();
}
if(force||(lkWh!=(int)(kWh_trip[0]*100))){ //only update if changed
tt.foreground(Navy);
tt.set_font((unsigned char*) Arial28x28);
tt.locate(6,210);
printf("kWh : %s : Eff\n",distanceUnit());
tt.set_font((unsigned char*) Arial12x12);
tt.locate(260,220);
if(inclCC){
printf(" (+CC)\n");
} else {
printf("(noCC)\n");
}
tt.set_font((unsigned char*) Arial28x28);
for(int i=0; i<3; i++){
kWh_f = kWh_trip[i];
if(inclCC){
kWh_f += CCkWh_trip[i];
}
if(kWh_f>0.01){
mpkWh_f = convertDistance(miles_trip[i])/kWh_f;
} else {
mpkWh_f = 0;
}
tt.locate(6,20+i*60);
printf("%3.2f : %3.1f : %2.1f \n",kWh_f,convertDistance(miles_trip[i]),mpkWh_f);
}
tt.foreground(Navy);
tt.set_font((unsigned char*) Arial12x12);
tt.locate(274,18);
printf("per\n");
tt.locate(274,33);
printf("trip\n");
tt.locate(274,78);
printf("per\n");
tt.locate(265,93);
printf("charge\n");
tt.locate(265,145);
printf("custom\n");
lkWh=(int)(kWh_trip[0]*100);
}
if(showButtons){
showButton(3,1," Cancel"," Day",4,4);
showButton(3,2," Reset","Custom",4,4);
}
}
void healthDisplay (bool force, bool showButtons){
unsigned short gids, SOC_x10, SOH_x2;
static unsigned short lgids=0, lSOC=0, lSOH=0;
static float lmaxTemp=0, lresr=0, lunlV=0;
static unsigned long lAh=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_x10 = (msg.data[0]<<2)+(msg.data[1]>>6);
msg = lastMsg[indexLastMsg[0x5b3]]; //Get SOH
SOH_x2 = msg.data[1];
tt.background(Blue);
tt.foreground(Yellow);
tt.set_font((unsigned char*) Arial28x28);
if(force) tt.cls();
/*if(force||tock){ // for esr debug
tt.locate(10,10);
printf("%d %d amps\n",Imax,Imin);
tt.locate(10,40);
printf(" %4.1f %4.1f\n",incRmax/2,incRmin/2);
tt.locate(10,70);
printf(" %4.1f %4.1f\n",redRmax/2,redRmin/2);
tt.locate(10,100);
printf(" %4.1f %4.1f\n",curRmax/2,curRmin/2);
//tt.locate(10,130);
curRmin=1000;
curRmax=0;
incRmin=1000;
incRmax=0;
redRmin=1000;
redRmax=0;
Imax=-1000;
Imin=1000;
}*/
if(force||gids!=lgids){
tt.locate(10,10);
if(dailyGids>5){ // Wh/gid, too
printf("%d gids (%0.0f)\n",gids,1000*(kWh_trip[3]+CCkWh_trip[3])/dailyGids);
}else{
printf("%d gids \n",gids);
}
lgids=gids;
}
if(force||SOC_x10!=lSOC){
tt.locate(10,40);
printf("%4.1f%s SOC \n",(float)SOC_x10/10,"%");
lSOC=SOC_x10;
}
if(force||SOH2_x100!=lSOH){
tt.locate(10,70);
printf("%d%s SOH, %3.1f Hx \n",SOH_x2/2,"%",(float)SOH2_x100/100);
lSOH=SOH2_x100;
}
if(force||Ah_x10000!=lAh){
tt.locate(10,100);
printf("%4.2f Ah cap \n",(float)Ah_x10000/10000);
lAh=Ah_x10000;
}
if(force||maxTemp!=lmaxTemp){
tt.locate(10,130);
printf("%4.1f %s (max) \n",convertC(maxTemp),temperatureUnit());
lmaxTemp=maxTemp;
}
if(force||unloadedV_x2!=lunlV){
tt.locate(10,160);
printf("%4.1f V \n",unloadedV_x2/2);
lunlV=unloadedV_x2;
}
if(force||Resr!=lresr){
tt.locate(10,190);
printf("%3.0f mOhms \n",Resr*1000);
lresr=Resr;
}
}
void braking (bool force, bool showButtons, bool prdata=false){
unsigned long targetBraking, regenBraking;
//static unsigned long maxTarget = 1000, maxRegen = 1000, tardivreg_x1000 = 1000;
static unsigned long 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]];
targetBraking = (msg.data[2]<<3)+(msg.data[3]>>5); //Get target total braking force
//regenBraking = (msg.data[0]<<3)+(msg.data[1]>>5); //Get target regen portion
msg = lastMsg[indexLastMsg[0x1d5]]; //Get regen portion - seems to be actual regen versus target regen
regenBraking = (msg.data[0]<<3)+(msg.data[1]>>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[BatDataBaseG2*7+i*2+3]<<8)+battData[BatDataBaseG2*7+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;
}
char* sTemperatureUnit = temperatureUnit();
switch(step){
case 0:
tt.cls();
showCP=true;
break;
case 1:
tt.locate(0,6);
printf(" MAX MIN AVG CVLI T1 T2 T3 T4\n %04d %04d %04d %04d %2.0f%s %2.0f%s %2.0f%s %2.0f%s\n\n",
max,min,avg,jv, convertC(battData[BatDataBaseG4*7+5]),sTemperatureUnit,convertC(battData[BatDataBaseG4*7+8]),sTemperatureUnit,
convertC(battData[BatDataBaseG4*7+11]),sTemperatureUnit,convertC(battData[BatDataBaseG4*7+14]),sTemperatureUnit);
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[BatDataBaseG2*7+i*12+3]<<8)+battData[BatDataBaseG2*7+i*12+4],(battData[BatDataBaseG2*7+i*12+5]<<8)+battData[BatDataBaseG2*7+i*12+6],
(battData[BatDataBaseG2*7+i*12+7]<<8)+battData[BatDataBaseG2*7+i*12+8],(battData[BatDataBaseG2*7+i*12+9]<<8)+battData[BatDataBaseG2*7+i*12+10],
(battData[BatDataBaseG2*7+i*12+11]<<8)+battData[BatDataBaseG2*7+i*12+12],(battData[BatDataBaseG2*7+i*12+13]<<8)+battData[BatDataBaseG2*7+i*12+14]);
}
for(i=(step-2)*24; i<(step-1)*24; i++){
bd=(battData[BatDataBaseG2*7+i*2+3]<<8)+battData[BatDataBaseG2*7+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(showButtons){
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
// 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","Health",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);
showButton(3,1," GoTo"," Config",4,4);
// bottom (not Nav) row
showButton(0,2," GoTo","Playback",4,4);
//showButton(1,2," GoTo","Set Time",4,4);
showButton(2,2," GoTo"," Log",4,4);
showButton(3,2," GoTo"," Trip",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[BatDataBaseG2*7+i*2+3]<<8)+battData[BatDataBaseG2*7+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
}
// label the Y axis
tt.locate( 2, yWinMin-14 ); printf("%04d = (%d) mv range.\n", max , max - min );
tt.locate( 2, yWinMax+5); printf("%04d\n", min );
// BatDataBaseG4 * 7 = 280
tt.locate( 0, yWinMax+40 );
char* sTemperatureUnit = temperatureUnit();
printf(" MAX MIN AVG CVLI T1 T2 T3 T4\n %04d %04d %04d %04d %2.0f%s %2.0f%s %2.0f%s %2.0f%s\n",
max,min,avg,jv, convertC(battData[BatDataBaseG4*7+5]),sTemperatureUnit,convertC(battData[BatDataBaseG4*7+8]),sTemperatureUnit,
convertC(battData[BatDataBaseG4*7+11]),sTemperatureUnit,convertC(battData[BatDataBaseG4*7+14]),sTemperatureUnit);
//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[BatDataBaseG4*7+5],battData[BatDataBaseG4*7+8], battData[BatDataBaseG4*7+11],battData[BatDataBaseG4*7+14]);
//---------------
// 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
if (shunt[i]){
tt.fillrect( xPos,yWinMax-height, xPos+nBarWidth-1,yWinMax, Red);
} else {
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){
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[BatDataBaseG2*7+i*2+3]<<8)+battData[BatDataBaseG2*7+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;
// binning
short nBin[301] ; // bins to count Min values in nBin[0], etc.
int height;
int iBinValMax = max - min ; // zero to N
int iBinIndxMax = (xWinMax-xWinMin)/2; // Maximum number of bars
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[BatDataBaseG2*7+i*2+3]<<8)+battData[BatDataBaseG2*7+i*2+4] - min ;
if( bd > iBinValMax ) bd = iBinValMax ;
nBin[bd]++ ;
}
//----------------
if( iBinValMax == 0 ) { // dummy data if no real data
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 ;
}
}
// label the Y axis
tt.locate( 0, yWinMin ); printf("25\n");
tt.locate( 0, yWinMax-6 ); printf("0\n");
tt.locate( xWinMin-12, yWinMax+6 ); printf("%04d\n", min);
tt.locate( xWinMax-18, yWinMax+6 ); printf("%04d\n", max);
// draw the Histogram Frame, 2 pixels wide
tt.rect( xWinMin-1,yWinMin-1, xWinMax+0,yWinMax+0,Red);
tt.rect( xWinMin-2,yWinMin-2, xWinMax+1,yWinMax+1,Green);
tt.locate( 0, yWinMax+40 );
char* sTemperatureUnit = temperatureUnit();
printf(" MAX MIN AVG CVLI T1 T2 T3 T4\n %04d %04d %04d %04d %2.0f%s %2.0f%s %2.0f%s %2.0f%s\n\n",
max,min,avg,jv, convertC(battData[BatDataBaseG4*7+5]),sTemperatureUnit,convertC(battData[BatDataBaseG4*7+8]),sTemperatureUnit,
convertC(battData[BatDataBaseG4*7+11]),sTemperatureUnit,convertC(battData[BatDataBaseG4*7+14]),sTemperatureUnit);
//---------------
// show the bars
int nBarWidth = (xWinMax-xWinMin)/(iBinValMax+1)-1;
if (nBarWidth < 1) nBarWidth = 1;
int nBarSpace = 1 ;
int xPos = (xWinMin + xWinMax)/2;
xPos -= ((iBinValMax+1)*(nBarWidth+nBarSpace))/2 ;
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){
showButton(1,0,"Request","CP Data",4,4);
}
}
//---------------
void config(bool force, bool showButtons){
if (force) {
tt.background(Black);
tt.cls();
}
//-------- top row --------
showButton(1,0," Reset","CANary",4,4);
showButton(2,0," Save"," Config",4,4);
//------- second row -----
if (logEn&&usbEn) {
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);
//------- third row -----
if(brakeMon)
showButton(0,2,"Disable","BrkMon",4,4);
else
showButton(0,2," Enable"," BrkMon",4,4);
if(regenMon)
showButton(1,2,"Disable","RegMon",4,4);
else
showButton(1,2," Enable"," RegMon",4,4);
if(heaterMon)
showButton(2,2,"Disable","HeatMon",4,4);
else
showButton(2,2," Enable","HeatMon",4,4);
}
void config2(bool force, bool showButtons){
if (force) {
tt.background(Black);
tt.cls();
}
//-------- top row --------
showButton(0,0,"Calibrate"," Touch",4,4); // gg - 4x4
showButton(1,0," Reset","Max/Min",4,4);
if (showHealth) {
sprintf(sTemp1," Hide");
} else {
sprintf(sTemp1," Show");
}
showButton(2,0,sTemp1," Health",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 -----
// add Enable/Disable Debug - debugMode
if (debugMode) {
sprintf(sTemp1," Disable");
} else {
sprintf(sTemp1," Enable");
}
showButton(3,1,sTemp1," Debug",4,4);
//------- third row -----
if (autoSync) {
sprintf(sTemp1," Disable");
} else {
sprintf(sTemp1," Enable");
}
showButton(0,2,sTemp1," tSync",4,4);
showButton(1,2," Set"," Time",4,4);
showButton(2,2," Update"," Config",4,4);
showButton(3,2," Update","Firmware",4,4);
}
void pbScreen(bool force, bool showButtons){
if (force) {
tt.background(Black);
tt.cls();
}
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){
CANMessage msg;
struct tm t; // pointer to a static tm structure
time_t seconds ;
tt.foreground(Yellow);
tt.background(Black);
if (force||tock) {
tt.cls();
tt.locate(10,10);
tt.set_font((unsigned char*) Arial12x12);
if(accOn){
seconds = time(NULL);
t = *localtime(&seconds);
if(modelYear<2013){
msg = lastMsg[indexLastMsg[0x5fa]];
t.tm_mon = (msg.data[5]>>4)-1;
t.tm_mday = msg.data[2]>>3;
// Have not figured out where the year is on MY2011
msg = lastMsg[indexLastMsg[0x5fc]];
t.tm_hour = msg.data[0]>>3;
t.tm_min = (msg.data[1]<<4&0x30)+(msg.data[2]>>4);
t.tm_sec = msg.data[1]>>2;
}else{
// Have not figured out where Year, Month, or Day is for MY2013
msg = lastMsg[indexLastMsg[0x5f9]];
t.tm_hour = msg.data[5]>>3;
t.tm_min = msg.data[4];
msg = lastMsg[indexLastMsg[0x509]];
t.tm_sec = msg.data[2]>>2;
}
strftime(sTemp1, 32, "%a %m/%d/%Y %X \n", &t);
printf("Leaf: %s",sTemp1);
}
seconds = time(NULL);
t = *localtime(&seconds);
strftime(sTemp1, 32, "%a %m/%d/%Y %X \n", &t);
tt.locate(10,24);
printf("CANary: %s",sTemp1);
if(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;
default:
break;
}
showButton(0,1,sTemp1,"",4,4);
showButton(1,1," Up","",4,4);
showButton(2,1," Down","",4,4);
if(accOn){
showButton(3,1," Sync","w/ car",4,4);
}
if(autoSync){
showButton(3,2,"disable"," auto",4,4);
}else{
showButton(3,2,"enable"," auto",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,availableRegen=0;
static unsigned short lgids=0;
static unsigned char leff[39]={0};
CANMessage msg;
unsigned long targetBraking, regenBraking, motorSpeed, motorAmps, frictionBraking;
static unsigned char lr=0, lt=0, lar=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;
lar=0;
}
toVal=33;
if(force||lgids!=gids){ // update Y axis when kWh changes
tt.set_font((unsigned char*) Arial24x23);
for(i=2;i<7;i++){
y=200-(i-2)*40;
tt.locate(0,y-8);
if (showMiles){
printf("%3.0f\n",convertDistance(i*((float)(gids-5)*.075))); // LM - Added metric support
}else{
printf("%d.0\n",i);
}
tt.line(48,y,toVal*6+56,y,DarkGrey);
}
lgids=gids;
}
if(tock||force){
for(i=2;i<7;i++){
y=200-(i-2)*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(Yellow);
if (showMiles){
float miles = mpkWh[dtePeriod]*((float)(gids-5)*.075);
miles = convertDistance(miles); // LM - Metric support
// Right justify
if (miles>99.9){ //space=18; num=31; . = 23
tt.locate(161,1);
printf("%4.1f\n",miles);
} else if (miles>9.9){
tt.locate(156,1);
printf(" %3.1f\n",miles);
} else {
tt.locate(151,1);
printf(" %2.1f\n",miles);
}
if(CCon) {
tt.foreground(GreenYellow);
tt.set_font((unsigned char*) Arial24x23);
miles = (mpkWh_noCC-mpkWh[dtePeriod])*((float)(gids-5)*.075);
miles = convertDistance(miles); // LM - Metric support
// Right justify
if (miles>9.9){
tt.locate(190,52);
printf(" +%3.1f \n",miles);
} else {
tt.locate(182,52);
printf(" +%2.1f \n",miles);
}
}
} else {
tt.locate(200,1);
printf("%3.1f \n",mpkWh[dtePeriod]);
if(CCon) {
tt.foreground(GreenYellow);
tt.set_font((unsigned char*) Arial24x23);
tt.locate(190,52);
printf(" +%2.1f \n",(mpkWh_noCC-mpkWh[dtePeriod]));
}
}
lx=50;
ly=mpkWh[0]*40;
if(dtePeriod==0){
radius=6;
color=Yellow;
}else{
radius=2;
color=Green;
}
if(ly<60){
ly=220;
color=Red;
}else if(ly<280) {
ly=280-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<60){
y=220;
color=Red;
}else if(y<280) {
y=280-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;
}
// Plot Braking friction/regen bar graph
msg = lastMsg[indexLastMsg[0x176]]; //Get RPMs
motorSpeed = (msg.data[2]<<8)+msg.data[3];
msg = lastMsg[indexLastMsg[0x260]]; //Get available regen
availableRegen = msg.data[1]*4;
msg = lastMsg[indexLastMsg[0x1cb]]; //Get target total braking
targetBraking = (msg.data[2]<<3)+(msg.data[3]>>5);
msg = lastMsg[indexLastMsg[0x292]]; //Get friction braking
frictionBraking = msg.data[6];
msg = lastMsg[indexLastMsg[0x180]]; //Get motor amps
motorAmps = (msg.data[2]<<4)+(msg.data[3]>>4);
if(motorAmps>0x7ff){ // invert and chop positive current
motorAmps=0x1000-motorAmps;
}else{
motorAmps=0;
}
targetBraking *= motorSpeed;
targetBraking /= tbScalar; //0.0000345 * 4
regenBraking = motorAmps;
regenBraking *= motorSpeed;
regenBraking /= rbScalar; //0.00002875 * 4
frictionBraking *= motorSpeed;
frictionBraking /= fbScalar; //0.0019 * 4
// Plot available regen brackets
if(availableRegen>lar){
tt.fillrect(273,238-availableRegen,275,239-lar,White);
tt.fillrect(317,238-availableRegen,319,239-lar,White);
if(availableRegen>0){
for(i=0;i<=availableRegen;i+=24){
tt.fillrect(270,238-i,272,239-i,White);
}
}
lar=availableRegen;
}else if(availableRegen<lar){
tt.fillrect(270,238-lar,275,239-availableRegen,Navy);
tt.fillrect(317,238-lar,319,239-availableRegen,Navy);
lar=availableRegen;
}
t = (unsigned char) regenBraking+frictionBraking;
if (t>160) t=160;
r = (unsigned char) regenBraking;
if (r>160) r=160;
if (r>t) t=r; //Should never happen
if(lr!=r||lt!=t){
if (t<160) tt.fillrect(277,239-160,315,238-t,Navy);
if (r<t) tt.fillrect(277,239-t,315,238-r,Red);
if (0<r) tt.fillrect(277,239-r,315,238,Green);
}
lt=t;
lr=r;
}
void testDisplay (bool force, bool showButtons){
static unsigned short maxPS=0, oldData[8]={0};
unsigned char i, uData[8];//, year, month, day, hour, minute, second;
CANMessage msg;
tt.set_font((unsigned char*) Arial24x23);
tt.foreground(Yellow);
tt.background(Navy);
if(force){
tt.cls();
}
if(logEn){
if(pointerSep>maxPS){maxPS=pointerSep;}
tt.locate(10,10);
printf("%3d sep %3d max\n",pointerSep,maxPS);
}else{
tt.locate(10,10);
printf("%d maxT\n",maxTarget);
}
for (i=0; i<8; i++){
msg = lastMsg[indexLastMsg[(uMsgId[i]>>4)]];
uData[i] = msg.data[(uMsgId[i]&0x000f)];
if(i%2==0){
tt.locate(10,90+(i/2)*30);
}else{
tt.locate(170,90+(i/2)*30);
}
if(clearTest){
maxPS=0;
oldData[i]=uData[i];
tt.foreground(Yellow);
tt.background(Navy);
printf("%4x:%2x\n",uMsgId[i],uData[i]);
}else if(uData[i]!=oldData[i]){
tt.foreground(Navy);
tt.background(Yellow);
printf("%4x:%2x\n",uMsgId[i],uData[i]);
oldData[i]=uData[i];
}else if(force){
tt.foreground(Yellow);
tt.background(Navy);
printf("%4x:%2x\n",uMsgId[i],uData[i]);
}
}
clearTest=false;
showButton(3,0,"Reset","flags",4,4);
}
void updateDisplay(char display){
bool changed,showButtons;
changed = (dMode[display]!=lastDMode[display]);
showButtons = (display==whichTouched)&&(sMode==1);
tt.set_display(display);
switch (dMode[display]) {
case logScreen:
printLog(changed,showButtons);
break;
case mainScreen:
mainDisplay(changed,showButtons);
break;
case brakeScreen:
braking(changed,showButtons);
break;
case dteScreen:
dteDisplay(changed,showButtons,true);
break;
case effScreen:
dteDisplay(changed,showButtons,false);
break;
case monitorScreen:
printLast(changed,showButtons);
break;
case changedScreen:
printChanged(changed,showButtons);
break;
case cpScreen:
cpData(changed||showCP,showButtons);
break;
case configScreen:
config(changed,showButtons);
break;
case config2Screen:
config2(changed,showButtons);
break;
case playbackScreen:
pbScreen(changed,showButtons);
break;
case dateScreen:
showDateTime(changed,showButtons);
break;
case cpHistScreen: // gg - hist
cpHistogram(changed||showCP,showButtons);
break;
case cpBarScreen: // gg - cpbars
cpBarPlot(changed||showCP,showButtons);
break;
case indexScreen:
showIndex(changed,showButtons);
break;
case tripScreen:
tripDisplay(changed,showButtons,false);
break;
case ccTripScreen:
tripDisplay(changed,showButtons,true);
break;
case healthScreen:
healthDisplay(changed,showButtons);
break;
case testScreen:
testDisplay(changed,showButtons);
break;
default:
if (changed){
tt.background(Black);
tt.cls();
}
break;
}
lastDMode[display]=dMode[display];
if(display==whichTouched){
switch (sMode) {
case 1: // Select screens
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
if (enableSound) {
sprintf(sTemp1," Mute");
} else {
sprintf(sTemp1,"Un-Mute");
}
// col 1 in Nav row
switch (dMode[display]) {
case offScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2," Off");
break;
case logScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2," Log");
break;
case mainScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2," Main");
break;
case brakeScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2,"Braking");
break;
case dteScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2," DTE");
break;
case effScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2," Eff");
break;
case monitorScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2," Monitor");
break;
case changedScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2,"DeltaMon");
break;
case cpScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2,"CP Data");
break;
case configScreen:
sprintf(sTemp2," Config");
break;
case config2Screen:
sprintf(sTemp2,"Config2");
break;
case playbackScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2,"Playback");
break;
case dateScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2,"Set Time");
break;
case cpHistScreen: // gg - hist
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2,"CP Hist");
break;
case cpBarScreen: // gg - cpbars
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2,"CP Bars");
break;
case tripScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2," Trip");
break;
case healthScreen:
showButton(3,0,sTemp1,"",4,4);
sprintf(sTemp2,"Health");
break;
case testScreen:
sprintf(sTemp2," Test");
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
showButton(0,0," 1","",4,4);
showButton(1,0," 2","",4,4);
showButton(2,0," 3","",4,4);
showButton(0,1," 4","",4,4);
showButton(1,1," 5","",4,4);
showButton(2,1," 6","",4,4);
showButton(0,2," 7","",4,4);
showButton(1,2," 8","",4,4);
showButton(2,2," 9","",4,4);
showButton(1,3," 0","",4,4);
showButton(0,3,"<--","",4,4);
showButton(2,3,"-->","",4,4);
showButton(3,3,"return","",4,4);
case 3:
break;
default:
break;
}
}
tock=false;
} // updateDisplay
//---------------------
// 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);
tt.foreground(Yellow);
tt.background(DarkCyan);
tt.set_font((unsigned char*) Arial12x12);
// 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);
}
//The temps are stored as metric, distances as imperial... I'm assuming the input based on that - LM
float convertC(float input)
{
if (!metric) {
//convert!
float output = input *1.8f;
output += 32.0f;
return output;
}
return input;
}
float convertF(float input)
{
if (metric) {
//convert!
float output = input -32.0f;
output /= 1.8f;
return output;
}
return input;
}
float convertDistance(float input)
{
if (metric) {
return input / 0.62137f;
}
return input;
}
char* distanceUnit()
{
if(metric)
return "km";
return "mi";
}
char* temperatureUnit()
{
if(metric)
return "C";
return "F";
}
