Sorting by

×

Vehicle 12V Battery Monitoring with ESP8266 and ESPHome

Changes

2022-10-19 V1.1 Addition of some graphs showing voltage measurements
2023-05-27 V1.2 Minor changes to the ESPHome yaml & notes… (I built a second one for another vehicle)

Summary

Using the Analogue input on an ESP8266 and voltage divider to monitor the status of a 12V battery in a car.

Features

  • A calibrated measure of the battery, which could be up to 15Vdc
  • Sending regular reports to MQTT (say, every 10 mins)
  • Use low power (and deep sleep mode where possible) to avoid draining the battery further
  • Easy removal/install
  • A decent Wifi Range

Method

I have a Nissan Leaf, and they seem poorly designed to keep the 12V battery topped up. They charge when the car is charging (i.e. the drive battery is on charge) and also when you are actually moving. Obviously this should be better than ICE vehicles, as they also only when the engine is on.

Leaf 12V batteries seem to quite commonly be the cause of issues, and especially when they have been sitting unused for a while. It is sad really that they have to keep the HV and 12V system completely separated, as there are times when the 12V battery (around 1kWh of storage) can go flat even though the car main drive battery (24kWh) is full. This is no doubt similar to other EVs though, and maybe newer cars just charge the 12V quicker when charging is possible.

Tiny Solar trickle charger on the G and X models, on the spoiler in front of the High Brake light.

X and G models of leaf have a small solar panel <5W on the rear spoiler which may help, but it is only a tiny amount of current, so who knows (mine doesn’t have one).

I did experiment with changing the 12V battery to a Lithium setup (documented separately), but in the mean time I wanted a way to monitor the battery Voltage, and my home automation could notify me if it drops too low.

Using this simple setup below, I can get an accurate reading and a graph of voltage, but ONLY if the car is at home and in WiFi range. Normally I’d put potential improvements at the bottom of my project info, but I’ll list them here and maybe will try and tick some off in the future.

Improvements to be done

A Hall effect CT
  1. Measure current in and out of the battery.
    I have bought a range of current measuring sensors, and something like the hall effect CT is what I’ll be using. 100A range would likely do, and it gives 0-10V out. I ordered a few options to play with.
    Using an ESP8266 is a bit of a pain for trying to do this as it only has one Analog input though. An esp32 would probably be a better idea, or maybe an i2c adaptor. It would be great to see just how much current is flowing in and out when driving and charging.
  2. Measure 24/7 when the car is not at home
    Having SD storage and logging to that would be a good idea. It would be nice to be able to push historic data to influx DB (haven’t investigated this… and not sure whether time series databases like this idea). Doing this would mean going away from something simple like core ESPHome though… but there have been a couple of feature requests and discussions about having ESPHome log to SD.
    It might be nice to see if the car can keep up with charging the 12V battery when other systems are on.
  3. Have a method of complete/automatic disconnection
    It would be nice to have the device disconnect itself completely if the voltage was too low – and eliminate all loads when needed. Probably not really necessary as it draws very little in sleep mode at <10mA, but it could be done by having the device switch on with the car ACC circuit) and latch until the voltage dropped below a set level. Mosfet control probably best, but it would need +ve switching.

Hardware

I used a Wemos D1 Mini Pro (or a clone of it..) and an off the shelf ‘power shield’ to power it from the 12V. I wanted the Pro due to the aerial connector (don’t forget to move the 0 Ohm resistor bridge to be able to use the attached aerial). Note that some of my D1 Minis wouldn’t even get a wifi signal without the external aerial, I suspect due to the switching of the power supply components on the power shield.

I just used some leads with crocodile clips for the power so I could just clip it on my battery (and to a close grounded bolt) and it could be removed when no longer needed.

Voltage Divider

On the back of the power shield, I soldered up some resistors in a voltage divider arrangement, and connected it up to the 12V input (you can see in a photo that I went though the hole in the power board). You can buy a ‘voltage divider’ sensor, but a couple of resistors (plus some screw terminals) is all that is on it. I connected the divider from the +ve and GND inputs to the Analog input pin on the ESP8266.

Something in the order of 30k Ohms and 7.5k Ohms would be about right, but I just used what I had that was close (you can calibrate the input later) – not pretty as I added a couple to tweak the overall values.

These values should get you a safe range from 0-16V. The ESP requires maximum of 1V on its A input, but the Wemos has another voltage divider to get the required 1V from its 3.3V supply range (so the max allowed to the Wemos Analogue pin is 3.3V)

A voltage divider with 30k and 7.5k would give you 3.3V on the Wemos input, from about 16.5V input which should be fine.

Deep Sleep Hardware

In order to get deep sleep capability, you also need to connect the “Wake” pin (GPIO16 or D0 on the D1 Mini I used) with the “Reset Pin” RST. You can see this loop of green wire on my board. That’s all you need to do hardware-wise.

Nissan Leaf Installation

I wrapped the board in some wide heatshrink and some tape to make it relatively water resistant, and mounted it in the front left cowl area in front of the windscreen. This is nice and close to the battery and there is a lift out piece of plastic above the shock tower mounts (I got some shock tower covers at the same time, as this is a common place that you get rust in a leaf).

I also wanted to be sure the aerial wasn’t hidden away under metal, as it wasn’t that close to my nearest WiFi access point when parked in its usual spot outside.

The plastic piece that I mounted the aerial in… and you can just see the tip of the aerial sticking out above the bonnet. (yes I should have cleaned away a few leaves before taking photos)

ESPHome Configuration

