Welcome to Tesla Motors Club
Discuss Tesla's Model S, Model 3, Model X, Model Y, Cybertruck, Roadster and More.
Register

HPWC Hacking

This site may earn commission on affiliate links.

wk057

Former Tesla Tinkerer
Feb 23, 2014
6,504
17,139
X
So, I decided a while back that I need a smarter charger. I want one where I can dynamically lower the output current (pilot signal) remotely based on solar output for my new off-grid system.

Since the HPWC is basically just a J1772 charger, the J1772 protocol is pretty well documented, and there are open source implementations of the J1772 protocol, I figure it would be pretty simple to replace the digital guts of the HPWC, leave the power-related guts (power wiring, contactor, fuses, etc) and just replace the control board with something custom. Additionally, I believe I'll be adding WiFi and/or ethernet capability to the units to integrate them into my home network for monitoring and adjusting. Should be pretty sweet.

I recently purchased a HPWC that had a damaged control PCB in an effort to prototype such a modification. Eventually once I have a board finalized to replace the normal one I will print some up and just replace the boards in my two units that are already in place.

Since the J1772 side of things is pretty well known already, I decided to just jump into figuring out the important stuff :rolleyes: like the HPWC front cover's connector that controller the LEDs on the face.

2015-04-07 12.32.05-crop.jpg


Initially I thought this was just a wire that was used to power a few LEDs. After poking around with it a bit I decided to remove it from the front panel of the damaged unit I have (it's not going to be used really anyway) which meant some permanent plastic surgery to remove it since it is held in by plastic rivet type holders. Turns out there is actually an I2C-based digital LED driver chip on that LED board... the chip is hard to read through the conformal coating, but it appears to be a Texas Instruments TLC59108 LED driver chip.

I spent a few minutes working out the pinout of the 6-pin flat ribbon cable from the board and while untested yet, I think I have it worked out to be:

Looking at the pins of male-pinned connector LED-board side of the cable with the notch upward and using the pin numbering on the original control board makes the left pin #1 and the right pin #6:

1 - +3.3 to 5V VCC (To LED Anodes)
2 - I2C SDA
3 - I2C SCL
4 - +3.3 to 5V VCC (To driver chip VCC)
5 - Red LED active high signal (+3.3 - 5V = on)
6 - GND

(Update 2015-04-08: Verified pinout described above, see post below)

I put a "?" on the 5V because I haven't measured this on a working HPWC yet, but the chip and everything else appears to be 5V compatible. (Edit: see above)

With this I should be able to whip up a test circuit to control this driver chip and make these LEDs behave how I want them too. Unfortunately I don't seem to have the right connector in my stock and I don't want to destroy the one that came with it so I can easily test my board with it later.

My idea would be to make them a little more intelligent in a way similar to a mechanical electric meter. More current, faster LED movement. Less current, slower LED movement. Maybe one steady blinking or some other indication for when the contactor is closed, and probably a "breathing" one for when idle. Should be pretty simple. This driver chip even has on-board per-LED PWM output for dimming.

I'll mess with it more later, just figured I would share this since I hadn't seen any info on this little board posted anywhere as of yet. More updates as I get deeper into this and I'll update or add links in this post with relevant info.

-wk
 
Last edited:
So, I decided a while back that I need a smarter charger. I want one where I can dynamically lower the output current (pilot signal) remotely based on solar output for my new off-grid system.


-wk

There is a HUGE demand for this... I'm kinda surprised that Tesla hasn't thrown in a quick charging algorithm where you just type in your array details and the charge rate of your car matches the expected output of the array. I'm sure that's coming.
 
I am working on this exact setup on OpenEVSE. Here is my setup.

5.8kw Solar
Open Energy Monitor reading output
Data posted to Open Energy Monitor site emoncms.org

OpenEVSE with Remote API enabled
Serial TTL
OpenWRT Wifi travel router (GL iNET)
Python

Every 10 seconds the Python script reads data from emoncms.org to get solar output and polls OpenEVSE for a real time current measurement. The OpenEVSE pilot is dynamicly set based on avaliable solar output or OpenEVSE is put to sleep is avaliable power is under the J1772 6A current limit.

I will post the Python code in a couple days after I clean it up and finish testing.

Here is my current dashboard.
http://emoncms.org/chris1howell/
 
My goal is to make a custom board the same dimensions and with the same/similar connectors as the existing control board in the HPWC. That way I can just pop out the old board, pop in the new board, do all of the hookups, and presto. :)

