Niall’s virtual diary archives – Friday 22 October 2022

by . Last updated .

Friday 21 October 2022: 23:43. Around a year ago in my series on my future house build, I wrote about a Devantech ethernet relay board, then I went on to review the state of the market as of Q3 2021 comparing various microcontrollers and microcomputers, and I decided at the time to plump for a mixture of STM32F4 and Raspberry Pi Zero for my house automation. I made a custom Home Assistant integration for the Devantech board (it and the cove lighting continue to work perfectly, incidentally, I type to you now under said cove lighting), and all seemed well until August just gone when I mentioned that instead of all that I had bought fifty ESP32 boards, with a promise of a future post about them. This is that post!

Here is the board I dropped about a grand upon buying fifty of them plus convenience breakouts:

You may remember that a year ago I was not keen on the ESP32, as it is markedly inferior to the STM32F4 in terms of quality and quirks, albeit with bucket loads more features. So why change my mind now?

First reason is cost: when you’re spending a grand of money, saving a third of it is a good move. In my Q3 2021 review post, I reckoned a STM32F4 could be had for €12 inc VAT and a Raspberry Pi for €20 inc VAT, but that didn’t include the PoE adapter which probably can’t be had for less than €10 inc VAT. The Olimex ESP32-POE-IND (with industrial grade components) is under €15 inc VAT if you buy fifty of them, which is nearly one third cheaper.

The second reason is convenience: These boards have already wired a bunch of stuff together for me into a single PCB, which saves me having to wire bits together. Its premounted UEXT connector exposes the UART, I2C and SPI pins plus 3.3v power which will save me soldering in i/o pins in many cases (I also bought a bunch of UEXT daisy chain boards, they were very cheap and let me use dupont wiring instead of hand soldering and crimping). They’re correspondingly more compact, which means I can use smaller much cheaper waterproof enclosures, saving even more money.

The third reason is that for all the things the ESP32 is bad at e.g. Analogue to Digital conversion, or keeping accurate time – I can cheaply buy an I2C peripheral which does have quality ADCs, or quality time. And it’s only rarely I’ll need to do that in any case as the majority of those boards will go on PWM control of RGBWW LED strips. The PWM in the ESP32 isn’t as good as the one in the STM32F4 or the Raspberry Pi, but it can still push 15kHz, which is plenty. One of these boards can PWM up to three LED strips (four channels each, therefore twelve I/Os) if I solder on the i/o headers, but something very attractive is that the UEXT header alone is sufficient to drive two LED strips no soldering needed.

Finally, the ESP32 alone has rather the killer app for my use cases: https://esphome.io/. But more on that shortly.

The Olimex ESP32-POE board

Olimex are a Bulgarian manufacturer of IoT and embedded boards, and have been around for a few decades now so they’re well established. I believe their ESP32-POE board is their most popular by some margin, for some reason nobody else makes a PoE powered ESP32 board for under €31 (the LilyGo TTGO) and more usually €65 (the WESP32; the official Espressif dev board). The nearest cheap equivalent is the WT32-ETH01 which combines an ESP32 with Ethernet, but you won’t get one for under €13 inc VAT, and it doesn’t include PoE. So no wonder that the Olimex board is so popular!

For under €15 inc VAT the feature set is pretty good. You get a 100 Mbit claiming Ethernet port which can draw up to four watts of power from PoE. If you need more, there is a micro USB port through which you can supply up to ten watts. There is a lithium battery connection with a 100 mA charge circuit, this will accept a 3.7v LiPo battery. If the battery is fitted and charged, power can be removed and the board will keep running, however only 3.3v TTL is supplied, the 5v power rail disappears. So you need to make sure any relays you use are fully 3.3v based if you want them to work on battery. Finally, you can connect a SD card if you need local storage, though for me ethernet is where data ought to be stored.

The ESP32 running full belt minus wifi at 240 Mhz will consume about 50 mA, peripherals can’t draw more than 250 mA if on PoE, and perhaps less than that if on battery. An idling ESP32 might draw 4 mA, therefore a 3000 mAh battery could run the device for between 30 and 750 hours (one month) assuming board power overhead of 20-50 mA. If you can put the device into deep sleep, that draws only 0.1 mA, which could be up to 30,000 hours (or over three years)!

I’ve been running mine for several months now, and it has been reliable:

As you may be able to read from its little OLED display, it has three sensors, two are NDIR CO2 sensors and one is a IAQ + Humidity + Pressure sensor. Every few seconds the readings are posted by the board via REST to an Influx DB over the network, and it slowly pulses the LED from fully on to off by PWM. This has been running for a long time now on a ESPHome built firmware, it looks to me as reliable as the Devantech board. You may also note the lithium battery to the left, I have a 3000 mAh unit in there which I reckoned to be the best bang for the buck in terms of capacity to price ratio. Here is Grafana rendering the last week of InfluxDB records:

