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:
Thu Aug 14 23:08:10 2014 +0000
Revision:
195:ef0af84a4340
Parent:
194:ac10f8f4c4e3
Child:
196:c1bfa3ed21a6
Added keypad and ability to edit user watchpoints

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