I want to retain the installer-only DIP switches for max current as well, but let the digital controls adjust this anywhere below and up to the setting. This should keep it code compliant.

I've made an OpenEVSE J1772 charger a while back when I had my volt. Honestly, that's probably the easy part. Getting everything working in the existing housing with the existing contactor and such is probably going to take a little more effort.
 
After writing some I2C protocol stuff from scratch for an ATtiny85 (and debugging that with my scope...) and finding a connector with the right pin size I was able to whip up a test interface for the front cover. After digging through the datasheet for the little driver chip Tesla used for a little while I was able to initialize it and get the thing to come to life.

I did up some demo code that just bounces back and forth. Can also dim the LEDs individually. Pretty cool. Not that lighting some LEDs is something spectacular or anything, but, it's cool that I'll be able to utilize the front panel LEDs without modification. :)

 
Last edited by a moderator:
I want to retain the installer-only DIP switches for max current as well, but let the digital controls adjust this anywhere below and up to the setting. This should keep it code compliant.

I've made an OpenEVSE J1772 charger a while back when I had my volt. Honestly, that's probably the easy part. Getting everything working in the existing housing with the existing contactor and such is probably going to take a little more effort.

Once you modify the Main board or firmware you will lose the UL certification which will also kill NEC compliance (NEC requires the EVSE to be certified by a NRTL). The UL certification is tied to a tested contactor - board - firmware combination. The firmware is validated by UL with a Checksum. Will an inspector notice, probibly not...?

Getting everything working in the exsisting housing sould be very easy with OpenEVSE v3. The contactor is a Curtis - Albright which has a 240 DC coil. I believe there is a board that rectifies the incoming AC to DC on the contactor itself, if not all you need is a bridge rectifier. The lights could be controlled with the i2c LCD output and everything elso shoud be plug and play.

- - - Updated - - -

Here is the Python Code I am using on an OpenWRT travel router (GL iNET). I am connecting to OpenEVSE with a serial TTL cable to get current readings and dynamicly adjust pilot based on solar output. My Solar is sending data to emoncms.org via an Open Energy Monitor setup.

import time, httplib, urllib, os, serial

lcd = False
done = False
amp_ct = 0
evse_sleep = 0

# Setup for Serial Port
comm = serial.Serial()
comm.port='/dev/ttyUSB0'
comm.baudrate=115200
comm.open()

# Setup for Open Energy Monitor Emoncms.org
host = 'www.emoncms.org'
feed_solar = 'id=67524'
feed_volt = 'id=67526'
url_get = '/feed/value.json?'
url_post = '/input/post.json?'
apikey = '&apikey=07abcde2c15e5222e4a4075b95e12345'
values = urllib.urlencode({'value' : '1234',}) headers = {
'User-Agent': 'python',
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'text/plain',
}
url_solar = url_get + feed_solar + apikey
url_volt = url_get + feed_volt + apikey
conn = httplib.HTTPConnection(host)

#Main Loop
while not done:
#read RAPI current from OpenEVSE and Post HTTP
if evse_sleep == 0:
comm.write("$GG*B2\r")
print (" ")
print ("Send RAPI>>$GG*B2")
time.sleep(1)
out = ''
while comm.inWaiting() > 0:
out += comm.read(1)
if out != '':
print "OpenEVSE>>" + out
if out != "$NK":
amp_ct = out.replace("$OK ", "")
input_amp = 'json={OpenEVSE:' + amp_ct + '}'
url_amp_ct = url_post + input_amp + apikey
conn.request("POST", url_amp_ct, values, headers)
response = conn.getresponse()
print "POST OpenEVSE current to emoncms.org"
if response != '':
print "Recieved HTTP Response"
else:
print "Serial Error: No response"

if out == "$NK":
print "OpenEVSE>> Error"

#connect HTTP to retrieve Solar output power
conn.request("POST", url_solar, values, headers)
response = conn.getresponse()
data = response.read()
data = data.replace('"', "")
data = data.replace("-", "")
solar = data
amp = int(solar) / 240
print "GET Solar power from emoncms.org"

