Pimoroni SCD41 Communication Failed on ESP32

I’m trying to use this breakout board for the SCD41 with an ESP32 running ESPHome, using the built in scd4x platform. While other I2C devices work, I get the message “Communication failed! Is the sensor connected?” with the SCD41. I tried the breakout with a raspberry pi and this python library and it worked without issue. I also tried everything obvious I could think of, like explicitly specifying the address or only trying to measure one parameter. After triple checking my wiring and continuity, I’m pretty stumped. Is there any reason this breakout wouldn’t be compatible with ESP32? I thought any I2C host could talk to any device.

1 Like

Without config & logs nobody can help you…

esphome:
  name: ada-bedroom-air-quality

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:
  password: [redacted]

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Ada-Bedroom-Air-Quality"
    password: [redacted]

captive_portal:

i2c:
  sda: 21
  scl: 22
  scan: true

sensor:
  - platform: scd4x
    co2:
      name: "Ada's Room CO2"
    temperature:
      name: "Ada's Room Temperature"
    humidity:
      name: "Ada's Room Humidity"
    
    
  - platform: sgp40
    name: "Ada's Room VOC"

This is the config I used, pretty much standard. Like I said originally, I tried tweaking various options here but nothing seemed to fix it. The logs are also what you’d expect, all normal except for the communication failed message. Provided here for completeness

[11:35:14][C][wifi:488]: WiFi:
[11:35:14][C][wifi:350]:   Local MAC: [redacted]
[11:35:14][C][wifi:351]:   SSID: [redacted]
[11:35:14][C][wifi:352]:   IP Address: [redacted]
[11:35:14][C][wifi:354]:   BSSID: [redacted]
[11:35:14][C][wifi:355]:   Hostname: 'ada-bedroom-air-quality'
[11:35:14][C][wifi:357]:   Signal strength: -63 dB ▂▄▆█
[11:35:14][C][wifi:361]:   Channel: 3
[11:35:14][C][wifi:362]:   Subnet: 255.255.255.0
[11:35:14][C][wifi:363]:   Gateway: 192.168.0.1
[11:35:14][C][wifi:364]:   DNS1: 192.168.0.1
[11:35:14][C][wifi:365]:   DNS2: 0.0.0.0
[11:35:14][C][logger:233]: Logger:
[11:35:14][C][logger:234]:   Level: DEBUG
[11:35:14][C][logger:235]:   Log Baud Rate: 115200
[11:35:14][C][logger:236]:   Hardware UART: UART0
[11:35:14][C][i2c.arduino:037]: I2C Bus:
[11:35:14][C][i2c.arduino:038]:   SDA Pin: GPIO21
[11:35:14][C][i2c.arduino:039]:   SCL Pin: GPIO22
[11:35:14][C][i2c.arduino:040]:   Frequency: 50000 Hz
[11:35:14][C][i2c.arduino:043]:   Recovery: bus successfully recovered
[11:35:14][C][scd4x:121]: scd4x:
[11:35:14][C][scd4x:122]:   Address: 0x62
[11:35:14][W][scd4x:126]: Communication failed! Is the sensor connected?
[11:35:14][C][scd4x:139]:   Automatic self calibration: OFF
[11:35:14][C][scd4x:144]:   Ambient pressure compensation disabled
[11:35:14][C][scd4x:145]:   Altitude compensation: 0m
[11:35:14][C][scd4x:147]:   Temperature offset: 4.00 °C
[11:35:14][C][scd4x:148]:   Update Interval: 60.0s
[11:35:14][C][scd4x:149]:   CO2 'Ada's Room CO2'
[11:35:14][C][scd4x:149]:     Device Class: 'carbon_dioxide'
[11:35:14][C][scd4x:149]:     State Class: 'measurement'
[11:35:14][C][scd4x:149]:     Unit of Measurement: 'ppm'
[11:35:14][C][scd4x:149]:     Accuracy Decimals: 0
[11:35:14][C][scd4x:149]:     Icon: 'mdi:molecule-co2'
[11:35:14][C][scd4x:150]:   Temperature 'Ada's Room Temperature'
[11:35:14][C][scd4x:150]:     Device Class: 'temperature'
[11:35:14][C][scd4x:150]:     State Class: 'measurement'
[11:35:14][C][scd4x:150]:     Unit of Measurement: '°C'
[11:35:14][C][scd4x:150]:     Accuracy Decimals: 2
[11:35:14][C][scd4x:150]:     Icon: 'mdi:thermometer'
[11:35:14][C][scd4x:151]:   Humidity 'Ada's Room Humidity'
[11:35:14][C][scd4x:151]:     Device Class: 'humidity'
[11:35:14][C][scd4x:151]:     State Class: 'measurement'
[11:35:14][C][scd4x:151]:     Unit of Measurement: '%'
[11:35:14][C][scd4x:151]:     Accuracy Decimals: 2
[11:35:14][C][scd4x:151]:     Icon: 'mdi:water-percent'
[11:35:15][C][sgp40:267]: SGP40:
[11:35:15][C][sgp40:268]:   Address: 0x59
[11:35:15][C][sgp40:269]:   store_baseline: 1
[11:35:15][C][sgp40:281]:   Serial number: 54360397
[11:35:15][C][sgp40:282]:   Minimum Samples: 45.000000
[11:35:15][C][sgp40:284]:   Update Interval: 60.0s
[11:35:15][C][sgp40:291]:   Compensation: No source configured
[11:35:15][C][captive_portal:144]: Captive Portal:
[11:35:15][C][ota:082]: Over-The-Air Updates:
[11:35:15][C][ota:083]:   Address: ada-bedroom-air-quality.local:3232
[11:35:15][C][ota:086]:   Using Password.
[11:35:15][C][api:134]: API Server:
[11:35:15][C][api:135]:   Address: ada-bedroom-air-quality.local:6053
[11:35:15][C][api:139]:   Using noise encryption: NO
[11:35:15][C][mdns:084]: mDNS:
[11:35:15][C][mdns:085]:   Hostname: ada-bedroom-air-quality

