Dual CANbus monitor and instrumentation cluster

Eagle Schematic and Board design

/media/uploads/TickTock/canaryr5.zip

/media/uploads/TickTock/sch_r4.jpg /media/uploads/TickTock/lcdsch.jpg /media/uploads/TickTock/brd_r4.jpg

Parts List

qtyinstancepart #packagesupplierDescription
1BAT3Vhttp://www.ebay.com/itm/10x-CR2032-SMD-Battery-Holder-for-CR2032-Battery-/180938057979?pt=LH_DefaultDomain_0&hash=item2a20bfa8fbLithium 2032 coin battery holder
4C1-C4ECST1DC106R6032Tantalium capacitor 10uF
3FC1-FC3ZF1-20-01-T-WThttp://www.samtec.com/cable-systems/idc-ffc/ffc/zero-insertion.aspx20 conductor 1mm pitch flex cable connector (optional)
1FJ-20-R-08.00-4http://www.samtec.com/cable-systems/idc-ffc/ffc/zero-insertion.aspx8\" 20 conductor 1mm pitch flex connector, end reversed (optional)
2H1-H4(DON'T populate H1-H4 headers - solder mbed directly)
1H5http://www.ebay.com/itm/221186042943?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l26491x12 .1\" pitch header (optional)
1H62x6 .1\" pitch header (optional)
2IC1,IC2VP230LMDSOP8http://www.ebay.com/itm/130488665247?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649canbus transciever
1IC3LM1117-5VSOT2235V regulator
5JP*2 pin .1\" jumper header
1mbedLPC1768http://www.ebay.com/itm/200830573509?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649mbed uC
2Q1,Q22N2222SOT23General purpose NPN transistor
1R1R392M12063.9K resistor
4R2,R4-R6R102M12061K resistor
1R3R500M120650 Ohm resistor
2TR1-TR5ZJYS81R5-2PL51TG01http://www.digikey.com/product-detail/en/ZJYS81R5-2PL51T-G01/445-2223-1-ND/765232CM Choke
1Z11N5340BGC1702-15http://www.ebay.com/itm/150878122425?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l26496V, 5W Zener Diode
1X1USBhttp://www.ebay.com/itm/New-Vertical-USB-2-0-A-pcb-connector-socket-USB-A-Type-/300553895292?pt=LH_DefaultDomain_0&hash=item45fa687d7cvertical USB connector
2LCD0,LCD1TFThttp://www.mikroe.com/add-on-boards/display/tft-proto/320x240 LCD with touch screen

Assembly

1) LCD Displays

I found ribbon cable is a nice way to organize the wires to the displays. You'll need 12 conductors and I connected them in the following order:

1LED+
2LED-
3RSTB
4MOSI
5SCLK
6CSB
7X+
8X-
9Y+
10Y-
11VDD
12GND

First I connected all the GND connections (IM0, IM1, IM3, & 2 GND). Do not connect the bottom GND until you have the ribbon cable connected. After making all the ribbon cable connections (connecting the GND of the ribbon cable to the bottom GND pad), solder the GND bar from the previous step to the back of the bottom GND connection. Finally, make a connection from the back side 3.3V pin to IM2. Take a break and repeat for the second display. /media/uploads/TickTock/lcdtop.jpg /media/uploads/TickTock/lcdbot.jpg Once the two displays are complete combine all wires except CS0, CS1, X+, X-, Y+, and Y-. Connect X- of the left display to X+ of the right. Similarly connect Y- of the left display to Y+ of the right. Insulate any exposed wires.

2) PCB

Refer to the schematics to place all the components on the board. If you plan to install into the CANary 3D enclosure, DO NOT install the battery holder or the socket for the mbed and, instead, connect two wires to the VB and GND pads nearby. You will have to install the battery holder against the back wall to avoid interfering with the right-hand display and the mbed will have to be directly soldered. I have not found a socket with a low enough profile to fit in the space provided (depth of enclosure is limited by the space behind the center console). Also, I recommend keeping as much lead as possible on the Zener diode (bending it as shown to clear the back wall). Although it is operating well within parameters, the Zener gets quite hot during extended operation and the leads help dissipate the heat and keep it away from the PCB and other components.

/media/uploads/TickTock/pcbtop.jpg /media/uploads/TickTock/pcbbot.jpg

Once the PCB is populated, solder the LCDs to the PCB. CS0 connects to the right display and CS1 connects to the left. /media/uploads/TickTock/brddis.jpg

3) Testing

1)First step is to buzz out all connections from the LCDs to the pins in the main board
2)Next check the touch screen connections. On the main board, place an Ohm meter across X+ and X-. You should read 700 Ohms. Repeat for Y+ and Y-. Then test the resistance from X+ to Y+. With nothing touching the screens, it should read >100K Ohms and <1K when touching either screen.
3)When all connections are checked, solder in the mbed. Download and install the touch2 program http://mbed.org/users/TickTock/code/touch2/ to test the basic operation of the mbed and touch screens.
tips:
Touch screen is sensitive - excess flux on X+,X-,Y+,Y- connection on mbed can result in flakey operation
If touch is not working, double-check the LCD0_CS and LCD1_CS are not swapped. LCD0_CS must connect to the CS of the LCD that has X- & Y- connected to the mbed. LCD1_CS must connect to the CS of the LCD that has X+ & Y+ connected to the mbed.
4)Once touch2 works, it is time to connect to the OBD connector. I highly recommend double checking all connections from the OBD to the PCB with the cable in place before connecting to the Leaf. Buzz out all the pins in the OBS to make sure none are shorting to each other, Check that the 12V goes to the Zener (and nothing else) and the switched 12V to the resistor divider (and nothing else). Test the ground connection properly connects to ground and nothing else.
5)Once you are confident there are no shorts or wrong connections from the OBD connector, take a deep breath and plug it into your leaf. Touch2 program should come up and function. Unplug and install the latest CANary firmware. Test all features before installing into the enclosure (gids, cellpair, menu system, logging) since installing and removing from the enclosure is a PITA.