#connect HTTP to retrieve Voltage
conn.request("POST", url_volt, values, headers)
response = conn.getresponse()
data = response.read()
data = data.replace('"', "")
data = data.replace("-", "")
volt = data
print "GET AC Voltage from emoncms.org"


#send new pilot value to OpenEVSE
comm.flushInput()
def append_checksum(s): return s + "*" + ('%02X' % ((sum(ord(c) for c in s) % 256) & 0xFF))
pilot = append_checksum("$SC " + str(amp))
print pilot

if amp < 6:
if evse_sleep == 0:
evse_sleep = 1
comm.write("$FS*BD\r")
print "FS*BD"
out = ''
time.sleep(1)
while comm.inWaiting() > 0:
out += comm.read(1)
if out != '':
print ">>" + out


if amp >= 6:
if evse_sleep == 1:
evse_sleep = 0
comm.write("$FE*AF\r")
print "$FE*AF"
out = ''
time.sleep(1)
while comm.inWaiting() > 0:
out += comm.read(1)
if out != '':
print ">>" + out
comm.write(pilot + "\r")
out = ''
time.sleep(1)
while comm.inWaiting() > 0:
out += comm.read(1)
if out != '':
print ">>" + out


#Text Output
if lcd == False:
#print response.status, response.reason
print " "
print " "
print "---------------------------------"
print "Solar Output - " + solar + " watts"
print " Voltage - " + volt + " volts"
print " "
print " "
if amp > 5:
print "OpenEVSE Pilot - " + str(amp) + " Amps"
print " Output - " + str(amp_ct) + " watts"
else:
print "OpenEVSE is Sleeping"
print "---------------------------------"
print " "
print " "
time.sleep(8)
 
if you keep the wiring and connector and replace the digital guts, won't you have a problem with the communication protocol with the car? wouldn't the car expect some sort of tesla proprietary handshaking that you wouldn't have access to? how does the Model S know (or does it know at all) that the things plugged in is a Tesla proprietary connector vs a J1772?
 
if you keep the wiring and connector and replace the digital guts, won't you have a problem with the communication protocol with the car? wouldn't the car expect some sort of tesla proprietary handshaking that you wouldn't have access to? how does the Model S know (or does it know at all) that the things plugged in is a Tesla proprietary connector vs a J1772?
The original Tesla HPWC uses J1772 protocol. The only thing different is the physical connector, which is being retained.
 
Once you modify the Main board or firmware you will lose the UL certification which will also kill NEC compliance (NEC requires the EVSE to be certified by a NRTL). The UL certification is tied to a tested contactor - board - firmware combination. The firmware is validated by UL with a Checksum. Will an inspector notice, probibly not...?

Getting everything working in the exsisting housing sould be very easy with OpenEVSE v3. The contactor is a Curtis - Albright which has a 240 DC coil. I believe there is a board that rectifies the incoming AC to DC on the contactor itself, if not all you need is a bridge rectifier. The lights could be controlled with the i2c LCD output and everything elso shoud be plug and play.

I'm not sure I completely agree with how you describe NEC compliance here. The most detail the NEC goes into on this in particular for EVSEs is here:

625.5 Listed. All electrical materials, devices, fittings, and associated equipment shall be listed.

Certainly modifying the device in the way I intend to will technically cause the unit's UL listing to no longer be valid. However, I think it would be a stretch to think that at any point in time the checksum of the firmware on the board would come into question. I'm actually kind of doubtful it'd be required to release such a thing in the first place. And never in the history of the world will an inspector ever think they would need to check a firmware checksum... lol.

In any case, the majority of the components are remaining unchanged. Contactor, fuses, HV wiring, charge connector and its wiring, housing, HV input terminals, etc. The only truly important thing that I have to recreate when replacing the original board is the GFCI protection circuit. As long as that works as intended I believe any additional risk associated with the whole process will be less than minimal, IMO.


Here is the Python Code I am using on an OpenWRT travel router (GL iNET). I am connecting to OpenEVSE with a serial TTL cable to get current readings and dynamicly adjust pilot based on solar output. My Solar is sending data to emoncms.org via an Open Energy Monitor setup.

Very cool!

Having successfully reverse engineered the front cover LED board I'll probably jump on a custom board for the OpenEVSE-type stuff soon that will be the same shape as the original board with connectors in the same places.

