Sunday, March 12. 2017
I wrote a man in the middle for the leaf battery communication. It uses can4python and Kayak's kcd format to describe the signals. It probably only works on Linux. Source code is here https://carrott.org/git/leaf-can-utils.git
It decodes all the messages received on one interface (from the battery) into signals, lets me change their values, and then re-encodes them back into the can bus format, recalculates the new checksum when necessary and sends them out the other interface (to the car). It displays each signal and the received and sent signals:
Hexadecimal Decimal In Out In Out 1db Checksum: 007e 007e 126 126 1db Counter: 0002 0002 2 2 1dc Checksum: 005d 005d 93 93 55b Checksum: 007e 00dc 126 220 5bc 2_2: 0002 0002 2 2 Capacity Bars: 000a 000a 10 10 Li-ion battery available charge signal (%): 0040 0040 64 64 Li-ion battery capacity signal (GID): 0074 0074 116 116 Li-ion battery current signal: -0001 -0001 -1 -1 Li-ion battery gradual capacity loss signal?: 0068 0068 104 104 Li-ion battery voltage signal: 017f 017f 383 383 Temperature: 007e 007e 126 126 Wheel Speed: 0000 0000 0 0 _1db 1_2: 00 00 0 0 _1db 3_2: 2a 2a 42 42 _1db 4: 00 00 0 0 _1db 5: 00 00 0 0 _1dc 0: 6e 6e 110 110 _1dc 1: 04 04 4 4 _1dc 2: df df 223 223 _1dc 3: fd fd 253 253 _1dc 4: 04 04 4 4 _1dc 5: d8 d8 216 216 _1dc 6: c6 c6 198 198 _55b 1_2: 00 00 0 0 _55b 2: aa aa 170 170 _55b 3: 00 00 0 0 _55b 4: e0 e0 224 224 _55b 5: 00 00 0 0 _55b 6: 10 10 16 16 _5bc 1_2: 03 03 3 3 _5bc 3: 3f 3f 63 63 _5bc 4_1: 09 09 9 9 _5bc 5: 05 05 5 5 _5bc 6: 40 40 64 64 _5bc 7: 5a 5a 90 90 _5bc Mux_02: 07 07 7 7 _5c0 3: 00 00 0 0 _5c0 6: 00 00 0 0 _5c0 7: 02 02 2 2 _5c0 Mux_1_40: 7e 7e 126 126 _5c0 Mux_1_80: 7e 7e 126 126 _5c0 Mux_1_c0: 7e 7e 126 126 _5c0 Mux_2_80: 7e 7e 126 126 _5c0 Mux_2_c0: 7e 7e 126 126 _5c0 Mux_5_40: 6c 6c 108 108 _5c0 Mux_5_80: d0 d0 208 208 _5c0 Mux_5_c0: c4 c4 196 196
Yesterday I spent some time testing it on a Gen 1 leaf at Blue Cars
We cut the can bus wires inside the battery box, just after they go through the water proof connector to the outside and connected about 1 metre of thin figure 8 wire to each side of the cut. This let us access the bus on the car and the bus on the battery while the battery was plugged in under the car. It's possible to get enough slack in the internal battery loom to feed the connector all the way through the machined hole and make room for some extra wires to pass through. This is obviously only suitable for testing as the battery is no longer waterproof, but let us fasten the lid onto the battery before sliding it back under the car and lifting it up to meet the cables below the car.
With the two pairs connected together, the car behaved normally, going into ready and spinning the wheels.
The BMS module terminates the bus so we connected a termination resistor to the car side of the cut and used termination on the CAN interface talking to the battery. We plugged the other end of the man in the middle to the OBD2 port and didn't use termination.
The MitM just worked!
The car is very tolerant of errors on the CAN bus. You can stop the battery messages and it goes into turtle mode and all the battery info disappears off the instrument cluster. When you re-start the battery messages it goes back to normal mode and the battery info reappears. Start-up is quite critical, if you don't let the battery send it's start up messages the car doesn't go into ready mode. The car never shut down or went into a permanent turtle mode while I was messing with data on the bus -- it always went back to normal mode if I restored the unmodified message flow from the BMS. I modified the data in nearly every field to see what would happen.
The car will go into ready and turn the wheels even when it cannot send messages to the battery. This means the startup sequence doesn't involve a car to battery handshake, even if the car is expecting some startup messages from the battery within a time window. The "check engine" light comes on and it does record some DTCs:
My MitM only works in one direction (from the battery to the car) and it turns out my CAN bus setup wouldn't let two programs play together, so when I started a CAN repeater (candump -b) to copy data from the car to the battery I got corrupted frames and no buffer space errors. I'm going to make the MitM work in both directions to resolve this.
If you play a different car's battery messages into this car, it does not go into ready. I didn't spend much time on this and I didn't write code to start the BMS messages at the right time, I just started playing the recording of a running BMS and switched the car on. One experiment that I should have tried was to start the car with it's real battery and then switch to messages recorded from a different car. There are some new DTCs when you try to start a the car while playing messages recorded from another car including
The next experiment is to swap in a BMS module from another car.
I figured out some more of the BMS protocol by messing with the data and seeing how the car reacted.
The Fuel Gauge display on the instrument cluster is powered by the GIDs signal (the first 10 bits of 0x5BC), not the state of charge signal (first 10 bits of 0x55B). I guess it knows how many GIDS is "full" because the battery will have fewer gids and still read full as it ages.
0x5BC bits 36-39 (ie the high nibble of the 5th byte) somehow effects the Fuel Gauge, lower numbers mean more bars, all other things being the same. Maybe this is used to calculate how many GIDs each bar is worth? I haven't explored this.
The battery capacity gauge (the bars outside the fuel gauge) is controlled by a muxed field, when 0x5BC bits 32-35 (ie the low nibble of the 5th byte) is 0x3, 0x5BC bits 16-19 (ie the low nibble of the 3rd byte) contains the capacity bars. I haven't yet used the mux field support in the kcd format to express this -- can4python doesn't support it so I had to hand code it. The cluster does not remember the capacity -- changing this value directly manipulates the number of bars displayed, the value on the can bus is literally the number of bars (0x0 -> no bars, 0xC -> 12 bars).
The indicated temperature on the instrument cluster is controlled by another muxed field, when 0x5C0 is 0x40, the indicated temperature is controlled by the 3rd byte of 0x5C0. This mux has 3 values, on this car all 3 are similar in the 3rd byte, but only the when the mux is 0x40 does the 3rd byte control the temperature in the instrument cluster.
Many thanks to Carl at Blue Cars for letting me torture his car and Bill & Ed for assisting.
Friday, June 3. 2016
I've added remote climate control support in the Nissan Leaf OVMS firmware. This is relatively straightforward because Nissan built this feature into the Leaf's CARWINGS package. In New Zealand CARWINGS wasn't sold with the Leaf and Japanese import Leaves have a Japanese cell phone which doesn't work in New Zealand. Making it work here means emulating the function of the TCU module. On a Gen 2 Leaf this is simple, send a CAN bus frame to wake the car up and another frame to tell it to turn on or off the climate control, or start charging.
The Gen 1 Leaf is a little more complicated. The TCU wakes up the car by applying 12v to a wire, telling the VCU to wake up. After the VCU wakes up, the TCU sends the same command message as on the Gen 2 car. The OVMS hardware doesn't have an external 12V GPIO so I had to make something. I had a small relay lying around and using that was easier than building a 12v protected output. I glued a drive transistor on one side of the expansion port and the relay to the cell phone module. The LED catches the relay's turn off spike but any diode would do.
OVMS Module with modification to wake up Gen 1 Nissan Leaf
I used the previously unconnected Ring Indicate pin on the DIAG serial port to get the 12V signal out of the OVMS. RI is a good pin because it's an output from the OVMS and it is intended to tell the host the phone is ringing which matches up well with the "hey something important is happening, pay attention" use here. RS232 uses +12v signaling so a normal serial device will still be ok to plug into the port. The wire from the relay goes through one of the mounting holes for the serial port to access the pins on the back side of the circuit board, this avoids fouling the case which is pretty tight on all sides of the circuit board.
I've disconnected Nissan's TCU and stuffed a wire into it's plug to connect the OVMS to the Leaf's wiring loom. Nothing has complained about the disconnected TCU that I can see.
I'll post a schematic shortly.
Remote climate control is great, you can press a button on the OVMS cell phone app to get the car headed to toasty warm or cooled down before you get to it. If it's not plugged in then you get 15 minutes of cooling or heating, and more if it is plugged in. You can't control what the climate control does, Nissan have hard coded it to target 25C which is likely to cool the cabin in the summer and certainly heats it in the winter. Nissan have programmed the remote climate control to use recirculated air so in winter the windows are usually fogged up. I don't think there is anything I can do about that but the windscreen button once you're in the car doesn't take long to clear it.
Tuesday, February 3. 2015
I've replaced the Mini's mechanical speedometer with an electronic unit from a Mitsubishi FTO. This speedometer requires 2548 pulses per km, but my motor controller outputs a 7031 pulses per km. I need to make a box that outputs 1 pulse for every 2.764 input pulses. I made a fairly naive 2.75:1 implementation in an arduino by outputting one pulse for every 3 input pulses except every 4th pulse, where it only waits for 2 input pulses. This jitter doesn't seem to affect the speedo needle even at fairly low speeds.
The current implementation counts to 11 and uses a switch statement to output pulses which isn't really generalizable to other ratios but is probably close enough to what I need.
Saturday, January 31. 2015
I printed a 3 part adaptor to mount the Mitisubishi FTO speedometer inside the mini instrument cluster. I printed them in PET-G which hopefully won't soften in the sun -- it's apparently good for 75°C so that does seem unlikely. I must thank Daniel Dillan at www.vivenda.co.nz for suggesting PET-G and advice on getting good results with it (print it hotter and slower than PLA).
I'm not entirely sure why I needed so many prototypes. Good thing I have my own printer.
I now need to create an appropriate speed pulse signal from the inverter. Initial investigation suggests I cannot configure it to make less than 6000 pulses per kilometre, which is a little more than double what the speedometer expects. A simple arduino sketch will fix that.
Saturday, January 3. 2015
I reverse engineered the data stored in my Mitsubishi FTO Speedometer in order to re-calibrate it to suit the Mini face. Both faces show 180km/h, but the mini face spreads it over a slightly wider angle than the FTO does. The data is stored in an OKI 16811G 128 byte Serial EEPROM. This is quite an old part which uses Microwire (a predecessor and subset of SPI) to communicate. I had some trouble finding the data sheet for this part so I tried to sniff the communications between the odometer's CPU and the EEPROM with an Arduino running gillham's SUMP compatible firmware. Unfortunately the Arduino only has 2k of ram so recording all the state changes wouldn't fit. The communication is clocked at about 1MHz and I wasn't able to write a parser fast enough to stay in sync.
There is a fair amount of questionable information about odometer EEPROMs on the Internet, mostly related to tools for sale to wind your odometer back. One of these references claimed the part was compatible with a 93C46 so I wrote an EEPROM reader for that part and read out the data. Unfortunately this wiped the EEPROM! Somehow my reader code triggered the erase all command. This isn't entirely surprising because the right data sheet shows this EEPROM uses a different protocol to that used in the 93C46.
With a wiped EEPROM the odometer stop working, so I had to get another one. I also got an Open Bench Logic Sniffer which let me observe the entire communication between the odometer and the EEPROM and confirm that the protocol in the correct data sheet was the protocol actually in use. While re-scaling the speedometer for the new face I also reverse engineered the stored kilometre value and re-set the odometer to zero to celebrate the conversion to electric power. I also made some somewhat comprehensible notes about how this data is stored, an Arduino sketch to read and write the EEPROM which includes some tools to re-format the data, and an Arduino sketch to test an electronic speedometer and find the number of pulses per km.
Tuesday, April 29. 2014
Surprisingly the new gearbox's speedometer cable connects to the Mini speedometer. Unfortunately it interferes with the body at the gearbox end so I haven't been able to test it's calibration. I've been using the speed display on my EVision which listens to a speed pulse from my motor controller, but there is no odometer or trip meter and I would like to use display other data on the EVision, so I've been looking for an electronic speedometer to mount inside the mini instrument cluster. At the weekend I found a small electronic speedo from a Mitsubishi FTO which was new enough to be electronic but old enough to not be use the CAN bus and be small and separate from the other gauges.
The mechanism is small enough to fit into the mini instrument pod, but the face is too big. The original mini face will fit if I make the window for the odometer bigger and enlarge the center hole slightly. The shaft is smaller but it shouldn't be too hard to fit the mini needle. I'm not sure if I should mount a remote trip meter button, or drill through everything and try to mount a button in the normal position. I'm now designing an adapter to mount the mechanism. Interestingly both cars have 180km/h speedometers, but the Mini spreads it out over more degrees. I'm not sure how hard it will be to calibrate the needle.I'm considering whether to wind the speedo forward to 200,000km and call that "electric zero" or to attempt to align it with the car's current speedo -- TachoSoft indicate that the mileage data is stored in a separate serial EEPROM.
Sunday, August 11. 2013
Many high voltage DC contactors, switches and circuit breakers are only able to perform to their specifications if the current is flowing in the expected direction. This is because they include magnets which push the arc away from the switching element and into an arc chute or other plasma management device. A wire carrying a current through a magnetic field experiences a force (this is how motors work!) and this is particularly effective in the case of an arc because the "wire" is actually made of ionized gas. The problem comes when you reverse the direction of the current -- the "blow out" magnets suddenly become "blow in" magnets and the switch catches fire.
RISE did some testing of polarized DC circuit breakers intended for solar power and the results were quite spectacular. Do wait for the 40A tests towards the end!
Consult the manufacturer's datasheet to ensure your switches are correctly installed!
Friday, August 9. 2013
I tested a few circuit breakers rated for AC using my car's 250V DC battery. I used my load tester to limit the current to about 27A. I found that with a resistive load, the breakers successfully interrupted the current but failed safely after 5 or 10 switching cycles. Since I didn't have the equipment to limit the current to 50 or 100A, I used one of the windings in an isolation transformer to make the load more inductive and sort-of simulate a higher fault current situation. With this additional resistance, the current dropped to 23A. The results were quite scary:
It's important to note these tests represent abuse of the circuit breakers, if you ask them to switch AC they will likely give years of trouble free operation. The key is that 50Hz AC current falls to zero for long enough that the plasma cools, when the voltage rises during the next cycle, the arc can't re-establish without the plasma. With DC, the current doesn't stop and the arc just keeps burning.
Wednesday, March 13. 2013
Tuesday, January 15. 2013
I made a little load tester with some stove elements. They draw 27A at 260V. The camera is sensitive to near infrared -- they don't look as bright in real life. I think I will have to improve the cooling system before running it at higher voltage. The 3rd element away from the fan runs hottest, probably because the 4th element radiates heat away on it's outside and heats the 3rd element with the other.
Connecting this thing is not entirely straightforward. At low currents, you can use an Anderson disconnect with moderate safety, but things go badly at 27A and 260V. When I connected all 4 elements for the first time, the pins hit end on and the plug didn't go together. I don't know if disconnecting would have gone better with the small run-up that a fully mated connector offers, but I do know that separating from half connected went badly. There was a pop and a ball of white a big bigger than a hand span. When the after-image started to fade I could see the outline of the connector with a jet of white exiting the connector at 45 degrees on each side.
Safe disconnection is easily achieved with the right contactor. A small flash is visible inside the arc chamber during disconnection.
(Page 1 of 16, totaling 154 entries) » next page