The SGP40 works without issue, it’s only the SCD41 module I’m having issues with. Like I said, it works fine with a pi.

I’m missing the log part with the results of the i2c scan something like:

[13:52:12][I][i2c.arduino:054]: Results from i2c bus scan:
[13:52:12][I][i2c.arduino:060]: Found i2c device at address 0x3C

And how did you connect the sensor to the ESP?

The problem seems to have resolved itself. I think there may be an issue with the board I was using, I connected the sensors to an identical esp32 devboard and the SCD41 jumped to life. Alternatively, maybe there was a bad connection I inadvertently fixed in the process, although I could have sworn I checked every connection. Thanks anyway for your time @jsuanet. In case anyone in the future is googling, this setup is now working fine using the provided config and no additional pull up resistors in the circuit.

Same issue with VERY_VERBOSE logs

INFO Successfully compiled program.
INFO Resolving IP address of scd43-basement.local
INFO  -> 192.168.1.82
INFO Uploading .esphome/build/scd43-basement/.pioenvs/scd43-basement/firmware.bin (830848 bytes)
Uploading: [============================================================] 100% Done...

INFO Waiting for result...
INFO OTA successful
INFO Successfully uploaded program.
INFO Starting log output from scd43-basement.local using esphome API
INFO Successfully connected to scd43-basement.local
[20:21:17][I][app:102]: ESPHome version 2022.6.3 compiled on Aug 16 2022, 20:20:00
[20:21:17][C][wifi:491]: WiFi:
[20:21:17][C][wifi:353]:   Local MAC: 84:F7:03:5F:CE:A0
[20:21:17][C][wifi:354]:   SSID: 'ATT8GlU9XN'
[20:21:17][C][wifi:355]:   IP Address: 192.168.1.82
[20:21:17][C][wifi:357]:   BSSID: F8:2C:18:8E:FA:B5
[20:21:17][C][wifi:358]:   Hostname: 'scd43-basement'
[20:21:17][C][wifi:360]:   Signal strength: -43 dB ▂▄▆█
[20:21:17][V][wifi:362]:   Priority: 0.0
[20:21:17][C][wifi:364]:   Channel: 11
[20:21:17][C][wifi:365]:   Subnet: 255.255.255.0
[20:21:17][C][wifi:366]:   Gateway: 192.168.1.254
[20:21:17][C][wifi:367]:   DNS1: 192.168.1.254
[20:21:17][C][wifi:368]:   DNS2: 0.0.0.0
[20:21:18][C][logger:275]: Logger:
[20:21:18][C][logger:276]:   Level: VERY_VERBOSE
[20:21:18][C][logger:277]:   Log Baud Rate: 115200
[20:21:18][C][logger:278]:   Hardware UART: UART0
[20:21:18][C][i2c.idf:047]: I2C Bus:
[20:21:18][C][i2c.idf:048]:   SDA Pin: GPIO1
[20:21:18][C][i2c.idf:049]:   SCL Pin: GPIO0
[20:21:18][C][i2c.idf:050]:   Frequency: 50000 Hz
[20:21:18][C][i2c.idf:053]:   Recovery: bus successfully recovered
[20:21:18][I][i2c.idf:063]: Results from i2c bus scan:
[20:21:18][I][i2c.idf:069]: Found i2c device at address 0x62
[20:21:18][C][scd4x:094]: scd4x:
[20:21:18][C][scd4x:095]:   Address: 0x62
[20:21:18][W][scd4x:105]: Unable to read sensor firmware version
[20:21:18][C][scd4x:112]:   Automatic self calibration: ON
[20:21:18][C][scd4x:121]:   Ambient pressure compensation disabled
[20:21:18][C][scd4x:122]:   Altitude compensation: 0m
[20:21:18][C][scd4x:127]:   Measurement mode: periodic (5s)
[20:21:18][C][scd4x:139]:   Temperature offset: 4.00 °C
[20:21:18][C][scd4x:140]:   Update Interval: 60.0s
[20:21:18][C][scd4x:141]:   CO2 'scd43 CO2'
[20:21:18][C][scd4x:141]:     Device Class: 'carbon_dioxide'
[20:21:18][C][scd4x:141]:     State Class: 'measurement'
[20:21:18][C][scd4x:141]:     Unit of Measurement: 'ppm'
[20:21:18][C][scd4x:141]:     Accuracy Decimals: 0
[20:21:18][C][scd4x:141]:     Icon: 'mdi:molecule-co2'
[20:21:18][C][scd4x:142]:   Temperature 'scd43 Temperature'
[20:21:18][C][scd4x:142]:     Device Class: 'temperature'
[20:21:18][C][scd4x:142]:     State Class: 'measurement'
[20:21:18][C][scd4x:142]:     Unit of Measurement: '°C'
[20:21:18][C][scd4x:142]:     Accuracy Decimals: 2
[20:21:18][C][scd4x:142]:     Icon: 'mdi:thermometer'
[20:21:18][C][scd4x:143]:   Humidity 'scd43 Humidity'
[20:21:18][C][scd4x:143]:     Device Class: 'humidity'
[20:21:18][C][scd4x:143]:     State Class: 'measurement'
[20:21:18][C][scd4x:143]:     Unit of Measurement: '%'
[20:21:18][C][scd4x:143]:     Accuracy Decimals: 2
[20:21:18][C][scd4x:143]:     Icon: 'mdi:water-percent'
[20:21:18][C][mdns:084]: mDNS:
[20:21:18][C][mdns:085]:   Hostname: scd43-basement
[20:21:18][V][mdns:086]:   Services:
[20:21:18][V][mdns:088]:   - _esphomelib, _tcp, 6053
[20:21:18][V][mdns:090]:     TXT: version = 2022.6.3
[20:21:18][V][mdns:090]:     TXT: mac = 84f7035fcea0
[20:21:18][V][mdns:090]:     TXT: platform = ESP32
[20:21:18][V][mdns:090]:     TXT: board = esp32-c3-devkitm-1
[20:21:18][C][ota:085]: Over-The-Air Updates:
[20:21:18][C][ota:086]:   Address: scd43-basement.local:3232
[20:21:18][C][ota:089]:   Using Password.
[20:21:18][C][api:138]: API Server:
[20:21:18][C][api:139]:   Address: scd43-basement.local:6053
[20:21:18][C][api:141]:   Using noise encryption: YES
[20:21:20][D][api:102]: Accepted ::FFFF:192.168.1.91
[20:21:20][VV][api.socket:693]: ::FFFF:192.168.1.91: Handshake complete!
[20:21:20][VV][api.service:337]: on_hello_request: HelloRequest {
  client_info: 'Home Assistant 2022.8.1'
}
[20:21:20][V][api.connection:843]: Hello from client: 'Home Assistant 2022.8.1 (::FFFF:192.168.1.91)'
[20:21:20][VV][api.service:013]: send_hello_response: HelloResponse {
  api_version_major: 1
  api_version_minor: 6
  server_info: 'scd43-basement (esphome v2022.6.3)'
  name: 'scd43-basement'
}
[20:21:20][VV][api.service:346]: on_connect_request: ConnectRequest {
  password: ''
}
[20:21:20][D][api.connection:861]: Home Assistant 2022.8.1 (::FFFF:192.168.1.91): Connected successfully
[20:21:20][VV][api.service:019]: send_connect_response: ConnectResponse {
  invalid_password: NO
}
[20:21:20][VV][api.service:391]: on_device_info_request: DeviceInfoRequest {}
[20:21:20][VV][api.service:049]: send_device_info_response: DeviceInfoResponse {
  uses_password: NO
  name: 'scd43-basement'
  mac_address: '84:F7:03:5F:CE:A0'
  esphome_version: '2022.6.3'
  compilation_time: 'Aug 16 2022, 20:20:00'
  model: 'esp32-c3-devkitm-1'
  has_deep_sleep: NO
  project_name: ''
  project_version: ''
  webserver_port: 0
}
[20:21:20][VV][api.service:400]: on_list_entities_request: ListEntitiesRequest {}
[20:21:20][VV][api.service:132]: send_list_entities_sensor_response: ListEntitiesSensorResponse {
  object_id: 'scd43_co2'
  key: 3367911371
  name: 'scd43 CO2'
  unique_id: 'scd43-basementsensorscd43_co2'
  icon: 'mdi:molecule-co2'
  unit_of_measurement: 'ppm'
  accuracy_decimals: 0
  force_update: NO
  device_class: 'carbon_dioxide'
  state_class: STATE_CLASS_MEASUREMENT
  legacy_last_reset_type: LAST_RESET_NONE
  disabled_by_default: NO
  entity_category: ENTITY_CATEGORY_NONE
}
[20:21:20][VV][api.service:132]: send_list_entities_sensor_response: ListEntitiesSensorResponse {
  object_id: 'scd43_temperature'
  key: 2337085905
  name: 'scd43 Temperature'
  unique_id: 'scd43-basementsensorscd43_temperature'
  icon: 'mdi:thermometer'
  unit_of_measurement: '°C'
  accuracy_decimals: 2
  force_update: NO
  device_class: 'temperature'
  state_class: STATE_CLASS_MEASUREMENT
  legacy_last_reset_type: LAST_RESET_NONE
  disabled_by_default: NO
  entity_category: ENTITY_CATEGORY_NONE
}
[20:21:20][VV][api.service:132]: send_list_entities_sensor_response: ListEntitiesSensorResponse {
  object_id: 'scd43_humidity'
  key: 1595359302
  name: 'scd43 Humidity'
  unique_id: 'scd43-basementsensorscd43_humidity'
  icon: 'mdi:water-percent'
  unit_of_measurement: '%'
  accuracy_decimals: 2
  force_update: NO
  device_class: 'humidity'
  state_class: STATE_CLASS_MEASUREMENT
  legacy_last_reset_type: LAST_RESET_NONE
  disabled_by_default: NO
  entity_category: ENTITY_CATEGORY_NONE
}
[20:21:20][VV][api.service:306]: send_list_entities_button_response: ListEntitiesButtonResponse {
  object_id: 'scd41_factory_reset'
  key: 2736634639
  name: 'scd41 factory reset'
  unique_id: 'scd43-basementbuttonscd41_factory_reset'
  icon: ''
  disabled_by_default: NO
  entity_category: ENTITY_CATEGORY_NONE
  device_class: ''
}
[20:21:20][VV][api.service:055]: send_list_entities_done_response: ListEntitiesDoneResponse {}
[20:21:20][VV][api.service:409]: on_subscribe_states_request: SubscribeStatesRequest {}
[20:21:20][VV][api.service:471]: on_subscribe_homeassistant_services_request: SubscribeHomeassistantServicesRequest {}
[20:21:20][VV][api.service:140]: send_sensor_state_response: SensorStateResponse {
  key: 3367911371
  state: nan
  missing_state: YES
}
[20:21:20][VV][api.service:498]: on_subscribe_home_assistant_states_request: SubscribeHomeAssistantStatesRequest {}
[20:21:20][VV][api.service:140]: send_sensor_state_response: SensorStateResponse {
  key: 2337085905
  state: nan
  missing_state: YES
}
[20:21:20][VV][api.service:140]: send_sensor_state_response: SensorStateResponse {
  key: 1595359302
  state: nan
  missing_state: YES
}