I'll have to design and test a driver circuit for this contactor, which appears to want 240VDC at ~10W if the datasheet's I've seen are accurate. Shouldn't be too hard, but I'll verify readings on a working HPWC before building that circuit. 99% sure I'm right, since the factory driver circuit seems pretty simple.

I may not actually use OpenEVSE software, however. I'm not a huge fan of Arduino code, really, and the J1772 signalling is pretty straightforward. I'll likely just use the OpenEVSE hardware schematics as a reference for things like their GFCI implementation since it's pretty simple and possibly some code behavior reference. I plan on adding AC voltage measurement and CT-based current measurement while I'm at it.

I'm going to investigate the power utilized for the little transmitter in the charge handle, also, so that I can retain that crucial functionality. It's likely it just leeches off of the pilot signal, but not sure.
 
Funny...we are all trying to build the same thing...I bought a OpenEVSE v3 last month...been using it to dynamically charge...of course we are all optimizing for different things...=)

Wow very cool. And I honestly thought I was kind of alone on this project initially.

Perhaps I'll have to open source my design once I get a design going so others can participate. :)

For now, I'll post my crappy from-scratch code for bit-banged I2C control of the HPWC's LED face using two PORT pins on an AVR.

AVR Studio GCC for ATtiny85.

Code:
// Copyright 2015 - Jason Hughes (wk057)
// All rights reserved
// For demonstration only, will probably open source soon
// No warranty is given or implied.  All liability disclaimed.




#define F_CPU 1000000 // internal 1MHz clock


#include <avr/io.h>
#include <util/delay.h>


// lots of hard coding here... but it is embedded software...// SDA is on PB4, SCL on PB3

#define SDA(x) PORTB = ((PORTB & ~0x10) | (x<<4))
#define SCL(x) PORTB = ((PORTB & ~0x08) | (x<<3))
#define SDA_INPUT()\
DDRB &= ~0x10;\
PORTB |= 0x10;
#define SDA_OUTPUT() DDRB |= 0x10;


// kind of confusing... "double_delay" is one SCL clock cycle.  Probably can speed this up
#define i2c_half_delay() _delay_us(7)
#define i2c_delay() _delay_us(14)
#define i2c_double_delay() _delay_us(28)


void start_i2c() {
    SDA_OUTPUT();
    SDA(0);
    i2c_double_delay();
    SCL(0);
    i2c_double_delay();
    i2c_delay();
}


void stop_i2c() {
    SDA(1);
    i2c_double_delay();
    SDA(0);
    i2c_double_delay();
    SCL(1);
    i2c_double_delay();
    SDA(1);
    i2c_double_delay();
    i2c_double_delay();
}