There are plenty of places that go over ESPHome setup, but a summary of my configuration is:

  • It provides a Voltage value sensor, which I calibrated on the bench with an adjustable power supply
  • It provides a ‘Wifi Level’ sensor so I can see if it has good signal
  • it runs for 20 seconds, then deep sleeps for 10 Minutes. This is plenty of time to start up and send values.
  • It uses a static IP, so there is no time spend asking for an IP address (quicker to send sensor values)
  • It allows me to push a value to my MQTT server to turn OFF the sleep mode. Use the retain flag when you publish to give the ESP time to start up and pull these values. This is needed to do updates etc (you need a way to prevent it sleeping).
    In my case I write values to
    commands/leafbat2/deepsleepon and commands/leafbat2/deepsleepoff
  • It has some linear calibration values (I set these with trial and error on the bench)

Note that I use a secrets file for the personalized values. and the below is the esphome-leafbat2.yaml file, the rest of which is pretty well commented.

#############################################
# Common
#############################################  
substitutions:
  devicename: esp-leafbat2
  nice_devicename: "Leaf Battery Monitor 2"


#############################################
# ESPHome
#############################################  
esphome:
  name: $devicename

########################################    
# Specific board for ESPHome device
########################################    
esp8266:
  board: d1_mini

#############################################    
# ESPHome Logging Enable
#############################################  
logger:

########################################    
# Enable the Home Assistant API
########################################  
api:
  encryption:
    key: !secret esp-leafbat2_api_key

########################################    
# Enable Over the Air Update Capability
# Safe mode will detect boot loops
########################################  
ota:
  safe_mode: true
  password: !secret esp-leafbat2_ota_pass

########################################    
# Use Wifi 
# (credentials are in secrets file)
########################################  
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  # Details for fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp-Leafbat2 Fallback Hotspot"
    password: !secret fallback_ap_password
  # Static IP (for lower power/quicker on time)
  manual_ip:
    static_ip: !secret esp-leafbat2_static_ip
    gateway: !secret esp-leafbat2_gateway
    subnet: !secret esp-leafbat2_subnet

#############################################    
# Fallback captive portal
#############################################   
captive_portal:

########################################    
# Web Portal for display and monitoring
########################################   
web_server:
  port: 80
  auth:
    username: !secret web_server_username
    password: !secret web_server_password
    
########################################    
# MQTT Monitoring
########################################   
mqtt:
  broker: !secret mqtt_server
  topic_prefix: esphome/esp-leafbat2
  username: !secret mqtt_username
  password: !secret mqtt_password

  # A way to prevent deep sleep using MQTT command
  on_message:
    - topic: commands/leafbat2/deepsleepoff
      payload: 'ON'
      then:
        - deep_sleep.prevent: deep_sleep_1
    - topic: commands/leafbat2/deepsleepon
      payload: 'ON'
      then:
        - deep_sleep.enter: deep_sleep_1

########################################    
# Deep Sleep
########################################   
deep_sleep:
  run_duration: 20s
  sleep_duration: 10min
  id: deep_sleep_1
  
#############################################  
#############################################
# MAIN SENSORS
#############################################
#############################################  
sensor:
  # Quality of Wifi in dBm
  - platform: wifi_signal
    name: "WiFi Signal"
    update_interval: 10s
    retain: true
  # Analog sensor for voltage reading (A0)
  - platform: adc
    pin: A0
    name: "Battery Voltage"
    update_interval: 10s
    retain: true
    filters:
      # Map 0.0 (from sensor) to 0.0 (true value)
      - calibrate_linear:
        - 0.41 -> 6.00
        - 0.48 -> 7.00
        - 0.54 -> 8.00
        - 0.61 -> 9.00
        - 0.68 -> 10.00
        - 0.75 -> 11.00
        - 0.81 -> 12.00
        - 0.88 -> 13.00
        - 0.94 -> 13.99
        - 0.99 -> 14.70

Graphed Results (Influxdb and Grafana)

This is a graph showing charging power (in green, in Watts), which I was already monitoring elsewhere plus the overlay of 12V battery voltage and Wifi Strength from ESPHome.

There are sometimes the odd gap in the 10min cycle (eg Wifi Strength missed) and large gaps are when the car is away from home. This graph is since I have put a Lithium 12V battery in place, which should be fully charged to about 13.2V.

Below is the sort of measurement I was getting with the lead acid battery, before I replaced it. Interestingly, the car would ‘mostly’ start and drive when the battery was hovering around 10.5V. Occasionally it wouldn’t though, requiring us to carry around a lithium jump pack. Even with the traction battery charging, there wouldn’t be enough to get the 12V up to spec (it was pretty stuffed by this stage)

The car also did some weird things with a low 12V battery, including brake issues on startup… sometimes you’d start the car and put your foot on the brake and there would be none! Obviously the brake booster needed a but more Voltage to perform. After a few seconds it would kick back in.

The rapid rise again at just before 7am was when it was put on a mains fast charger.

Share

7 Responses

  1. Thanks, great project!
    I’d like to build one for my Kia Soul EV (same brake issues) and probably even for my lawnmower tractor

  2. Hi,
    I would like to build this myself. Which hall effect CT did you use? Do you have a link?

    Cheers

  3. Hi Zorruno,

    I have built one using a D1 mini with 1220k ohm and 100k ohm to measure the car battery. The data is sent to HA API at home. It works perfectly with the deep sleep. However, I am facing a problem when I drive my car to another place not within the intranet, the esphome node would continuously search the WIFI and not going to deepsleep. Do you have such kind of problem? Thanks

    • hmm, I don’t think mine does that sorry – it goes into deep sleep without fail as far as I’m aware. If it can’t find a recognised Wifi AP it still sleeps – I have tested it using my phone’s hotspot.

Leave a Reply

Your email address will not be published. Required fields are marked *

Post comment