When I try to factory reset:

[20:23:35][D][button:013]: 'scd41 factory reset' Pressed.
[20:23:35][VV][i2c.idf:164]: 0x62 TX 3F86
[20:23:36][VV][i2c.idf:204]: TX to 62 failed: timeout
[20:23:36][E][scd4x:240]: Failed to stop measurements
[20:23:36][V][component:199]: Component api took a long time for an operation (1.01 s).
[20:23:36][V][component:200]: Components should block for at most 20-30ms.
[20:23:36][VV][api.service:373]: on_ping_request: PingRequest {}
[20:23:36][VV][api.service:043]: send_ping_response: PingResponse {}
[20:23:39][VV][scheduler:196]: Running interval '' with interval=60000 last_execution=95003 (now=155004)
[20:23:49][VV][api.service:373]: on_ping_request: PingRequest {}
[20:23:49][VV][api.service:043]: send_ping_response: PingResponse {}
[20:23:51][VV][api.service:373]: on_ping_request: PingRequest {}
[20:23:51][VV][api.service:043]: send_ping_response: PingResponse {}

If you have the sensor on a 3v pin, move it over to a 5v pin. Too little power can cause issues.

Hello,

this are my parameter. It works ok. My question is:

ambient_pressure_compensation: 998    <--- is this right ? in my town wie have 1.025,1 hPa. 
- platform: template

    name: "Calibrate Zero (20 minutes at 400ppm)"

    id: calibrate_zero

    entity_category: diagnostic

    on_press:

      - scd4x.perform_forced_calibration:

         value: 419   # outside average April 2022

         id: scd41