// unrolled this for more consistent timings
unsigned char i2c_write_byte(unsigned char c) {
    
    unsigned char i;
    
    if((c&0x80) > 0) SDA(1); else SDA(0);
    i2c_delay();
    SCL(1);
    i2c_double_delay(); // bit on SDA is read here by slave
    SCL(0);
    i2c_delay();


    if((c&0x40) > 0) SDA(1); else SDA(0);
    i2c_delay();
    SCL(1);
    i2c_double_delay(); // bit on SDA is read here by slave
    SCL(0);
    i2c_delay();


    if((c&0x20) > 0) SDA(1); else SDA(0);
    i2c_delay();
    SCL(1);
    i2c_double_delay(); // bit on SDA is read here by slave
    SCL(0);
    i2c_delay();


    if((c&0x10) > 0) SDA(1); else SDA(0);
    i2c_delay();
    SCL(1);
    i2c_double_delay(); // bit on SDA is read here by slave
    SCL(0);
    i2c_delay();


    if((c&0x08) > 0) SDA(1); else SDA(0);
    i2c_delay();
    SCL(1);
    i2c_double_delay(); // bit on SDA is read here by slave
    SCL(0);
    i2c_delay();


    if((c&0x04) > 0) SDA(1); else SDA(0);
    i2c_delay();
    SCL(1);
    i2c_double_delay(); // bit on SDA is read here by slave
    SCL(0);
    i2c_delay();


    if((c&0x02) > 0) SDA(1); else SDA(0);
    i2c_delay();
    SCL(1);
    i2c_double_delay(); // bit on SDA is read here by slave
    SCL(0);
    i2c_delay();


    if((c&0x01) > 0) SDA(1); else SDA(0);
    i2c_delay();
    SCL(1);
    i2c_double_delay(); // bit on SDA is read here by slave
    SCL(0);
    SDA_INPUT();
    i2c_double_delay();
    SCL(1);
    i2c_delay();
    i = (PINB & 0x10)?1:0;
    i2c_delay();
    SCL(0);
    SDA(1);
    i2c_half_delay();
    SDA_OUTPUT(); // should already be high
    SDA(1);
    i2c_half_delay();
    SDA(1);
    
    return i;
    
}
void init_chip() {
    
    start_i2c();
    i2c_write_byte(0x80);
    i2c_write_byte(0x80);
    i2c_write_byte(0x00); // 0 MODE1
    i2c_write_byte(0x00); // 1 MODE2
    i2c_write_byte(0x00); // 2 PWM0
    i2c_write_byte(0x00); // 3 PWM1
    i2c_write_byte(0x00); // 4 PWM2
    i2c_write_byte(0x00); // 5 PWM3
    i2c_write_byte(0x00); // 6 PWM4
    i2c_write_byte(0x00); // 7 PWM5
    i2c_write_byte(0x00); // 8 PWM6
    i2c_write_byte(0x00); // 9 PWM7
    i2c_write_byte(0x00); // 10 A GRPPWM
    i2c_write_byte(0x00); // 11 B GRPFREQ
    i2c_write_byte(0xAA); // 12 C LEDOUT0
    i2c_write_byte(0xAA); // 13 D LEDOUT1
    stop_i2c();
    
}




// Set the PWM values for the 8 LEDs
void write_leds(unsigned char * leds) {


    unsigned char x;
    start_i2c();
    i2c_write_byte(0x80);
    i2c_write_byte(0xA2);
    for(x=0;x<8;x++)
    i2c_write_byte(leds[x]);
    stop_i2c();
    
}


int main( void )
{


    
    DDRB |= 1 | 0x8 | 0x10;
    PORTB |= 1 | 0x08 | 0x10;
    


    unsigned char leds[8], i, a, b, c;




    _delay_ms(100);




    init_chip();
    _delay_ms(1000);


    a = 0; c = 0;


    while(1) {


        // Fun test effect that has two LEDs bouncing back and forth from either side
        // one starts dimmer so they look like independent entities bouncing from end to end
        // once the brightness on the dimmer one gets closer to the other LED they start to look
        // like they're bouncing into each other at the half way mark :P
        for(i=0;i<8;i++) leds[i] = 0;
        if (a < 8) b = a; else b = 7-(a-8);
        leds[b] = 0xff;
        leds[7-b] = c;
        a++; c++;
        if (a == 16) a = 0;


        write_leds(leds);
        _delay_ms(25);


    }
    


}
 
Last edited:
I'm going to investigate the power utilized for the little transmitter in the charge handle, also, so that I can retain that crucial functionality. It's likely it just leeches off of the pilot signal, but not sure.

I believe the "violet" wire connects to the RF transmitter, is supplied by 3.3V, at least the Tesla UMC head I bought from Tony worked that way.
With the price of the HPWC very inexpensive now, I think it would be a mistake to NOT use OpenEVSE, since it's very well developed/supported, honestly, why re-invent the wheel, the one we have is very round and well developed.

I expect if WK & Chris work together, a custom replacement OpenEVSE can be designed for the HPWC, maybe even design it so you just plug in a Raspberry PI 2 compute module (when they come out) or just design it to mount the RPI 2 on the PCB, that could easily provide the web interface/Ethernet port, and even WiFi or Bluetooth. It could just drive a standard OpenEVSE built on to the PCB for the low level control, so the RPI doesn't have to focus on that.. Maybe not the exact way I've described this (I know Chris is has found the new router for the web interface, but the cost on that are very close to the Raspberry PI $35, which can be optional..)

anyway, when you need a victim (I mean test subject), I have a HPWC now as well in my 2nd house I can use, I also have a few of the new Raspberry Pi 2's as well.
 