I guess my only real issue with this board is how hot its PoE DC to 5v circuit runs:

Yup, about 80 C. That’s well below the temperature rating of the components – especially the industrial grade ones which mine are – and in fairness this the eighth revision of the board is the least hot of any of the preceding revisions. Still, it kinda feels like wasted power consumption for no good reason other than reducing cost.

Thanks to this being an open source hardware design, I discovered that the DC-DC stepdown chip is the TX4138 whose datasheet can be found at https://datasheet.lcsc.com/lcsc/1811141153_XDS-TX4138_C329267.pdf. It claims an 84% efficiency. Assuming it’s a linear regulator taking the 5v to 3.3v and therefore burns as heat 33% of the current the ESP32 uses, a 100 mA draw by the ESP32 at 3.3v (one third of a watt) would be 133 mA of 5v, or two thirds of a watt. That turns into a minimum of 0.8 watts of PoE power, which is a best case efficiency of 41%.

Olimex seem to think it draws around a watt of PoE power if you don’t attach energy hungry peripherals, maybe 1.5 watts if the wifi is maxed out. I guess that therefore is +50 watts of constant background heating in my home.

BTW, one watt at €0.30 per kWh is €2.63 per year, so if the board costing €31 were ideally power efficient, it would take 9.1 years to pay back the added cost over the board I chose. I very much doubt that that the €31 board is more efficient however, it looks to me to also use linear converters. The WESP32 specifically mentions in its docs that when running off PoE it will get hot, and I couldn’t find any information on the heat output of the official Espressif dev board. In any case, high efficiency power conversion costs money, and the repay time is unlikely to be worth it for such low wattages.

ESPHome

In my Q3 2021 survey I spoke a lot about ecosystem depth and breadth greatly favouring the STM32 over the ESP32, after claiming I had done a lot of research. Unfortunately I somehow missed the elephant in the room which is the amazing and astonishingly capable ESPHome which I assume at the time I didn’t realise just how amazing it is. And, a game changer in fact, as it made me go all in on ESP32.

ESPHome comes across initially as a dumb microcontroller convenience firmware for Home Assistant, and I think because of that I dismissed it from further investigation at the time. That was a mistake, thankfully realised in time. ESPHome is in fact so capable that you don’t need Home Assistant at all, you can create firmwares which work with other ESPHome firmwares to solve a problem without any central server to coordinate things. That is a killer application for my use case. Furthermore, you can bulk orchestrate the upgrading of the firmwares of many devices chosen by category with zero effort over ethernet, which is another killer application for my use case. Finally, while ESPHome has a limited selection of hardware with direct support, apart from a few mildly painful omissions it does have support for a wide enough range of hardware that so long as you only buy peripherals it supports, it ‘just works’ with very little added effort.

Here is the ESPHome configuration file for the board above. You feed this to esphome run and it will compile an ESP32 firmware for you and automatically write it to the board over ethernet.

esphome:
  name: esp32-poe
  platform: ESP32
  board: esp32-poe
  on_boot:
    - light.turn_on: led1
        
globals:
  - id: brightness
    type: float
    initial_value: '1.0f'
  - id: increment
    type: float
    initial_value: '0.01'

influxdb:
  host: 192.168.x.x
  database: HomeSensors
  username: x
  password: x

interval:
  - interval: 100ms
    then:
      - light.turn_on:
          id: led1
          transition_length: 0ms
          brightness: !lambda |-
            if(id(brightness) <= .0f) {
              id(brightness) = .0f;
              id(increment) = -id(increment);
            } else if(id(brightness) >= 1.0f) {
              id(brightness) = 1.0f;
              id(increment) = -id(increment);
            }
            id(brightness) += id(increment);
            return id(brightness);

ethernet:
  type: LAN8720
  mdc_pin: GPIO23
  mdio_pin: GPIO18
  clk_mode: GPIO17_OUT
  phy_addr: 0
  power_pin: GPIO12
  domain: .nedland
  manual_ip:
    static_ip: 192.168.x.x
    gateway: 192.168.x.x
    subnet: 255.255.255.0
  use_address: 192.168.x.x

uart:
  # Must use UART1 as UART0 is used by the logger!
  rx_pin:
    number: GPIO36
  tx_pin:
    number: GPIO4
  baud_rate: 9600
  id: uart1
  debug:

i2c:
  sda: SDA
  scl: SCL
  scan: true
  frequency: 400kHz

#spi:
#  clk_pin: GPIO14
#  mosi_pin: MOSI
#  miso_pin: MISO
  
binary_sensor:
  - platform: gpio
    pin:
      number: BUTTON
      inverted: true
    name: "Button 1"
  
  
# LED
output:
  - platform: ledc
    pin: GPIO33
    id: gpio_33
    frequency: "14648Hz"  # 80 Mhz clock so 4096 steps

light:
  - platform: monochromatic
    output: gpio_33
    id: led1
    name: "LED"

