Dual CANbus monitor and instrumentation cluster. Presently tuned for the Nissan Leaf EV.

Dependencies:   SPI_TFTx2_ILI9341 TFT_fonts TOUCH_TFTx2_ILI9341 mbed

Fork of CANary_corrupt by Tick Tock

After adding the LPC1768 platform, import as a program and do not select the "update to latest revision" box

User Guide

Eagle Schematic and Board design

/media/uploads/TickTock/canaryr6.zip

/media/uploads/TickTock/canary_sch.jpg

/media/uploads/TickTock/canaryr6brd.jpg

For LCD Rev 1.01:

/media/uploads/TickTock/lcdsch.jpg

For VCD Rev 2.00:

/media/uploads/TickTock/lcdr2.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
1R1R393M120639K resistor
1R2R103M120610K resistor
4R4-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
1Z1DC-DC conveterhttp://www.ebay.com/itm/251142727849?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l264912V-7V, 3W DC-DC converter
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
1E0Enclosurehttp://www.shapeways.com/model/1077799/canary.html?li=user-profile&materialId=63d printed enclosure

Assembly

1) LCD Displays

I found ribbon cable is a nice way to organize the wires to the displays. There are two versions of the display and each must be wired differently. The original project used HW REV. 1.01. For that version, you'll need 12 conductors and I connected them in the following order:

1LED+
2LED-
3RST
4SDI
5WR/SCLK
6CS
7X+
8X-
9Y+
10Y-
11VDD
12GND

If, instead, you have HW REV 2.0, you will need 13 conductors with the following order:

1LED+
2LED-
3RST
4SDI
5RS (SCLK)
6WR (DC)
7CS
8X+
9X-
10Y+
11Y-
12VDD
13GND

First I connected all the GND connections (2 GND & IM0, IM1, IM3 for REV1.01 or 2 GND, RD, & IM0 for REV2.00). 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 for REV1.01 or to IM1,IM2,&IM3 for REV2.00. Take a break and repeat for the second display.

Examples of REV1.01 boards:

/media/uploads/TickTock/lcdtop.jpg /media/uploads/TickTock/lcdbot.jpg

Examples of REV2.00:

/media/uploads/TickTock/rev2front.jpg /media/uploads/TickTock/rev2back.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.Update: Several Zeners have failed resulting in damage to some users boards so I recommend using a DC-DC converter instead to bring the 12V down to 7V.

/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

Update: The Zener diodes tended to fail after a few months so I am recommending removing them and replacing with a DC-DC converter. This will run cooler and waste less energy, too. To install, remove the left display panel to gain access to the Zener. From there, the Zener can be removed and it's pads used to connect to the DC-DC converter. I recommend setting the output voltage on the bench before installing since the trim pot is tricky to reach once installed. Set it to 7V. The input can be connected to the left pad previously occupied by the zener and the output can connect to the right. GND(-) can be connected to the bottom right pad on the 2x6 header below the flex cable connector. Make sure the GND wire lies flat so it doesn't interfere with the connection of the flex cable. /media/uploads/TickTock/dcdcinst2.jpg

Once soldered in place, the DC-DC converter can easily be mounted to the back wall with double sided tape above the battery holder. /media/uploads/TickTock/dcdcinst3.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. If you have the REV2.00 LCD boards, you will need to edit the precompile.h file in the TOUCH_TFTx2_w9341 library and set USE_ILI9341 to 1. 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. /media/uploads/TickTock/enclosure.jpg

5) Final Assembly

Make sure you are well rested with lots of patience before attempting assembly. It is a puzzle figuring out how to get both displays and the PCB in place. Enclosure was too expensive for me to keep iterating to optimize for assembly. I ended up snipping the thin display posts shorter and using various tools to push the displays into place. Also, some USB connectors are taller than others. If you have one of the taller ones, you will have to deflect the back wall a bit while inserting the PCB (being careful not to bend the housing) to get it to it's opening in the back wall. Do use a screw in the provided post to secure the PCB as USB insertion will otherwise dislodge it.

I added an additional safety line which wraps around the center post to prevent the enclosure from becoming a projectile in the event of an accident. /media/uploads/TickTock/safety.jpg Installed: /media/uploads/TickTock/installed.jpg