I believe the "violet" wire connects to the RF transmitter, is supplied by 3.3V, at least the Tesla UMC head I bought from Tony worked that way.
With the price of the HPWC very inexpensive now, I think it would be a mistake to NOT use OpenEVSE, since it's very well developed/supported, honestly, why re-invent the wheel, the one we have is very round and well developed.

I expect if WK & Chris work together, a custom replacement OpenEVSE can be designed for the HPWC, maybe even design it so you just plug in a Raspberry PI 2 compute module (when they come out) or just design it to mount the RPI 2 on the PCB, that could easily provide the web interface/Ethernet port, and even WiFi or Bluetooth. It could just drive a standard OpenEVSE built on to the PCB for the low level control, so the RPI doesn't have to focus on that.. Maybe not the exact way I've described this (I know Chris is has found the new router for the web interface, but the cost on that are very close to the Raspberry PI $35, which can be optional..)

anyway, when you need a victim (I mean test subject), I have a HPWC now as well in my 2nd house I can use, I also have a few of the new Raspberry Pi 2's as well.

Mainly I think form factor will come into play here. For example... a Raspberry Pi won't fit in the HPWC. There also isn't too much room for components, so I wouldn't want to stack boards. I think the existing OpenEVSE boards are also too wide... the original board is not even as wide as the height of a credit card.

Software wise, I just don't like Arduino for production projects... *shrugs* ... Last I checked OpenEVSE was Arduino based. I'd prefer a stripped down C version, personally.

Form factor wise, definitely need a custom board.
 
Mainly I think form factor will come into play here. For example... a Raspberry Pi won't fit in the HPWC. There also isn't too much room for components, so I wouldn't want to stack boards. I think the existing OpenEVSE boards are also too wide... the original board is not even as wide as the height of a credit card.

Software wise, I just don't like Arduino for production projects... *shrugs* ... Last I checked OpenEVSE was Arduino based. I'd prefer a stripped down C version, personally.

Form factor wise, definitely need a custom board.

I expect Chris can design an OpenEVSE that is the exact same size as the existing HPWC PCB.
maybe that's all that's needed, the control/current adjustment you are looking for can then be done via the RAPI interface (serial commands sent to the OpenEVSE). Would just need a way to interface to it, a small bluetooth or wifi interface could get that done without making any additional holes, or have any cabling enter/exit the HPWC... Raspberry Pi controller, wifi router, whatever you choose to use can be external. The OpenEVSE could drive the front panel LEDs via I2C, which it already has (RTC and LCD display use it now)
 
I expect Chris can design an OpenEVSE that is the exact same size as the existing HPWC PCB.
maybe that's all that's needed, the control/current adjustment you are looking for can then be done via the RAPI interface (serial commands sent to the OpenEVSE). Would just need a way to interface to it, a small bluetooth or wifi interface could get that done without making any additional holes, or have any cabling enter/exit the HPWC... Raspberry Pi controller, wifi router, whatever you choose to use can be external. The OpenEVSE could drive the front panel LEDs via I2C, which it already has (RTC and LCD display use it now)

Definitely multiple ways to go about this. If someone wants to make up an OpenEVSE board that fits in the HPWC and utilizes everything existing like I've described, by all means.

Finding an elegant solution that works within the form factor of the existing board, within the constraints of the existing external user interface (one button, 9 LEDs), and still have some way to configure for more advanced access and usage is probably going to be harder than it sounds. A WiFi of Bluetooth module is going to need a way to be programmed.

I personally was thinking about using a microSD card with a configuration file and a PC/web-based UI for creating the config file to configure the WiFi module to connect to the network. A microSD slot on the outside edge of the board would be pretty unobtrusive. Could also use it for local logging and such, or even firmware updates. The relevant configuration options could be loaded into the micro controller EEPROM(s) for operation without a mircoSD card installed once configured. Something like 5 taps and a long hold on the external Reset button could tell the unit to reload the configuration file.

I also want to keep Tesla's four DIP switches for the new board for a "hard-wired" installer configured max current setting that can not be overridden by the software/firmware/UI/etc.

OpenEVSE's circuit may be the basis for the J1772 stuff in my board design, but I'll basically just use it for that and then expose what I need from it, probably via a serial link, to another microcontroller on the board for everything else. Having a dedicated chip that can handle the crucial stuff on its own if needed (ie, original functionality) is probably a sane design idea anyway.

