Residential EVSEs are almost always for Level 1 (L1, 120v) and Level 2 (L2, typically 240v) charging.
For L1 & L2, the actual "charger", which converts the 120/240/etc to ~400VDC, is onboard the vehicle.
There are a LOT of mfgrs of EVSEs. I bought an OpenEVSE charging station for my first EV in Aug2017; $600 for the "Advanced" version (with WiFi and color LCD), assembled -- I did not have the time to assemble myself, though I would have loved to.
It has the WiFi option board, but until this week, I'd never explored it.
I want to use features of this OpenEVSE to tailor the charge start time every night. My goal is to have the battery charged just before I'm ready to depart. The car's onboard scheduler is too conservative, often completing a charge three hours before I leave, and if I try to fool it by changing the departure time, the pre-climate feature has to be disabled.
The OpenEVSE can circumvent the vehicle's scheduled charge feature. I can put the car in "charge now" mode, and schedule the EVSE when to turn on, to more precisely control charge start time than the car's scheduler allows.
Like most appliances these days, the OpenEVSE has a CPU: Atmel MEGA328P. It has firmware. It shipped with 3.11.1; current is 5.0.1.
The WiFi option board has its own CPU, ESP8266-12F, and its own firmware that also is out-of-date: current is 2.8.2 . It's an AdaFruit unit.
The WiFi CPU's firmware is (usually) upgradeable via a web interface. I ran through the procedure, but finally could not get it to tell me the version of the uploaded firmware, and it wouldn't work correctly after that.
The EVSE's main module's firmware cannot be upgraded via a web interface; wires are needed.
I got to the point where I had to remove both CPUs from the OpenEVSE's enclosure, connect them to a PC, and re-flash them. Argh, the learning curve. Below summarizes the successful path I took; not necessarily an optimized path, but I'm leaving out most of the cruft of wrong turns I took along the way. This is a recipe, probably not the best recipe.
This is an all-Linux recipe (Ubuntu 18.04, in my case). See below for later (Apr2022) Windows notes.
The WiFi module firmware
The WiFi's ESP8266 has to be flashed using the serial interface. On modern PCs, this requires a USB<->serial (not RS232, which is 5-25v) 3.3v signal level converter, and the better ones use an FTDI IC to facilitate the conversion. I ordered two of those, one an AdaFruit via Amazon, and another no-name unit via eBay (FT232RL FTDI USB 3.3V 5.5V to TTL Serial Adapter Module for Arduino Mini Ports). The AdaFruit unit looks great, but I've never been able to make it work. The no-name worked OK.
I had to install esptool, a Python program. My Ubuntu 18.04 has Python 2.7 installed, but not pypi. I think I installed esptool using "python -m pip install esptool
[Apr2022: python 3, default on newer versions of Ubuntu, does not support the above. Instead:
Code: Select all
sudo apt install esptool
Now, to locate the correct USB port. Plug in the USB cable to the PC, and see what dev Ubuntu has assigned to it:
Code: Select all
asavage@Ubuntu1:~/Downloads$ [b]sudo dmesg | grep tty[/b]
[ . . . ]
[790893.659693] usb 4-1: FTDI USB Serial Device converter now attached to ttyUSB0
asavage@Ubuntu1:~/Downloads$
There are a couple of different ways to allow a program to access the USB<->serial converter, but for a one-time thing, chmod worked. The problem with using chmod is that you have to re-run the command every time the converter is plugged in to the PC.
Assuming that the flash data file is located in the Downloads folder . . .
In a terminal window, preload these two lines into the terminal buffer:
- sudo chmod 666 /dev/ttyUSB0 (<-May have to type password, if the last sudo has gone stale)
- esptool.py --port /dev/ttyUSB0 -b 115200 write_flash 0x00000 firmware.bin (<-this will not complete, because the converter's not been plugged in yet, and that's OK. We're just preloading the command for later use.).
ESP8266:
In order for the ESP8266 to use its serial interface to input flash data, you have to put the chip in flash mode, by grounding the GPIO0 line on powerup. The Adafruit WiFi module conveniently has a tactile switch to do this.
- Press the flash button and hold it down
- Plug in the USB<->Serial converter to the PC. This powers up the WiFi module
- Continue pressing the flash button until . . .
- In the terminal window, scroll back and run both the above commands, in that order
- . . . you see "erasing" or similar, then release the flash button
- Results: see below
Code: Select all
asavage@Ubuntu1:~/Downloads$ [b]sudo chmod 666 /dev/ttyUSB0[/b]
[sudo] password for asavage:
asavage@Ubuntu1:~/Downloads$ [b]esptool.py --port /dev/ttyUSB0 -b 115200 write_flash 0x00000 firmware.bin[/b]
esptool.py v2.7
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 5c:cf:7f:19:92:42
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 705152 bytes to 399582...
Wrote 705152 bytes (399582 compressed) at 0x00000000 in 35.3 seconds (effective 159.9 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
asavage@Ubuntu1:~/Downloads$
ESP32:
I upgraded my original ESP8266 WiFi hardware to the current ESP32-WROOM-32 version. I bought the module from Adafruit for $13.50 + shipping, around $22 on my doorstep, and it comes with some pin header strips. OpenEVSE does sell their version (same Espressif chip, different PCB and headers) for $40 + shipping, and it comes pre-loaded with a recent firmware, but since I already have the USB<>UART programming tool, I decided to buy the bare/no-firmware-installed board. I cut off a chunk of pin header, six pins long, and soldered it to the board: hardware part done.
Instructions for the esptool command line are here. Since this is a new install, flashing the bootloader and the partitions file is required, as well as the actual firmware, so for Ubuntu 21.10 and python 3 and the esptool Ubuntu package installed, I used:
Code: Select all
esptool --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader.bin 0x8000 partitions.bin 0x10000 openevse_huzzah32.bin
- partitions.bin
- bootloader.bin
- openevse_huzzah32.bin
Subsequent firmware updates should be able to be OTA via the unit's web UI, but if I ever needed re-flash this module, I would not need to re-flash the bootloader or partitions info.
- Connect the ESP32 to the USB<>UART converter (four wires, and Rx/Tx on one board connects to Tx/Rx on the other).
- Plug in the USB<->Serial converter to the PC.
- The converter then powers up the WiFi module.
- The OS assigns a dev to the USB port. See above instructions for using dmesg to confirm that port. In my case, it's always ended up being ttyUSB0
Code: Select all
asavage@Ubuntu1:~/Downloads$ sudo chmod 666 /dev/ttyUSB0 [sudo] password for asavage: asavage@Ubuntu1:~/Downloads$ esptool --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader.bin 0x8000 partitions.bin 0x10000 openevse_huzzah32.bin
- esptool should be "connecting" . . .
Code: Select all
asavage@Ubuntu1:~/Downloads$ esptool --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 bootloader.bin 0x8000 partitions.bin 0x10000 openevse_huzzah32.bin esptool.py v2.8 Serial port /dev/ttyUSB0 Connecting........_____....._____.....___
- You'll have around 20 seconds to get the ESP32 to begin accepting data. In order for the ESP32 to use its serial interface to input flash data, you have to put the chip in flash mode, by using the two switches on the Adafruit ESP32 Huzzah.
- Press and hold the GPIO0 button
- Press and hold the Reset button for ~1/2 second
- Release both buttons
- If the button pressing/releasing timing was right, esptool will stop "connecting" and move on to "Detecting chip type..."
The OpenEVSE main module firmware
The OpenEVSE's main module uses the Atmel MEGA328P, which is an AVR microcontroller, and uses In System Programming (ISP) (or In-circuit Serial Programming: ICSP) to update its code, using the board's Serial Peripheral Interface (SPI). I purchased an AVR programming tool from the OpenEVSE online store, but though they accepted my order on Wednesday, I received no tracking info until I emailed them Friday asking for it, and then they returned a USPS tracking number that shows they haven't actually shipped it yet (Sunday night). Sigh. After calling around a bit to try to find an alternate AVR programming tool locally, I fell back to Amazon: ordered Fri. night, dropped at my work's Amazon locker Sunday morning. I purchased a Waveshare AVRISP XPII programmer (clone of discontinued Atmel AVRISP mkII) for $42. It worked perfectly, and after checking the pinouts of it and the OpenEVSE's main module's SPI header pinout, they matched, so I didn't even have to get out the jumpers.
The Waveshare's docs warn that it won't power the unit to be programmed, so I used power from one of FTDIs to run the main module.
I had to install avrdude.
Code: Select all
sudo apt install avrdude
Code: Select all
sudo apt install libusb-dev
These lines are the meat of it. I only had to substitute "avrisp2" where the orginals contained "USBasp". The Waveshare AVR ISP programmer is a clone of an Atmel AVR ISP mkII, which uses the parameters in avrdude.conf associated with avrisp2.
- avrdude -c avrisp2 -p m328p -U lfuse:w:0xFF:m -U hfuse:w:0xDF:m -U efuse:w:0x04:m [see comment in "Windows notes" below about "0x04"]
- avrdude -c avrisp2 -B0.5 -p m328p -V -U flash:w:open_evse.hex
- avrdude -c avrisp2 -p m328p -V -U eeprom:w:eeprom_24.bin -V
Code: Select all
avrdude: reading input file "0x04"
avrdude: writing efuse (1 bytes):
Writing | ################################################## | 100% 0.01s
avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0x04:
avrdude: load data efuse data from input file 0x04:
avrdude: input file 0x04 contains 1 bytes
avrdude: reading on-chip efuse data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
0xfc != 0x04
avrdude: verification error; content mismatch
Bits 0-2 are to enable/disable Brown Out Detection (BOD), and if enabled, to set the voltage below which the AT328P will not run. The OpenEVSE code sets it to only run when the supply voltage is above 4.3v .oPossum wrote:Bits 3 to 7 of efuse will always read 0 - they are not used.
So 0xFC (1111 1100) is the same as 0x04 (0000 0100)
The default for this chip is/was 0xFF (B1111 1111) (opinions vary), or different programming tools/versions read-back an unset bit (which on this device: unset = 1) as either 0 or 1, so depending on the tool and version and age of the chip, one might get 0x04 or 0xFC.
See this post for more.
It's even possible that the WinAVR version of avrdude, and the Linux version read-back unset bits differently. I'm not chasing it down further, I'm happy with it working.
=================================================
After the above, the EVSE's web UI shows the updated firmwares: A couple of reference pics from Oct2019: =================================================
Windows notes (Apr2022)
The Waveshare USB AVRISP XPII is a clone of a long-ago discontinued Atmel AVR ISP mkII. Above, in 2019, I successfully used it to update the OpenEVSE controller's firmware, under Ubuntu Linux. At that time, I had the controller on my workbench. Today, I wanted to update the firmware again (from 5.0.1 to 8.2.0) with the EVSE still mounted outside, using my all-purpose auto diagnostic laptop which runs Win8.1, but it took a bit of reading to get that working.
The Guide to updating the OpenEVSE controller firmware is here. It's riddled with errors, though. It probably was mostly correct when it was written, but things have changed.
WinAVR (from 2010!) has to be installed.
By default, the tool avrdude, running under Windows, expects the OS to supply a COMx port for the Waveshare USB device, but I was unable to find a suitable driver that worked with that device. Without a COMx port, the command lines I used with Ubuntu returned errors stating that no COM1 was found.
The successful steps I used were:
- I used the Zadig tool v2.7 to switch the Windows USB driver for the Waveshare USB AVRISP XPII to the libusb-win32 driver.
- Added a commandline parameter to instruct avrdude to use USB rather than COM1.
- avrdude -c avrisp2 -P usb -p m328p -U lfuse:w:0xFF:m -U hfuse:w:0xDF:m -U efuse:w:0x05:m [*this has changed from :x04 in previous versions, or I typo'd it above in 2019]
- avrdude -c avrisp2 -B0.5 -P usb -p m328p -V -U flash:w:openevse.hex
- avrdude -c avrisp2 -P usb -p m328p -V -U eeprom:w:eeprom_24.bin -V
Other issues
The OpenEVSE project at GitHub isn't terribly well maintained for use by non-programmers. In particular, it's non-obvious to a casual user just where the firmware files you want are to be downloaded. First, you've got to select the correct release (pre-selected in the link in the previous sentence), then scroll to the bottom of the page to find "Assets". Yes, "openevse.hex" is there (note: it's been renamed from "open_evse.hex" that's specified in the Guide. At the time of writing this, there is no "flash.bat", nor "eeprom_24.bin".
In order to find those missing files, I had to poke around in older release directories.
The "flash.bat" is for the usbasp programming tool, and has to be adapted for different programming tools; this is not a fault of the Guide.
The Guide specifies wire harness wire colors not present in the harness supplied by OpenEVSE's store; the ISP programmer they sent me -- and which I didn't use -- is a Pololu USB AVR Programmer v2.1 . It, like the Waveshare unit, is supplied with a grey ribbon cable and IDC plug with key. There are many different PCB versions of the OpenEVSE controller, and on my version, the key on the plastic IDC connector of the ISP must be shaved off in order to allow insertion onto the controller's pins, as there's no room for the key on my version of the controller: the key fouls the DC-DC converter. Later PCB versions moved the ISP pins left to provide more room, and yet other PCB versions have rotated the ISP pins on the PCB, so there are a lot of variables.