# CO2 sensor
# Temperature, pressure, humidity sensor
bme680_bsec:
  address: 0x77

sensor:
  - platform: adc
    pin: GPIO35
    name: "Battery voltage"
  - platform: adc
    pin: GPIO39
    name: "External voltage"
  - platform: mhz19
    co2:
      name: "MH-Z19 CO2 Value"
      id: co_1
    temperature:
      name: "MH-Z19 Temperature"
    update_interval: 30s
    uart_id: uart1
    automatic_baseline_calibration: true
  - platform: scd30
    co2:
      name: "SCD30 CO2 Value"
      id: co_2
    temperature:
      name: "SCD30 Temperature"
      id: temp_2
    humidity:
      name: "SCD30 Humidity"
      id: hum_2
    update_interval: 30s
    address: 0x61
    automatic_self_calibration: true
#  - platform: bme680
#    i2c_id: i2c0
#    temperature:
#      name: "BME680 Temperature"
#      oversampling: 16x
#    pressure:
#      name: "BME680 Pressure"
#    humidity:
#      name: "BME680 Humidity"
#    gas_resistance:
#      name: "BME680 Gas Resistance"
#    address: 0x77
#    update_interval: 5s
  - platform: bme680_bsec
    temperature:
      name: "BME680 Temperature"
      id: temp_1
    pressure:
      name: "BME680 Pressure"
      id: press_1
      #on_update:
      #  write scd30.ambient_pressure_compensation
    humidity:
      name: "BME680 Humidity"
      id: hum_1
    iaq:
      name: "BME680 IAQ"
      id: iaq_1
    co2_equivalent:
      name: "BME680 CO2 Equivalent"
    breath_voc_equivalent:
      name: "BME680 Breath VOC Equivalent"
#  - platform: ltr390
#    uv:
#      name: "LTR390 UV Index"
#    light:
#      name: "LTR390 Light"
#    address: 0x23

font:
  - file: "gfonts://Roboto"
    id: roboto
    size: 12
    
display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    rotation: 180

    lambda: |-
      it.fill(Color::BLACK);
      it.printf(0, 0, id(roboto), Color(255,255,255), TextAlign::TOP_LEFT, "CO2 A: %.0f B: %.0f", id(co_1).state, id(co_2).state);    
      it.printf(0, 13, id(roboto), Color(255,255,255), TextAlign::TOP_LEFT, "Tmp A: %.2f B: %.2f", id(temp_1).state, id(temp_2).state);    
      it.printf(0, 26, id(roboto), Color(255,255,255), TextAlign::TOP_LEFT, "Hum A: %.2f B: %.2f", id(hum_1).state, id(hum_2).state);    
      it.printf(0, 39, id(roboto), Color(255,255,255), TextAlign::TOP_LEFT, "IAQ: %.2f %%", (id(iaq_1).state/5.0f));    
      it.printf(0, 51, id(roboto), Color(255,255,255), TextAlign::TOP_LEFT, "Press: %.0f", id(press_1).state);    
    

# Enable logging
#logger:
#  level: VERBOSE
#  level: VERY_VERBOSE

# Enable Home Assistant API
api:
  password: "xxxx"
  reboot_timeout: 0s

ota:
  password: "xxxx"

# Enable webserver
web_server:
  port: 80

As you can see, it’s basically YAML describing the board and what is connected to it and where. Rather usefully it autogenerates a live web page on a web server served by the board, just like the one I made for the Devantech board:

I haven’t really exercised the support for writing out complex logic much yet – you can easily do stuff such as ‘if humidity exceeds 80%, switch relay on’ – but I shall be doing so when I set up my 12v battery installation. I have bought a small 20w solar panel and a cheap low end 12v solar charger which isn’t very clever, so I will also be adding one of these PoE boards with a lithium battery and an added high quality time and date peripheral over I2C. It will calculate sunrise and sunset from the current date, and physically disconnect the solar charger from the battery during night times to prevent it sucking power out of the battery. I then will have various things hanging off the 12v battery, specifically 24v LED strip lighting and an alarm system so if anybody tries to rob me, I can light the place up and set off loud sirens, and it’ll be completely independent of mains power so even if they disconnect or cut the power lines going into the container, it won’t help them.

Once I have the security system in place I can start filling the shipping container with expensive stuff, currently I can’t take the expensive stuff out there as I can’t risk it – even though the shipping container has a CEN class 4 lock on it (the highest CEN grade is 6, and those locks cost half a grand or more each), and it would take a cutting torch to get in there, the easiest way to rob it is simply to steal the whole container and I have no protection against that until I get my battery powered alarm system installed.

#house




Go back to the archive index Go back to the latest entries

Contact the webmaster: Niall Douglas @ webmaster2<at symbol>nedprod.com (Last updated: 2022-10-21 23:43:10 +0000 UTC)