My completely alternative plan for this would be to simply leave the existing board in place and cram a smaller board in with it that just sits between the existing board and the pilot/proximity lines and possibly the external LED board (just for fun). Let Tesla's board handle all of the hard stuff and just modify the pilot signal as desired. This is definitely the quick and dirty way out and I could probably have a prototype of this working in a couple of days if I went this route.

However, since a J1772 EVSE isn't all that complicated it makes sense to just make a whole new board.

I'd also like to do things like have the low level GFCI circuit have direct control of the contactor driver at the board level independent of the microcontroller if possible. Right now if there is a ground fault OpenEVSE's design relies on the microcontroller to open the contactor. I'd prefer safety functions be independent of firmware when possible and allow the GFCI circuit to override the microcontroller's output to the contactor driver circuit.

Overall it just seems like a very simple project to start from scratch since all of the difficult stuff (hardware) pretty much needs to be done from scratch anyway. The software is the easy part.

My thoughts at the moment are to design the replacement HPWC board like this:


  • Microcontroller handling all J1772 functions (probably 8-bit AVR)
    • Possibly OpenEVSE
    • GFCI circuit hardened against potential firmware issues
    • Able to operate the charging functions independent of any additional functionality when needed or as fallback
    • Utilizes the 4 dip switches for max possible current for the pilot signal
    • Should be firmware that will basically never need to be changed
    • Properly powers the door-popper in the charge handle



  • Microcontroller for advanced functionality (probably 32-bit AVR or similar)
    • Controls front LEDs and 'Reset" button
    • Communicates with the above J1772 microcontroller for setting pilot current and "on/off" of charging
    • AC Ammeter for current monitoring on the AC output lines to the car
    • AC Volt meter for local voltage monitoring
    • microSD reader for configuration and future software features
    • Possibly small buzzer speaker for audio cues
    • WiFi
    • Possibly Ethernet if space permits
    • Ability to cooperate with other WiFi or Ethernet connected chargers with configurable behavior independent of an external controller
    • Ability to utilize
    • Local and remote usage/date logging
    • Web Interface
    • More




 
Hi wk057

I really like your projects!

I developed Smart EVSE a while ago, for dynamically changing the charging current, based on what's used in the house.
It shoudn't be to hard to implement support for Solar Power, actually that it still on my to-do list.

project is here:
SmartEVSE/smartevse · GitHub

also some pictures of the installed module here:
Smart EVSE | Open Source EV charging


It communicates with a sensorbox over RS485. The sensorbox does the actual measurements of the current (on three phases)
My solar inverter (from SMA) also uses the same RS485 connection for status/logging data.
 
However, I think it would be a stretch to think that at any point in time the checksum of the firmware on the board would come into question. I'm actually kind of doubtful it'd be required to release such a thing in the first place. And never in the history of the world will an inspector ever think they would need to check a firmware checksum... lol.

I was not refering to an inspector. A checksum for the firmware has to be provided to UL for certification. The firmware has to comply with UL1998, which requires an extensive documentation and testimg procidure. Documentation has to prove that the firmware with the validated checksum has complied and passed all testing. To recieve UL listing the control board, contactor and firmware checksum all have to match. A change in any of the 3 requires re-certification.

My point was any modification will invalidate the UL listing which also kills NEC complieance due to the clause in 625 that requires the equiptment to be listed by a NRTL.

- - - Updated - - -

I think the existing OpenEVSE boards are also too wide... the original board is not even as wide as the height of a credit card.

Software wise, I just don't like Arduino for production projects... *shrugs* ... Last I checked OpenEVSE was Arduino based. I'd prefer a stripped down C version, personally.

Form factor wise, definitely need a custom board.

