Dual CANbus monitor and instrumentation cluster supporting ILI9341 display controller
Dependencies: SPI_TFTx2_ILI9341 TOUCH_TFTx2_ILI9341 TFT_fonts mbed
Fork of CANary by
Revision 121:553faf139a20, committed 2013-07-11
- Comitter:
- TickTock
- Date:
- Thu Jul 11 05:29:18 2013 +0000
- Branch:
- Metric
- Parent:
- 120:041edeec08f5
- Child:
- 122:138a40892a4c
- Commit message:
- Added shunt identification to cpbars display
Changed in this revision
--- a/common.h Mon Jul 08 02:08:08 2013 +0000 +++ b/common.h Thu Jul 11 05:29:18 2013 +0000 @@ -31,7 +31,8 @@ #define BatDataBaseG3 0x23 // 5 frames #define BatDataBaseG4 0x28 // 3 frames - Temperature data #define BatDataBaseG5 0x2B // 11 frames -#define BatDataBaseG6 0x36 +#define BatDataBaseG6 0x36 // 4 frames +#define BatDataBaseG7 0x3A #define BatDataBufMax 0x1B2 // 7 x 3E bytes #define VP230Sleep 1 // Set to 0 if using VP231 (sleep disables RX) \ No newline at end of file
--- a/displayModes.cpp Mon Jul 08 02:08:08 2013 +0000 +++ b/displayModes.cpp Thu Jul 11 05:29:18 2013 +0000 @@ -235,6 +235,26 @@ 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); printf("%4d gids \n",gids); @@ -631,8 +651,11 @@ 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); - + 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 @@ -983,7 +1006,7 @@ } lgids=gids; } - if(updateDTE||force){ + if(tock||force){ for(i=3;i<8;i++){ y=200-(i-3)*40; tt.line(40,y,158,y,DarkGrey); @@ -1074,7 +1097,6 @@ ly=y; } leff[i-1]=y; - updateDTE=false; } msg = lastMsg[indexLastMsg[0x1cb]]; //Get Target and Regen @@ -1276,7 +1298,8 @@ break; } } -} + tock=false; +} // updateDisplay //--------------------- // gg - highlight
--- a/displayModes.h Mon Jul 08 02:08:08 2013 +0000 +++ b/displayModes.h Thu Jul 11 05:29:18 2013 +0000 @@ -40,7 +40,7 @@ extern unsigned char whichTouched; extern unsigned char skin; extern unsigned char dtePeriod; -extern bool updateDTE; +extern bool tock; extern DigitalOut led4; extern unsigned char tNavRow; // gg - 4x4 extern unsigned short pointerSep; // log write buffer pointer separation @@ -54,6 +54,9 @@ extern bool debugMode; extern float unloadedV_x2; extern float Resr; +extern bool shunt[96]; +extern float unloadedV_x2,Resr,curRmax,curRmin,redRmax,redRmin,incRmax,incRmin; +extern signed short Imax, Imin; extern "C" { void printLast (bool force, bool showButtons);
--- a/main.cpp Mon Jul 08 02:08:08 2013 +0000 +++ b/main.cpp Thu Jul 11 05:29:18 2013 +0000 @@ -23,7 +23,7 @@ #include "displayModes.h" #include "TOUCH_TFTx2.h" -char revStr[7] = "120"; // gg - revision string, max 6 characters +char revStr[7] = "122"; // gg - revision string, max 6 characters FATFS USBdrive; LocalFileSystem local("local"); @@ -126,13 +126,14 @@ float kW[39]={0}; float mpkWh[39]={0}; float unloadedV_x2,Resr,curRmax,curRmin,redRmax,redRmin,incRmax,incRmin; +signed short Imax, Imin; // Logarithmic division scale (roughly - snapped to common units of time) float timeConstant[39] = {1, 1.58, 2.51, 3.98, 6.31, 10, 15.8, 25.1, 39.8, 60, // 1 minute 60*1.58, 60*2.51, 60*3.98, 60*6.31, 60*10, 60*15.8, 60*25.1, 60*39.8, 60*60, // 1 hour 60*60*1.58, 60*60*2.51, 60*60*3.98, 60*60*6.31, 60*60*10, 60*60*15.8, 60*60*24, // 1 day 60*60*24*1.58, 60*60*24*2.51, 60*60*24*3.98, 60*60*24*6.31, 60*60*24*10, 60*60*24*15.8, 60*60*24*30, // 1 month 60*60*24*39.8, 60*60*24*63.1, 60*60*24*100, 60*60*24*158, 60*60*24*251, 60*60*24*365}; // 1 year -bool updateDTE = false; +bool tock = false; unsigned short pointerSep; unsigned char reqMsgCnt = 99; unsigned long Ah_x10000 = 0; @@ -140,6 +141,8 @@ unsigned short SOH_x100 = 0; float maxTemp = 0; bool metric = false; +bool shunt[96]={0}; +bool charging=false; int main() { //can1SleepMode.mode(OpenDrain); @@ -674,6 +677,7 @@ headlights = (lastMsg[indexLastMsg[0x358]].data[1]&0x80)?true:false; // headlight/turn signal indicator accV=floor(mon12V*scale12V*10+0.5)/10; //Round to nearest 10th accOn=(accV>5)?true:false; + charging=(mph[0]<0.1)&&(kW[0]<-1); // not moving and generating energy so much be charging if(laccOn&&!accOn){ // Car turned off if (repeatPoll) { // Log on shutdown if autopoll enabled tripLog(); // Write trip log on powerdown @@ -718,12 +722,10 @@ if(mph[0]>99){ mph[0]=0; } - miles_trip[0]+=mph[0]/3600; - miles_trip[1]+=mph[0]/3600; - miles_trip[2]+=mph[0]/3600; + numSsamples=0; - mpkWh[0]=mph[0]; if(numWsamples>0){ // Avoid div0 + mpkWh[0]=mph[0]; kW[0]=((float) mWs_x4)/numWsamples/4e3; mpkWh[0]/=kW[0]; if (mpkWh[0]<0) { @@ -733,14 +735,23 @@ kW[0]=0; mpkWh[0]=0; } - kWh_trip[0]+=kW[0]/3600; - kWh_trip[1]+=kW[0]/3600; - kWh_trip[2]+=kW[0]/3600; + numWsamples=0; + + if (!charging){ + miles_trip[0]+=mph[0]/3600; + miles_trip[1]+=mph[0]/3600; + miles_trip[2]+=mph[0]/3600; + kWh_trip[0]+=kW[0]/3600; + kWh_trip[1]+=kW[0]/3600; + kWh_trip[2]+=kW[0]/3600; + } + motorRPM=0; - numSsamples=0; mWs_x4=0; - if((curRmax-curRmin)<10){ // At least 5V change? - // do nothing - insufficient delta_V to measure resistance + + // Compute ESR + if((Imax-Imin)<40){ // do nothing - insufficient delta_I to measure + unloadedV_x2 = (curRmax+curRmin)/2; }else if ((redRmax-redRmin)<(curRmax-curRmin)) { Resr-=0.001; unloadedV_x2 = (redRmax+redRmin)/2; @@ -756,15 +767,17 @@ incRmax=0; redRmin=1000; redRmax=0; - numWsamples=0; - if(accOn||playbackEn){ + Imax=-1000; + Imin=1000; + + if((accOn||playbackEn)&&!charging){ for(i=1;i<39;i++){ average=mph[i]/timeConstant[i]; mph[i]-=average; mph[i]+=mph[0]; mpkWh[i]=average; average=kW[i]/timeConstant[i]; - if((mph[0]>0)||(kW[0]>0)){ //Not charging - so include in efficiency data + if(!charging){ //Not charging - so include in efficiency data kW[i]-=average; kW[i]+=kW[0]; } @@ -775,7 +788,6 @@ //mpkWh[i]=floor(mpkWh[i]*10+0.5)/10; // Round to nearest 10th } } - updateDTE=true; if(logCP&&usbEn){ if(logOnce){ tripLog(); @@ -787,7 +799,8 @@ usbEn=detectUSB(); // Keep looking if none found } waitasec=false; // work around to avoid hang when USB tries to init immediately - } + tock=true; + } // tick display=display<1?display+1:0; // toggle display updateDisplay(display);
--- a/utility.cpp Mon Jul 08 02:08:08 2013 +0000 +++ b/utility.cpp Thu Jul 11 05:29:18 2013 +0000 @@ -208,35 +208,41 @@ if((mType==1)&&(canRXmsg.id==0x7bb)){ // is battery data? Need to store all responses if(canRXmsg.data[0]<0x20){ if(canRXmsg.data[3]==1){//Group 1 data - bdi=BatDataBaseG1; // index offset for Group 1 data (uses 20 - 22) + bdi=BatDataBaseG1; // index offset for Group 1 data if(debugMode){ printMsg(" Getting Group 1 data\n"); } }else if(canRXmsg.data[3]==2){//Group 2 = cellpair data - bdi=BatDataBaseG2; // index offset for CP data (uses 00 - 1C) + bdi=BatDataBaseG2; // index offset for CP data if(debugMode){ printMsg(" Getting cell pair data\n"); } }else if(canRXmsg.data[3]==3){//Group 3 data - bdi=BatDataBaseG3; // index offset for Group 3 data (uses 20 - 22) + bdi=BatDataBaseG3; // index offset for Group 3 data if(debugMode){ printMsg(" Getting Group 3 data\n"); } }else if(canRXmsg.data[3]==4){//Group 4 = temperature data - bdi=BatDataBaseG4; // index offset for Temperature data (uses 20 - 22) + bdi=BatDataBaseG4; // index offset for Temperature data if(debugMode){ printMsg(" Getting temperature data\n"); } }else if(canRXmsg.data[3]==5){//Group 5 data - bdi=BatDataBaseG5; // index offset for Group 5 data (uses 20 - 22) + bdi=BatDataBaseG5; // index offset for Group 5 data if(debugMode){ printMsg(" Getting Group 5 data\n"); } + }else if(canRXmsg.data[3]==6){//Group 6 data = shunt data + bdi=BatDataBaseG6; // index offset for Group 6 data + if(debugMode){ + printMsg(" Getting Group 6 data\n"); + } + }else bdi=0xff; // ignore other messages (for now) lasti=0; } @@ -249,12 +255,23 @@ lasti=i; //remember the msb to detect rollover next time around i+=bdi; //------- - if(i==BatDataBaseG5){ // Last of Temperature data was loaded last time + //------- + i*=7; + if(i+6 < BatDataBufMax) { + battData[i+0]=canRXmsg.data[1]; + battData[i+1]=canRXmsg.data[2]; + battData[i+2]=canRXmsg.data[3]; + battData[i+3]=canRXmsg.data[4]; + battData[i+4]=canRXmsg.data[5]; + battData[i+5]=canRXmsg.data[6]; + battData[i+6]=canRXmsg.data[7]; + } + if(i==(BatDataBaseG6+3)*7){ // All data loaded logCP=yesBattLog; // Only log if logging enabled showCP=true; // Always show + + // Find hottest temperature by finding smallest ADC value // 2013 models only have three sensors - // Or =25+(467-ADC)/9.33 (C) - // Find hottest temperature by finding smallest ADC value k=battData[(BatDataBaseG4*7)+3]*0x100+battData[(BatDataBaseG4*7)+4]; j=battData[(BatDataBaseG4*7)+6]*0x100+battData[(BatDataBaseG4*7)+7]; if(j<k)k=j; @@ -272,20 +289,18 @@ maxTemp*=(temp_C[ii-1]-temp_C[ii]); maxTemp+=temp_C[ii]; + // Get state of health SOH_x100=battData[(BatDataBaseG1*7)+29]*0x100+battData[(BatDataBaseG1*7)+30]; Ah_x10000=battData[(BatDataBaseG1*7)+36]*0x10000+battData[(BatDataBaseG1*7)+37]*0x100+battData[(BatDataBaseG1*7)+38]; SOC_x10000=battData[(BatDataBaseG1*7)+32]*0x10000+battData[(BatDataBaseG1*7)+33]*0x100+battData[(BatDataBaseG1*7)+34]; - } - //------- - i*=7; - if(i+6 < BatDataBufMax) { - battData[i+0]=canRXmsg.data[1]; - battData[i+1]=canRXmsg.data[2]; - battData[i+2]=canRXmsg.data[3]; - battData[i+3]=canRXmsg.data[4]; - battData[i+4]=canRXmsg.data[5]; - battData[i+5]=canRXmsg.data[6]; - battData[i+6]=canRXmsg.data[7]; + + // Save shunt data + for(j=0; j<24; j++){ + shunt[j*4+0]=battData[BatDataBaseG6*7+j+3]&0x08; + shunt[j*4+1]=battData[BatDataBaseG6*7+j+3]&0x04; + shunt[j*4+2]=battData[BatDataBaseG6*7+j+3]&0x02; + shunt[j*4+3]=battData[BatDataBaseG6*7+j+3]&0x01; + } } } }else if((mType==1)&&(canRXmsg.id==0x1db)){ //Battery Volts and Amps @@ -295,22 +310,34 @@ packA_x2|=0xf800;//extend sign; } packA_x2 -= 1; //Slight correction to value required (unique to my Leaf?) + if (-packA_x2<Imin){ + Imin=-packA_x2; + } else if (-packA_x2>Imax){ + Imax=-packA_x2; + } imWs_x4 = packV_x2; // Volts*milliSeconds*2 imWs_x4 *= -packA_x2; // milliWattseconds*4 mWs_x4 += imWs_x4; // total mWs_x4 - float temp = packV_x2-Resr*packA_x2; + float temp; + temp = Resr; + temp *= (float) -packA_x2; + temp += (float) packV_x2; if(temp>curRmax){ curRmax=temp; } else if(temp<curRmin){ curRmin=temp; } - temp = packV_x2-(Resr-0.001)*packA_x2; + temp = Resr-0.001; + temp *= (float) -packA_x2; + temp += (float) packV_x2; if(temp>redRmax){ redRmax=temp; } else if(temp<redRmin){ redRmin=temp; } - temp = packV_x2-(Resr+0.001)*packA_x2; + temp = Resr+0.001; + temp *= (float) -packA_x2; + temp += (float) packV_x2; if(temp>incRmax){ incRmax=temp; } else if(temp<incRmin){ @@ -392,7 +419,12 @@ data[1]=0x21; data[2]=0x05; break; - case BatDataBaseG6: // group 5 has 11 frames + case BatDataBaseG6: // group 4 has 3 frames + data[0]=0x02; //change to request group 5 + data[1]=0x21; + data[2]=0x06; + break; + case BatDataBaseG7: // group 5 has 11 frames reqMsgCnt = 99; can1SleepMode = VP230Sleep; // disable TX can1.monitor(true); // set to snoop mode
--- a/utility.h Mon Jul 08 02:08:08 2013 +0000 +++ b/utility.h Thu Jul 11 05:29:18 2013 +0000 @@ -27,15 +27,11 @@ extern char indexLastMsg[0x800]; extern unsigned char dMode[2]; extern unsigned char msgChanged[100]; - -//extern unsigned char battData[256]; // extern unsigned char battData[BatDataBufMax]; // BatDataBufMax - extern CANMessage lastMsg[100]; extern CAN can1,can2; extern unsigned int fwCount; extern DigitalOut can1SleepMode,can2SleepMode; -//extern DigitalInOut can1SleepMode,can2SleepMode; extern bool tick; extern bool ZeroSecTick; extern bool headlights; @@ -64,9 +60,11 @@ extern unsigned char lastDMode[2]; extern unsigned char whichTouched; extern float unloadedV_x2,Resr,curRmax,curRmin,redRmax,redRmin,incRmax,incRmin; +extern signed short Imax, Imin; extern unsigned char tNavRow ; // gg - 4x4 extern char revStr[7]; // gg - version extern bool debugMode; +extern bool shunt[96]; extern "C" { void mbed_reset();