/media/uploads/TickTock/pcbdone.jpg /media/uploads/TickTock/functioning.jpg

4) Enclosure

The 3D printer leaves a lot of powder behind - I used a strong spray of water to get it out of all the cracks. The enclosure comes with a rather rough finish. I recommend convincing yourself you like it, then simply lightly sand then paint before assembly. Sanding is very difficult - the nylon is very nicely fused and doesn't want to sand. I tried sandblasting and that didn't work either. I had some limited success with filler and then sanding, but only on the outside - it is too difficult to sand the face.

5) Final Assembly

Committer:
TickTock
Date:
Sat Mar 16 02:47:26 2013 +0000
Revision:
27:6bd073c33977
Parent:
26:462ccb580472
Child:
28:f24ac05645d9
Energy based braking screen working

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TickTock 13:62e0f7f39ff5 1 //displayModes.cpp
TickTock 13:62e0f7f39ff5 2
TickTock 13:62e0f7f39ff5 3 #include "displayModes.h"
TickTock 25:ddf0ec209f03 4 char sTemp1[40];
TickTock 24:6cf76ed8c432 5 char sTemp2[16];
TickTock 13:62e0f7f39ff5 6
TickTock 13:62e0f7f39ff5 7 void printLast (bool force){
TickTock 13:62e0f7f39ff5 8 CANMessage msg;
TickTock 13:62e0f7f39ff5 9 tt.locate(0,6);
TickTock 13:62e0f7f39ff5 10 tt.foreground(Red);
TickTock 13:62e0f7f39ff5 11 tt.background(Yellow);
TickTock 13:62e0f7f39ff5 12 if(force) tt.cls(); // Just clear screen if forced - always update display
TickTock 13:62e0f7f39ff5 13 tt.set_font((unsigned char*) Arial12x12_prop); // select the font
TickTock 13:62e0f7f39ff5 14 for(int i=0; i<19; i++){
TickTock 13:62e0f7f39ff5 15 msg = lastMsg[i+indexOffset];
TickTock 13:62e0f7f39ff5 16 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]);
TickTock 13:62e0f7f39ff5 17 }
TickTock 25:ddf0ec209f03 18 if(sMode==1){
TickTock 25:ddf0ec209f03 19 tt.foreground(Yellow);
TickTock 25:ddf0ec209f03 20 tt.background(DarkCyan);
TickTock 25:ddf0ec209f03 21 tt.set_font((unsigned char*) Arial12x12);
TickTock 25:ddf0ec209f03 22 sprintf(sTemp1,"<up>");
TickTock 25:ddf0ec209f03 23 sprintf(sTemp2,"");
TickTock 25:ddf0ec209f03 24 showButton(0,0,sTemp1,sTemp2,3,3);
TickTock 25:ddf0ec209f03 25 tt.foreground(Yellow);
TickTock 25:ddf0ec209f03 26 tt.background(DarkCyan);
TickTock 25:ddf0ec209f03 27 tt.set_font((unsigned char*) Arial12x12);
TickTock 25:ddf0ec209f03 28 sprintf(sTemp1,"<down>");
TickTock 25:ddf0ec209f03 29 showButton(2,0,sTemp1,sTemp2,3,3);
TickTock 25:ddf0ec209f03 30 }
TickTock 13:62e0f7f39ff5 31 }
TickTock 13:62e0f7f39ff5 32
TickTock 13:62e0f7f39ff5 33 void printChanged (bool force){
TickTock 13:62e0f7f39ff5 34 CANMessage msg;
TickTock 13:62e0f7f39ff5 35 unsigned char i,j;
TickTock 13:62e0f7f39ff5 36 tt.locate(0,6);
TickTock 13:62e0f7f39ff5 37 tt.foreground(Red);
TickTock 13:62e0f7f39ff5 38 tt.background(Yellow);
TickTock 13:62e0f7f39ff5 39 if(force) tt.cls(); // Just clear screen if forced - always update display
TickTock 13:62e0f7f39ff5 40 tt.set_font((unsigned char*) Arial12x12_prop); // select the font
TickTock 13:62e0f7f39ff5 41 i=0;
TickTock 13:62e0f7f39ff5 42 j=indexOffset;
TickTock 13:62e0f7f39ff5 43 do{
TickTock 13:62e0f7f39ff5 44 j=j<99?j+1:j;
TickTock 13:62e0f7f39ff5 45 if(msgChanged[j]>0){
TickTock 13:62e0f7f39ff5 46 msg = lastMsg[j];
TickTock 13:62e0f7f39ff5 47 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]);
TickTock 13:62e0f7f39ff5 48 i++;
TickTock 13:62e0f7f39ff5 49 }// if changed
TickTock 13:62e0f7f39ff5 50 }while(i<19&&j<99);
TickTock 13:62e0f7f39ff5 51 }
TickTock 13:62e0f7f39ff5 52
TickTock 13:62e0f7f39ff5 53 void printLog (bool force){
TickTock 13:62e0f7f39ff5 54 static unsigned char lastDisplayLoc = 0;
TickTock 13:62e0f7f39ff5 55 if(force||displayLoc!=lastDisplayLoc){ //only update if changed
TickTock 13:62e0f7f39ff5 56 tt.foreground(Amber);
TickTock 13:62e0f7f39ff5 57 tt.background(Black);
TickTock 13:62e0f7f39ff5 58 tt.cls();
TickTock 13:62e0f7f39ff5 59 tt.locate(0,6);
TickTock 13:62e0f7f39ff5 60 tt.set_font((unsigned char*) Arial12x12);
TickTock 13:62e0f7f39ff5 61 for(int i=0; i<19; i++){
TickTock 13:62e0f7f39ff5 62 printf("%s",displayLog[displayLoc]);
TickTock 13:62e0f7f39ff5 63 displayLoc=displayLoc>17?0:displayLoc+1;
TickTock 13:62e0f7f39ff5 64 }
TickTock 13:62e0f7f39ff5 65 }
TickTock 13:62e0f7f39ff5 66 lastDisplayLoc=displayLoc;
TickTock 13:62e0f7f39ff5 67 }
TickTock 13:62e0f7f39ff5 68
TickTock 13:62e0f7f39ff5 69 void printDTE (bool force){
TickTock 13:62e0f7f39ff5 70 unsigned short gids, SOC, packV;
TickTock 13:62e0f7f39ff5 71 static unsigned short lgids=0, lSOC=0, lpackV=0;
TickTock 13:62e0f7f39ff5 72 CANMessage msg;
TickTock 13:62e0f7f39ff5 73
TickTock 13:62e0f7f39ff5 74 msg = lastMsg[indexLastMsg[0x5bc]]; //Get gids
TickTock 13:62e0f7f39ff5 75 gids = (msg.data[0]<<2)+(msg.data[1]>>6);
TickTock 13:62e0f7f39ff5 76 msg = lastMsg[indexLastMsg[0x55b]]; //Get SOC
TickTock 13:62e0f7f39ff5 77 SOC = (msg.data[0]<<2)+(msg.data[1]>>6);
TickTock 13:62e0f7f39ff5 78 msg = lastMsg[indexLastMsg[0x1db]]; //Get pack volts
TickTock 13:62e0f7f39ff5 79 packV = (msg.data[2]<<2)+(msg.data[3]>>6);
TickTock 13:62e0f7f39ff5 80
TickTock 13:62e0f7f39ff5 81 tt.background(Navy);
TickTock 13:62e0f7f39ff5 82 if(force) tt.cls();
TickTock 13:62e0f7f39ff5 83 if(force||gids!=lgids){
TickTock 25:ddf0ec209f03 84 tt.foreground(Yellow);
TickTock 13:62e0f7f39ff5 85 tt.set_font((unsigned char*) Arial28x28);
TickTock 13:62e0f7f39ff5 86 tt.locate(10,10);
TickTock 13:62e0f7f39ff5 87 printf("%4d gids\n",gids);
TickTock 13:62e0f7f39ff5 88 tt.locate(10,200);
TickTock 13:62e0f7f39ff5 89 printf("%4.1f kWh\n",(float)gids*0.08);
TickTock 13:62e0f7f39ff5 90 tt.set_font((unsigned char*) SCProSB31x55);
TickTock 13:62e0f7f39ff5 91 //tt.set_font((unsigned char*) Neu42x35);
TickTock 13:62e0f7f39ff5 92 tt.foreground(Green);
TickTock 13:62e0f7f39ff5 93 tt.locate(60,96);
TickTock 13:62e0f7f39ff5 94 printf("%4.1f mi \n",(float)(gids-5)*0.33); // Approx for now
TickTock 13:62e0f7f39ff5 95 lgids=gids;
TickTock 13:62e0f7f39ff5 96 }
TickTock 13:62e0f7f39ff5 97 if(force||SOC!=lSOC){
TickTock 25:ddf0ec209f03 98 tt.foreground(Yellow);
TickTock 13:62e0f7f39ff5 99 tt.set_font((unsigned char*) Arial28x28);
TickTock 13:62e0f7f39ff5 100 tt.locate(200,10);
TickTock 13:62e0f7f39ff5 101 printf("%4.1f%s\n",(float)SOC/10,"%");
TickTock 13:62e0f7f39ff5 102 lSOC=SOC;
TickTock 13:62e0f7f39ff5 103 }
TickTock 13:62e0f7f39ff5 104 if(force||packV!=lpackV){
TickTock 25:ddf0ec209f03 105 tt.foreground(Yellow);
TickTock 13:62e0f7f39ff5 106 tt.set_font((unsigned char*) Arial28x28);
TickTock 13:62e0f7f39ff5 107 tt.locate(200,200);
TickTock 13:62e0f7f39ff5 108 printf("%4.1fV\n",(float)packV/2);
TickTock 13:62e0f7f39ff5 109 lpackV=packV;
TickTock 13:62e0f7f39ff5 110 }
TickTock 13:62e0f7f39ff5 111 }
TickTock 13:62e0f7f39ff5 112
TickTock 25:ddf0ec209f03 113 void braking (bool force, bool prdata=false){
TickTock 23:cd03f9c3395e 114 unsigned long targetBraking, regenBraking, speed;
TickTock 27:6bd073c33977 115 static unsigned long maxTarget = 20000, maxRegen = 20000, tarDivReg = 1000;
TickTock 13:62e0f7f39ff5 116 short rpm;
TickTock 13:62e0f7f39ff5 117 unsigned long temp;
TickTock 13:62e0f7f39ff5 118 static unsigned char lastPressure[4] = {200,200,200,200};
TickTock 13:62e0f7f39ff5 119 unsigned char i,r,t;
TickTock 13:62e0f7f39ff5 120 static unsigned char lr, lt;
TickTock 13:62e0f7f39ff5 121 CANMessage msg;
TickTock 13:62e0f7f39ff5 122
TickTock 13:62e0f7f39ff5 123 msg = lastMsg[indexLastMsg[0x1cb]]; //Get Target and Regen
TickTock 13:62e0f7f39ff5 124 regenBraking = (msg.data[0]<<3)+(msg.data[1]>>5);
TickTock 13:62e0f7f39ff5 125 targetBraking = (msg.data[2]<<3)+(msg.data[3]>>5);
TickTock 13:62e0f7f39ff5 126 msg = lastMsg[indexLastMsg[0x176]]; //Get rpms - not sure what this is but scales to mph with .0725
TickTock 13:62e0f7f39ff5 127 rpm = ((short)msg.data[0]<<8)+msg.data[1];
TickTock 13:62e0f7f39ff5 128 speed =rpm>0?rpm>>3:-rpm>>3; //Take absolute to get speed; div8
TickTock 23:cd03f9c3395e 129 if ((targetBraking>2039)||(speed>200)) { //Filter weird messages
TickTock 23:cd03f9c3395e 130 targetBraking = 0;
TickTock 23:cd03f9c3395e 131 regenBraking = 0;
TickTock 23:cd03f9c3395e 132 } else {
TickTock 23:cd03f9c3395e 133 if ((targetBraking>50)&&(regenBraking>50)){
TickTock 23:cd03f9c3395e 134 temp = targetBraking;
TickTock 23:cd03f9c3395e 135 temp *= 1000;
TickTock 23:cd03f9c3395e 136 temp /= regenBraking;
TickTock 23:cd03f9c3395e 137 if (temp<tarDivReg) tarDivReg=temp;
TickTock 23:cd03f9c3395e 138 }
TickTock 23:cd03f9c3395e 139 targetBraking *= speed;
TickTock 23:cd03f9c3395e 140 regenBraking *= speed;
TickTock 23:cd03f9c3395e 141 if (targetBraking>maxTarget) maxTarget=targetBraking;
TickTock 23:cd03f9c3395e 142 if (regenBraking>maxRegen) maxRegen=regenBraking;
TickTock 23:cd03f9c3395e 143 }
TickTock 23:cd03f9c3395e 144
TickTock 13:62e0f7f39ff5 145 msg = lastMsg[indexLastMsg[0x1ca]]; //Get brake pressure
TickTock 13:62e0f7f39ff5 146 tt.background(Navy);
TickTock 13:62e0f7f39ff5 147 if (force) {
TickTock 13:62e0f7f39ff5 148 tt.cls();
TickTock 13:62e0f7f39ff5 149 tt.rect(0,111,170,239,White);
TickTock 13:62e0f7f39ff5 150 tt.line(0,207,170,207,White);
TickTock 13:62e0f7f39ff5 151 tt.line(0,175,170,175,White);
TickTock 13:62e0f7f39ff5 152 tt.line(0,143,170,143,White);
TickTock 13:62e0f7f39ff5 153 lastPressure[0] = 200;
TickTock 13:62e0f7f39ff5 154 lastPressure[1] = 200;
TickTock 13:62e0f7f39ff5 155 lastPressure[2] = 200;
TickTock 13:62e0f7f39ff5 156 lastPressure[3] = 200;
TickTock 13:62e0f7f39ff5 157 }
TickTock 13:62e0f7f39ff5 158 // plot bar graph for each wheel pressure
TickTock 13:62e0f7f39ff5 159 for (i=0; i<4; i++){
TickTock 13:62e0f7f39ff5 160 if (msg.data[i]<239) {
TickTock 13:62e0f7f39ff5 161 if (msg.data[i]>lastPressure[i]){
TickTock 13:62e0f7f39ff5 162 tt.fillrect(10+40*i,239-msg.data[i],40+40*i,239,Red);
TickTock 13:62e0f7f39ff5 163 } else if (msg.data[i]<lastPressure[i]) {
TickTock 13:62e0f7f39ff5 164 tt.fillrect(10+40*i,238-lastPressure[i],40+40*i,238-msg.data[i],Navy);
TickTock 13:62e0f7f39ff5 165 }
TickTock 13:62e0f7f39ff5 166 lastPressure[i]=msg.data[i];
TickTock 13:62e0f7f39ff5 167 }
TickTock 13:62e0f7f39ff5 168 }
TickTock 13:62e0f7f39ff5 169
TickTock 27:6bd073c33977 170 temp = targetBraking;
TickTock 27:6bd073c33977 171 temp *=200;
TickTock 27:6bd073c33977 172 temp /= maxTarget;
TickTock 27:6bd073c33977 173 t = (char) temp;
TickTock 27:6bd073c33977 174 if (t>200) t=200;
TickTock 27:6bd073c33977 175 temp = regenBraking;
TickTock 27:6bd073c33977 176 temp *= tarDivReg;
TickTock 27:6bd073c33977 177 temp /= maxTarget;
TickTock 27:6bd073c33977 178 temp /= 5;
TickTock 27:6bd073c33977 179 r = (char) temp;
TickTock 27:6bd073c33977 180 if (r>200) r=200;
TickTock 27:6bd073c33977 181 if(lr!=r&&prdata){
TickTock 27:6bd073c33977 182 tt.foreground(Yellow);
TickTock 27:6bd073c33977 183 tt.set_font((unsigned char*) Arial28x28);
TickTock 27:6bd073c33977 184 tt.locate(100,40);
TickTock 27:6bd073c33977 185 printf("%d %d \n",regenBraking,maxRegen);
TickTock 27:6bd073c33977 186 tt.locate(100,70);
TickTock 27:6bd073c33977 187 printf("%3.1f (%3.1f%s) \n",(float)tarDivReg/10,(float)regenBraking*tarDivReg/targetBraking/10,"%");
TickTock 27:6bd073c33977 188 }
TickTock 27:6bd073c33977 189 if(lt!=t&&prdata){
TickTock 27:6bd073c33977 190 tt.foreground(Yellow);
TickTock 27:6bd073c33977 191 tt.set_font((unsigned char*) Arial28x28);
TickTock 27:6bd073c33977 192 tt.locate(100,10);
TickTock 27:6bd073c33977 193 printf("%d %d \n",targetBraking,maxTarget);
TickTock 13:62e0f7f39ff5 194 }
TickTock 27:6bd073c33977 195 if (r>t) t=r; //Should never happen
TickTock 27:6bd073c33977 196 if((lr!=r||lt!=t)&&!prdata){
TickTock 27:6bd073c33977 197 tt.fillrect(200,10,300,239-t,Navy);
TickTock 27:6bd073c33977 198 tt.fillrect(200,239-t,300,239-r,Red);
TickTock 27:6bd073c33977 199 tt.fillrect(200,239-r,300,239,Green);
TickTock 27:6bd073c33977 200 }
TickTock 27:6bd073c33977 201 lt=t;
TickTock 27:6bd073c33977 202 lr=r;
TickTock 13:62e0f7f39ff5 203 }
TickTock 13:62e0f7f39ff5 204
TickTock 13:62e0f7f39ff5 205 void cpData(bool force){
TickTock 13:62e0f7f39ff5 206 short unsigned max, min, jv, i, bd;
TickTock 13:62e0f7f39ff5 207 unsigned avg;
TickTock 13:62e0f7f39ff5 208 if(force){
TickTock 13:62e0f7f39ff5 209 tt.foreground(White);
TickTock 13:62e0f7f39ff5 210 tt.background(Navy);
TickTock 13:62e0f7f39ff5 211 tt.set_font((unsigned char*) Arial12x12_prop); // select the font
TickTock 13:62e0f7f39ff5 212 max=0;
TickTock 13:62e0f7f39ff5 213 min=9999;
TickTock 13:62e0f7f39ff5 214 avg=0;
TickTock 13:62e0f7f39ff5 215 for(i=0; i<96; i++){
TickTock 13:62e0f7f39ff5 216 bd=(battData[i*2+3]<<8)+battData[i*2+4];
TickTock 13:62e0f7f39ff5 217 avg+=bd;
TickTock 13:62e0f7f39ff5 218 if(bd>max) max=bd;
TickTock 13:62e0f7f39ff5 219 if(bd<min) min=bd;
TickTock 13:62e0f7f39ff5 220 }
TickTock 13:62e0f7f39ff5 221 avg /= 96;
TickTock 13:62e0f7f39ff5 222 if(min<3713) {
TickTock 13:62e0f7f39ff5 223 jv=avg-(max-avg)*1.5;
TickTock 13:62e0f7f39ff5 224 } else { // Only compute judgement value if min cellpair meets <= 3712mV requirement
TickTock 13:62e0f7f39ff5 225 jv=0;
TickTock 13:62e0f7f39ff5 226 }
TickTock 13:62e0f7f39ff5 227 tt.cls();
TickTock 13:62e0f7f39ff5 228 tt.locate(0,6);
TickTock 13:62e0f7f39ff5 229 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]);
TickTock 13:62e0f7f39ff5 230 tt.locate(0,36);
TickTock 13:62e0f7f39ff5 231 for(i=0; i<16; i++){
TickTock 13:62e0f7f39ff5 232 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]);
TickTock 13:62e0f7f39ff5 233 }
TickTock 13:62e0f7f39ff5 234 tt.rect(8+0*41,16,40+0*41,28,Green);
TickTock 13:62e0f7f39ff5 235 tt.rect(8+1*41,16,40+1*41,28,Yellow);
TickTock 13:62e0f7f39ff5 236 //tt.rect(8+2*41,16,40+2*41,28,White);
TickTock 13:62e0f7f39ff5 237 tt.rect(8+3*41,16,40+3*41,28,Red);
TickTock 13:62e0f7f39ff5 238 for(i=0; i<96; i++){
TickTock 13:62e0f7f39ff5 239 bd=(battData[i*2+3]<<8)+battData[i*2+4];
TickTock 13:62e0f7f39ff5 240 if(bd>0){
TickTock 13:62e0f7f39ff5 241 if(bd==max) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Green);
TickTock 13:62e0f7f39ff5 242 //if(bd==avg) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,White);
TickTock 13:62e0f7f39ff5 243 if(bd==min) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Yellow);
TickTock 13:62e0f7f39ff5 244 if(bd<jv) tt.rect(58+(i%6)*41,34+(int)(i/6)*12,90+(i%6)*41,46+(int)(i/6)*12,Red);
TickTock 13:62e0f7f39ff5 245 }
TickTock 13:62e0f7f39ff5 246 }
TickTock 13:62e0f7f39ff5 247 showCP=false;
TickTock 13:62e0f7f39ff5 248 }
TickTock 25:ddf0ec209f03 249 if(sMode==1){
TickTock 25:ddf0ec209f03 250 tt.foreground(Yellow);
TickTock 25:ddf0ec209f03 251 tt.background(DarkCyan);
TickTock 25:ddf0ec209f03 252 tt.set_font((unsigned char*) Arial12x12);
TickTock 25:ddf0ec209f03 253 sprintf(sTemp1,"Request");
TickTock 25:ddf0ec209f03 254 sprintf(sTemp2,"CP data");
TickTock 25:ddf0ec209f03 255 showButton(1,0,sTemp1,sTemp2,3,3);
TickTock 25:ddf0ec209f03 256 }
TickTock 13:62e0f7f39ff5 257 }
TickTock 13:62e0f7f39ff5 258
TickTock 23:cd03f9c3395e 259 void config1(bool force){
TickTock 23:cd03f9c3395e 260 if (force) {
TickTock 23:cd03f9c3395e 261 tt.background(Black);
TickTock 23:cd03f9c3395e 262 tt.cls();
TickTock 23:cd03f9c3395e 263 }
TickTock 23:cd03f9c3395e 264 tt.foreground(Yellow);
TickTock 23:cd03f9c3395e 265 tt.background(DarkCyan);
TickTock 23:cd03f9c3395e 266 tt.set_font((unsigned char*) Arial12x12);
TickTock 24:6cf76ed8c432 267 sprintf(sTemp1," Calibrate");
TickTock 24:6cf76ed8c432 268 sprintf(sTemp2," Touch");
TickTock 24:6cf76ed8c432 269 showButton(0,0,sTemp1,sTemp2,3,3);
TickTock 24:6cf76ed8c432 270 sprintf(sTemp1," Reset");
TickTock 24:6cf76ed8c432 271 sprintf(sTemp2,"");
TickTock 24:6cf76ed8c432 272 showButton(1,0,sTemp1,sTemp2,3,3);
TickTock 24:6cf76ed8c432 273 sprintf(sTemp1," Save");
TickTock 24:6cf76ed8c432 274 sprintf(sTemp2," Config");
TickTock 24:6cf76ed8c432 275 showButton(2,0,sTemp1,sTemp2,3,3);
TickTock 23:cd03f9c3395e 276 if (logEn) {
TickTock 24:6cf76ed8c432 277 sprintf(sTemp1," Disable");
TickTock 23:cd03f9c3395e 278 } else {
TickTock 24:6cf76ed8c432 279 sprintf(sTemp1," Enable");
TickTock 23:cd03f9c3395e 280 }
TickTock 24:6cf76ed8c432 281 sprintf(sTemp2," Logging");
TickTock 24:6cf76ed8c432 282 showButton(0,1,sTemp1,sTemp2,3,3);
TickTock 23:cd03f9c3395e 283 }
TickTock 23:cd03f9c3395e 284
TickTock 25:ddf0ec209f03 285 void showDateTime(bool force){
TickTock 25:ddf0ec209f03 286 struct tm t; // pointer to a static tm structure
TickTock 25:ddf0ec209f03 287 time_t seconds ;
TickTock 25:ddf0ec209f03 288 tt.foreground(Yellow);
TickTock 25:ddf0ec209f03 289 tt.background(Navy);
TickTock 25:ddf0ec209f03 290 if (force) {
TickTock 25:ddf0ec209f03 291 tt.cls();
TickTock 25:ddf0ec209f03 292 seconds = time(NULL);
TickTock 25:ddf0ec209f03 293 t = *localtime(&seconds) ;
TickTock 25:ddf0ec209f03 294
TickTock 25:ddf0ec209f03 295 tt.locate(10,10);
TickTock 25:ddf0ec209f03 296 strftime(sTemp1, 32, "%a %m/%d/%Y %X \n", &t);
TickTock 25:ddf0ec209f03 297 printf("%s",sTemp1);
TickTock 25:ddf0ec209f03 298 if(sMode==1){
TickTock 25:ddf0ec209f03 299 tt.foreground(Yellow);
TickTock 25:ddf0ec209f03 300 tt.background(DarkCyan);
TickTock 25:ddf0ec209f03 301 tt.set_font((unsigned char*) Arial12x12);
TickTock 26:462ccb580472 302 sprintf(sTemp2,"");
TickTock 25:ddf0ec209f03 303 switch(dtMode){
TickTock 25:ddf0ec209f03 304 case 0:
TickTock 26:462ccb580472 305 sprintf(sTemp1,"Year");
TickTock 25:ddf0ec209f03 306 break;
TickTock 25:ddf0ec209f03 307 case 1:
TickTock 26:462ccb580472 308 sprintf(sTemp1,"Month");
TickTock 25:ddf0ec209f03 309 break;
TickTock 25:ddf0ec209f03 310 case 2:
TickTock 26:462ccb580472 311 sprintf(sTemp1,"Day");
TickTock 25:ddf0ec209f03 312 break;
TickTock 25:ddf0ec209f03 313 case 3:
TickTock 26:462ccb580472 314 sprintf(sTemp1,"Hour");
TickTock 25:ddf0ec209f03 315 break;
TickTock 25:ddf0ec209f03 316 case 4:
TickTock 26:462ccb580472 317 sprintf(sTemp1,"Minute");
TickTock 25:ddf0ec209f03 318 break;
TickTock 25:ddf0ec209f03 319 case 5:
TickTock 26:462ccb580472 320 sprintf(sTemp1,"Second");
TickTock 25:ddf0ec209f03 321 break;
TickTock 25:ddf0ec209f03 322 case 6:
TickTock 26:462ccb580472 323 sprintf(sTemp1,"Select");
TickTock 25:ddf0ec209f03 324 break;
TickTock 25:ddf0ec209f03 325 default:
TickTock 25:ddf0ec209f03 326 break;
TickTock 25:ddf0ec209f03 327 }
TickTock 25:ddf0ec209f03 328 showButton(0,1,sTemp1,sTemp2,3,3);
TickTock 26:462ccb580472 329 sprintf(sTemp1," UP");
TickTock 25:ddf0ec209f03 330 showButton(1,1,sTemp1,sTemp2,3,3);
TickTock 26:462ccb580472 331 sprintf(sTemp1," DOWN");
TickTock 25:ddf0ec209f03 332 showButton(2,1,sTemp1,sTemp2,3,3);
TickTock 25:ddf0ec209f03 333 }
TickTock 25:ddf0ec209f03 334 }
TickTock 25:ddf0ec209f03 335 }
TickTock 25:ddf0ec209f03 336
TickTock 13:62e0f7f39ff5 337 void updateDisplay(char display){
TickTock 13:62e0f7f39ff5 338 bool changed;
TickTock 13:62e0f7f39ff5 339 changed = dMode[display]!=lastDMode[display];
TickTock 13:62e0f7f39ff5 340 tt.set_display(display);
TickTock 13:62e0f7f39ff5 341 switch (dMode[display]) {
TickTock 13:62e0f7f39ff5 342 case logScreen:
TickTock 13:62e0f7f39ff5 343 printLog(changed);
TickTock 13:62e0f7f39ff5 344 break;
TickTock 13:62e0f7f39ff5 345 case dteScreen:
TickTock 13:62e0f7f39ff5 346 printDTE(changed);
TickTock 13:62e0f7f39ff5 347 break;
TickTock 13:62e0f7f39ff5 348 case brakeScreen:
TickTock 27:6bd073c33977 349 braking(changed);
TickTock 13:62e0f7f39ff5 350 break;
TickTock 13:62e0f7f39ff5 351 case powerScreen:
TickTock 27:6bd073c33977 352 //braking(changed, true);
TickTock 27:6bd073c33977 353 //break;
TickTock 13:62e0f7f39ff5 354 case monitorScreen:
TickTock 13:62e0f7f39ff5 355 printLast(changed);
TickTock 13:62e0f7f39ff5 356 break;
TickTock 13:62e0f7f39ff5 357 case changedScreen:
TickTock 13:62e0f7f39ff5 358 printChanged(changed);
TickTock 13:62e0f7f39ff5 359 break;
TickTock 13:62e0f7f39ff5 360 case cpScreen:
TickTock 13:62e0f7f39ff5 361 cpData(changed||showCP);
TickTock 13:62e0f7f39ff5 362 break;
TickTock 25:ddf0ec209f03 363 case config1Screen:
TickTock 23:cd03f9c3395e 364 config1(changed);
TickTock 22:a43df3905863 365 break;
TickTock 25:ddf0ec209f03 366 case config2Screen:
TickTock 25:ddf0ec209f03 367 showDateTime(changed);
TickTock 25:ddf0ec209f03 368 break;
TickTock 13:62e0f7f39ff5 369 default:
TickTock 13:62e0f7f39ff5 370 tt.background(Black);
TickTock 13:62e0f7f39ff5 371 tt.cls();
TickTock 13:62e0f7f39ff5 372 break;
TickTock 13:62e0f7f39ff5 373 }
TickTock 13:62e0f7f39ff5 374 lastDMode[display]=dMode[display];
TickTock 13:62e0f7f39ff5 375
TickTock 13:62e0f7f39ff5 376 switch (sMode) {
TickTock 22:a43df3905863 377 case 1: // Select screens
TickTock 13:62e0f7f39ff5 378 tt.foreground(Yellow);
TickTock 13:62e0f7f39ff5 379 tt.background(DarkCyan);
TickTock 13:62e0f7f39ff5 380 tt.set_font((unsigned char*) Arial12x12);
TickTock 24:6cf76ed8c432 381 sprintf(sTemp1,"<-Prev");
TickTock 24:6cf76ed8c432 382 sprintf(sTemp2,"");
TickTock 24:6cf76ed8c432 383 showButton(0,2,sTemp1,sTemp2,3,3);
TickTock 24:6cf76ed8c432 384 sprintf(sTemp1," Select %d",dMode[display]);
TickTock 24:6cf76ed8c432 385 showButton(1,2,sTemp1,sTemp2,3,3);
TickTock 24:6cf76ed8c432 386 sprintf(sTemp1," Next->");
TickTock 24:6cf76ed8c432 387 showButton(2,2,sTemp1,sTemp2,3,3);
TickTock 13:62e0f7f39ff5 388 break;
TickTock 22:a43df3905863 389 case 2: // numpad
TickTock 24:6cf76ed8c432 390 sprintf(sTemp2,"");
TickTock 22:a43df3905863 391 tt.foreground(Yellow);
TickTock 22:a43df3905863 392 tt.background(DarkCyan);
TickTock 22:a43df3905863 393 tt.set_font((unsigned char*) Arial24x23);
TickTock 24:6cf76ed8c432 394 sprintf(sTemp1," 1");
TickTock 24:6cf76ed8c432 395 showButton(0,0,sTemp1,sTemp2,4,4);
TickTock 24:6cf76ed8c432 396 sprintf(sTemp1," 2");
TickTock 24:6cf76ed8c432 397 showButton(1,0,sTemp1,sTemp2,4,4);
TickTock 24:6cf76ed8c432 398 sprintf(sTemp1," 3");
TickTock 24:6cf76ed8c432 399 showButton(2,0,sTemp1,sTemp2,4,4);
TickTock 24:6cf76ed8c432 400 sprintf(sTemp1," 4");
TickTock 24:6cf76ed8c432 401 showButton(0,1,sTemp1,sTemp2,4,4);
TickTock 24:6cf76ed8c432 402 sprintf(sTemp1," 5");
TickTock 24:6cf76ed8c432 403 showButton(1,1,sTemp1,sTemp2,4,4);
TickTock 24:6cf76ed8c432 404 sprintf(sTemp1," 6");
TickTock 24:6cf76ed8c432 405 showButton(2,1,sTemp1,sTemp2,4,4);
TickTock 24:6cf76ed8c432 406 sprintf(sTemp1," 7");
TickTock 24:6cf76ed8c432 407 showButton(0,2,sTemp1,sTemp2,4,4);
TickTock 24:6cf76ed8c432 408 sprintf(sTemp1," 8");
TickTock 24:6cf76ed8c432 409 showButton(1,2,sTemp1,sTemp2,4,4);
TickTock 24:6cf76ed8c432 410 sprintf(sTemp1," 9");
TickTock 24:6cf76ed8c432 411 showButton(2,2,sTemp1,sTemp2,4,4);
TickTock 24:6cf76ed8c432 412 sprintf(sTemp1," 0");
TickTock 24:6cf76ed8c432 413 showButton(1,3,sTemp1,sTemp2,4,4);
TickTock 24:6cf76ed8c432 414 sprintf(sTemp1,"<--");
TickTock 24:6cf76ed8c432 415 showButton(0,3,sTemp1,sTemp2,4,4);
TickTock 24:6cf76ed8c432 416 sprintf(sTemp1,"-->");
TickTock 24:6cf76ed8c432 417 showButton(2,3,sTemp1,sTemp2,4,4);
TickTock 24:6cf76ed8c432 418 sprintf(sTemp1,"return");
TickTock 24:6cf76ed8c432 419 showButton(3,3,sTemp1,sTemp2,4,4);
TickTock 23:cd03f9c3395e 420 case 3:
TickTock 23:cd03f9c3395e 421 break;
TickTock 13:62e0f7f39ff5 422 default:
TickTock 13:62e0f7f39ff5 423 break;
TickTock 13:62e0f7f39ff5 424 }
TickTock 13:62e0f7f39ff5 425 }
TickTock 22:a43df3905863 426
TickTock 24:6cf76ed8c432 427 void showButton(unsigned char column, unsigned char row, char * text1, char * text2, unsigned char columns, unsigned char rows){
TickTock 22:a43df3905863 428 unsigned short x1,x2,y1,y2;
TickTock 22:a43df3905863 429 x1=column*(320/columns)+btnGap/2;
TickTock 22:a43df3905863 430 x2=(column+1)*(320/columns)-btnGap/2;
TickTock 22:a43df3905863 431 y1=row*(240/rows)+btnGap/2;
TickTock 22:a43df3905863 432 y2=(row+1)*(240/rows)-btnGap/2;
TickTock 22:a43df3905863 433 tt.fillrect(x1,y1,x2,y2,DarkCyan);
TickTock 22:a43df3905863 434 tt.locate(x1+btnGap,y1+btnGap);
TickTock 24:6cf76ed8c432 435 printf("%s\n",text1);
TickTock 24:6cf76ed8c432 436 tt.locate(x1+btnGap,y1+btnGap+30);
TickTock 24:6cf76ed8c432 437 printf("%s\n",text2);
TickTock 22:a43df3905863 438 }
TickTock 23:cd03f9c3395e 439