OpenEVSE boards are tiny 55mm (2.2") x 45mm (1.75") x 20mm (1"), it is smaller than a credit card. If fact the longest side is the same length as the shortest side of a credit card.

OpenEVSE is written in C, it can be compiled in the Arduino IDE but it can also be compiled with a make file in avr-gcc. There is also alternate firmware called "noSpark" which is native C++11.

- - - Updated - - -

I'd also like to do things like have the low level GFCI circuit have direct control of the contactor driver at the board level independent of the microcontroller if possible. Right now if there is a ground fault OpenEVSE's design relies on the microcontroller to open the contactor. I'd prefer safety functions be independent of firmware when possible and allow the GFCI circuit to override the microcontroller's output to the contactor driver circuit.

OpenEVSE GFCI uses an auto supervisory circuit which is compliant with UL requirements. On boot OpenEVSE generates a fault to test GFCI if it passes OpenEVSE continues the boot. During operation OpenEVSE re-tests the GFCI every time before the contactors are closed. If there is a GFCI fault OpenEVSE will not continue until the GFCI passes the self test. Once the self test passes OpenEVSE will rerty. If an immediate fault is detected the EVSE is locked out.
 
Last edited:
OpenEVSE boards are tiny 55mm (2.2") x 45mm (1.75") x 20mm (1") Hole , it is smaller than a credit card. If fact the longest side is the same length as the shortest side of a credit card.

First, thanks for your work on OpenEVSE. It is certainly appreciated by myself and many. :)

The widest part of the HPWC board is 1.9", so I suppose an OpenEVSE board would fit in the right orientation and position in the case. The original board has some tapers and cuts, which bring it to as small as 1" near the ends. It is about 11" long though.

That said, definitely will *not* be using an OpenEVSE board as it sits (the 55x45x20mm board you mentioned) in the final version. Possibly for prototyping simplicity if I go that route. I might copy the layout of that board, or a new layout based on it, and place it on a section of the new HPWC-sized board for the J1772 stuff, but my final solution will be one complete board sized the same as the original HPWC board with connections to external components in the same place for swapping ease.

OpenEVSE is written in C, it can be compiled in the Arduino IDE but it can also be compiled with a make file in avr-gcc. There is also alternate firmware called "noSpark" which is native C++11.

Definitely like staying away from C++ for small embedded stuff, personally. Too much potential for disaster there. I actually think C is even a little too high level for an 8-bit microcontroller and prefer ASM... but, C is fine and I use it.

When I had last done anything with OpenEVSE was ~3 years ago when I built the J1772 16A EVSE for my Chevy Volt. At the time everything I saw used Arduino libraries and such and had Arduino IDE related files. While I may just be stubborn on this, I just don't like Arduino for production projects. For prototyping I think it's fine, but for something I'm going to have wired up in my garage commanding 20kW of power... no thanks.

I'll investigate further later. As mentioned, I'm not against using OpenEVSE if it fits the bill. It very well may, I'm just not at the point in this project where I'm looking to actually dive in on that part yet.

OpenEVSE GFCI uses an auto supervisory circuit which is compliant with UL requirements. On boot OpenEVSE generates a fault to test GFCI if it passes OpenEVSE continues the boot. During operation OpenEVSE re-tests the GFCI every time before the contactors are closed. If there is a GFCI fault OpenEVSE will not continue until the GFCI passes the self test. Once the self test passes OpenEVSE will rerty. If an immediate fault is detected the EVSE is locked out.

All of this still relies on the firmware, which is fine. I just was thinking out loud that an added plus would be that the GFCI tripping being able to open the contactor on it's own, without the microcontroller's help, would be an added redundancy at the expense of some very cheap additional components.


On a side note, I'm actually curious how steep field listing would be for a custom EVSE.
 
Last edited:
I think it would be a mistake to NOT use OpenEVSE, since it's very well developed/supported, honestly, why re-invent the wheel, the one we have is very round and well developed.

I think it would be great to have another talented developer contributing to OpenEVSE. I think it is a shame there are so many similar but parallel projects out there. I think if we all worked together we would advance charging station capabilities faster.

- - - Updated - - -

All of this still relies on the firmware, which is fine. I just was thinking out loud that an added plus would be that the GFCI tripping being able to open the contactor on it's own, without the microcontroller's help, would be an added redundancy at the expense of some very cheap additional components.

The earliest version of the OpenEVSE boards (not pubicly released), had a logic controlled GFCI which used 4 logic gates to create a flip flop and set reset hardware circuits. It worked fine but added a lot of complexity to the layout. The hardware logic did not add any redundancy to the circuit, as the dependancy was just moved elsewhere. The hardware based GFCI was reliant on 4 components instead of just 1 but... it does not rely on firmware at all. I can dig up the schematics if you would like them. In the end OpenEVSE went with simplisity.