>>> Join Us in the Fight Against Air Pollution

AirGradient Forum

I2C bus freezes ony the presoldered Pro Kit

I am using the presoldered version on PCB v3.3 with an additional SGP41 sensor from the airgradient shop. Unfortunately, the I2C bus hangs after a while (I haven’t reliably gotten a reproducable time frame, yet). This leads to the SHT, SGP and SSD1306 to stop working altogether.

So I tried adding a reboot cycle every 24 hours, but that won’t recover the I2C bus once it hangs. Only physical power cycling allows for the I2C bus to be available once again.

I was under the impression that the presoldered kit in combination with the “official” SGP addon would be constructed in a way (line lengths, pullups, clock speeds, voltages) so this won’t happen? Now I’m not so sure anymore, so what could I test in order to make this work consistently?

Those are the relevant parts of my esphome config yaml:

# Airgradient Pro presoldered edition on D1 mini v4.0.0 with usb c port
substitutions:
  devicename: "airgradient-pro"
  upper_devicename: "Airgradient Pro"

esphome:
  name: "${devicename}"
  # Automatically add the mac address to the name
  # so you can use a single firmware for all devices
  # name_add_mac_suffix: true
  platform: ESP8266
  board: d1_mini

# Enable logging
logger:
  #level: INFO
  #level: DEBUG
  level: VERY_VERBOSE

display:
  - platform: ssd1306_i2c
    id: oled
    address: 0x3c
    rotation: 180°
    model: "SH1106 128x64"
    update_interval: 10s
    setup_priority: -100
    # contrast: 30%
    pages:
      - id: display_all
        lambda: |-
          int i=0;
          if(id(temp).state != id(temp).state) {} else {it.printf(0, i, id(opensans), "Temperature: %0.2f C", id(temp).state);i=i+10;}
          if(id(hum).state != id(hum).state) {} else {it.printf(0, i, id(opensans), "Humidity: %0.2f %%", id(hum).state);i=i+10;}
          if(id(pm10).state != id(pm10).state) {} else {it.printf(0, i, id(opensans), "PM1/2.5/10: %.f/%.f/%.f", id(pm10).state, id(pm25).state, id(pm100).state);i=i+10;}
          if(id(co2).state != id(co2).state) {} else {it.printf(0, i, id(opensans), "CO2: %.f ppm", id(co2).state);i=i+10;}
          if(id(voc).state != id(voc).state) {} else {it.printf(0, i, id(opensans), "VOC Index: %.f", id(voc).state);i=i+10;}
          if(id(nox).state != id(nox).state) {} else {it.printf(0, i, id(opensans), "NOx Index: %.f", id(nox).state);i=i+10;}

time:
  - platform: sntp
    id: sntp_time
    timezone: UTC+1
    servers:
      - 192.168.0.1
    on_time:
      - cron: '0 59 3 * * *'
        then:
          switch.toggle: reboot

interval:
  - interval: 10s
    then:
      - component.update: oled

i2c:
  sda: D2
  scl: D1
  #frequency: 10kHz
  setup_priority: -100

sensor:
  - platform: sht3xd
    temperature:
      id: temp
      name: ${upper_devicename} Temperature
    humidity:
      id: hum
      name: ${upper_devicename} Humidity
    address: 0x44
    update_interval: 10s

  - platform: sgp4x
    voc:
      id: voc
      name: "VOC Index"
    nox:
      id: nox
      name: "NOx Index"
    compensation:
      humidity_source: hum
      temperature_source: temp
    address: 0x59

switch:
  - platform: restart
    name: "Restart"
    id: reboot

font:
  - file: "monofont.ttf"
    id: opensans
    size: 12

Did you try with a different power supply? We have experienced some of these issues and they disappeared with a more stable power supply.

I am using a 3100mA power supply, and since you suggest that 2400mA are sufficient I would assume this isn’t the cause of this issue?

Anyways, I will be monitoring the logs until I2C breaks again, so I might get a more precise clue about what’s happening, although I think it will just show something like:

[10:35:04][I][i2c.arduino:068]: Results from i2c bus scan:
[10:35:04][E][i2c.arduino:076]: Unknown error at address 0x08
[...]

After testing another power supply for around one week, the i2c bus freezes regardless:

[13:26:29][C][i2c.arduino:052]: I2C Bus:
[13:26:29][C][i2c.arduino:053]:   SDA Pin: GPIO4
[13:26:29][C][i2c.arduino:054]:   SCL Pin: GPIO5
[13:26:29][C][i2c.arduino:055]:   Frequency: 50000 Hz
[13:26:29][C][i2c.arduino:064]:   Recovery: failed, SDA is held low on the bus
[13:26:29][I][i2c.arduino:068]: Results from i2c bus scan:
[13:26:29][E][i2c.arduino:076]: Unknown error at address 0x08
[...]

Any idea on how to approach this issue? I took out the i2c components and reinserted them to make sure their contacts are ok, but other than that I am at a loss.

The SDA shouldnt be held low so that causes an issue with i2c. That could be a short between GPIO4 and ground or a possibly faulty sensor. Try removing all sensors and check if this error comes again in your log. Otherwise add sensors till the error does popup and report back.

After a couple of more weeks of testing I found out that the Airgradient Unit works more reliably when I power the D1 directly instead of plugging the USB-C cable into the PCB. I think this implies some imperfections on the PCB quality, which is why I reached out to Airgradient, asking for a replacement PCB. Unfortunately, I never received an answer, so I don’t know if this will ever get resolved…

What speed are you running your I2C bus at? You should run it at close to standard speed (100kHz).

Is this ESPHome? You should reproduce this with stock AirGradient firmware compiled using the just-released ESP8266 Arduino v3.1.2 library to eliminate all other factors.

I was having screen freezes every few days at random. The screen would also show some white blocks. I did try the frequency change to 100kHz, but it didn’t help.

I finally changed the power supply and it’s now stable. It’s been about 7 days without a freeze.

Approximately 5.15v was creating the screen freeze and 5.35v is stable.

Spoke too soon. Just froze.
Back to troubleshooting.