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 Jun 20 23:07:27 2013 +0000
Branch:
Metric
Revision:
103:1389e9efe8c3
Parent:
102:fd19f777a0b4
Child:
104:5a19101aaac5
Fixed formatting

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TickTock 13:62e0f7f39ff5 1 // main.cpp
TickTock 13:62e0f7f39ff5 2
TickTock 4:8d7759f4fe7a 3 //To Do:
TickTock 33:a277743ebdeb 4 // * USB device detect
TickTock 102:fd19f777a0b4 5 // * Enable file timestamps
TickTock 33:a277743ebdeb 6 // * Audible friction brake feedback
TickTock 33:a277743ebdeb 7 // * User-configurable watchpoint
TickTock 33:a277743ebdeb 8 // * Add 50% charge option
TickTock 33:a277743ebdeb 9 // * Tire Pressure Sensor display
TickTock 77:7c136766466c 10 // * Fix bug in playback while connected to canbus (hangs)
TickTock 97:a25940fd7b5b 11 // * Force regen display to zero when in neutral
TickTock 102:fd19f777a0b4 12 // * Add coasting regen to regen/braking display
TickTock 103:1389e9efe8c3 13 // * Change semilog efficiency graph to linear with 10 minute values
TickTock 102:fd19f777a0b4 14 // * Add Trip meter (kWh and efficiency for current trip)
TickTock 102:fd19f777a0b4 15 // * Make unique sound when log file write fails and logging disabled
TickTock 102:fd19f777a0b4 16 // * Make display updates interruptable for log writes
TickTock 102:fd19f777a0b4 17 // * Add additional 79b bank readouts
TickTock 102:fd19f777a0b4 18 // * Ignore the missing 4th pemperature sensor on 2013 models
TickTock 102:fd19f777a0b4 19 // * Add ability to transfer settings config file to/from USB
TickTock 103:1389e9efe8c3 20 // * Add once-on-powerup/powerdown log
TickTock 103:1389e9efe8c3 21 // * Move log dump to ISR (but CAN RX at higher priority)
TickTock 13:62e0f7f39ff5 22
TickTock 12:8e42d7ba8468 23 #include "mbed.h"
TickTock 12:8e42d7ba8468 24 #include "CAN.h"
TickTock 12:8e42d7ba8468 25 #include "beep.h"
TickTock 12:8e42d7ba8468 26 #include "MSCFileSystem.h"
TickTock 12:8e42d7ba8468 27 #include "PowerControl.h"
TickTock 12:8e42d7ba8468 28 #include "EthernetPowerControl.h"
TickTock 12:8e42d7ba8468 29 #include "utility.h"
TickTock 12:8e42d7ba8468 30 #include "displayModes.h"
TickTock 23:cd03f9c3395e 31 #include "TOUCH_TFTx2.h"
TickTock 4:8d7759f4fe7a 32
TickTock 101:94b8aca2d47a 33 char revStr[7] = "100";
TickTock 99:c05abf8e1cdc 34
TickTock 13:62e0f7f39ff5 35 LocalFileSystem local("local");
TickTock 13:62e0f7f39ff5 36
TickTock 13:62e0f7f39ff5 37 // to write to USB Flash Drives, or equivalent (SD card in Reader/Writer)
TickTock 35:5acbd8a64a89 38 MSCFileSystem fs("usb"); // to write to a USB Flash Drive
TickTock 13:62e0f7f39ff5 39
TickTock 13:62e0f7f39ff5 40 time_t seconds ;
TickTock 13:62e0f7f39ff5 41
TickTock 36:dbd39c315258 42 Ticker autoPoll;
TickTock 36:dbd39c315258 43 Ticker playback;
TickTock 78:a383971fe02f 44 Ticker msgReq;
TickTock 13:62e0f7f39ff5 45 Timer timer;
TickTock 13:62e0f7f39ff5 46
TickTock 13:62e0f7f39ff5 47 DigitalOut led1(LED1);
TickTock 13:62e0f7f39ff5 48 DigitalOut led2(LED2);
TickTock 13:62e0f7f39ff5 49 DigitalOut led3(LED3);
TickTock 13:62e0f7f39ff5 50 DigitalOut led4(LED4);
TickTock 13:62e0f7f39ff5 51
TickTock 13:62e0f7f39ff5 52 InterruptIn touchpad(p17);
TickTock 13:62e0f7f39ff5 53 CAN can1(p9, p10); // CAN1 (EV) uses pins 9 and 10 (rx, tx) and pin 8 (rs)
TickTock 13:62e0f7f39ff5 54 DigitalOut can1SleepMode(p8); // Use pin 8 to control the sleep mode of can2
TickTock 13:62e0f7f39ff5 55 CAN can2(p30, p29); // CAN2 (CAR) uses pins 30 and 29 (rx, tx) and pin 28 (rs)
TickTock 13:62e0f7f39ff5 56 DigitalOut can2SleepMode(p28); // Use pin 28 to control the sleep mode of can1
TickTock 35:5acbd8a64a89 57 AnalogIn mon12V(p15);
TickTock 13:62e0f7f39ff5 58 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 59 PwmOut dled(p23);
TickTock 35:5acbd8a64a89 60 Beep spkr(p21);
TickTock 13:62e0f7f39ff5 61
garygid 69:6bfdfc002036 62 // revision string, max 6 characters
garygid 71:7e87256d6c9a 63 // gg - revStr is used in 2 places
garygid 71:7e87256d6c9a 64 // gg - and is easy to edit here
garygid 71:7e87256d6c9a 65 // gg - added ZeroSecTick and revStr
garygid 69:6bfdfc002036 66
garygid 87:46ac3f2519d6 67 bool debugMode = false;
TickTock 48:d1ce92104a1f 68 bool logEn = false, logOpen = false;
TickTock 48:d1ce92104a1f 69 bool yesBattLog = false ; // gg - Batt Log
garygid 54:6ce808d0995e 70 unsigned char tNavRow = 3 ; // gg - 4x4 touch
garygid 54:6ce808d0995e 71
TickTock 97:a25940fd7b5b 72 FILE *hfile; // config file
TickTock 97:a25940fd7b5b 73 FILE *lfile; // log file
TickTock 13:62e0f7f39ff5 74 char fileName[35] = "" ;
TickTock 84:fd21e5d32dab 75 char writeBuffer[maxBufLen][13] __attribute__ ((section("AHBSRAM1"))); // buffer for USB write
TickTock 13:62e0f7f39ff5 76 char indexLastMsg[0x800]={0}; // index table for last message
TickTock 13:62e0f7f39ff5 77 CANMessage lastMsg[100]; // table to store last message of eachtype
garygid 87:46ac3f2519d6 78
garygid 87:46ac3f2519d6 79 //unsigned char battData[256]={0}; // 7 * 0x3D = BatDataBufMax
garygid 87:46ac3f2519d6 80 unsigned char battData[BatDataBufMax]={0}; // 7 * 0x3D = BatDataBufMax
garygid 87:46ac3f2519d6 81
TickTock 13:62e0f7f39ff5 82 unsigned char msgChanged[100]; // inidcates which bytes changed
TickTock 13:62e0f7f39ff5 83 char c;
TickTock 76:fb6779d0963e 84 volatile int writePointer = 0;
TickTock 76:fb6779d0963e 85 int readPointer=0;
TickTock 75:77bd26829dca 86 volatile unsigned short secsNoMsg = 0;
TickTock 75:77bd26829dca 87 volatile unsigned short secsNoTouch = 0;
TickTock 20:3bf176d14b14 88 volatile bool canIdle;
TickTock 20:3bf176d14b14 89 volatile bool userIdle;
TickTock 26:462ccb580472 90 bool touched=false; //flag to read touchscreen
TickTock 42:4533b13b297d 91 unsigned char whichTouched = 0;
TickTock 13:62e0f7f39ff5 92 char counter = 0;
TickTock 41:8d4609ea7259 93 unsigned char dMode[2] = {mainScreen,brakeScreen}; //display mode
TickTock 13:62e0f7f39ff5 94 unsigned char sMode = 0; // setup mode
TickTock 13:62e0f7f39ff5 95 unsigned char lastDMode[2] = {0,0}; //last screen mode
TickTock 25:ddf0ec209f03 96 unsigned char dtMode = 6;
TickTock 13:62e0f7f39ff5 97 char displayLog[20][40];
TickTock 13:62e0f7f39ff5 98 unsigned char displayLoc = 0;
leafman 98:9f8bab96edff 99 unsigned int fwCount=1;
TickTock 13:62e0f7f39ff5 100 unsigned char indexOffset = 1;
TickTock 13:62e0f7f39ff5 101 bool showCP = false;
TickTock 78:a383971fe02f 102 //bool pollCP = false;
TickTock 39:eef8beac7411 103 bool logCP = false; //Turbo3
TickTock 103:1389e9efe8c3 104 bool repeatPoll = true;
TickTock 34:4751a8259b18 105 bool headlights = false;
TickTock 34:4751a8259b18 106 bool tick = false;
garygid 69:6bfdfc002036 107 bool ZeroSecTick = false;
TickTock 35:5acbd8a64a89 108 float ledHi = 0.8; // Bright LED value (until config file read)
TickTock 35:5acbd8a64a89 109 float ledLo = 0.1; // Dim LED value (until config file read)
TickTock 35:5acbd8a64a89 110 unsigned short pollInt = 300; // polling interval=5 minutes (until config file read)
TickTock 35:5acbd8a64a89 111 bool accOn = false; // Accessories on
TickTock 49:a3d2c5bb3cfa 112 bool laccOn = false;
TickTock 35:5acbd8a64a89 113 float scale12V = 16.2; // R1:R2 ratio
TickTock 40:0e6e71a7323f 114 signed long mWs_x4 = 0;
TickTock 40:0e6e71a7323f 115 unsigned short numWsamples = 0;
TickTock 41:8d4609ea7259 116 unsigned short numSsamples = 0;
TickTock 35:5acbd8a64a89 117 float accV = 0;
TickTock 36:dbd39c315258 118 bool playbackEn = false;
TickTock 36:dbd39c315258 119 bool playbackOpen = false;
TickTock 49:a3d2c5bb3cfa 120 //float playbackInt = 0.05; //read messages every 50 ms
TickTock 78:a383971fe02f 121 float playbackInt = 0.005; //read messages every 5 ms
TickTock 36:dbd39c315258 122 bool step = false;
TickTock 37:fea2c1d52c5f 123 char header[5];
TickTock 36:dbd39c315258 124 char data[8];
TickTock 41:8d4609ea7259 125 signed long motorRPM;
garygid 65:821fc79cd7fe 126 unsigned char skin = ttSkin ;
TickTock 50:83d5864c64a0 127 unsigned char dtePeriod = 14; //ten minute averaging interval
TickTock 49:a3d2c5bb3cfa 128 float mph[39]={0};
TickTock 49:a3d2c5bb3cfa 129 float kW[39]={0};
TickTock 49:a3d2c5bb3cfa 130 float mpkWh[39]={0};
TickTock 49:a3d2c5bb3cfa 131 // Logarithmic division scale (roughly - snapped to common units of time)
TickTock 49:a3d2c5bb3cfa 132 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 133 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 134 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 135 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 136 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 49:a3d2c5bb3cfa 137 bool updateDTE = false;
TickTock 73:62ee8eae3a84 138 unsigned short pointerSep;
TickTock 78:a383971fe02f 139 unsigned char reqMsgCnt = 99;
TickTock 96:a6c6a6fd1d28 140 unsigned char battTemp_x4 = 0;
TickTock 102:fd19f777a0b4 141 unsigned long Ah_x10000 = 0;
TickTock 102:fd19f777a0b4 142 unsigned long SOC_x10000 = 0;
TickTock 102:fd19f777a0b4 143 unsigned short SOH_x100 = 0;
TickTock 102:fd19f777a0b4 144 signed short battTemp_x10 = 0;
leafman 98:9f8bab96edff 145 bool metric = false;
leafman 98:9f8bab96edff 146
TickTock 0:1596b8644523 147 int main() {
TickTock 4:8d7759f4fe7a 148 char sTemp[40];
TickTock 2:71b1999a8ea5 149 unsigned long secs;
TickTock 49:a3d2c5bb3cfa 150 unsigned char i,j,display=0,lwt=0;
TickTock 22:a43df3905863 151 point lastTouch;
TickTock 52:d5385fbf4ea1 152 float average;
TickTock 7:17bf9ceaf0aa 153
TickTock 3:3e879b043bc5 154 tt.set_orientation(1);
TickTock 4:8d7759f4fe7a 155 tt.background(Black);
TickTock 19:d576298c46f3 156 tt.set_display(2); // select both displays
TickTock 3:3e879b043bc5 157 tt.cls();
TickTock 1:9dcd70c32180 158 tt.claim(stdout); // send stdout to the TFT display
TickTock 12:8e42d7ba8468 159 touchpad.rise(&touch_ISR);
TickTock 4:8d7759f4fe7a 160 tt.wfi(); // enable interrupt on touch
TickTock 7:17bf9ceaf0aa 161 dled = 0.8; // turn on display LED 80%
TickTock 26:462ccb580472 162
TickTock 2:71b1999a8ea5 163 timer.start() ;
TickTock 2:71b1999a8ea5 164 RTC_Init(); // start the RTC Interrupts that sync the timer
TickTock 1:9dcd70c32180 165 struct tm t; // pointer to a static tm structure
TickTock 93:c2402e8cd0e2 166 NVIC_SetPriority(CAN_IRQn, 2); //set can priority just below RTC
TickTock 93:c2402e8cd0e2 167 NVIC_SetPriority(TIMER3_IRQn, 3); //set ticker priority just below can
TickTock 33:a277743ebdeb 168
TickTock 1:9dcd70c32180 169 seconds = time(NULL);
TickTock 1:9dcd70c32180 170 t = *localtime(&seconds) ;
TickTock 1:9dcd70c32180 171 // is it a date before 2012 ?
TickTock 26:462ccb580472 172 if ((t.tm_year + 1900) < 2012 ) {
TickTock 26:462ccb580472 173 // before 2013 so update year to make date entry easier
TickTock 26:462ccb580472 174 t.tm_year = 2013 - 1900;
TickTock 1:9dcd70c32180 175 // set the RTC
TickTock 1:9dcd70c32180 176 set_time(mktime(&t));
TickTock 1:9dcd70c32180 177 seconds = time(NULL);
TickTock 26:462ccb580472 178 }
TickTock 20:3bf176d14b14 179 t = *localtime(&seconds) ;
TickTock 20:3bf176d14b14 180 strftime(sTemp, 32, "%a %m/%d/%Y %X\n", &t);
TickTock 93:c2402e8cd0e2 181 printMsg(sTemp); // record RTC
garygid 54:6ce808d0995e 182
TickTock 62:ffd15edb5431 183 // revision
garygid 70:0700b769ac15 184 sprintf(sTemp,"CANary firmware rev%s\n", revStr); // gg - for Logging the revision
TickTock 93:c2402e8cd0e2 185 printMsg(sTemp); // revision
TickTock 15:a359fecf85ba 186
TickTock 26:462ccb580472 187 // Look for new binary on thumbdrive
TickTock 17:e32324a2678d 188 // Can't make this work right now since USB doesn't attach the right timestamp (so new binary isn't loaded)
TickTock 35:5acbd8a64a89 189 /*cfile = fopen("/usb/CANary.bin", "rb");
TickTock 50:83d5864c64a0 190 lastDMode[whichTouched]=99;//force refresh
TickTock 17:e32324a2678d 191 if (cfile!=NULL){ //found a new binary on the thumbdrive so copy it over
TickTock 17:e32324a2678d 192 sprintf(sTemp,"New binary found.\n");
TickTock 93:c2402e8cd0e2 193 printMsg(sTemp); // new binary
TickTock 97:a25940fd7b5b 194 lfile = fopen("/local/CANary.bin", "wb");
TickTock 97:a25940fd7b5b 195 if (lfile==NULL){ //failed to open destination
TickTock 17:e32324a2678d 196 sprintf(sTemp,"Unable to open destination file.\n");
TickTock 93:c2402e8cd0e2 197 printMsg(sTemp); // cannot open CANary.bin
TickTock 17:e32324a2678d 198 } else {
TickTock 18:999401f359a5 199 tt.set_display(2);
TickTock 18:999401f359a5 200 tt.foreground(White);
TickTock 18:999401f359a5 201 tt.background(Black);
TickTock 18:999401f359a5 202 tt.cls();
TickTock 18:999401f359a5 203 tt.locate(1,40);
TickTock 18:999401f359a5 204 printf("%s\n","Copying binary - Do no remove power.");
TickTock 18:999401f359a5 205 tt.locate(1,80);
TickTock 18:999401f359a5 206 printf("CANary will reset when complete.\n");
TickTock 18:999401f359a5 207 wait(1); //Wait 1 sec for display DMA to finish before writing file
TickTock 17:e32324a2678d 208 while ( int size = fread( writeBuffer, sizeof(char), maxBufLen*13, cfile )){
TickTock 97:a25940fd7b5b 209 fwrite( writeBuffer, sizeof(char), size, lfile );
TickTock 18:999401f359a5 210 led4=led3;
TickTock 18:999401f359a5 211 led3=led2;
TickTock 18:999401f359a5 212 led2=led1;
TickTock 18:999401f359a5 213 led1=!led4;
TickTock 17:e32324a2678d 214 }
TickTock 17:e32324a2678d 215 fclose(cfile);
TickTock 97:a25940fd7b5b 216 fclose(lfile);
TickTock 35:5acbd8a64a89 217 remove("/usb/CANary.bin"); // delete original
TickTock 17:e32324a2678d 218 mbed_reset(); //restart
TickTock 17:e32324a2678d 219 }
TickTock 18:999401f359a5 220 }*/
TickTock 17:e32324a2678d 221
TickTock 26:462ccb580472 222 secsNoMsg = 0;
TickTock 43:e7f6f80590e3 223
TickTock 49:a3d2c5bb3cfa 224 //read efficiency history data
TickTock 97:a25940fd7b5b 225 hfile = fopen("/local/ehist.cny", "r");
TickTock 97:a25940fd7b5b 226 if (hfile!=NULL){ // found a efficiency history file
TickTock 92:935adef49ea4 227 for(i=0;i<39;i++){
TickTock 97:a25940fd7b5b 228 if(!feof(hfile)){
TickTock 97:a25940fd7b5b 229 fscanf(hfile,"%f %f\r\n",&mph[i],&kW[i]);
TickTock 49:a3d2c5bb3cfa 230 mpkWh[i]=mph[i]/kW[i];
TickTock 49:a3d2c5bb3cfa 231 }
TickTock 49:a3d2c5bb3cfa 232 }
TickTock 97:a25940fd7b5b 233 fclose(hfile);
TickTock 49:a3d2c5bb3cfa 234 sprintf(sTemp,"History Loaded.\n");
TickTock 93:c2402e8cd0e2 235 printMsg(sTemp); // History loaded
TickTock 49:a3d2c5bb3cfa 236 } else { // create initial file
TickTock 49:a3d2c5bb3cfa 237 sprintf(sTemp,"History not found. Created.\n");
TickTock 93:c2402e8cd0e2 238 printMsg(sTemp); // history not found, created
TickTock 92:935adef49ea4 239 for(i=0;i<39;i++){
TickTock 49:a3d2c5bb3cfa 240 // Pre-load with 4 mpkWh @ 40 mph
TickTock 49:a3d2c5bb3cfa 241 mph[i]=40*timeConstant[i];
TickTock 49:a3d2c5bb3cfa 242 kW[i]=10*timeConstant[i];
TickTock 49:a3d2c5bb3cfa 243 mpkWh[i]=4;
TickTock 49:a3d2c5bb3cfa 244 }
TickTock 49:a3d2c5bb3cfa 245 }
TickTock 49:a3d2c5bb3cfa 246
TickTock 46:73e8716f976f 247 // Read config file
TickTock 46:73e8716f976f 248 readConfig();
TickTock 43:e7f6f80590e3 249
TickTock 77:7c136766466c 250 // Start monitors
TickTock 77:7c136766466c 251 can1.monitor(true); // set to snoop mode
TickTock 77:7c136766466c 252 can2.monitor(true); // set to snoop mode
TickTock 77:7c136766466c 253 can1.frequency(500000);
TickTock 77:7c136766466c 254 can2.frequency(500000);
TickTock 77:7c136766466c 255 can1SleepMode = 1; // Turn on Monitor_only Mode
TickTock 77:7c136766466c 256 can2SleepMode = 1; // Turn on Monitor_only Mode
TickTock 77:7c136766466c 257 can1.attach(&recieve1);
TickTock 77:7c136766466c 258 can2.attach(&recieve2);
TickTock 77:7c136766466c 259
TickTock 26:462ccb580472 260 touched=false;
TickTock 26:462ccb580472 261 secsNoTouch=2;
TickTock 2:71b1999a8ea5 262 while (true) {
TickTock 4:8d7759f4fe7a 263 if (!logOpen) { // Open new file if one is not already open
TickTock 7:17bf9ceaf0aa 264 if(logEn){ //logging enable
TickTock 7:17bf9ceaf0aa 265 seconds = time(NULL);
TickTock 7:17bf9ceaf0aa 266 t = *localtime(&seconds) ;
TickTock 35:5acbd8a64a89 267 strftime(fileName, 32, "/usb/%m%d%H%M.alc", &t); //mmddhhmm.alc
TickTock 16:2a6ca248e1cb 268 //sprintf(sTemp,"Using file %s\n",fileName);
TickTock 93:c2402e8cd0e2 269 //printMsg(sTemp); // using alc file ...
TickTock 97:a25940fd7b5b 270 lfile = fopen(fileName, "ab");
TickTock 94:c3a14b3975d6 271 lastDMode[0]=99;//force refresh
TickTock 94:c3a14b3975d6 272 lastDMode[1]=99;//force refresh
TickTock 97:a25940fd7b5b 273 if(lfile==NULL){
TickTock 7:17bf9ceaf0aa 274 sprintf(sTemp,"\nUnable to open %s\n\n\n\n",fileName);
TickTock 93:c2402e8cd0e2 275 printMsg(sTemp); // cannot open alc file
TickTock 7:17bf9ceaf0aa 276 logEn=false;
TickTock 26:462ccb580472 277 spkr.beep(1000,0.25);
TickTock 7:17bf9ceaf0aa 278 } else {
TickTock 7:17bf9ceaf0aa 279 logOpen = true;
TickTock 7:17bf9ceaf0aa 280 readPointer=writePointer;
TickTock 7:17bf9ceaf0aa 281 sprintf(sTemp,"Starting Can Log %s\n",fileName);
TickTock 93:c2402e8cd0e2 282 printMsg(sTemp); // starting alc log file
garygid 69:6bfdfc002036 283
garygid 69:6bfdfc002036 284 logTS(); // Date Time at start
TickTock 93:c2402e8cd0e2 285 logEvent("Starting"); // Log startup msg for testing
garygid 69:6bfdfc002036 286 sprintf(sTemp,"Cr%s",revStr);
TickTock 93:c2402e8cd0e2 287 logEvent(sTemp); // gg - log firmware version
garygid 69:6bfdfc002036 288
TickTock 26:462ccb580472 289 spkr.beep(2000,0.25);
TickTock 7:17bf9ceaf0aa 290 }
TickTock 7:17bf9ceaf0aa 291 }//logging enabled
TickTock 15:a359fecf85ba 292 } else { // if (logOpen)
TickTock 73:62ee8eae3a84 293 pointerSep=(writePointer+maxBufLen-readPointer)%maxBufLen;
TickTock 73:62ee8eae3a84 294 if (pointerSep>(maxBufLen/16)||canIdle||!logEn) {
TickTock 7:17bf9ceaf0aa 295 // Dump buffer if > 1/16 full or canbus has stopped
TickTock 97:a25940fd7b5b 296 if (lfile == NULL) {
TickTock 7:17bf9ceaf0aa 297 logOpen = false;
TickTock 37:fea2c1d52c5f 298 sprintf(sTemp,"Failed to append log file.\n");
TickTock 93:c2402e8cd0e2 299 printMsg(sTemp); // failed to append
TickTock 26:462ccb580472 300 spkr.beep(1000,0.25);
TickTock 7:17bf9ceaf0aa 301 logEn=false;
TickTock 7:17bf9ceaf0aa 302 } else {
TickTock 7:17bf9ceaf0aa 303 while (readPointer != writePointer) {
TickTock 92:935adef49ea4 304 for (j = 0; j<13; j++){
TickTock 97:a25940fd7b5b 305 fprintf(lfile,"%c",writeBuffer[readPointer][j]);
TickTock 4:8d7759f4fe7a 306 }
TickTock 86:d1c9e8ac1c4b 307 if(++readPointer >= maxBufLen){
TickTock 7:17bf9ceaf0aa 308 readPointer=0;
TickTock 86:d1c9e8ac1c4b 309 led4 = !led4;
TickTock 86:d1c9e8ac1c4b 310 }
TickTock 4:8d7759f4fe7a 311 }
TickTock 7:17bf9ceaf0aa 312 }
TickTock 30:e633a63eb257 313 } // if > 1/16 full, canbus has stopped, or logging stopped
TickTock 30:e633a63eb257 314 if (!logEn) {
TickTock 77:7c136766466c 315 sprintf(sTemp,"Stopping Can Log %s\n",fileName);
TickTock 93:c2402e8cd0e2 316 printMsg(sTemp); // stopping alc log file
TickTock 97:a25940fd7b5b 317 fclose(lfile);
TickTock 30:e633a63eb257 318 logOpen=false;
TickTock 77:7c136766466c 319 pointerSep=0;
TickTock 30:e633a63eb257 320 }
TickTock 4:8d7759f4fe7a 321 } // if logOpen
TickTock 36:dbd39c315258 322 if (canIdle&&userIdle&&!playbackEn) { // canbus idle --> sleep to save power
TickTock 95:248b3c25a7df 323 if (repeatPoll) { // stop autopolling if enabled
TickTock 95:248b3c25a7df 324 autoPoll.detach();
TickTock 95:248b3c25a7df 325 }
TickTock 26:462ccb580472 326 if (logOpen){
TickTock 97:a25940fd7b5b 327 fclose(lfile);
TickTock 7:17bf9ceaf0aa 328 } // if (logOpen)*/
TickTock 20:3bf176d14b14 329 seconds = time(NULL);
TickTock 20:3bf176d14b14 330 t = *localtime(&seconds) ;
TickTock 21:22bdce9efcb5 331 strftime(sTemp, 40, "Sleeping: %a %m/%d/%Y %X\n", &t);
TickTock 93:c2402e8cd0e2 332 printMsg(sTemp); // sleeping date time
TickTock 25:ddf0ec209f03 333 updateDisplay(0); //Added for turbo3 who has a display override and wants to see the sleep message before going to sleep
TickTock 25:ddf0ec209f03 334 updateDisplay(1);
TickTock 4:8d7759f4fe7a 335 //LPC_RTC->CIIR=0x00; // block RTC interrupts
TickTock 4:8d7759f4fe7a 336 led1=0;
TickTock 4:8d7759f4fe7a 337 led2=0;
TickTock 4:8d7759f4fe7a 338 led3=0;
TickTock 4:8d7759f4fe7a 339 led4=0;
TickTock 4:8d7759f4fe7a 340 dled=0; // turn off display
TickTock 4:8d7759f4fe7a 341 secs = time(NULL); // seconds past 12:00:00 AM 1 Jan 1900
TickTock 22:a43df3905863 342 while (secsNoMsg>canTimeout && !touched) {
TickTock 4:8d7759f4fe7a 343 //DeepPowerDown();
TickTock 12:8e42d7ba8468 344 tt.wfi(); //enable touch interrupt
TickTock 21:22bdce9efcb5 345 //__wfi(); // freeze CPU and wait for interrupt (from canbus or touch)
TickTock 21:22bdce9efcb5 346 Sleep();
TickTock 4:8d7759f4fe7a 347 }
TickTock 97:a25940fd7b5b 348 lastDMode[0]=99;
TickTock 97:a25940fd7b5b 349 lastDMode[1]=99;
TickTock 43:e7f6f80590e3 350 secsNoTouch=2;
TickTock 4:8d7759f4fe7a 351 canIdle=secsNoMsg>canTimeout;
TickTock 7:17bf9ceaf0aa 352 dled=0.8; // turn on display LED
TickTock 20:3bf176d14b14 353 seconds = time(NULL);
TickTock 20:3bf176d14b14 354 t = *localtime(&seconds) ;
TickTock 21:22bdce9efcb5 355 strftime(sTemp, 40, "Waking: %a %m/%d/%Y %X\n", &t);
TickTock 93:c2402e8cd0e2 356 printMsg(sTemp); // wakeup date time
TickTock 4:8d7759f4fe7a 357 if (time(NULL)>(secs+1800)) {
TickTock 4:8d7759f4fe7a 358 logOpen = false; // Start new file if asleep for more than 30 minutes
TickTock 4:8d7759f4fe7a 359 if (secsNoTouch>100) secsNoTouch = 100; // also mostly reset user Idle counter
TickTock 43:e7f6f80590e3 360 } else if (logOpen){ // insert timestamp on each wake if logging enabled (disabled for now)
TickTock 97:a25940fd7b5b 361 lfile = fopen(fileName, "ab");
TickTock 93:c2402e8cd0e2 362 logEvent("WakingUp"); // gg - use messeges
garygid 69:6bfdfc002036 363 logTS(); // Date-Time at wakeup
TickTock 4:8d7759f4fe7a 364 }
TickTock 95:248b3c25a7df 365 if (repeatPoll) { // re-enable autopolling if enabled
TickTock 95:248b3c25a7df 366 autoPoll.attach(&autoPollISR,pollInt);
TickTock 95:248b3c25a7df 367 }
TickTock 4:8d7759f4fe7a 368 } // if idle
TickTock 4:8d7759f4fe7a 369
TickTock 15:a359fecf85ba 370 if(touched){ // call touchscreen procedure if touch interrupt detected
TickTock 7:17bf9ceaf0aa 371 lastTouch = tt.get_touch();
TickTock 7:17bf9ceaf0aa 372 lastTouch = tt.to_pixel(lastTouch); // convert to pixel pos
TickTock 40:0e6e71a7323f 373 if((lastTouch.x!=639)&&(lastTouch.x!=319)&&(lastTouch.y!=239)){ // filter phantom touches
TickTock 43:e7f6f80590e3 374 if (userIdle) {
TickTock 43:e7f6f80590e3 375 secsNoTouch=2; // Ignore first touch if user idle
TickTock 43:e7f6f80590e3 376 userIdle=false;
TickTock 40:0e6e71a7323f 377 } else {
TickTock 43:e7f6f80590e3 378 secsNoTouch=0;
TickTock 40:0e6e71a7323f 379 }
TickTock 43:e7f6f80590e3 380 if (lastTouch.x>320){
TickTock 43:e7f6f80590e3 381 whichTouched=1;
TickTock 43:e7f6f80590e3 382 } else {
TickTock 43:e7f6f80590e3 383 whichTouched=0;
TickTock 43:e7f6f80590e3 384 }
TickTock 43:e7f6f80590e3 385 if (whichTouched!=lwt){
TickTock 43:e7f6f80590e3 386 lastDMode[lwt]=99; // Repaint lastTouched
TickTock 43:e7f6f80590e3 387 lwt=whichTouched;
TickTock 43:e7f6f80590e3 388 }
TickTock 43:e7f6f80590e3 389 sMode = 1;
TickTock 22:a43df3905863 390 }
TickTock 22:a43df3905863 391 //sprintf(sTemp,"%d,%d ",lastTouch.x,lastTouch.y);
TickTock 93:c2402e8cd0e2 392 //printMsg(sTemp); // touch x,y - for debug
TickTock 12:8e42d7ba8468 393 touched = false; // clear interrupt flag
TickTock 7:17bf9ceaf0aa 394 }
garygid 54:6ce808d0995e 395 //---------------
garygid 54:6ce808d0995e 396 // gg - 4x4 touch
TickTock 62:ffd15edb5431 397 //unsigned char tScrn = 0 ; // screen 0
garygid 54:6ce808d0995e 398 unsigned char tCol ;
garygid 54:6ce808d0995e 399 unsigned char tRow ;
garygid 54:6ce808d0995e 400
TickTock 4:8d7759f4fe7a 401 if (!userIdle) {
TickTock 4:8d7759f4fe7a 402 if (secsNoTouch<2) {// Recently touched
TickTock 4:8d7759f4fe7a 403 secsNoTouch +=2; // increment to prevent double touch
TickTock 43:e7f6f80590e3 404 sMode = 1;
TickTock 22:a43df3905863 405 //sprintf(sTemp,"button %d %d,%d %d\n",i,buttonX(lastTouch.x,3),buttonY(lastTouch.y,3),lastTouch.x);
TickTock 93:c2402e8cd0e2 406 //printMsg(sTemp); // button parms - for debug
TickTock 23:cd03f9c3395e 407 switch (sMode) {
TickTock 23:cd03f9c3395e 408 case 0: // no select
TickTock 23:cd03f9c3395e 409 break;
TickTock 63:aa3bf6a33635 410 case 1: // select screen
garygid 54:6ce808d0995e 411 //--------------
garygid 54:6ce808d0995e 412 // gg - 4x4 touch
garygid 54:6ce808d0995e 413 tCol = buttonX(lastTouch.x,4) ;
TickTock 62:ffd15edb5431 414 if( tCol >= 4 ){ tCol -= 4; } // touch is on screen 1
garygid 54:6ce808d0995e 415
garygid 54:6ce808d0995e 416 tRow = buttonY(lastTouch.y,4) ;
garygid 54:6ce808d0995e 417
TickTock 63:aa3bf6a33635 418 highlightButton( tCol,tRow, whichTouched, 4,4) ; // gg - highlight
garygid 58:4d06288d75a2 419
TickTock 63:aa3bf6a33635 420 if( tRow == tNavRow ) tRow = 7 ; // gg
garygid 54:6ce808d0995e 421 switch ( (tCol*10) + tRow ) {
garygid 54:6ce808d0995e 422 //---------------------------------
garygid 67:2022fce701d0 423 case 00: // top row, left button on screen 0 or 1
TickTock 42:4533b13b297d 424 if (dMode[whichTouched]==monitorScreen||dMode[whichTouched]==changedScreen) {
garygid 67:2022fce701d0 425 indexOffset=indexOffset>4?indexOffset-4:1;
garygid 67:2022fce701d0 426 } else if (dMode[whichTouched] == indexScreen) { // gg - index
garygid 67:2022fce701d0 427 dMode[whichTouched] = mainScreen ; // GoTo Main Screen
TickTock 73:62ee8eae3a84 428 sMode=0;
leafman 98:9f8bab96edff 429 } else if (dMode[whichTouched]==configScreen) {
TickTock 23:cd03f9c3395e 430 wait_ms(500);
TickTock 37:fea2c1d52c5f 431 tt.background(Black);
TickTock 23:cd03f9c3395e 432 tt.calibrate();
TickTock 42:4533b13b297d 433 } else if (dMode[whichTouched]==playbackScreen) { // slower
TickTock 36:dbd39c315258 434 playbackInt *=2;
TickTock 36:dbd39c315258 435 if(playbackEn){
TickTock 36:dbd39c315258 436 playback.detach();
TickTock 36:dbd39c315258 437 playback.attach(&playbackISR,playbackInt);
TickTock 36:dbd39c315258 438 }
TickTock 62:ffd15edb5431 439 } else {
TickTock 62:ffd15edb5431 440 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 23:cd03f9c3395e 441 }
TickTock 23:cd03f9c3395e 442 break;
garygid 54:6ce808d0995e 443 //-----------------------------------------------
garygid 67:2022fce701d0 444 case 10: // 1,0 (col left of center,top row) on screen 0 or 1
TickTock 42:4533b13b297d 445 if (dMode[whichTouched]==changedScreen) {
TickTock 92:935adef49ea4 446 for(j=0;j<100;j++) msgChanged[j]=0; // clear changed data
TickTock 42:4533b13b297d 447 lastDMode[whichTouched]=99;//force refresh
garygid 67:2022fce701d0 448 } else if (dMode[whichTouched] == indexScreen) { // gg - index
TickTock 73:62ee8eae3a84 449 sMode=0;
garygid 67:2022fce701d0 450 dMode[whichTouched] = brakeScreen ; // GoTo Brake Screen
TickTock 42:4533b13b297d 451 } else if (dMode[whichTouched]==cpScreen) {
TickTock 78:a383971fe02f 452 reqMsgCnt=0;
TickTock 94:c3a14b3975d6 453 msgReq.attach(&sendReq,0.015);
TickTock 48:d1ce92104a1f 454 } else if (dMode[whichTouched]==cpHistScreen) { // gg - hist
TickTock 78:a383971fe02f 455 reqMsgCnt=0;
TickTock 94:c3a14b3975d6 456 msgReq.attach(&sendReq,0.015);
TickTock 48:d1ce92104a1f 457 } else if (dMode[whichTouched]==cpBarScreen) { // gg - cpbars
TickTock 78:a383971fe02f 458 reqMsgCnt=0;
TickTock 94:c3a14b3975d6 459 msgReq.attach(&sendReq,0.015);
leafman 98:9f8bab96edff 460 } else if (dMode[whichTouched]==configScreen) {
TickTock 23:cd03f9c3395e 461 mbed_reset();
TickTock 42:4533b13b297d 462 } else if (dMode[whichTouched]==playbackScreen) { // pause/unpause
TickTock 36:dbd39c315258 463 playbackEn=!playbackEn;
TickTock 36:dbd39c315258 464 if(playbackEn){
TickTock 36:dbd39c315258 465 playback.attach(&playbackISR,playbackInt);
TickTock 62:ffd15edb5431 466 } else {
TickTock 36:dbd39c315258 467 playback.detach();
TickTock 36:dbd39c315258 468 }
TickTock 62:ffd15edb5431 469 } else {
TickTock 62:ffd15edb5431 470 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 23:cd03f9c3395e 471 }
TickTock 62:ffd15edb5431 472
TickTock 23:cd03f9c3395e 473 break;
garygid 54:6ce808d0995e 474 //--------------------------------------
garygid 54:6ce808d0995e 475 case 20: // col 2 and row 0 on either screen 0 or 1
TickTock 42:4533b13b297d 476 if (dMode[whichTouched]==monitorScreen||dMode[whichTouched]==changedScreen) {
TickTock 23:cd03f9c3395e 477 indexOffset=indexOffset<77?indexOffset+4:80;
garygid 67:2022fce701d0 478 } else if (dMode[whichTouched] == indexScreen) { // gg - index
garygid 67:2022fce701d0 479 dMode[whichTouched] = effScreen ; // GoTo EFF Screen
TickTock 73:62ee8eae3a84 480 sMode=0;
leafman 98:9f8bab96edff 481 } else if (dMode[whichTouched]==configScreen) {
TickTock 23:cd03f9c3395e 482 sprintf(sTemp,"Saving config file.\n");
TickTock 93:c2402e8cd0e2 483 printMsg(sTemp); // saving config
TickTock 25:ddf0ec209f03 484 saveConfig();
TickTock 26:462ccb580472 485 spkr.beep(2000,0.25);
TickTock 42:4533b13b297d 486 } else if (dMode[whichTouched]==playbackScreen) { // faster
TickTock 36:dbd39c315258 487 if(playbackInt>.002){
TickTock 36:dbd39c315258 488 playbackInt/=2;
TickTock 36:dbd39c315258 489 if(playbackEn){
TickTock 36:dbd39c315258 490 playback.detach();
TickTock 36:dbd39c315258 491 playback.attach(&playbackISR,playbackInt);
TickTock 36:dbd39c315258 492 }
TickTock 36:dbd39c315258 493 }
TickTock 86:d1c9e8ac1c4b 494 } else {
TickTock 62:ffd15edb5431 495 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 23:cd03f9c3395e 496 }
TickTock 62:ffd15edb5431 497
TickTock 23:cd03f9c3395e 498 break;
garygid 65:821fc79cd7fe 499
garygid 67:2022fce701d0 500 case 30: // right-most on top row
garygid 65:821fc79cd7fe 501
leafman 98:9f8bab96edff 502 if (dMode[whichTouched]==configScreen) {
garygid 65:821fc79cd7fe 503 // step through skins
garygid 65:821fc79cd7fe 504 if( skin < maxSkin ) skin += 1 ;
garygid 65:821fc79cd7fe 505 else skin = 0 ;
garygid 65:821fc79cd7fe 506
garygid 65:821fc79cd7fe 507 // repaint both screens, I think
garygid 65:821fc79cd7fe 508 lastDMode[whichTouched]=99;//repaint to clear highlight
garygid 65:821fc79cd7fe 509 // and re-paint the other screen too, to see new skin there
garygid 65:821fc79cd7fe 510 lastDMode[whichTouched ^ 1]=99; // repaint other screen (^ = XOR)
garygid 65:821fc79cd7fe 511
garygid 65:821fc79cd7fe 512 //sprintf(sTemp,"Changed Skin to %d.\n");
TickTock 93:c2402e8cd0e2 513 //printMsg(sTemp); /// changed skin - for debug
garygid 65:821fc79cd7fe 514 //saveConfig();
garygid 65:821fc79cd7fe 515 //spkr.beep(2000,0.25);
garygid 69:6bfdfc002036 516
garygid 67:2022fce701d0 517 } else if (dMode[whichTouched] == indexScreen) { // gg - index
garygid 67:2022fce701d0 518 dMode[whichTouched] = dteScreen ; // GoTo DTE Screen
TickTock 73:62ee8eae3a84 519 sMode=0;
TickTock 86:d1c9e8ac1c4b 520 } else {
garygid 65:821fc79cd7fe 521 lastDMode[whichTouched]=99;//repaint to clear highlight
garygid 65:821fc79cd7fe 522 }
garygid 65:821fc79cd7fe 523
garygid 65:821fc79cd7fe 524 break;
garygid 54:6ce808d0995e 525 //----------------------------------
garygid 54:6ce808d0995e 526 //----------------------------------
garygid 67:2022fce701d0 527 case 01: // left col middle row
leafman 98:9f8bab96edff 528 if (dMode[whichTouched]==configScreen) {
TickTock 23:cd03f9c3395e 529 logEn = !logEn;
TickTock 103:1389e9efe8c3 530 //if (!logEn) {
TickTock 103:1389e9efe8c3 531 // repeatPoll=false; // disable auto polling, too
TickTock 103:1389e9efe8c3 532 // autoPoll.detach();
TickTock 103:1389e9efe8c3 533 //}
garygid 67:2022fce701d0 534 } else if (dMode[whichTouched] == indexScreen) { // gg - index
TickTock 73:62ee8eae3a84 535 dMode[whichTouched] = cpScreen ; // GoTo CP Data Screen
TickTock 73:62ee8eae3a84 536 sMode=0;
TickTock 42:4533b13b297d 537 } else if (dMode[whichTouched]==dateScreen){
TickTock 25:ddf0ec209f03 538 dtMode=(dtMode<6)?dtMode+1:0;
TickTock 42:4533b13b297d 539 lastDMode[whichTouched]=99;
TickTock 62:ffd15edb5431 540 } else {
TickTock 62:ffd15edb5431 541 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 23:cd03f9c3395e 542 }
TickTock 62:ffd15edb5431 543
TickTock 23:cd03f9c3395e 544 break;
garygid 54:6ce808d0995e 545 //------------------------------
TickTock 23:cd03f9c3395e 546 case 11:
leafman 98:9f8bab96edff 547 if (dMode[whichTouched]==configScreen){
TickTock 77:7c136766466c 548 repeatPoll = !repeatPoll;
TickTock 33:a277743ebdeb 549 if (repeatPoll) {
TickTock 36:dbd39c315258 550 autoPoll.attach(&autoPollISR,pollInt);
TickTock 33:a277743ebdeb 551 } else {
TickTock 36:dbd39c315258 552 autoPoll.detach();
TickTock 33:a277743ebdeb 553 }
garygid 67:2022fce701d0 554 } else if (dMode[whichTouched] == indexScreen) { // gg - index
garygid 67:2022fce701d0 555 dMode[whichTouched] = cpHistScreen ; // GoTo CP Hist Screen
TickTock 73:62ee8eae3a84 556 sMode=0;
TickTock 42:4533b13b297d 557 } else if (dMode[whichTouched]==playbackScreen) {
TickTock 36:dbd39c315258 558 // Start/stop playback
TickTock 36:dbd39c315258 559 if(!playbackOpen){
TickTock 36:dbd39c315258 560 if(!logOpen){
TickTock 97:a25940fd7b5b 561 lfile = fopen("/usb/playback.alc", "rb");
TickTock 50:83d5864c64a0 562 lastDMode[whichTouched]=99;//force refresh
TickTock 97:a25940fd7b5b 563 if(lfile==NULL){
TickTock 36:dbd39c315258 564 sprintf(sTemp,"Unable to open /usb/playback.alc\n");
TickTock 93:c2402e8cd0e2 565 printMsg(sTemp); // no playback.alc
TickTock 36:dbd39c315258 566 spkr.beep(1000,0.25);
TickTock 36:dbd39c315258 567 } else {
TickTock 36:dbd39c315258 568 playbackOpen = true;
TickTock 50:83d5864c64a0 569 playbackEn=true;
TickTock 50:83d5864c64a0 570 playback.attach(&playbackISR,playbackInt);
TickTock 36:dbd39c315258 571 sprintf(sTemp,"Starting playback\n");
TickTock 93:c2402e8cd0e2 572 printMsg(sTemp); // start playback
TickTock 36:dbd39c315258 573 spkr.beep(2000,0.25);
TickTock 36:dbd39c315258 574 can1.attach(&doNothing);// Stop recieving CAN data
TickTock 36:dbd39c315258 575 can2.attach(&doNothing);
TickTock 36:dbd39c315258 576 }
TickTock 36:dbd39c315258 577 } else {
TickTock 36:dbd39c315258 578 sprintf(sTemp,"Must stop logging first\n");
TickTock 93:c2402e8cd0e2 579 printMsg(sTemp); // Must stop logging first
TickTock 36:dbd39c315258 580 }
TickTock 36:dbd39c315258 581 } else {
TickTock 36:dbd39c315258 582 playback.detach();
TickTock 97:a25940fd7b5b 583 fclose(lfile);
TickTock 36:dbd39c315258 584 playbackOpen=false;
TickTock 50:83d5864c64a0 585 playbackEn=false;
TickTock 36:dbd39c315258 586 can1.attach(&recieve1);// Restore CAN data recieve
TickTock 36:dbd39c315258 587 can2.attach(&recieve2);
TickTock 42:4533b13b297d 588 lastDMode[whichTouched]=99;
TickTock 36:dbd39c315258 589 }
TickTock 42:4533b13b297d 590 } else if (dMode[whichTouched]==dateScreen){
TickTock 25:ddf0ec209f03 591 upDate(dtMode,true);
TickTock 42:4533b13b297d 592 lastDMode[whichTouched]=99;
TickTock 62:ffd15edb5431 593 } else {
TickTock 62:ffd15edb5431 594 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 25:ddf0ec209f03 595 }
TickTock 62:ffd15edb5431 596
TickTock 23:cd03f9c3395e 597 break;
garygid 54:6ce808d0995e 598 //---------------------------------
garygid 54:6ce808d0995e 599 case 21: // col 2 row 1
leafman 98:9f8bab96edff 600 if (dMode[whichTouched]==configScreen) { // gg - Batt Log Enable Button
TickTock 48:d1ce92104a1f 601 yesBattLog = !yesBattLog;
garygid 67:2022fce701d0 602 } else if (dMode[whichTouched] == indexScreen) { // gg - index
garygid 67:2022fce701d0 603 dMode[whichTouched] = cpBarScreen ; // GoTo CP Bars Screen
TickTock 73:62ee8eae3a84 604 sMode=0;
TickTock 48:d1ce92104a1f 605 } else if (dMode[whichTouched]==dateScreen){
TickTock 25:ddf0ec209f03 606 upDate(dtMode,false);
TickTock 42:4533b13b297d 607 lastDMode[whichTouched]=99;
TickTock 62:ffd15edb5431 608 } else {
TickTock 62:ffd15edb5431 609 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 25:ddf0ec209f03 610 }
TickTock 62:ffd15edb5431 611
TickTock 23:cd03f9c3395e 612 break;
garygid 54:6ce808d0995e 613
garygid 87:46ac3f2519d6 614 case 31: // col 3 row 1
leafman 98:9f8bab96edff 615 if (dMode[whichTouched]==configScreen) { // gg - Batt Log Enable Button
garygid 87:46ac3f2519d6 616 debugMode = !debugMode;
leafman 98:9f8bab96edff 617 } else if (dMode[whichTouched] == indexScreen) { // gg - index
leafman 98:9f8bab96edff 618 dMode[whichTouched] = configScreen ; // GoTo Config Screen
garygid 87:46ac3f2519d6 619 } else {
garygid 87:46ac3f2519d6 620 lastDMode[whichTouched]=99;//repaint to clear highlight
garygid 87:46ac3f2519d6 621 }
garygid 87:46ac3f2519d6 622 break;
garygid 87:46ac3f2519d6 623
garygid 54:6ce808d0995e 624 //-----------------------------------
garygid 67:2022fce701d0 625 case 02: // left col, bottom row (not nav)
garygid 67:2022fce701d0 626 if (dMode[whichTouched] == indexScreen) { // gg - index
leafman 98:9f8bab96edff 627 dMode[whichTouched] = playbackScreen ; // GoTo Playback Screen
leafman 98:9f8bab96edff 628 } else if (dMode[whichTouched]==configScreen) {
leafman 98:9f8bab96edff 629 metric = !metric; // toggle metric/imperial display
garygid 87:46ac3f2519d6 630 } else {
garygid 87:46ac3f2519d6 631 lastDMode[whichTouched]=99;//repaint to clear highlight
garygid 87:46ac3f2519d6 632 }
garygid 67:2022fce701d0 633 break;
garygid 67:2022fce701d0 634
garygid 67:2022fce701d0 635 case 12: // left-middle col, bottom row (not nav)
garygid 67:2022fce701d0 636 if (dMode[whichTouched] == indexScreen) { // gg - index
leafman 98:9f8bab96edff 637 dMode[whichTouched] = dateScreen ; // GoTo Set Date/Time Screen
garygid 87:46ac3f2519d6 638 } else {
garygid 87:46ac3f2519d6 639 lastDMode[whichTouched]=99;//repaint to clear highlight
garygid 87:46ac3f2519d6 640 }
garygid 67:2022fce701d0 641 break;
garygid 67:2022fce701d0 642
garygid 67:2022fce701d0 643 case 22: // right-middle col, bottom row (not nav)
garygid 67:2022fce701d0 644 if (dMode[whichTouched] == indexScreen) { // gg - index
leafman 98:9f8bab96edff 645 dMode[whichTouched] = logScreen ;
garygid 87:46ac3f2519d6 646 } else {
garygid 87:46ac3f2519d6 647 lastDMode[whichTouched]=99;//repaint to clear highlight
garygid 87:46ac3f2519d6 648 }
garygid 67:2022fce701d0 649 break;
TickTock 72:f9a6faa28873 650
leafman 98:9f8bab96edff 651 case 32: // right col, bottom row (not nav)
leafman 98:9f8bab96edff 652 if (dMode[whichTouched] == configScreen) {
leafman 98:9f8bab96edff 653 updateFirmware();
leafman 98:9f8bab96edff 654 } else {
garygid 87:46ac3f2519d6 655 lastDMode[whichTouched]=99;//repaint to clear highlight
leafman 98:9f8bab96edff 656 }
TickTock 72:f9a6faa28873 657 break;
TickTock 72:f9a6faa28873 658
garygid 67:2022fce701d0 659 //-----------------------------------
garygid 54:6ce808d0995e 660 //-----------------------------------
garygid 54:6ce808d0995e 661 // Prev Navigation
garygid 54:6ce808d0995e 662 case 07: // col 0 row tNavRow
TickTock 42:4533b13b297d 663 dMode[whichTouched]=dMode[whichTouched]>0?dMode[whichTouched]-1:maxScreens;
TickTock 22:a43df3905863 664 break;
garygid 54:6ce808d0995e 665 //-----------------------------------
garygid 54:6ce808d0995e 666 // Select Screen Navigation
garygid 54:6ce808d0995e 667 case 17:
TickTock 43:e7f6f80590e3 668 //secsNoTouch = userTimeout; // immediately exit config mode
TickTock 43:e7f6f80590e3 669 sMode=0;
TickTock 43:e7f6f80590e3 670 lastDMode[whichTouched]=99; // Repaint
TickTock 22:a43df3905863 671 break;
garygid 54:6ce808d0995e 672 //-----------------------------------
garygid 54:6ce808d0995e 673 // Index Navigation
garygid 54:6ce808d0995e 674 case 27: // col 2 row tNavRow
garygid 67:2022fce701d0 675 dMode[whichTouched]= indexScreen ; // gg - index
garygid 54:6ce808d0995e 676 break;
garygid 54:6ce808d0995e 677 //------------------------------------
garygid 54:6ce808d0995e 678 // Next Navigation
garygid 54:6ce808d0995e 679 case 37: // lower right on Nav Line gg - move next
TickTock 42:4533b13b297d 680 dMode[whichTouched]=dMode[whichTouched]<maxScreens?dMode[whichTouched]+1:0;
TickTock 22:a43df3905863 681 break;
garygid 54:6ce808d0995e 682 //------------------------------------
garygid 54:6ce808d0995e 683 //------------------------------------
TickTock 22:a43df3905863 684 default:
TickTock 62:ffd15edb5431 685 lastDMode[whichTouched]=99;//repaint to clear highlight
TickTock 25:ddf0ec209f03 686 break;
TickTock 25:ddf0ec209f03 687 }
TickTock 23:cd03f9c3395e 688 break;
TickTock 23:cd03f9c3395e 689 case 2: // numpad
TickTock 23:cd03f9c3395e 690 break;
TickTock 23:cd03f9c3395e 691 case 3:
TickTock 23:cd03f9c3395e 692 break;
TickTock 23:cd03f9c3395e 693 default:
TickTock 23:cd03f9c3395e 694 break;
TickTock 23:cd03f9c3395e 695 } // case sMode
TickTock 22:a43df3905863 696 } //recently touched
TickTock 4:8d7759f4fe7a 697 } else { // userIdle
TickTock 8:67eed72f3e10 698 if(sMode==1){
TickTock 8:67eed72f3e10 699 sMode=0;
TickTock 43:e7f6f80590e3 700 lastDMode[whichTouched]=99;
TickTock 8:67eed72f3e10 701 }
TickTock 4:8d7759f4fe7a 702 }
TickTock 34:4751a8259b18 703
TickTock 34:4751a8259b18 704 if(tick){ // Executes once a second
TickTock 93:c2402e8cd0e2 705 headlights = (lastMsg[indexLastMsg[0x358]].data[1]&0x80)?true:false; // headlight/turn signal indicator
TickTock 41:8d4609ea7259 706 accV=floor(mon12V*scale12V*10+0.5)/10; //Round to nearest 10th
TickTock 35:5acbd8a64a89 707 accOn=(accV>5)?true:false;
TickTock 49:a3d2c5bb3cfa 708 if(laccOn&&!accOn){ // Car turned off
TickTock 49:a3d2c5bb3cfa 709 //write efficiency history data
TickTock 97:a25940fd7b5b 710 hfile = fopen("/local/ehist.cny", "w");
TickTock 97:a25940fd7b5b 711 if (hfile!=NULL){ // found a efficiency history file
TickTock 92:935adef49ea4 712 for(i=0;i<39;i++){
TickTock 97:a25940fd7b5b 713 fprintf(hfile,"%f %f\r\n",mph[i],kW[i]);
TickTock 49:a3d2c5bb3cfa 714 }
TickTock 97:a25940fd7b5b 715 fclose(hfile);
TickTock 49:a3d2c5bb3cfa 716 }
TickTock 49:a3d2c5bb3cfa 717 }
TickTock 49:a3d2c5bb3cfa 718 laccOn=accOn;
TickTock 97:a25940fd7b5b 719 if(!accOn&&!logEn&&userIdle&&!playbackEn){
TickTock 35:5acbd8a64a89 720 dled = 0; // turn off display if car off and logging disabled and no user activity
TickTock 35:5acbd8a64a89 721 }else if(!headlights){
TickTock 35:5acbd8a64a89 722 dled = ledHi;
TickTock 86:d1c9e8ac1c4b 723 } else {
TickTock 35:5acbd8a64a89 724 dled = ledLo;
TickTock 34:4751a8259b18 725 }
TickTock 49:a3d2c5bb3cfa 726
TickTock 49:a3d2c5bb3cfa 727 //compute historic efficiency
TickTock 41:8d4609ea7259 728 if(numSsamples>0){ // Avoid div0
TickTock 49:a3d2c5bb3cfa 729 mph[0]=((float) motorRPM)/numSsamples/215; // Empirically derived - may change car to car
TickTock 86:d1c9e8ac1c4b 730 } else {
TickTock 49:a3d2c5bb3cfa 731 mph[0]=0;
TickTock 36:dbd39c315258 732 }
TickTock 49:a3d2c5bb3cfa 733 if(mph[0]>99){
TickTock 49:a3d2c5bb3cfa 734 mph[0]=0;
TickTock 49:a3d2c5bb3cfa 735 }
TickTock 49:a3d2c5bb3cfa 736 mpkWh[0]=mph[0];
TickTock 41:8d4609ea7259 737 if(numWsamples>0){ // Avoid div0
TickTock 49:a3d2c5bb3cfa 738 kW[0]=((float) mWs_x4)/numWsamples/4e3;
TickTock 49:a3d2c5bb3cfa 739 mpkWh[0]/=kW[0];
TickTock 49:a3d2c5bb3cfa 740 if (mpkWh[0]<0) {
TickTock 49:a3d2c5bb3cfa 741 mpkWh[0]=99;// negative means inf.
TickTock 49:a3d2c5bb3cfa 742 }
TickTock 86:d1c9e8ac1c4b 743 } else {
TickTock 49:a3d2c5bb3cfa 744 kW[0]=0;
TickTock 49:a3d2c5bb3cfa 745 mpkWh[0]=0;
TickTock 49:a3d2c5bb3cfa 746 }
TickTock 49:a3d2c5bb3cfa 747 //mpkWh[0]=floor(mpkWh[0]*10+0.5)/10; // Round to nearest 10th
TickTock 49:a3d2c5bb3cfa 748 motorRPM=0;
TickTock 41:8d4609ea7259 749 numSsamples=0;
TickTock 40:0e6e71a7323f 750 mWs_x4=0;
TickTock 40:0e6e71a7323f 751 numWsamples=0;
TickTock 53:8a51361434ae 752 if(accOn||playbackEn){
TickTock 92:935adef49ea4 753 for(i=1;i<39;i++){
TickTock 49:a3d2c5bb3cfa 754 average=mph[i]/timeConstant[i];
TickTock 49:a3d2c5bb3cfa 755 mph[i]-=average;
TickTock 52:d5385fbf4ea1 756 mph[i]+=mph[0];
TickTock 52:d5385fbf4ea1 757 mpkWh[i]=average;
TickTock 49:a3d2c5bb3cfa 758 average=kW[i]/timeConstant[i];
TickTock 97:a25940fd7b5b 759 if((mph[0]>0)||(kW[0]>0)){ //Not charging - so include in efficiency data
TickTock 97:a25940fd7b5b 760 kW[i]-=average;
TickTock 97:a25940fd7b5b 761 kW[i]+=kW[0];
TickTock 97:a25940fd7b5b 762 }
TickTock 52:d5385fbf4ea1 763 mpkWh[i]/=average;
TickTock 49:a3d2c5bb3cfa 764 if (mpkWh[i]<0) {
TickTock 49:a3d2c5bb3cfa 765 mpkWh[i]=99;// negative means inf.
TickTock 49:a3d2c5bb3cfa 766 }
TickTock 49:a3d2c5bb3cfa 767 //mpkWh[i]=floor(mpkWh[i]*10+0.5)/10; // Round to nearest 10th
TickTock 52:d5385fbf4ea1 768 }
TickTock 49:a3d2c5bb3cfa 769 }
TickTock 49:a3d2c5bb3cfa 770 updateDTE=true;
TickTock 40:0e6e71a7323f 771 if(logCP)
garygid 69:6bfdfc002036 772 logPackVoltages(); // Turbo3, only call
TickTock 34:4751a8259b18 773 tick=false;
TickTock 92:935adef49ea4 774 }
TickTock 36:dbd39c315258 775
TickTock 39:eef8beac7411 776 display=display<1?display+1:0; // toggle display
TickTock 39:eef8beac7411 777 updateDisplay(display);
TickTock 39:eef8beac7411 778
TickTock 36:dbd39c315258 779 if(step){ // playback
TickTock 36:dbd39c315258 780 if(playbackOpen&&playbackEn){
TickTock 92:935adef49ea4 781 for(i=0;i<120;i++){
TickTock 97:a25940fd7b5b 782 if(!feof(lfile)){
TickTock 97:a25940fd7b5b 783 fscanf(lfile,"%5c%8c",&header,&data);
garygid 69:6bfdfc002036 784 logCan(header[0],CANMessage(0x7ff&((header[4]<<8)+header[3]), data, 8)); // Playback
TickTock 86:d1c9e8ac1c4b 785 } else {
TickTock 97:a25940fd7b5b 786 fclose(lfile); // restart
TickTock 97:a25940fd7b5b 787 lfile = fopen("/usb/playback.alc", "rb");
TickTock 50:83d5864c64a0 788 lastDMode[whichTouched]=99;//force refresh
TickTock 36:dbd39c315258 789 spkr.beep(2000,0.25);
TickTock 36:dbd39c315258 790 }
TickTock 36:dbd39c315258 791 }
TickTock 36:dbd39c315258 792 }
TickTock 36:dbd39c315258 793 step=false;
TickTock 36:dbd39c315258 794 }
TickTock 37:fea2c1d52c5f 795
TickTock 2:71b1999a8ea5 796 } //while (true)
TickTock 0:1596b8644523 797 }