Committer:
TickTock
Date:
Sat Aug 16 01:35:36 2014 +0000
Revision:
196:c1bfa3ed21a6
Parent:
195:ef0af84a4340
Child:
197:f566f65ff034
Fixed bug causing lag during long press

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TickTock 13:62e0f7f39ff5 1 // main.cpp
TickTock 108:29b5a760adc2 2 //
TickTock 4:8d7759f4fe7a 3 //To Do:
TickTock 166:ec3951ba9701 4 // * Fix USB hot plug (must reset every time USB plugged)
TickTock 33:a277743ebdeb 5 // * Add 50% charge option
TickTock 152:a4d66901785d 6 // * Add linear efficiency graph with 10 minute values
TickTock 146:88f7bda79d8e 7 // * Add in-device config editor
TickTock 149:e9739523109f 8 // * Change pack volt color when CVLI fails
TickTock 149:e9739523109f 9 // * Add tire pressure cal (40psi for me = FR 38, RR 38.2, FL 37.8, RL 38 - maybe 2psi error on my tire gauge?)
TickTock 164:46ed06263b0e 10 // * Add on screen messages for heater on, etc, and use refresh feature above to clear in x seconds
TickTock 169:84d790ac18a2 11 // * Be more efficient with write buffer (use msgLen instead of always storing 8 bytes)
TickTock 195:ef0af84a4340 12 // * fix bug where charging while on screws up efficiency computation
TickTock 195:ef0af84a4340 13 // * find better kWh estimate than gids
TickTock 191:292debe95cba 14
TickTock 195:ef0af84a4340 15 // rev195
TickTock 196:c1bfa3ed21a6 16 // Added in-device watchpoint editor
TickTock 188:8cf15e4610aa 17
TickTock 188:8cf15e4610aa 18 // Include this before other header files
TickTock 188:8cf15e4610aa 19 #include "precompile.h"
TickTock 134:ad243e4f1a17 20
TickTock 12:8e42d7ba8468 21 #include "mbed.h"
TickTock 12:8e42d7ba8468 22 #include "CAN.h"
TickTock 109:3e6f0e8fca0d 23 #include "ff.h"
TickTock 12:8e42d7ba8468 24 #include "PowerControl.h"
TickTock 12:8e42d7ba8468 25 #include "EthernetPowerControl.h"
TickTock 12:8e42d7ba8468 26 #include "utility.h"
TickTock 12:8e42d7ba8468 27 #include "displayModes.h"
TickTock 23:cd03f9c3395e 28 #include "TOUCH_TFTx2.h"
TickTock 172:53548bf8bf85 29
TickTock 195:ef0af84a4340 30 char revStr[7] = "195";
TickTock 170:7ee98e3611bc 31 unsigned long maxTarget = 1000;
TickTock 109:3e6f0e8fca0d 32 FATFS USBdrive;
TickTock 13:62e0f7f39ff5 33 LocalFileSystem local("local");
TickTock 115:549410af477d 34 unsigned char wait5secs = 5;
TickTock 13:62e0f7f39ff5 35 // to write to USB Flash Drives, or equivalent (SD card in Reader/Writer)
TickTock 119:0e2b641e98a2 36 // class10 SDcard in Reader/Writer recommended
TickTock 111:d1559bb25c43 37 FRESULT mfr = f_mount(0,&USBdrive);
TickTock 13:62e0f7f39ff5 38 time_t seconds ;
TickTock 13:62e0f7f39ff5 39
TickTock 36:dbd39c315258 40 Ticker autoPoll;
TickTock 36:dbd39c315258 41 Ticker playback;
TickTock 78:a383971fe02f 42 Ticker msgReq;
TickTock 140:ab3e94eb0227 43 Ticker geiger;
TickTock 13:62e0f7f39ff5 44 Timer timer;
TickTock 13:62e0f7f39ff5 45
TickTock 13:62e0f7f39ff5 46 DigitalOut led1(LED1);
TickTock 13:62e0f7f39ff5 47 DigitalOut led2(LED2);
TickTock 13:62e0f7f39ff5 48 DigitalOut led3(LED3);
TickTock 13:62e0f7f39ff5 49 DigitalOut led4(LED4);
TickTock 13:62e0f7f39ff5 50
TickTock 13:62e0f7f39ff5 51 InterruptIn touchpad(p17);
TickTock 13:62e0f7f39ff5 52 CAN can1(p9, p10); // CAN1 (EV) uses pins 9 and 10 (rx, tx) and pin 8 (rs)
TickTock 13:62e0f7f39ff5 53 DigitalOut can1SleepMode(p8); // Use pin 8 to control the sleep mode of can2
TickTock 13:62e0f7f39ff5 54 CAN can2(p30, p29); // CAN2 (CAR) uses pins 30 and 29 (rx, tx) and pin 28 (rs)
TickTock 13:62e0f7f39ff5 55 DigitalOut can2SleepMode(p28); // Use pin 28 to control the sleep mode of can1
TickTock 35:5acbd8a64a89 56 AnalogIn mon12V(p15);
TickTock 188:8cf15e4610aa 57 #if USE_ILI9341 == 1
TickTock 188:8cf15e4610aa 58 TOUCH_TFTx2 tt(p16, p17, p19, p20, p11, p12, p13, p6, p7, p5, p14, "TFT"); // x+, x-, y+, y-, mosi, miso, sclk, cs0, cs1, reset, dc
TickTock 188:8cf15e4610aa 59 #else
TickTock 13:62e0f7f39ff5 60 TOUCH_TFTx2 tt(p16, p17, p19, p20, p11, p12, p13, p6, p7, p5, "TFT"); // x+,x-,y+,y-,mosi, miso, sclk, cs0, cs1, reset
TickTock 188:8cf15e4610aa 61 #endif
TickTock 35:5acbd8a64a89 62 PwmOut dled(p23);
TickTock 155:f31006516956 63 PwmOut spkr(p21);
TickTock 13:62e0f7f39ff5 64
garygid 87:46ac3f2519d6 65 bool debugMode = false;
TickTock 108:29b5a760adc2 66 bool usbEn = false;
TickTock 131:0d926c080a65 67 bool logEn = false;
TickTock 108:29b5a760adc2 68 bool logOpen = false;
TickTock 115:549410af477d 69 bool yesBattLog = true; // gg - Batt Log
TickTock 108:29b5a760adc2 70 unsigned char tNavRow = 3; // gg - 4x4 touch
TickTock 140:ab3e94eb0227 71 bool brakeMon = false; // disable until desired value read from config
TickTock 155:f31006516956 72 bool regenMon = false;
TickTock 159:577e9d015693 73 bool heaterMon = false;
TickTock 152:a4d66901785d 74 bool autoSync = false; // auto clock sync on powerup
TickTock 152:a4d66901785d 75 bool syncDone = true;
TickTock 159:577e9d015693 76 bool heaterOn = false;
TickTock 159:577e9d015693 77 bool lHeaterOn = false;
TickTock 164:46ed06263b0e 78 bool CCon = false;
TickTock 164:46ed06263b0e 79 bool lCCon = false;
TickTock 188:8cf15e4610aa 80 bool checkFWupdate = true;
garygid 54:6ce808d0995e 81
TickTock 109:3e6f0e8fca0d 82 FILE *hfile; // history file
TickTock 109:3e6f0e8fca0d 83 FIL efile; // external usb file
TickTock 109:3e6f0e8fca0d 84 FRESULT efr; // external file access flags
TickTock 109:3e6f0e8fca0d 85 unsigned int bytesRW;
TickTock 108:29b5a760adc2 86 char fileName[35] = "";
TickTock 84:fd21e5d32dab 87 char writeBuffer[maxBufLen][13] __attribute__ ((section("AHBSRAM1"))); // buffer for USB write
TickTock 13:62e0f7f39ff5 88 char indexLastMsg[0x800]={0}; // index table for last message
TickTock 13:62e0f7f39ff5 89 CANMessage lastMsg[100]; // table to store last message of eachtype
garygid 87:46ac3f2519d6 90
TickTock 124:0d622967b764 91 unsigned char battData[BatDataBufMax]={0}; // 7 * 0x3D = BatDataBufMax
garygid 87:46ac3f2519d6 92
TickTock 13:62e0f7f39ff5 93 unsigned char msgChanged[100]; // inidcates which bytes changed
TickTock 13:62e0f7f39ff5 94 char c;
TickTock 76:fb6779d0963e 95 volatile int writePointer = 0;
TickTock 76:fb6779d0963e 96 int readPointer=0;
TickTock 141:cf13a632ddb5 97 volatile unsigned short secsNoCarCanMsg = canTimeout;
TickTock 141:cf13a632ddb5 98 volatile unsigned short secsNoEvCanMsg = canTimeout;
TickTock 75:77bd26829dca 99 volatile unsigned short secsNoTouch = 0;
TickTock 195:ef0af84a4340 100 volatile unsigned short secsTouch = 0;
TickTock 132:08748a67280a 101 volatile bool carCanIdle,evCanIdle,userIdle;
TickTock 26:462ccb580472 102 bool touched=false; //flag to read touchscreen
TickTock 195:ef0af84a4340 103 bool longTouch=false; //flag for long touch
TickTock 42:4533b13b297d 104 unsigned char whichTouched = 0;
TickTock 13:62e0f7f39ff5 105 char counter = 0;
TickTock 41:8d4609ea7259 106 unsigned char dMode[2] = {mainScreen,brakeScreen}; //display mode
TickTock 13:62e0f7f39ff5 107 unsigned char sMode = 0; // setup mode
TickTock 13:62e0f7f39ff5 108 unsigned char lastDMode[2] = {0,0}; //last screen mode
TickTock 131:0d926c080a65 109 unsigned char dtMode = 0;
TickTock 13:62e0f7f39ff5 110 char displayLog[20][40];
TickTock 13:62e0f7f39ff5 111 unsigned char displayLoc = 0;
leafman 98:9f8bab96edff 112 unsigned int fwCount=1;
TickTock 13:62e0f7f39ff5 113 unsigned char indexOffset = 1;
TickTock 13:62e0f7f39ff5 114 bool showCP = false;
TickTock 39:eef8beac7411 115 bool logCP = false; //Turbo3
TickTock 108:29b5a760adc2 116 bool logOnce = false;
TickTock 103:1389e9efe8c3 117 bool repeatPoll = true;
TickTock 34:4751a8259b18 118 bool headlights = false;
TickTock 140:ab3e94eb0227 119 bool miles_kmbar = true;
TickTock 34:4751a8259b18 120 bool tick = false;
garygid 69:6bfdfc002036 121 bool ZeroSecTick = false;
TickTock 192:1d5f0ee9dc59 122 float ledHi = 0.5; // Bright LED value (until config file read)
TickTock 192:1d5f0ee9dc59 123 float ledLo = 0.5; // Dim LED value (until config file read)
TickTock 35:5acbd8a64a89 124 unsigned short pollInt = 300; // polling interval=5 minutes (until config file read)
TickTock 35:5acbd8a64a89 125 bool accOn = false; // Accessories on
TickTock 49:a3d2c5bb3cfa 126 bool laccOn = false;
TickTock 35:5acbd8a64a89 127 float scale12V = 16.2; // R1:R2 ratio
TickTock 170:7ee98e3611bc 128 float kWperGid = 0.080;
TickTock 170:7ee98e3611bc 129 unsigned short startGids = 0; // Gids at start of trip
TickTock 177:6fda79c2fda1 130 unsigned short dailyGids = 0; // Gids per day
TickTock 172:53548bf8bf85 131 bool getGids = false;
TickTock 40:0e6e71a7323f 132 signed long mWs_x4 = 0;
TickTock 40:0e6e71a7323f 133 unsigned short numWsamples = 0;
TickTock 41:8d4609ea7259 134 unsigned short numSsamples = 0;
TickTock 195:ef0af84a4340 135 unsigned short keypad = 0;
TickTock 195:ef0af84a4340 136 unsigned char uidx = 99;
TickTock 35:5acbd8a64a89 137 float accV = 0;
TickTock 143:88b5155622a5 138 float accV2 = 0;
TickTock 161:71ac85d11f03 139 float CCkW = 0;
TickTock 36:dbd39c315258 140 bool playbackEn = false;
TickTock 36:dbd39c315258 141 bool playbackOpen = false;
TickTock 49:a3d2c5bb3cfa 142 //float playbackInt = 0.05; //read messages every 50 ms
TickTock 78:a383971fe02f 143 float playbackInt = 0.005; //read messages every 5 ms
TickTock 36:dbd39c315258 144 bool step = false;
TickTock 37:fea2c1d52c5f 145 char header[5];
TickTock 36:dbd39c315258 146 char data[8];
TickTock 174:cd27e80f197d 147 signed long motorRPM;
garygid 65:821fc79cd7fe 148 unsigned char skin = ttSkin ;
TickTock 50:83d5864c64a0 149 unsigned char dtePeriod = 14; //ten minute averaging interval
TickTock 176:9c19f9856c76 150 float CCkWh_trip[4]={0};
TickTock 176:9c19f9856c76 151 float kWh_trip[4]={0};
TickTock 176:9c19f9856c76 152 float miles_trip[4]={0};
TickTock 144:b0c9d30dd346 153 float curEff = 0;
TickTock 158:059abeb44ba1 154 float maxTripEff = 0;
TickTock 158:059abeb44ba1 155 float minTripEff = 5;
TickTock 167:58d4edf403d4 156 float maxTripMiles = 0;
TickTock 167:58d4edf403d4 157 float maxTripkWh = 1;
TickTock 167:58d4edf403d4 158 float maxTripCCkWh = 0;
TickTock 167:58d4edf403d4 159 float minTripMiles = 5;
TickTock 167:58d4edf403d4 160 float minTripkWh = 1;
TickTock 167:58d4edf403d4 161 float minTripCCkWh = 0;
TickTock 49:a3d2c5bb3cfa 162 float mph[39]={0};
TickTock 49:a3d2c5bb3cfa 163 float kW[39]={0};
TickTock 49:a3d2c5bb3cfa 164 float mpkWh[39]={0};
TickTock 162:c6545fc0164a 165 float mpkWh_noCC=0;
TickTock 120:041edeec08f5 166 float unloadedV_x2,Resr,curRmax,curRmin,redRmax,redRmin,incRmax,incRmin;
TickTock 121:553faf139a20 167 signed short Imax, Imin;
TickTock 49:a3d2c5bb3cfa 168 // Logarithmic division scale (roughly - snapped to common units of time)
TickTock 49:a3d2c5bb3cfa 169 float timeConstant[39] = {1, 1.58, 2.51, 3.98, 6.31, 10, 15.8, 25.1, 39.8, 60, // 1 minute
TickTock 52:d5385fbf4ea1 170 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
TickTock 52:d5385fbf4ea1 171 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
TickTock 52:d5385fbf4ea1 172 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
TickTock 52:d5385fbf4ea1 173 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
TickTock 121:553faf139a20 174 bool tock = false;
TickTock 73:62ee8eae3a84 175 unsigned short pointerSep;
TickTock 78:a383971fe02f 176 unsigned char reqMsgCnt = 99;
TickTock 102:fd19f777a0b4 177 unsigned long Ah_x10000 = 0;
TickTock 102:fd19f777a0b4 178 unsigned long SOC_x10000 = 0;
TickTock 143:88b5155622a5 179 unsigned short SOH2_x100 = 0;
TickTock 108:29b5a760adc2 180 float maxTemp = 0;
leafman 98:9f8bab96edff 181 bool metric = false;
TickTock 121:553faf139a20 182 bool shunt[96]={0};
TickTock 121:553faf139a20 183 bool charging=false;
TickTock 131:0d926c080a65 184 bool showHealth=false;
TickTock 175:0357b4159b40 185 unsigned char saveDmode[2] = {99, 99};
TickTock 131:0d926c080a65 186 bool moving=false;
TickTock 140:ab3e94eb0227 187 unsigned short chirpInt;
TickTock 150:ef46ce63345c 188 unsigned short uMsgId[8] = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}; // messages to display on debug screen msgId:byte
TickTock 152:a4d66901785d 189 unsigned short modelYear = 2011;
TickTock 153:e94cfe3c339c 190 bool idir, lidir;
TickTock 195:ef0af84a4340 191 bool enableSound=true;
TickTock 158:059abeb44ba1 192 bool clearTest=true;
TickTock 171:355e284f5201 193 unsigned long tbScalar = 72464;
TickTock 171:355e284f5201 194 unsigned long rbScalar = 8696;
TickTock 171:355e284f5201 195 unsigned long fbScalar = 132;
TickTock 177:6fda79c2fda1 196 int effCheckTime = 3;
TickTock 177:6fda79c2fda1 197 bool ignoreDayData = true;
TickTock 179:e4094e55f079 198 unsigned short cgids,lgids=0;
TickTock 179:e4094e55f079 199 unsigned short whpg[300]={0};
TickTock 180:5fdeeb86f3a3 200 float wh[300];
TickTock 180:5fdeeb86f3a3 201 float maxWhpg,minWh,whOff;
TickTock 13:62e0f7f39ff5 202
TickTock 0:1596b8644523 203 int main() {
TickTock 4:8d7759f4fe7a 204 char sTemp[40];
TickTock 2:71b1999a8ea5 205 unsigned long secs;
TickTock 179:e4094e55f079 206 unsigned short i,j;
TickTock 179:e4094e55f079 207 unsigned char display=0,lwt=0;
TickTock 22:a43df3905863 208 point lastTouch;
TickTock 52:d5385fbf4ea1 209 float average;
TickTock 3:3e879b043bc5 210 tt.set_orientation(1);
TickTock 4:8d7759f4fe7a 211 tt.background(Black);
TickTock 19:d576298c46f3 212 tt.set_display(2); // select both displays
TickTock 3:3e879b043bc5 213 tt.cls();
TickTock 137:70853cf5a30f 214 tt.foreground(White);
TickTock 137:70853cf5a30f 215 tt.set_font((unsigned char*) Arial12x12_prop); // select the font
TickTock 137:70853cf5a30f 216 tt.locate(0,0);
TickTock 1:9dcd70c32180 217 tt.claim(stdout); // send stdout to the TFT display
TickTock 12:8e42d7ba8468 218 touchpad.rise(&touch_ISR);
TickTock 4:8d7759f4fe7a 219 tt.wfi(); // enable interrupt on touch
TickTock 155:f31006516956 220 dled.period(0.001);
TickTock 154:90ea16ca7475 221 dled = ledHi; // turn on display LED 80%
TickTock 155:f31006516956 222 spkr = 0;
TickTock 120:041edeec08f5 223 Resr = 0.075; // initial guess of Resr
TickTock 2:71b1999a8ea5 224 timer.start() ;
TickTock 2:71b1999a8ea5 225 RTC_Init(); // start the RTC Interrupts that sync the timer
TickTock 176:9c19f9856c76 226 struct tm t,lt; // pointer to a static tm structure
TickTock 93:c2402e8cd0e2 227 NVIC_SetPriority(CAN_IRQn, 2); //set can priority just below RTC
TickTock 117:49883c779a74 228 NVIC_SetPriority(TIMER3_IRQn, 3); //set ticker priority just below can
TickTock 33:a277743ebdeb 229
TickTock 1:9dcd70c32180 230 seconds = time(NULL);
TickTock 177:6fda79c2fda1 231 t = *localtime(&seconds);
TickTock 177:6fda79c2fda1 232 lt = t; // initialize
TickTock 1:9dcd70c32180 233 // is it a date before 2012 ?
TickTock 26:462ccb580472 234 if ((t.tm_year + 1900) < 2012 ) {
TickTock 26:462ccb580472 235 // before 2013 so update year to make date entry easier
TickTock 26:462ccb580472 236 t.tm_year = 2013 - 1900;
TickTock 1:9dcd70c32180 237 // set the RTC
TickTock 1:9dcd70c32180 238 set_time(mktime(&t));
TickTock 1:9dcd70c32180 239 seconds = time(NULL);
TickTock 26:462ccb580472 240 }
TickTock 20:3bf176d14b14 241 t = *localtime(&seconds) ;
TickTock 20:3bf176d14b14 242 strftime(sTemp, 32, "%a %m/%d/%Y %X\n", &t);
TickTock 93:c2402e8cd0e2 243 printMsg(sTemp); // record RTC
garygid 54:6ce808d0995e 244
TickTock 62:ffd15edb5431 245 // revision
garygid 70:0700b769ac15 246 sprintf(sTemp,"CANary firmware rev%s\n", revStr); // gg - for Logging the revision
TickTock 93:c2402e8cd0e2 247 printMsg(sTemp); // revision
TickTock 17:e32324a2678d 248
TickTock 179:e4094e55f079 249 for(i=0;i<300;i++){ // initialize wh lookup
TickTock 181:396fdcceefd2 250 wh[i]=i*kWperGid*1000;
TickTock 179:e4094e55f079 251 }
TickTock 179:e4094e55f079 252
TickTock 49:a3d2c5bb3cfa 253 //read efficiency history data
TickTock 150:ef46ce63345c 254 hfile = fopen("/local/ehist.cny", "r");
TickTock 97:a25940fd7b5b 255 if (hfile!=NULL){ // found a efficiency history file
TickTock 49:a3d2c5bb3cfa 256 for(i=0;i<39;i++){
TickTock 97:a25940fd7b5b 257 if(!feof(hfile)){
TickTock 97:a25940fd7b5b 258 fscanf(hfile,"%f %f\r\n",&mph[i],&kW[i]);
TickTock 49:a3d2c5bb3cfa 259 mpkWh[i]=mph[i]/kW[i];
TickTock 166:ec3951ba9701 260 if(i==dtePeriod) mpkWh_noCC=mpkWh[i];
TickTock 49:a3d2c5bb3cfa 261 }
TickTock 49:a3d2c5bb3cfa 262 }
TickTock 134:ad243e4f1a17 263 if(!feof(hfile)){
TickTock 134:ad243e4f1a17 264 fscanf(hfile,"%f %f\r\n",&maxTripEff,&minTripEff);
TickTock 134:ad243e4f1a17 265 }
TickTock 155:f31006516956 266 if(!feof(hfile)){
TickTock 155:f31006516956 267 fscanf(hfile,"%f\r\n",&Resr);
TickTock 155:f31006516956 268 }
TickTock 167:58d4edf403d4 269 if(!feof(hfile)){
TickTock 167:58d4edf403d4 270 fscanf(hfile,"%f %f\r\n",&maxTripMiles,&minTripMiles);
TickTock 167:58d4edf403d4 271 }
TickTock 167:58d4edf403d4 272 if(!feof(hfile)){
TickTock 167:58d4edf403d4 273 fscanf(hfile,"%f %f\r\n",&maxTripkWh,&minTripkWh);
TickTock 167:58d4edf403d4 274 }
TickTock 167:58d4edf403d4 275 if(!feof(hfile)){
TickTock 167:58d4edf403d4 276 fscanf(hfile,"%f %f\r\n",&maxTripCCkWh,&minTripCCkWh);
TickTock 167:58d4edf403d4 277 }
TickTock 180:5fdeeb86f3a3 278 for(i=0;i<300;i++){
TickTock 180:5fdeeb86f3a3 279 if(feof(hfile)) break;
TickTock 180:5fdeeb86f3a3 280 fscanf(hfile,"%f\r\n",&wh[i]);
TickTock 179:e4094e55f079 281 }
TickTock 97:a25940fd7b5b 282 fclose(hfile);
TickTock 116:5cd72bae7c12 283 printMsg("History Loaded.\n"); // History loaded
TickTock 49:a3d2c5bb3cfa 284 } else { // create initial file
TickTock 116:5cd72bae7c12 285 printMsg("History not found. Created.\n"); // history not found, created
TickTock 49:a3d2c5bb3cfa 286 for(i=0;i<39;i++){
TickTock 49:a3d2c5bb3cfa 287 // Pre-load with 4 mpkWh @ 40 mph
TickTock 49:a3d2c5bb3cfa 288 mph[i]=40*timeConstant[i];
TickTock 49:a3d2c5bb3cfa 289 kW[i]=10*timeConstant[i];
TickTock 49:a3d2c5bb3cfa 290 mpkWh[i]=4;
TickTock 49:a3d2c5bb3cfa 291 }
TickTock 49:a3d2c5bb3cfa 292 }
TickTock 49:a3d2c5bb3cfa 293
TickTock 46:73e8716f976f 294 // Read config file
TickTock 46:73e8716f976f 295 readConfig();
TickTock 140:ab3e94eb0227 296 if (brakeMon){
TickTock 140:ab3e94eb0227 297 geiger.attach(&chirp,0.02);
TickTock 140:ab3e94eb0227 298 }
TickTock 108:29b5a760adc2 299 if (repeatPoll) { // enable autopolling if enabled
TickTock 108:29b5a760adc2 300 autoPoll.attach(&autoPollISR,pollInt);
TickTock 108:29b5a760adc2 301 }
TickTock 108:29b5a760adc2 302
TickTock 77:7c136766466c 303 // Start monitors
TickTock 77:7c136766466c 304 can1.monitor(true); // set to snoop mode
TickTock 77:7c136766466c 305 can2.monitor(true); // set to snoop mode
TickTock 77:7c136766466c 306 can1.frequency(500000);
TickTock 77:7c136766466c 307 can2.frequency(500000);
TickTock 120:041edeec08f5 308 can1SleepMode = VP230Sleep; // Turn on Monitor_only Mode
TickTock 120:041edeec08f5 309 can2SleepMode = VP230Sleep; // Turn on Monitor_only Mode
TickTock 77:7c136766466c 310 can1.attach(&recieve1);
TickTock 77:7c136766466c 311 can2.attach(&recieve2);
TickTock 77:7c136766466c 312
TickTock 26:462ccb580472 313 touched=false;
TickTock 195:ef0af84a4340 314 longTouch=false;
TickTock 26:462ccb580472 315 secsNoTouch=2;
TickTock 195:ef0af84a4340 316 secsTouch=0;
TickTock 2:71b1999a8ea5 317 while (true) {
TickTock 4:8d7759f4fe7a 318 if (!logOpen) { // Open new file if one is not already open
TickTock 131:0d926c080a65 319 if(logEn&&usbEn){ //logging enabled and USB device detected
TickTock 109:3e6f0e8fca0d 320 strftime(fileName, 32, "%m%d%H%M.alc", &t); //mmddhhmm.alc
TickTock 109:3e6f0e8fca0d 321 efr = f_open(&efile,fileName,FA_WRITE|FA_OPEN_ALWAYS);
TickTock 7:17bf9ceaf0aa 322 seconds = time(NULL);
TickTock 7:17bf9ceaf0aa 323 t = *localtime(&seconds) ;
TickTock 94:c3a14b3975d6 324 lastDMode[0]=99;//force refresh
TickTock 94:c3a14b3975d6 325 lastDMode[1]=99;//force refresh
TickTock 109:3e6f0e8fca0d 326 if(efr != FR_OK){
TickTock 109:3e6f0e8fca0d 327 sprintf(sTemp,"\nERR:%d Unable to open %s\n\n\n\n",efr,fileName);
TickTock 93:c2402e8cd0e2 328 printMsg(sTemp); // cannot open alc file
TickTock 7:17bf9ceaf0aa 329 logEn=false;
TickTock 155:f31006516956 330 beep(1000,0.25);
TickTock 109:3e6f0e8fca0d 331 wait_ms(500);
TickTock 155:f31006516956 332 beep(1000,0.25);
TickTock 7:17bf9ceaf0aa 333 } else {
TickTock 7:17bf9ceaf0aa 334 logOpen = true;
TickTock 7:17bf9ceaf0aa 335 readPointer=writePointer;
TickTock 7:17bf9ceaf0aa 336 sprintf(sTemp,"Starting Can Log %s\n",fileName);
TickTock 93:c2402e8cd0e2 337 printMsg(sTemp); // starting alc log file
garygid 69:6bfdfc002036 338
garygid 69:6bfdfc002036 339 logTS(); // Date Time at start
TickTock 93:c2402e8cd0e2 340 logEvent("Starting"); // Log startup msg for testing
garygid 69:6bfdfc002036 341 sprintf(sTemp,"Cr%s",revStr);
TickTock 108:29b5a760adc2 342 logEvent(sTemp); // gg - log firmware version
TickTock 155:f31006516956 343 beep(2000,0.25);
TickTock 7:17bf9ceaf0aa 344 }
TickTock 108:29b5a760adc2 345 }//logging enabled and USB detected
TickTock 15:a359fecf85ba 346 } else { // if (logOpen)
TickTock 73:62ee8eae3a84 347 pointerSep=(writePointer+maxBufLen-readPointer)%maxBufLen;
TickTock 131:0d926c080a65 348 if (pointerSep>(maxBufLen/16)||carCanIdle||!logEn) {
TickTock 7:17bf9ceaf0aa 349 // Dump buffer if > 1/16 full or canbus has stopped
TickTock 117:49883c779a74 350 if (efr != FR_OK) {
TickTock 7:17bf9ceaf0aa 351 logOpen = false;
TickTock 117:49883c779a74 352 printMsg("Failed to append log file.\n"); // failed to append
TickTock 155:f31006516956 353 beep(3000,0.25);
TickTock 155:f31006516956 354 beep(1500,0.25);
TickTock 155:f31006516956 355 beep(750,0.25);
TickTock 155:f31006516956 356 beep(375,0.25);
TickTock 7:17bf9ceaf0aa 357 logEn=false;
TickTock 7:17bf9ceaf0aa 358 } else {
TickTock 7:17bf9ceaf0aa 359 while (readPointer != writePointer) {
TickTock 117:49883c779a74 360 efr=f_write(&efile,&writeBuffer[readPointer][0],13,&bytesRW);
TickTock 117:49883c779a74 361 if(++readPointer >= maxBufLen){
TickTock 117:49883c779a74 362 readPointer=0;
TickTock 117:49883c779a74 363 led4 = !led4;
TickTock 4:8d7759f4fe7a 364 }
TickTock 4:8d7759f4fe7a 365 }
TickTock 7:17bf9ceaf0aa 366 }
TickTock 30:e633a63eb257 367 } // if > 1/16 full, canbus has stopped, or logging stopped
TickTock 30:e633a63eb257 368 if (!logEn) {
TickTock 77:7c136766466c 369 sprintf(sTemp,"Stopping Can Log %s\n",fileName);
TickTock 93:c2402e8cd0e2 370 printMsg(sTemp); // stopping alc log file
TickTock 109:3e6f0e8fca0d 371 f_close(&efile);
TickTock 30:e633a63eb257 372 logOpen=false;
TickTock 77:7c136766466c 373 pointerSep=0;
TickTock 108:29b5a760adc2 374 led4=false;
TickTock 30:e633a63eb257 375 }
TickTock 4:8d7759f4fe7a 376 } // if logOpen
TickTock 132:08748a67280a 377 if (carCanIdle && (evCanIdle || !logOpen) && userIdle && !playbackEn) { // canbus idle --> sleep to save power
TickTock 95:248b3c25a7df 378 if (repeatPoll) { // stop autopolling if enabled
TickTock 95:248b3c25a7df 379 autoPoll.detach();
TickTock 95:248b3c25a7df 380 }
TickTock 111:d1559bb25c43 381 if (logOpen){ //close file to dump buffer
TickTock 111:d1559bb25c43 382 f_close(&efile);
TickTock 134:ad243e4f1a17 383 } else { //detach EVcan so only carcan will trigger wake
TickTock 134:ad243e4f1a17 384 can1.attach(NULL);
TickTock 134:ad243e4f1a17 385 }// if (logOpen)
TickTock 20:3bf176d14b14 386 seconds = time(NULL);
TickTock 20:3bf176d14b14 387 t = *localtime(&seconds) ;
TickTock 21:22bdce9efcb5 388 strftime(sTemp, 40, "Sleeping: %a %m/%d/%Y %X\n", &t);
TickTock 93:c2402e8cd0e2 389 printMsg(sTemp); // sleeping date time
TickTock 25:ddf0ec209f03 390 updateDisplay(0); //Added for turbo3 who has a display override and wants to see the sleep message before going to sleep
TickTock 25:ddf0ec209f03 391 updateDisplay(1);
TickTock 4:8d7759f4fe7a 392 //LPC_RTC->CIIR=0x00; // block RTC interrupts
TickTock 4:8d7759f4fe7a 393 led1=0;
TickTock 4:8d7759f4fe7a 394 led2=0;
TickTock 4:8d7759f4fe7a 395 led3=0;
TickTock 4:8d7759f4fe7a 396 led4=0;
TickTock 4:8d7759f4fe7a 397 dled=0; // turn off display
TickTock 4:8d7759f4fe7a 398 secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
TickTock 132:08748a67280a 399 while (secsNoCarCanMsg>canTimeout && (secsNoEvCanMsg>canTimeout || !logOpen) && !touched) {
TickTock 4:8d7759f4fe7a 400 //DeepPowerDown();
TickTock 12:8e42d7ba8468 401 tt.wfi(); //enable touch interrupt
TickTock 21:22bdce9efcb5 402 //__wfi(); // freeze CPU and wait for interrupt (from canbus or touch)
TickTock 21:22bdce9efcb5 403 Sleep();
TickTock 4:8d7759f4fe7a 404 }
TickTock 135:89986950d501 405 if (!logOpen){ // Re-attach EVcan
TickTock 134:ad243e4f1a17 406 can1.attach(&recieve1);
TickTock 134:ad243e4f1a17 407 }
TickTock 43:e7f6f80590e3 408 secsNoTouch=2;
TickTock 195:ef0af84a4340 409 secsTouch=0;
TickTock 131:0d926c080a65 410 carCanIdle=secsNoCarCanMsg>canTimeout;
TickTock 132:08748a67280a 411 evCanIdle=secsNoEvCanMsg>canTimeout;
TickTock 154:90ea16ca7475 412 dled=ledHi; // turn on display LED
TickTock 20:3bf176d14b14 413 seconds = time(NULL);
TickTock 20:3bf176d14b14 414 t = *localtime(&seconds) ;
TickTock 21:22bdce9efcb5 415 strftime(sTemp, 40, "Waking: %a %m/%d/%Y %X\n", &t);
TickTock 93:c2402e8cd0e2 416 printMsg(sTemp); // wakeup date time
TickTock 4:8d7759f4fe7a 417 if (time(NULL)>(secs+1800)) {
TickTock 110:ffddff3ad2f2 418 if (logOpen){
TickTock 110:ffddff3ad2f2 419 f_close(&efile);
TickTock 110:ffddff3ad2f2 420 logOpen = false; // Start new file if asleep for more than 30 minutes
TickTock 110:ffddff3ad2f2 421 } // if (logOpen)
TickTock 4:8d7759f4fe7a 422 if (secsNoTouch>100) secsNoTouch = 100; // also mostly reset user Idle counter
TickTock 43:e7f6f80590e3 423 } else if (logOpen){ // insert timestamp on each wake if logging enabled (disabled for now)
TickTock 111:d1559bb25c43 424 efr = f_open(&efile,fileName,FA_WRITE|FA_OPEN_ALWAYS);
TickTock 111:d1559bb25c43 425 f_lseek(&efile,0xffffffff); // goto end of file (append existing)
TickTock 93:c2402e8cd0e2 426 logEvent("WakingUp"); // gg - use messeges
garygid 69:6bfdfc002036 427 logTS(); // Date-Time at wakeup
TickTock 4:8d7759f4fe7a 428 }
TickTock 95:248b3c25a7df 429 if (repeatPoll) { // re-enable autopolling if enabled
TickTock 124:0d622967b764 430 autoPoll.attach(&autoPollISR,pollInt);
TickTock 95:248b3c25a7df 431 }
TickTock 136:41a204105511 432 wait5secs=5; // Refresh screen after 5 seconds
TickTock 4:8d7759f4fe7a 433 } // if idle
TickTock 4:8d7759f4fe7a 434
TickTock 15:a359fecf85ba 435 if(touched){ // call touchscreen procedure if touch interrupt detected
TickTock 7:17bf9ceaf0aa 436 lastTouch = tt.get_touch();
TickTock 7:17bf9ceaf0aa 437 lastTouch = tt.to_pixel(lastTouch); // convert to pixel pos
TickTock 40:0e6e71a7323f 438 if((lastTouch.x!=639)&&(lastTouch.x!=319)&&(lastTouch.y!=239)){ // filter phantom touches
TickTock 43:e7f6f80590e3 439 if (userIdle) {
TickTock 43:e7f6f80590e3 440 secsNoTouch=2; // Ignore first touch if user idle
TickTock 43:e7f6f80590e3 441 userIdle=false;
TickTock 40:0e6e71a7323f 442 } else {
TickTock 43:e7f6f80590e3 443 secsNoTouch=0;
TickTock 40:0e6e71a7323f 444 }
TickTock 43:e7f6f80590e3 445 if (lastTouch.x>320){
TickTock 43:e7f6f80590e3 446 whichTouched=1;
TickTock 43:e7f6f80590e3 447 } else {
TickTock 43:e7f6f80590e3 448 whichTouched=0;
TickTock 43:e7f6f80590e3 449 }
TickTock 43:e7f6f80590e3 450 if (whichTouched!=lwt){
TickTock 43:e7f6f80590e3 451 lastDMode[lwt]=99; // Repaint lastTouched
TickTock 43:e7f6f80590e3 452 lwt=whichTouched;
TickTock 195:ef0af84a4340 453 if(sMode==2){ // Exit keypad mode if other screen touched
TickTock 195:ef0af84a4340 454 sMode=0; // end keypad mode
TickTock 195:ef0af84a4340 455 dMode[0]=saveDmode[0];
TickTock 195:ef0af84a4340 456 dMode[1]=saveDmode[1];
TickTock 195:ef0af84a4340 457 lastDMode[0]=99;
TickTock 195:ef0af84a4340 458 lastDMode[1]=99;
TickTock 195:ef0af84a4340 459 uidx=99;
TickTock 195:ef0af84a4340 460 }
TickTock 43:e7f6f80590e3 461 }
TickTock 195:ef0af84a4340 462 if (sMode==0) sMode = 1; //Go to select mode1 unless already in select mode2
TickTock 22:a43df3905863 463 }
TickTock 22:a43df3905863 464 //sprintf(sTemp,"%d,%d ",lastTouch.x,lastTouch.y);
TickTock 93:c2402e8cd0e2 465 //printMsg(sTemp); // touch x,y - for debug
TickTock 12:8e42d7ba8468 466 touched = false; // clear interrupt flag
TickTock 7:17bf9ceaf0aa 467 }
garygid 54:6ce808d0995e 468 //---------------
garygid 54:6ce808d0995e 469 // gg - 4x4 touch
TickTock 62:ffd15edb5431 470 //unsigned char tScrn = 0 ; // screen 0
garygid 54:6ce808d0995e 471 unsigned char tCol ;
garygid 54:6ce808d0995e 472 unsigned char tRow ;
garygid 54:6ce808d0995e 473
TickTock 4:8d7759f4fe7a 474 if (!userIdle) {
TickTock 196:c1bfa3ed21a6 475 if(longTouch&&(sMode<2)){ //long touch
TickTock 195:ef0af84a4340 476 if (dMode[whichTouched]==testScreen) {
TickTock 195:ef0af84a4340 477 whichTouched = whichTouched ^ 1; //long press opens keypad on *other* screen
TickTock 196:c1bfa3ed21a6 478 lwt=whichTouched;
TickTock 195:ef0af84a4340 479 saveDmode[0]=dMode[0];
TickTock 195:ef0af84a4340 480 saveDmode[1]=dMode[1];
TickTock 195:ef0af84a4340 481 dMode[whichTouched]=offScreen;
TickTock 195:ef0af84a4340 482 sMode=2; //start numPad entry mode
TickTock 195:ef0af84a4340 483 keypad=0;
TickTock 195:ef0af84a4340 484 if((lastTouch.y>64)&&(lastTouch.y<184)){
TickTock 195:ef0af84a4340 485 uidx=(lastTouch.y-64)/30;
TickTock 195:ef0af84a4340 486 uidx*=2;
TickTock 195:ef0af84a4340 487 if((lastTouch.x%320)>160){
TickTock 195:ef0af84a4340 488 uidx+=1;
TickTock 195:ef0af84a4340 489 }
TickTock 195:ef0af84a4340 490 }else{
TickTock 195:ef0af84a4340 491 uidx=99;
TickTock 195:ef0af84a4340 492 }
TickTock 195:ef0af84a4340 493 }
TickTock 195:ef0af84a4340 494 } else if (secsNoTouch<2) {// Recently touched
TickTock 4:8d7759f4fe7a 495 secsNoTouch +=2; // increment to prevent double touch
TickTock 195:ef0af84a4340 496 if (sMode==0) sMode = 1; //Go to select mode1 unless already in select mode2
TickTock 22:a43df3905863 497 //sprintf(sTemp,"button %d %d,%d %d\n",i,buttonX(lastTouch.x,3),buttonY(lastTouch.y,3),lastTouch.x);
TickTock 93:c2402e8cd0e2 498 //printMsg(sTemp); // button parms - for debug
TickTock 23:cd03f9c3395e 499 switch (sMode) {
TickTock 23:cd03f9c3395e 500 case 0: // no select
TickTock 23:cd03f9c3395e 501 break;
TickTock 63:aa3bf6a33635 502 case 1: // select screen
garygid 54:6ce808d0995e 503 //--------------
garygid 54:6ce808d0995e 504 // gg - 4x4 touch
garygid 54:6ce808d0995e 505 tCol = buttonX(lastTouch.x,4) ;
TickTock 62:ffd15edb5431 506 if( tCol >= 4 ){ tCol -= 4; } // touch is on screen 1
garygid 54:6ce808d0995e 507
garygid 54:6ce808d0995e 508 tRow = buttonY(lastTouch.y,4) ;
garygid 54:6ce808d0995e 509
TickTock 63:aa3bf6a33635 510 highlightButton( tCol,tRow, whichTouched, 4,4) ; // gg - highlight
garygid 58:4d06288d75a2 511
TickTock 63:aa3bf6a33635 512 if( tRow == tNavRow ) tRow = 7 ; // gg
garygid 54:6ce808d0995e 513 switch ( (tCol*10) + tRow ) {
garygid 54:6ce808d0995e 514 //---------------------------------
garygid 67:2022fce701d0 515 case 00: // top row, left button on screen 0 or 1
TickTock 42:4533b13b297d 516 if (dMode[whichTouched]==monitorScreen||dMode[whichTouched]==changedScreen) {
garygid 67:2022fce701d0 517 indexOffset=indexOffset>4?indexOffset-4:1;
garygid 67:2022fce701d0 518 } else if (dMode[whichTouched] == indexScreen) { // gg - index
garygid 67:2022fce701d0 519 dMode[whichTouched] = mainScreen ; // GoTo Main Screen
TickTock 73:62ee8eae3a84 520 sMode=0;
TickTock 157:1a100a5ed06f 521 } else if (dMode[whichTouched]==config2Screen) {
TickTock 23:cd03f9c3395e 522 wait_ms(500);
TickTock 37:fea2c1d52c5f 523 tt.background(Black);
TickTock 23:cd03f9c3395e 524 tt.calibrate();
TickTock 42:4533b13b297d 525 } else if (dMode[whichTouched]==playbackScreen) { // slower
TickTock 36:dbd39c315258 526 playbackInt *=2;
TickTock 36:dbd39c315258 527 if(playbackEn){
TickTock 36:dbd39c315258 528 playback.detach();
TickTock 36:dbd39c315258 529 playback.attach(&playbackISR,playbackInt);
TickTock 36:dbd39c315258 530 }
TickTock 62:ffd15edb5431 531 } else {
TickTock 62:ffd15edb5431 532 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 23:cd03f9c3395e 533 }
TickTock 23:cd03f9c3395e 534 break;
garygid 54:6ce808d0995e 535 //-----------------------------------------------
garygid 67:2022fce701d0 536 case 10: // 1,0 (col left of center,top row) on screen 0 or 1
TickTock 42:4533b13b297d 537 if (dMode[whichTouched]==changedScreen) {
TickTock 23:cd03f9c3395e 538 for(j=0;j<100;j++) msgChanged[j]=0; // clear changed data
TickTock 42:4533b13b297d 539 lastDMode[whichTouched]=99;//force refresh
TickTock 169:84d790ac18a2 540 sMode=0;
garygid 67:2022fce701d0 541 } else if (dMode[whichTouched] == indexScreen) { // gg - index
TickTock 73:62ee8eae3a84 542 sMode=0;
garygid 67:2022fce701d0 543 dMode[whichTouched] = brakeScreen ; // GoTo Brake Screen
TickTock 42:4533b13b297d 544 } else if (dMode[whichTouched]==cpScreen) {
TickTock 78:a383971fe02f 545 reqMsgCnt=0;
TickTock 79:68f0dd8d1f19 546 msgReq.attach(&sendReq,0.015);
TickTock 48:d1ce92104a1f 547 } else if (dMode[whichTouched]==cpHistScreen) { // gg - hist
TickTock 78:a383971fe02f 548 reqMsgCnt=0;
TickTock 79:68f0dd8d1f19 549 msgReq.attach(&sendReq,0.015);
TickTock 48:d1ce92104a1f 550 } else if (dMode[whichTouched]==cpBarScreen) { // gg - cpbars
TickTock 78:a383971fe02f 551 reqMsgCnt=0;
TickTock 79:68f0dd8d1f19 552 msgReq.attach(&sendReq,0.015);
leafman 98:9f8bab96edff 553 } else if (dMode[whichTouched]==configScreen) {
TickTock 23:cd03f9c3395e 554 mbed_reset();
TickTock 157:1a100a5ed06f 555 } else if (dMode[whichTouched]==config2Screen) { // reset DTE Max/Min
TickTock 158:059abeb44ba1 556 maxTripEff = 0;
TickTock 158:059abeb44ba1 557 minTripEff = 5;
TickTock 161:71ac85d11f03 558 beep(2000,0.25);
TickTock 184:5ca7b78297fe 559 for(i=0;i<300;i++){ // initialize wh lookup
TickTock 184:5ca7b78297fe 560 wh[i]=i*kWperGid*1000;
TickTock 184:5ca7b78297fe 561 }
TickTock 42:4533b13b297d 562 } else if (dMode[whichTouched]==playbackScreen) { // pause/unpause
TickTock 36:dbd39c315258 563 playbackEn=!playbackEn;
TickTock 36:dbd39c315258 564 if(playbackEn){
TickTock 36:dbd39c315258 565 playback.attach(&playbackISR,playbackInt);
TickTock 62:ffd15edb5431 566 } else {
TickTock 36:dbd39c315258 567 playback.detach();
TickTock 36:dbd39c315258 568 }
TickTock 62:ffd15edb5431 569 } else {
TickTock 62:ffd15edb5431 570 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 23:cd03f9c3395e 571 }
TickTock 62:ffd15edb5431 572
TickTock 23:cd03f9c3395e 573 break;
garygid 54:6ce808d0995e 574 //--------------------------------------
garygid 54:6ce808d0995e 575 case 20: // col 2 and row 0 on either screen 0 or 1
TickTock 42:4533b13b297d 576 if (dMode[whichTouched]==monitorScreen||dMode[whichTouched]==changedScreen) {
TickTock 23:cd03f9c3395e 577 indexOffset=indexOffset<77?indexOffset+4:80;
garygid 67:2022fce701d0 578 } else if (dMode[whichTouched] == indexScreen) { // gg - index
garygid 67:2022fce701d0 579 dMode[whichTouched] = effScreen ; // GoTo EFF Screen
TickTock 73:62ee8eae3a84 580 sMode=0;
leafman 98:9f8bab96edff 581 } else if (dMode[whichTouched]==configScreen) {
TickTock 143:88b5155622a5 582 dMode[whichTouched]=mainScreen;
TickTock 169:84d790ac18a2 583 //write efficiency history data
TickTock 169:84d790ac18a2 584 hfile = fopen("/local/ehist.cny", "w");
TickTock 169:84d790ac18a2 585 if (hfile!=NULL){ // found a efficiency history file
TickTock 169:84d790ac18a2 586 for(i=0;i<39;i++){
TickTock 169:84d790ac18a2 587 fprintf(hfile,"%f %f\r\n",mph[i],kW[i]);
TickTock 169:84d790ac18a2 588 }
TickTock 169:84d790ac18a2 589 fprintf(hfile,"%f %f\r\n",maxTripEff,minTripEff); // Save max and min
TickTock 169:84d790ac18a2 590 fprintf(hfile,"%f \r\n",Resr); // Save series resistance
TickTock 169:84d790ac18a2 591 fprintf(hfile,"%f %f\r\n",maxTripMiles,minTripMiles); // Save max and min
TickTock 169:84d790ac18a2 592 fprintf(hfile,"%f %f\r\n",maxTripkWh,minTripkWh); // Save max and min
TickTock 169:84d790ac18a2 593 fprintf(hfile,"%f %f\r\n",maxTripCCkWh,minTripCCkWh); // Save max and min
TickTock 180:5fdeeb86f3a3 594 for(i=0;i<300;i++){
TickTock 180:5fdeeb86f3a3 595 fprintf(hfile,"%f\r\n",wh[i]);
TickTock 180:5fdeeb86f3a3 596 }
TickTock 169:84d790ac18a2 597 fclose(hfile);
TickTock 169:84d790ac18a2 598 }
TickTock 169:84d790ac18a2 599 beep(2000,0.25);
TickTock 184:5ca7b78297fe 600 saveConfig();
TickTock 184:5ca7b78297fe 601 beep(2000,0.25);
TickTock 169:84d790ac18a2 602 } else if (dMode[whichTouched]==config2Screen) {
TickTock 169:84d790ac18a2 603 showHealth = !showHealth;
TickTock 42:4533b13b297d 604 } else if (dMode[whichTouched]==playbackScreen) { // faster
TickTock 36:dbd39c315258 605 if(playbackInt>.002){
TickTock 36:dbd39c315258 606 playbackInt/=2;
TickTock 36:dbd39c315258 607 if(playbackEn){
TickTock 36:dbd39c315258 608 playback.detach();
TickTock 36:dbd39c315258 609 playback.attach(&playbackISR,playbackInt);
TickTock 36:dbd39c315258 610 }
TickTock 36:dbd39c315258 611 }
TickTock 86:d1c9e8ac1c4b 612 } else {
TickTock 62:ffd15edb5431 613 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 23:cd03f9c3395e 614 }
TickTock 62:ffd15edb5431 615
TickTock 23:cd03f9c3395e 616 break;
garygid 65:821fc79cd7fe 617
garygid 67:2022fce701d0 618 case 30: // right-most on top row
garygid 65:821fc79cd7fe 619
TickTock 157:1a100a5ed06f 620 if (dMode[whichTouched]==config2Screen) {
garygid 65:821fc79cd7fe 621 // step through skins
garygid 65:821fc79cd7fe 622 if( skin < maxSkin ) skin += 1 ;
garygid 65:821fc79cd7fe 623 else skin = 0 ;
garygid 65:821fc79cd7fe 624
garygid 65:821fc79cd7fe 625 // repaint both screens, I think
garygid 65:821fc79cd7fe 626 lastDMode[whichTouched]=99;//repaint to clear highlight
garygid 65:821fc79cd7fe 627 // and re-paint the other screen too, to see new skin there
garygid 65:821fc79cd7fe 628 lastDMode[whichTouched ^ 1]=99; // repaint other screen (^ = XOR)
garygid 67:2022fce701d0 629 } else if (dMode[whichTouched] == indexScreen) { // gg - index
TickTock 122:138a40892a4c 630 dMode[whichTouched] = healthScreen ; // Goto health screen
TickTock 73:62ee8eae3a84 631 sMode=0;
TickTock 169:84d790ac18a2 632 } else if (dMode[whichTouched] == testScreen) { // gg -
TickTock 158:059abeb44ba1 633 clearTest=true;
TickTock 158:059abeb44ba1 634 } else { // top-right corner always mute/unmute unless used by specific screen
TickTock 154:90ea16ca7475 635 enableSound = !enableSound;
TickTock 155:f31006516956 636 if(!enableSound) spkr=0;
garygid 65:821fc79cd7fe 637 }
garygid 65:821fc79cd7fe 638
garygid 65:821fc79cd7fe 639 break;
garygid 54:6ce808d0995e 640 //----------------------------------
garygid 54:6ce808d0995e 641 //----------------------------------
garygid 67:2022fce701d0 642 case 01: // left col middle row
leafman 98:9f8bab96edff 643 if (dMode[whichTouched]==configScreen) {
TickTock 23:cd03f9c3395e 644 logEn = !logEn;
garygid 67:2022fce701d0 645 } else if (dMode[whichTouched] == indexScreen) { // gg - index
TickTock 73:62ee8eae3a84 646 dMode[whichTouched] = cpScreen ; // GoTo CP Data Screen
TickTock 73:62ee8eae3a84 647 sMode=0;
TickTock 42:4533b13b297d 648 } else if (dMode[whichTouched]==dateScreen){
TickTock 131:0d926c080a65 649 dtMode=(dtMode<5)?dtMode+1:0;
TickTock 42:4533b13b297d 650 lastDMode[whichTouched]=99;
TickTock 62:ffd15edb5431 651 } else {
TickTock 62:ffd15edb5431 652 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 23:cd03f9c3395e 653 }
TickTock 62:ffd15edb5431 654
TickTock 23:cd03f9c3395e 655 break;
garygid 54:6ce808d0995e 656 //------------------------------
TickTock 23:cd03f9c3395e 657 case 11:
leafman 98:9f8bab96edff 658 if (dMode[whichTouched]==configScreen){
TickTock 77:7c136766466c 659 repeatPoll = !repeatPoll;
TickTock 33:a277743ebdeb 660 if (repeatPoll) {
TickTock 36:dbd39c315258 661 autoPoll.attach(&autoPollISR,pollInt);
TickTock 33:a277743ebdeb 662 } else {
TickTock 36:dbd39c315258 663 autoPoll.detach();
TickTock 33:a277743ebdeb 664 }
garygid 67:2022fce701d0 665 } else if (dMode[whichTouched] == indexScreen) { // gg - index
garygid 67:2022fce701d0 666 dMode[whichTouched] = cpHistScreen ; // GoTo CP Hist Screen
TickTock 73:62ee8eae3a84 667 sMode=0;
TickTock 42:4533b13b297d 668 } else if (dMode[whichTouched]==playbackScreen) {
TickTock 36:dbd39c315258 669 // Start/stop playback
TickTock 36:dbd39c315258 670 if(!playbackOpen){
TickTock 131:0d926c080a65 671 if(!carCanIdle){
TickTock 131:0d926c080a65 672 printMsg("Cannot playback while connected to canbus\n");
TickTock 131:0d926c080a65 673 }else if(!logOpen){
TickTock 109:3e6f0e8fca0d 674 efr = f_open(&efile,"playback.alc",FA_READ|FA_OPEN_EXISTING);
TickTock 50:83d5864c64a0 675 lastDMode[whichTouched]=99;//force refresh
TickTock 109:3e6f0e8fca0d 676 if(efr != FR_OK){
TickTock 116:5cd72bae7c12 677 printMsg("Unable to open /usb/playback.alc\n"); // no playback.alc
TickTock 155:f31006516956 678 beep(1000,0.25);
TickTock 36:dbd39c315258 679 } else {
TickTock 36:dbd39c315258 680 playbackOpen = true;
TickTock 50:83d5864c64a0 681 playbackEn=true;
TickTock 50:83d5864c64a0 682 playback.attach(&playbackISR,playbackInt);
TickTock 116:5cd72bae7c12 683 printMsg("Starting playback\n"); // start playback
TickTock 155:f31006516956 684 beep(2000,0.25);
TickTock 138:a2f5af85ed0d 685 can1.attach(NULL);// Stop recieving EVCAN data
TickTock 138:a2f5af85ed0d 686 can2.attach(NULL);// Stop recieving CARCAN data
TickTock 36:dbd39c315258 687 }
TickTock 36:dbd39c315258 688 } else {
TickTock 117:49883c779a74 689 printMsg("Must stop logging first\n");
TickTock 36:dbd39c315258 690 }
TickTock 36:dbd39c315258 691 } else {
TickTock 36:dbd39c315258 692 playback.detach();
TickTock 109:3e6f0e8fca0d 693 f_close(&efile);
TickTock 36:dbd39c315258 694 playbackOpen=false;
TickTock 50:83d5864c64a0 695 playbackEn=false;
TickTock 138:a2f5af85ed0d 696 can1.attach(&recieve1);// Restore EVCAN data recieve
TickTock 138:a2f5af85ed0d 697 can2.attach(&recieve2);// Restore EVCAN data recieve
TickTock 42:4533b13b297d 698 lastDMode[whichTouched]=99;
TickTock 36:dbd39c315258 699 }
TickTock 42:4533b13b297d 700 } else if (dMode[whichTouched]==dateScreen){
TickTock 25:ddf0ec209f03 701 upDate(dtMode,true);
TickTock 42:4533b13b297d 702 lastDMode[whichTouched]=99;
TickTock 62:ffd15edb5431 703 } else {
TickTock 62:ffd15edb5431 704 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 25:ddf0ec209f03 705 }
TickTock 62:ffd15edb5431 706
TickTock 23:cd03f9c3395e 707 break;
garygid 54:6ce808d0995e 708 //---------------------------------
garygid 54:6ce808d0995e 709 case 21: // col 2 row 1
leafman 98:9f8bab96edff 710 if (dMode[whichTouched]==configScreen) { // gg - Batt Log Enable Button
TickTock 48:d1ce92104a1f 711 yesBattLog = !yesBattLog;
garygid 67:2022fce701d0 712 } else if (dMode[whichTouched] == indexScreen) { // gg - index
garygid 67:2022fce701d0 713 dMode[whichTouched] = cpBarScreen ; // GoTo CP Bars Screen
TickTock 73:62ee8eae3a84 714 sMode=0;
TickTock 48:d1ce92104a1f 715 } else if (dMode[whichTouched]==dateScreen){
TickTock 25:ddf0ec209f03 716 upDate(dtMode,false);
TickTock 42:4533b13b297d 717 lastDMode[whichTouched]=99;
TickTock 62:ffd15edb5431 718 } else {
TickTock 62:ffd15edb5431 719 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 25:ddf0ec209f03 720 }
TickTock 62:ffd15edb5431 721
TickTock 23:cd03f9c3395e 722 break;
garygid 54:6ce808d0995e 723
garygid 87:46ac3f2519d6 724 case 31: // col 3 row 1
TickTock 157:1a100a5ed06f 725 if (dMode[whichTouched]==config2Screen) { // gg - Batt Log Enable Button
garygid 87:46ac3f2519d6 726 debugMode = !debugMode;
leafman 98:9f8bab96edff 727 } else if (dMode[whichTouched] == indexScreen) { // gg - index
TickTock 152:a4d66901785d 728 dMode[whichTouched] = configScreen ; // GoTo Config Screen
TickTock 177:6fda79c2fda1 729 } else if (dMode[whichTouched]==tripScreen) { // Cancel day trip meter
TickTock 177:6fda79c2fda1 730 ignoreDayData=true;
TickTock 177:6fda79c2fda1 731 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 152:a4d66901785d 732 } else if ((dMode[whichTouched]==dateScreen)&&accOn){
TickTock 160:905fe45ed54b 733 syncDone=false; // initiate clock sync
TickTock 152:a4d66901785d 734 lastDMode[whichTouched]=99;
TickTock 191:292debe95cba 735 } else if (dMode[whichTouched]==configScreen) {
TickTock 191:292debe95cba 736 if(!headlights){
TickTock 192:1d5f0ee9dc59 737 ledHi += 0.025;
TickTock 191:292debe95cba 738 if (ledHi>1.0) ledHi=1.0;
TickTock 191:292debe95cba 739 } else {
TickTock 192:1d5f0ee9dc59 740 ledLo += 0.025;
TickTock 191:292debe95cba 741 if (ledLo>1.0) ledLo=1.0;
TickTock 191:292debe95cba 742 }
garygid 87:46ac3f2519d6 743 } else {
garygid 87:46ac3f2519d6 744 lastDMode[whichTouched]=99;//repaint to clear highlight
garygid 87:46ac3f2519d6 745 }
garygid 87:46ac3f2519d6 746 break;
garygid 87:46ac3f2519d6 747
garygid 54:6ce808d0995e 748 //-----------------------------------
garygid 67:2022fce701d0 749 case 02: // left col, bottom row (not nav)
garygid 67:2022fce701d0 750 if (dMode[whichTouched] == indexScreen) { // gg - index
leafman 98:9f8bab96edff 751 dMode[whichTouched] = playbackScreen ; // GoTo Playback Screen
leafman 98:9f8bab96edff 752 } else if (dMode[whichTouched]==configScreen) {
TickTock 140:ab3e94eb0227 753 brakeMon = !brakeMon;
TickTock 140:ab3e94eb0227 754 if(brakeMon){
TickTock 140:ab3e94eb0227 755 geiger.attach(&chirp,0.02);
TickTock 140:ab3e94eb0227 756 }else{
TickTock 140:ab3e94eb0227 757 geiger.detach();
TickTock 140:ab3e94eb0227 758 }
TickTock 158:059abeb44ba1 759 } else if (dMode[whichTouched]==config2Screen) {
TickTock 158:059abeb44ba1 760 autoSync = !autoSync;
garygid 87:46ac3f2519d6 761 } else {
garygid 87:46ac3f2519d6 762 lastDMode[whichTouched]=99;//repaint to clear highlight
garygid 87:46ac3f2519d6 763 }
garygid 67:2022fce701d0 764 break;
garygid 67:2022fce701d0 765
garygid 67:2022fce701d0 766 case 12: // left-middle col, bottom row (not nav)
TickTock 158:059abeb44ba1 767 if (dMode[whichTouched]==configScreen) {
TickTock 158:059abeb44ba1 768 regenMon = !regenMon;
TickTock 158:059abeb44ba1 769 } else if (dMode[whichTouched]==config2Screen) { // gg - index
leafman 98:9f8bab96edff 770 dMode[whichTouched] = dateScreen ; // GoTo Set Date/Time Screen
garygid 87:46ac3f2519d6 771 } else {
garygid 87:46ac3f2519d6 772 lastDMode[whichTouched]=99;//repaint to clear highlight
garygid 87:46ac3f2519d6 773 }
garygid 67:2022fce701d0 774 break;
garygid 67:2022fce701d0 775
garygid 67:2022fce701d0 776 case 22: // right-middle col, bottom row (not nav)
TickTock 158:059abeb44ba1 777 if (dMode[whichTouched]==indexScreen) { // gg - index
leafman 98:9f8bab96edff 778 dMode[whichTouched] = logScreen ;
TickTock 169:84d790ac18a2 779 sMode=0;
TickTock 159:577e9d015693 780 } else if (dMode[whichTouched]==configScreen) {
TickTock 159:577e9d015693 781 heaterMon = !heaterMon;
TickTock 157:1a100a5ed06f 782 } else if (dMode[whichTouched]==config2Screen) {
TickTock 169:84d790ac18a2 783 updateConfig();
TickTock 169:84d790ac18a2 784 lastDMode[whichTouched]=99;//force refresh
TickTock 169:84d790ac18a2 785 sMode=0;
garygid 87:46ac3f2519d6 786 } else {
garygid 87:46ac3f2519d6 787 lastDMode[whichTouched]=99;//repaint to clear highlight
garygid 87:46ac3f2519d6 788 }
garygid 67:2022fce701d0 789 break;
TickTock 72:f9a6faa28873 790
leafman 98:9f8bab96edff 791 case 32: // right col, bottom row (not nav)
TickTock 158:059abeb44ba1 792 if (dMode[whichTouched]==config2Screen) {
TickTock 114:3f8c59a8a2b9 793 logEn=false;
leafman 98:9f8bab96edff 794 updateFirmware();
TickTock 158:059abeb44ba1 795 } else if (dMode[whichTouched]==tripScreen) {
TickTock 177:6fda79c2fda1 796 // Reset custom trip meter
TickTock 108:29b5a760adc2 797 miles_trip[2]=0;
TickTock 108:29b5a760adc2 798 kWh_trip[2]=0;
TickTock 167:58d4edf403d4 799 CCkWh_trip[2]=0;
TickTock 73:62ee8eae3a84 800 sMode=0;
TickTock 108:29b5a760adc2 801 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 158:059abeb44ba1 802 } else if (dMode[whichTouched]==indexScreen) {
TickTock 108:29b5a760adc2 803 dMode[whichTouched] = tripScreen ;
TickTock 169:84d790ac18a2 804 sMode=0;
TickTock 152:a4d66901785d 805 } else if (dMode[whichTouched]==dateScreen){
TickTock 152:a4d66901785d 806 autoSync=!autoSync; // toggle autoSync mode
TickTock 152:a4d66901785d 807 lastDMode[whichTouched]=99;
TickTock 191:292debe95cba 808 } else if (dMode[whichTouched]==configScreen) {
TickTock 191:292debe95cba 809 if(!headlights){
TickTock 192:1d5f0ee9dc59 810 ledHi -= 0.1;
TickTock 191:292debe95cba 811 if (ledHi<0) ledHi=0;
TickTock 191:292debe95cba 812 } else {
TickTock 192:1d5f0ee9dc59 813 ledLo -= 0.1;
TickTock 191:292debe95cba 814 if (ledLo<0) ledLo=0;
TickTock 191:292debe95cba 815 }
leafman 98:9f8bab96edff 816 } else {
garygid 87:46ac3f2519d6 817 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 72:f9a6faa28873 818 }
TickTock 72:f9a6faa28873 819 break;
TickTock 72:f9a6faa28873 820
garygid 67:2022fce701d0 821 //-----------------------------------
garygid 54:6ce808d0995e 822 //-----------------------------------
garygid 54:6ce808d0995e 823 // Prev Navigation
garygid 54:6ce808d0995e 824 case 07: // col 0 row tNavRow
TickTock 42:4533b13b297d 825 dMode[whichTouched]=dMode[whichTouched]>0?dMode[whichTouched]-1:maxScreens;
TickTock 22:a43df3905863 826 break;
garygid 54:6ce808d0995e 827 //-----------------------------------
garygid 54:6ce808d0995e 828 // Select Screen Navigation
garygid 54:6ce808d0995e 829 case 17:
TickTock 43:e7f6f80590e3 830 sMode=0;
TickTock 43:e7f6f80590e3 831 lastDMode[whichTouched]=99; // Repaint
TickTock 22:a43df3905863 832 break;
garygid 54:6ce808d0995e 833 //-----------------------------------
garygid 54:6ce808d0995e 834 // Index Navigation
garygid 54:6ce808d0995e 835 case 27: // col 2 row tNavRow
garygid 67:2022fce701d0 836 dMode[whichTouched]= indexScreen ; // gg - index
garygid 54:6ce808d0995e 837 break;
garygid 54:6ce808d0995e 838 //------------------------------------
garygid 54:6ce808d0995e 839 // Next Navigation
garygid 54:6ce808d0995e 840 case 37: // lower right on Nav Line gg - move next
TickTock 42:4533b13b297d 841 dMode[whichTouched]=dMode[whichTouched]<maxScreens?dMode[whichTouched]+1:0;
TickTock 22:a43df3905863 842 break;
garygid 54:6ce808d0995e 843 //------------------------------------
garygid 54:6ce808d0995e 844 //------------------------------------
TickTock 22:a43df3905863 845 default:
TickTock 62:ffd15edb5431 846 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 25:ddf0ec209f03 847 break;
TickTock 25:ddf0ec209f03 848 }
TickTock 23:cd03f9c3395e 849 break;
TickTock 23:cd03f9c3395e 850 case 2: // numpad
TickTock 195:ef0af84a4340 851 tCol = buttonX(lastTouch.x,5) ;
TickTock 195:ef0af84a4340 852 if( tCol >= 5 ){ tCol -= 5; } // touch is on screen 1
TickTock 195:ef0af84a4340 853 tRow = buttonY(lastTouch.y,4) ;
TickTock 195:ef0af84a4340 854 highlightButton( tCol,tRow, whichTouched, 5,4) ; // gg - highlight
TickTock 195:ef0af84a4340 855 if(tCol<4){
TickTock 195:ef0af84a4340 856 keypad = keypad<<4; // shift left
TickTock 195:ef0af84a4340 857 keypad += tRow*4+tCol; // add next digit
TickTock 195:ef0af84a4340 858 } else {
TickTock 195:ef0af84a4340 859 switch ( tRow ) {
TickTock 195:ef0af84a4340 860 case 0: // col 4 row 0
TickTock 195:ef0af84a4340 861 keypad = keypad>>4; // shift right
TickTock 195:ef0af84a4340 862 break;
TickTock 195:ef0af84a4340 863 case 1: // col 4 row 1
TickTock 195:ef0af84a4340 864 break;
TickTock 195:ef0af84a4340 865 case 2: // col 4 row 2
TickTock 195:ef0af84a4340 866 break;
TickTock 195:ef0af84a4340 867 case 3: // col 4 row 3
TickTock 195:ef0af84a4340 868 sMode=0; // end keypad mode
TickTock 195:ef0af84a4340 869 dMode[0]=saveDmode[0];
TickTock 195:ef0af84a4340 870 dMode[1]=saveDmode[1];
TickTock 195:ef0af84a4340 871 lastDMode[0]=99;
TickTock 195:ef0af84a4340 872 lastDMode[1]=99;
TickTock 195:ef0af84a4340 873 uidx=99;
TickTock 195:ef0af84a4340 874 break;
TickTock 195:ef0af84a4340 875 default:
TickTock 195:ef0af84a4340 876 break;
TickTock 195:ef0af84a4340 877 }
TickTock 195:ef0af84a4340 878 }
TickTock 23:cd03f9c3395e 879 break;
TickTock 23:cd03f9c3395e 880 case 3:
TickTock 23:cd03f9c3395e 881 break;
TickTock 23:cd03f9c3395e 882 default:
TickTock 23:cd03f9c3395e 883 break;
TickTock 23:cd03f9c3395e 884 } // case sMode
TickTock 22:a43df3905863 885 } //recently touched
TickTock 196:c1bfa3ed21a6 886 } else if(sMode<2) { // userIdle if not in hex entry mode
TickTock 195:ef0af84a4340 887 sMode=0;
TickTock 195:ef0af84a4340 888 lastDMode[whichTouched]=99;
TickTock 195:ef0af84a4340 889 } //!userIdle
TickTock 34:4751a8259b18 890
TickTock 153:e94cfe3c339c 891 // Sound tone on power reversal
TickTock 153:e94cfe3c339c 892 idir=(kW[0]>0)?true:false;
TickTock 155:f31006516956 893 if(regenMon){
TickTock 153:e94cfe3c339c 894 if (idir&&!lidir){
TickTock 155:f31006516956 895 beep(800,0.02); // Started sinking current
TickTock 153:e94cfe3c339c 896 }else if(!idir&&lidir){
TickTock 155:f31006516956 897 beep(3200,0.02); // Started regen
TickTock 153:e94cfe3c339c 898 }
TickTock 153:e94cfe3c339c 899 }
TickTock 154:90ea16ca7475 900 lidir=idir;
TickTock 153:e94cfe3c339c 901
TickTock 34:4751a8259b18 902 if(tick){ // Executes once a second
TickTock 108:29b5a760adc2 903 tick=false;
TickTock 196:c1bfa3ed21a6 904 carCanIdle=(++secsNoCarCanMsg>canTimeout)?true:false;
TickTock 196:c1bfa3ed21a6 905 evCanIdle=(++secsNoEvCanMsg>canTimeout)?true:false;
TickTock 195:ef0af84a4340 906 if(tt.is_touched()){
TickTock 195:ef0af84a4340 907 if(checkFWupdate){
TickTock 188:8cf15e4610aa 908 updateFirmware();
TickTock 188:8cf15e4610aa 909 }
TickTock 196:c1bfa3ed21a6 910 longTouch = (++secsTouch>1);
TickTock 195:ef0af84a4340 911 }else{
TickTock 196:c1bfa3ed21a6 912 userIdle=(++secsNoTouch>userTimeout)?true:false;
TickTock 195:ef0af84a4340 913 secsTouch = 0;
TickTock 188:8cf15e4610aa 914 }
TickTock 195:ef0af84a4340 915 checkFWupdate=false; // Only check once at first poweron
TickTock 164:46ed06263b0e 916 lCCon = CCon;
TickTock 161:71ac85d11f03 917 CCkW = (lastMsg[indexLastMsg[0x510]].data[3]&0x7f)*0.125;
TickTock 164:46ed06263b0e 918 if(lastMsg[indexLastMsg[0x510]].data[3]&0x80){
TickTock 196:c1bfa3ed21a6 919 CCon=true; // On when button pushed
TickTock 164:46ed06263b0e 920 } else if(CCkW==0) {
TickTock 164:46ed06263b0e 921 CCon=false; // Off when power drops back to zero
TickTock 164:46ed06263b0e 922 }
TickTock 164:46ed06263b0e 923 if(!CCon && lCCon){
TickTock 164:46ed06263b0e 924 lastDMode[0]=99;//force refresh
TickTock 164:46ed06263b0e 925 lastDMode[1]=99;//force refresh
TickTock 164:46ed06263b0e 926 }
TickTock 93:c2402e8cd0e2 927 headlights = (lastMsg[indexLastMsg[0x358]].data[1]&0x80)?true:false; // headlight/turn signal indicator
TickTock 160:905fe45ed54b 928 if(heaterOn){
TickTock 160:905fe45ed54b 929 lHeaterOn=true; // Only indicate heater once per power cycle
TickTock 160:905fe45ed54b 930 }
TickTock 184:5ca7b78297fe 931 heaterOn =((lastMsg[indexLastMsg[0x54f]].data[5]&0x3f)>2)?true:false;
TickTock 159:577e9d015693 932 if(heaterMon && heaterOn && !lHeaterOn){ //Heat on alarm
TickTock 160:905fe45ed54b 933 beep3(800,0.25,1200,0.25,1600,0.25);
TickTock 159:577e9d015693 934 }
TickTock 148:6e3b9135fad2 935 if(accOn&&indexLastMsg[0x355]>0){
TickTock 141:cf13a632ddb5 936 miles_kmbar = (lastMsg[indexLastMsg[0x355]].data[4]&0x20)?true:false; // indicates selected distance units
TickTock 141:cf13a632ddb5 937 metric = !miles_kmbar;
TickTock 141:cf13a632ddb5 938 }
TickTock 41:8d4609ea7259 939 accV=floor(mon12V*scale12V*10+0.5)/10; //Round to nearest 10th
TickTock 172:53548bf8bf85 940 accOn=(playbackOpen||(accV>5))?true:false;
TickTock 131:0d926c080a65 941 moving=(mph[0]>0.1);
TickTock 195:ef0af84a4340 942 charging=(lastMsg[indexLastMsg[0x5bf]].data[4]>0x40)?true:false; // MSB=QC, MSB-1=L2
TickTock 134:ad243e4f1a17 943 if (laccOn&&!accOn){ // Car turned off
TickTock 177:6fda79c2fda1 944 dailyGids += startGids-((lastMsg[indexLastMsg[0x5bc]].data[0]<<2)+(lastMsg[indexLastMsg[0x5bc]].data[1]>>6));
TickTock 160:905fe45ed54b 945 lHeaterOn=false;
TickTock 195:ef0af84a4340 946 if (showHealth&&!playbackOpen&&false){ //blah false
TickTock 175:0357b4159b40 947 if (saveDmode[0]==99){
TickTock 175:0357b4159b40 948 saveDmode[0]=dMode[0];
TickTock 175:0357b4159b40 949 saveDmode[1]=dMode[1];
TickTock 134:ad243e4f1a17 950 }
TickTock 134:ad243e4f1a17 951 dMode[0]=healthScreen;
TickTock 175:0357b4159b40 952 dMode[1]=tripScreen;
TickTock 135:89986950d501 953 secsNoTouch=2;// Keep display on a few seconds
TickTock 134:ad243e4f1a17 954 sMode=0;
TickTock 134:ad243e4f1a17 955 userIdle=false;
TickTock 134:ad243e4f1a17 956 }
TickTock 108:29b5a760adc2 957 if (repeatPoll) { // Log on shutdown if autopoll enabled
TickTock 108:29b5a760adc2 958 tripLog(); // Write trip log on powerdown
TickTock 108:29b5a760adc2 959 }
TickTock 49:a3d2c5bb3cfa 960 //write efficiency history data
TickTock 97:a25940fd7b5b 961 hfile = fopen("/local/ehist.cny", "w");
TickTock 97:a25940fd7b5b 962 if (hfile!=NULL){ // found a efficiency history file
TickTock 49:a3d2c5bb3cfa 963 for(i=0;i<39;i++){
TickTock 97:a25940fd7b5b 964 fprintf(hfile,"%f %f\r\n",mph[i],kW[i]);
TickTock 49:a3d2c5bb3cfa 965 }
TickTock 134:ad243e4f1a17 966 fprintf(hfile,"%f %f\r\n",maxTripEff,minTripEff); // Save max and min
TickTock 155:f31006516956 967 fprintf(hfile,"%f \r\n",Resr); // Save series resistance
TickTock 167:58d4edf403d4 968 fprintf(hfile,"%f %f\r\n",maxTripMiles,minTripMiles); // Save max and min
TickTock 167:58d4edf403d4 969 fprintf(hfile,"%f %f\r\n",maxTripkWh,minTripkWh); // Save max and min
TickTock 167:58d4edf403d4 970 fprintf(hfile,"%f %f\r\n",maxTripCCkWh,minTripCCkWh); // Save max and min
TickTock 180:5fdeeb86f3a3 971 for(i=0;i<300;i++){
TickTock 180:5fdeeb86f3a3 972 fprintf(hfile,"%f\r\n",wh[i]);
TickTock 180:5fdeeb86f3a3 973 }
TickTock 97:a25940fd7b5b 974 fclose(hfile);
TickTock 49:a3d2c5bb3cfa 975 }
TickTock 49:a3d2c5bb3cfa 976 }
TickTock 134:ad243e4f1a17 977 if (!laccOn&&accOn){ // Car turned on
TickTock 160:905fe45ed54b 978 lHeaterOn=false;
TickTock 177:6fda79c2fda1 979 getGids=true;
TickTock 108:29b5a760adc2 980 miles_trip[0]=0;
TickTock 108:29b5a760adc2 981 kWh_trip[0]=0;
TickTock 167:58d4edf403d4 982 CCkWh_trip[0]=0;
TickTock 176:9c19f9856c76 983 seconds = time(NULL);
TickTock 176:9c19f9856c76 984 t = *localtime(&seconds);
TickTock 183:a1fba6f76e69 985 if(miles_trip[1]<1){ // charged since last trip
TickTock 184:5ca7b78297fe 986
TickTock 184:5ca7b78297fe 987 // Adjust wh lookup with whpg data
TickTock 180:5fdeeb86f3a3 988 maxWhpg=0;
TickTock 180:5fdeeb86f3a3 989 minWh=0;
TickTock 180:5fdeeb86f3a3 990 whOff=0;
TickTock 180:5fdeeb86f3a3 991 for(i=1;i<300;i++){
TickTock 184:5ca7b78297fe 992 if(whpg[i]>maxWhpg){ //Find maxWhpg and associated Wh
TickTock 184:5ca7b78297fe 993 maxWhpg = (float) whpg[i];
TickTock 184:5ca7b78297fe 994 minWh = wh[i];
TickTock 182:10017d74de67 995 if(debugMode){
TickTock 184:5ca7b78297fe 996 sprintf(sTemp,"maxWhpg=%3.1f; minWh=%3.1f\n", maxWhpg, minWh);
TickTock 184:5ca7b78297fe 997 printMsg(sTemp);
TickTock 182:10017d74de67 998 }
TickTock 180:5fdeeb86f3a3 999 }
TickTock 184:5ca7b78297fe 1000 if(whpg[i]>0){ // Compute adjustment to measured range
TickTock 184:5ca7b78297fe 1001 whOff = (maxWhpg-(float)whpg[i])-(wh[i]-minWh);
TickTock 184:5ca7b78297fe 1002 }else if(whpg[i-1]>0){ // Compute final offset for rest of range
TickTock 184:5ca7b78297fe 1003 whOff = maxWhpg-(wh[i]-minWh);
TickTock 184:5ca7b78297fe 1004 if(debugMode){
TickTock 184:5ca7b78297fe 1005 sprintf(sTemp,"whOff=%3.1f\n", whOff);
TickTock 184:5ca7b78297fe 1006 printMsg(sTemp);
TickTock 180:5fdeeb86f3a3 1007 }
TickTock 180:5fdeeb86f3a3 1008 }
TickTock 184:5ca7b78297fe 1009 wh[i] += 0.1*whOff; // Add offset; use last known good offset when no data
TickTock 184:5ca7b78297fe 1010 whpg[i-1]=0;
TickTock 181:396fdcceefd2 1011 }
TickTock 184:5ca7b78297fe 1012 whpg[299]=0;
TickTock 184:5ca7b78297fe 1013
TickTock 184:5ca7b78297fe 1014 // Check and reset daily efficiency if charged since last trip and at least 24 hours has past
TickTock 183:a1fba6f76e69 1015 if((t.tm_yday>lt.tm_yday)&&(t.tm_hour>effCheckTime)){
TickTock 183:a1fba6f76e69 1016 if (!ignoreDayData&&(miles_trip[3]>15)){ // Ignore low mileage data
TickTock 183:a1fba6f76e69 1017 curEff = miles_trip[3]/kWh_trip[3]; // Get current daily efficiency
TickTock 183:a1fba6f76e69 1018 if (maxTripEff<curEff) {
TickTock 183:a1fba6f76e69 1019 maxTripEff=curEff;
TickTock 183:a1fba6f76e69 1020 maxTripMiles=miles_trip[3];
TickTock 183:a1fba6f76e69 1021 maxTripkWh=kWh_trip[3];
TickTock 183:a1fba6f76e69 1022 maxTripCCkWh=CCkWh_trip[3];
TickTock 183:a1fba6f76e69 1023 printMsg("New max efficiency.\n");
TickTock 183:a1fba6f76e69 1024 }
TickTock 183:a1fba6f76e69 1025 if (minTripEff>curEff) {
TickTock 183:a1fba6f76e69 1026 minTripEff=curEff;
TickTock 183:a1fba6f76e69 1027 minTripMiles=miles_trip[3];
TickTock 183:a1fba6f76e69 1028 minTripkWh=kWh_trip[3];
TickTock 183:a1fba6f76e69 1029 minTripCCkWh=CCkWh_trip[3];
TickTock 183:a1fba6f76e69 1030 printMsg("New min efficiency.\n");
TickTock 183:a1fba6f76e69 1031 }
TickTock 183:a1fba6f76e69 1032 }
TickTock 183:a1fba6f76e69 1033 // Clear daily efficiency data
TickTock 183:a1fba6f76e69 1034 dailyGids=0;
TickTock 183:a1fba6f76e69 1035 miles_trip[3]=0;
TickTock 183:a1fba6f76e69 1036 kWh_trip[3]=0;
TickTock 183:a1fba6f76e69 1037 CCkWh_trip[3]=0;
TickTock 183:a1fba6f76e69 1038 ignoreDayData=false;
TickTock 183:a1fba6f76e69 1039 lt=t; // Remember when counters were cleared (start time for new data)
TickTock 183:a1fba6f76e69 1040 }
TickTock 183:a1fba6f76e69 1041 } // Charged since last trip
TickTock 115:549410af477d 1042 wait5secs=5;
TickTock 195:ef0af84a4340 1043 if (showHealth&&!playbackOpen&&false){ //blah false
TickTock 175:0357b4159b40 1044 if (saveDmode[0]==99){
TickTock 175:0357b4159b40 1045 saveDmode[0]=dMode[0];
TickTock 134:ad243e4f1a17 1046 }
TickTock 131:0d926c080a65 1047 dMode[0]=healthScreen;
TickTock 131:0d926c080a65 1048 }
TickTock 152:a4d66901785d 1049 syncDone=!autoSync; // clear syncDone flag if autoSync enabled
TickTock 177:6fda79c2fda1 1050 } // Car turned on
TickTock 49:a3d2c5bb3cfa 1051 laccOn=accOn;
TickTock 135:89986950d501 1052 if(!accOn&&userIdle&&!playbackEn){ // Car off and no user activity - turn off screen
TickTock 134:ad243e4f1a17 1053 dled = 0;
TickTock 175:0357b4159b40 1054 if (saveDmode[0]<99){
TickTock 175:0357b4159b40 1055 dMode[0]=saveDmode[0];
TickTock 175:0357b4159b40 1056 saveDmode[0]=99;
TickTock 175:0357b4159b40 1057 }
TickTock 175:0357b4159b40 1058 if (saveDmode[1]<99){
TickTock 175:0357b4159b40 1059 dMode[1]=saveDmode[1];
TickTock 175:0357b4159b40 1060 saveDmode[1]=99;
TickTock 134:ad243e4f1a17 1061 }
TickTock 35:5acbd8a64a89 1062 }else if(!headlights){
TickTock 35:5acbd8a64a89 1063 dled = ledHi;
TickTock 115:549410af477d 1064 } else {
TickTock 35:5acbd8a64a89 1065 dled = ledLo;
TickTock 34:4751a8259b18 1066 }
TickTock 178:bf6404312c45 1067 cgids=(lastMsg[indexLastMsg[0x5bc]].data[0]<<2)+(lastMsg[indexLastMsg[0x5bc]].data[1]>>6);
TickTock 172:53548bf8bf85 1068 if(getGids){
TickTock 178:bf6404312c45 1069 startGids=cgids; //Get gids
TickTock 177:6fda79c2fda1 1070 if((startGids>0)&&(startGids<300)){ // Ignore bogus values at startup
TickTock 172:53548bf8bf85 1071 getGids=false;
TickTock 178:bf6404312c45 1072 lgids=startGids; // initialize wh/gid array
TickTock 172:53548bf8bf85 1073 }
TickTock 172:53548bf8bf85 1074 }
TickTock 179:e4094e55f079 1075 if((cgids>0)&&(cgids<300)){
TickTock 183:a1fba6f76e69 1076 if(cgids!=lgids){
TickTock 184:5ca7b78297fe 1077 if((kWh_trip[1]+CCkWh_trip[1])>0){
TickTock 184:5ca7b78297fe 1078 whpg[cgids] = (unsigned short) (1000*(kWh_trip[1]+CCkWh_trip[1])); // Save kWh for each gid since last charge
TickTock 184:5ca7b78297fe 1079 }else{
TickTock 184:5ca7b78297fe 1080 whpg[cgids] = 0;
TickTock 184:5ca7b78297fe 1081 }
TickTock 179:e4094e55f079 1082 lgids=cgids;
TickTock 179:e4094e55f079 1083 }
TickTock 178:bf6404312c45 1084 }
TickTock 115:549410af477d 1085 if(wait5secs>0){ // Wait a few seconds after poweron to give BMS time to measure CP's
TickTock 115:549410af477d 1086 wait5secs-=1;
TickTock 172:53548bf8bf85 1087 if(wait5secs==0){
TickTock 172:53548bf8bf85 1088 if (repeatPoll) { // Poll on startup if autopoll enabled
TickTock 172:53548bf8bf85 1089 logOnce=true;
TickTock 172:53548bf8bf85 1090 reqMsgCnt=0;
TickTock 172:53548bf8bf85 1091 msgReq.attach(&sendReq,0.015);
TickTock 172:53548bf8bf85 1092 lastDMode[0]=99;
TickTock 172:53548bf8bf85 1093 lastDMode[1]=99;
TickTock 172:53548bf8bf85 1094 }
TickTock 108:29b5a760adc2 1095 }
TickTock 107:e9be732c1ad4 1096 }
TickTock 173:9815b1467039 1097 //remove health screen once moving
TickTock 175:0357b4159b40 1098 if(moving&&(saveDmode[0]<99)&&(wait5secs==0)){
TickTock 175:0357b4159b40 1099 dMode[0]=saveDmode[0];
TickTock 175:0357b4159b40 1100 saveDmode[0]=99;
TickTock 173:9815b1467039 1101 }
TickTock 115:549410af477d 1102
TickTock 49:a3d2c5bb3cfa 1103 //compute historic efficiency
TickTock 41:8d4609ea7259 1104 if(numSsamples>0){ // Avoid div0
TickTock 160:905fe45ed54b 1105 // calibrated to dash mph which reads slightly fast.
TickTock 160:905fe45ed54b 1106 // 227 would give more accurate mph for MXV4s@40psi - 11.75" distance from center of tire to pavement
TickTock 160:905fe45ed54b 1107 // but then efficiency estimation would not track miles driven as read from the odometer so
TickTock 160:905fe45ed54b 1108 // making CANary have the same error as the Leaf instrumentation
TickTock 174:cd27e80f197d 1109 mph[0]=((float) motorRPM)/numSsamples/110;
TickTock 86:d1c9e8ac1c4b 1110 } else {
TickTock 49:a3d2c5bb3cfa 1111 mph[0]=0;
TickTock 36:dbd39c315258 1112 }
TickTock 49:a3d2c5bb3cfa 1113 if(mph[0]>99){
TickTock 49:a3d2c5bb3cfa 1114 mph[0]=0;
TickTock 49:a3d2c5bb3cfa 1115 }
TickTock 121:553faf139a20 1116 numSsamples=0;
TickTock 107:e9be732c1ad4 1117
TickTock 41:8d4609ea7259 1118 if(numWsamples>0){ // Avoid div0
TickTock 121:553faf139a20 1119 mpkWh[0]=mph[0];
TickTock 161:71ac85d11f03 1120 kW[0]=((float) mWs_x4)/numWsamples/4e3;
TickTock 49:a3d2c5bb3cfa 1121 mpkWh[0]/=kW[0];
TickTock 49:a3d2c5bb3cfa 1122 if (mpkWh[0]<0) {
TickTock 49:a3d2c5bb3cfa 1123 mpkWh[0]=99;// negative means inf.
TickTock 49:a3d2c5bb3cfa 1124 }
TickTock 161:71ac85d11f03 1125 kW[0]-=CCkW; // subtract climate control power from recorded value
TickTock 161:71ac85d11f03 1126 } else {
TickTock 49:a3d2c5bb3cfa 1127 kW[0]=0;
TickTock 49:a3d2c5bb3cfa 1128 mpkWh[0]=0;
TickTock 49:a3d2c5bb3cfa 1129 }
TickTock 121:553faf139a20 1130 numWsamples=0;
TickTock 121:553faf139a20 1131
TickTock 172:53548bf8bf85 1132 if(accOn&&!charging){ // Calculate averages
TickTock 161:71ac85d11f03 1133 for(i=1;i<39;i++){
TickTock 161:71ac85d11f03 1134 average=mph[i]/timeConstant[i];
TickTock 161:71ac85d11f03 1135 mph[i]-=average;
TickTock 161:71ac85d11f03 1136 mph[i]+=mph[0];
TickTock 161:71ac85d11f03 1137 mpkWh[i]=average;
TickTock 161:71ac85d11f03 1138 average=kW[i]/timeConstant[i];
TickTock 161:71ac85d11f03 1139 kW[i]-=average;
TickTock 161:71ac85d11f03 1140 kW[i]+=kW[0];
TickTock 162:c6545fc0164a 1141 if(i==dtePeriod) mpkWh_noCC=mpkWh[i]/average; // compute efficiency w/o CC for dtePeriod
TickTock 161:71ac85d11f03 1142 average+=CCkW; //add climate control power back in for display
TickTock 161:71ac85d11f03 1143 mpkWh[i]/=average;
TickTock 161:71ac85d11f03 1144 if (mpkWh[i]<0) {
TickTock 161:71ac85d11f03 1145 mpkWh[i]=99;// negative means inf.
TickTock 161:71ac85d11f03 1146 }
TickTock 161:71ac85d11f03 1147 }
TickTock 161:71ac85d11f03 1148 }
TickTock 161:71ac85d11f03 1149
TickTock 121:553faf139a20 1150 if (!charging){
TickTock 151:3047ebb3c9a8 1151 miles_trip[0]+=mph[0]/3600; // per trip
TickTock 151:3047ebb3c9a8 1152 miles_trip[1]+=mph[0]/3600; // per charge
TickTock 151:3047ebb3c9a8 1153 miles_trip[2]+=mph[0]/3600; // user
TickTock 179:e4094e55f079 1154 miles_trip[3]+=mph[0]/3600; // per day/roundtrip
TickTock 121:553faf139a20 1155 kWh_trip[0]+=kW[0]/3600;
TickTock 121:553faf139a20 1156 kWh_trip[1]+=kW[0]/3600;
TickTock 121:553faf139a20 1157 kWh_trip[2]+=kW[0]/3600;
TickTock 176:9c19f9856c76 1158 kWh_trip[3]+=kW[0]/3600;
TickTock 167:58d4edf403d4 1159 CCkWh_trip[0]+=CCkW/3600;
TickTock 167:58d4edf403d4 1160 CCkWh_trip[1]+=CCkW/3600;
TickTock 167:58d4edf403d4 1161 CCkWh_trip[2]+=CCkW/3600;
TickTock 176:9c19f9856c76 1162 CCkWh_trip[3]+=CCkW/3600;
TickTock 161:71ac85d11f03 1163 } else { // charging so reset per charge trip meter
TickTock 151:3047ebb3c9a8 1164 miles_trip[1]=0;
TickTock 151:3047ebb3c9a8 1165 kWh_trip[1]=0;
TickTock 167:58d4edf403d4 1166 CCkWh_trip[1]=0;
TickTock 121:553faf139a20 1167 }
TickTock 121:553faf139a20 1168
TickTock 174:cd27e80f197d 1169 motorRPM=0;
TickTock 40:0e6e71a7323f 1170 mWs_x4=0;
TickTock 121:553faf139a20 1171
TickTock 121:553faf139a20 1172 // Compute ESR
TickTock 121:553faf139a20 1173 if((Imax-Imin)<40){ // do nothing - insufficient delta_I to measure
TickTock 121:553faf139a20 1174 unloadedV_x2 = (curRmax+curRmin)/2;
TickTock 154:90ea16ca7475 1175 }else if ((redRmax-redRmin)<(curRmax-curRmin)) { // less variation on reduced Resr
TickTock 120:041edeec08f5 1176 Resr-=0.001;
TickTock 120:041edeec08f5 1177 unloadedV_x2 = (redRmax+redRmin)/2;
TickTock 154:90ea16ca7475 1178 } else if ((incRmax-incRmin)<(curRmax-curRmin)) { // less variation on increased Resr
TickTock 120:041edeec08f5 1179 Resr+=0.001;
TickTock 120:041edeec08f5 1180 unloadedV_x2 = (incRmax+incRmin)/2;
TickTock 154:90ea16ca7475 1181 } else { // current Resr is still best answer
TickTock 120:041edeec08f5 1182 unloadedV_x2 = (curRmax+curRmin)/2;
TickTock 120:041edeec08f5 1183 }
TickTock 120:041edeec08f5 1184 curRmin=1000;
TickTock 120:041edeec08f5 1185 curRmax=0;
TickTock 120:041edeec08f5 1186 incRmin=1000;
TickTock 120:041edeec08f5 1187 incRmax=0;
TickTock 120:041edeec08f5 1188 redRmin=1000;
TickTock 120:041edeec08f5 1189 redRmax=0;
TickTock 121:553faf139a20 1190 Imax=-1000;
TickTock 121:553faf139a20 1191 Imin=1000;
TickTock 121:553faf139a20 1192
TickTock 108:29b5a760adc2 1193 if(logCP&&usbEn){
TickTock 108:29b5a760adc2 1194 if(logOnce){
TickTock 108:29b5a760adc2 1195 tripLog();
TickTock 108:29b5a760adc2 1196 logOnce=false;
TickTock 108:29b5a760adc2 1197 }
garygid 69:6bfdfc002036 1198 logPackVoltages(); // Turbo3, only call
TickTock 108:29b5a760adc2 1199 }
TickTock 137:70853cf5a30f 1200 if(!usbEn){
TickTock 108:29b5a760adc2 1201 usbEn=detectUSB(); // Keep looking if none found
TickTock 132:08748a67280a 1202 if(usbEn){ // Force update to clear USB init garbage
TickTock 132:08748a67280a 1203 lastDMode[0]=99;
TickTock 132:08748a67280a 1204 lastDMode[1]=99;
TickTock 132:08748a67280a 1205 }
TickTock 108:29b5a760adc2 1206 }
TickTock 152:a4d66901785d 1207 if(!syncDone){
TickTock 153:e94cfe3c339c 1208 syncDone=syncDateTime();
TickTock 152:a4d66901785d 1209 }
TickTock 121:553faf139a20 1210 tock=true;
TickTock 121:553faf139a20 1211 } // tick
TickTock 39:eef8beac7411 1212
TickTock 36:dbd39c315258 1213 if(step){ // playback
TickTock 36:dbd39c315258 1214 if(playbackOpen&&playbackEn){
TickTock 38:155ec32c5e91 1215 for(i=0;i<120;i++){
TickTock 109:3e6f0e8fca0d 1216 if(!f_eof(&efile)){
TickTock 109:3e6f0e8fca0d 1217 efr=f_read(&efile,&header,5,&bytesRW);
TickTock 109:3e6f0e8fca0d 1218 efr=f_read(&efile,&data,8,&bytesRW);
garygid 69:6bfdfc002036 1219 logCan(header[0],CANMessage(0x7ff&((header[4]<<8)+header[3]), data, 8)); // Playback
TickTock 86:d1c9e8ac1c4b 1220 } else {
TickTock 109:3e6f0e8fca0d 1221 f_close(&efile); // restart
TickTock 109:3e6f0e8fca0d 1222 efr = f_open(&efile,"playback.alc",FA_READ|FA_OPEN_EXISTING);
TickTock 50:83d5864c64a0 1223 lastDMode[whichTouched]=99;//force refresh
TickTock 155:f31006516956 1224 beep(2000,0.25);
TickTock 36:dbd39c315258 1225 }
TickTock 36:dbd39c315258 1226 }
TickTock 36:dbd39c315258 1227 }
TickTock 36:dbd39c315258 1228 step=false;
TickTock 36:dbd39c315258 1229 }
TickTock 37:fea2c1d52c5f 1230
TickTock 140:ab3e94eb0227 1231 display=display<1?display+1:0; // toggle display
TickTock 140:ab3e94eb0227 1232 updateDisplay(display);
TickTock 2:71b1999a8ea5 1233 } //while (true)
TickTock 0:1596b8644523 1234 }