what happen if i trigger - scd4x.perform_forced_calibration: ?

can i see the scd41 is ready with new calibration ?

captive_portal:

sensor:

  - platform: scd4x

    id: scd41

    i2c_id: bus_a

    altitude_compensation: 129m

   

    co2:

      name: co2

      id: co2

     

    humidity:

      name: "Luftfeuchtigkeit"

      id: humidity

   

    temperature:

      name: "Raumtemperatur"

      id: temperature

   

    temperature_offset: 0.80

    automatic_self_calibration: true          # der Sensor kalibriert sich automatisch selbst - dauert wochen

    measurement_mode: low_power_periodic      # alle 30 Sekunden wird ein Wert gemessen

    ambient_pressure_compensation: 998          # Aktiviert die Kompensation gemessener CO₂-Werte basierend auf dem gegebenen Umgebungsdruck in mBar

                                                # in 63906 = 1.022,0 h Pascal = 1,022 mbar  

    update_interval: 60s

 # creates a button to calibrate the sensor - this will reset the zero point so use it only when it's been 20 minutes either outside

 # or in a room you know the co2 level is at a minimum

button:

  - platform: template

    name: "Calibrate Zero (20 minutes at 400ppm)"

    id: calibrate_zero

    entity_category: diagnostic

    on_press:

      - scd4x.perform_forced_calibration:

         value: 419   # outside average April 2022

         id: scd41

 # this will expose a switch to home assistant to turn on and off the ABC

switch:

  - platform: template

    name: "Reset SCL41"

    id: reset_scl41    

    turn_on_action:

      - scd4x.factory_reset: scd41

       

  - platform: template

    name: "Template Switch"

    id: temp1    

    turn_on_action:

      - switch.turn_on: cal1

    turn_off_action:

      - switch.turn_off: cal1

  - platform: template

    name: "Automatic Baseline Calibration"

    id: cal1

    entity_category: diagnostic

    optimistic: true

    on_turn_on:

       - switch.turn_on: temp1

    on_turn_off:

       - switch.turn_off: temp1

web_server: # creates a web server where you can access all this stuff without home assistant (good for debugging or working headless (no HA))

  port: 80

  include_internal: true

  ota: true

binary_sensor: # exposes online status

  - platform: status

    name: "Sensor Status"

text_sensor:

  - platform: wifi_info

    ip_address: # exposes the IP Address when connected

      internal: true

      id: wifi_ip_addr

      name: "IP Address"

    ssid: # exposes the SSID when connected

      internal: true

      id: wifi_ssid