How to Fix "Failed to Read Sensor: OSError" on Arduino Nano 33 BLE Sense with MicroPython?

Hey guys am developing an air quality monitoring system using an Arduino Nano 33 BLE Sense, MicroPython, and a CCS811 gas sensor. The system will use a TinyML model to predict air quality index (AQI) based on sensor data. I have set up the flash MicroPython firmware on the Arduino Nano 33 BLE Sense, connected the CJMCU-8128 module to the Arduino (I2C pins: SDA to A4, SCL to A5), also connected the OLED display to the Arduino using I2C. But am getting the error Failed to read sensor: OSError Here's my code
import machine
import time
import ssd1306
from ccs811 import CCS811
from hdc1080 import HDC1080
from bmp280 import BMP280
import tensorflow as tf

i2c = machine.I2C(scl=machine.Pin(22), sda=machine.Pin(21))
ccs811 = CCS811(i2c)
hdc1080 = HDC1080(i2c)
bmp280 = BMP280(i2c)

def read_sensor_data():
try:
co2, tvoc = ccs811.read_data()
temperature = hdc1080.read_temperature()
humidity = hdc1080.read_humidity()
pressure = bmp280.read_pressure()
return co2, tvoc, temperature, humidity, pressure
except OSError as e:
print('Failed to read sensor:', e)
return None, None, None, None, None

oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

def display_data(aqi):
oled.fill(0)
oled.text(f'AQI: {aqi}', 0, 0)
oled.show()

interpreter = tf.lite.Interpreter(model_path="aqi_predictor.tflite")
interpreter.allocate_tensors()

input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

def predict_aqi(co2, tvoc, temperature, humidity, pressure):
import machine
import time
import ssd1306
from ccs811 import CCS811
from hdc1080 import HDC1080
from bmp280 import BMP280
import tensorflow as tf

i2c = machine.I2C(scl=machine.Pin(22), sda=machine.Pin(21))
ccs811 = CCS811(i2c)
hdc1080 = HDC1080(i2c)
bmp280 = BMP280(i2c)

def read_sensor_data():
try:
co2, tvoc = ccs811.read_data()
temperature = hdc1080.read_temperature()
humidity = hdc1080.read_humidity()
pressure = bmp280.read_pressure()
return co2, tvoc, temperature, humidity, pressure
except OSError as e:
print('Failed to read sensor:', e)
return None, None, None, None, None

oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

def display_data(aqi):
oled.fill(0)
oled.text(f'AQI: {aqi}', 0, 0)
oled.show()

interpreter = tf.lite.Interpreter(model_path="aqi_predictor.tflite")
interpreter.allocate_tensors()

input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

def predict_aqi(co2, tvoc, temperature, humidity, pressure):
Solution:
Thanks @RED HAT o checked if my sensor was initialized using the script you sent and it was but I after I changed the frequency to 100kHz it started working properly 👍, thanks once again
Jump to solution
3 Replies
Enthernet Code
Enthernet Code4mo ago
interpreter.set_tensor(input_details[0]['index'], [[co2, tvoc, temperature, humidity, pressure]])
interpreter.invoke()
prediction = interpreter.get_tensor(output_details[0]['index'])
return prediction[0][0]

while True:
co2, tvoc, temperature, humidity, pressure = read_sensor_data()
if co2 is not None:
aqi = predict_aqi(co2, tvoc, temperature, humidity, pressure)
print(f"AQI: {aqi}")
display_data(aqi)
time.sleep(5)

interpreter.set_tensor(input_details[0]['index'], [[co2, tvoc, temperature, humidity, pressure]])
interpreter.invoke()
prediction = interpreter.get_tensor(output_details[0]['index'])
return prediction[0][0]

while True:
co2, tvoc, temperature, humidity, pressure = read_sensor_data()
if co2 is not None:
aqi = predict_aqi(co2, tvoc, temperature, humidity, pressure)
print(f"AQI: {aqi}")
display_data(aqi)
time.sleep(5)

RED HAT
RED HAT4mo ago
@Enthernet Code Sometimes, sensors might not be initialized correctly if their addresses are not detected. You can use an I2C scanner script to check if the sensors are detected on the I2C bus. Try this I2C scanner script:
import machine

i2c = machine.I2C(scl=machine.Pin(22), sda=machine.Pin(21))
devices = i2c.scan()

if len(devices) == 0:
print("No I2C devices found")
else:
print("I2C devices found:", [hex(device) for device in devices])
import machine

i2c = machine.I2C(scl=machine.Pin(22), sda=machine.Pin(21))
devices = i2c.scan()

if len(devices) == 0:
print("No I2C devices found")
else:
print("I2C devices found:", [hex(device) for device in devices])
Also, ensure that the I2C bus speed is compatible with your sensors. You might need to set the I2C frequency when initializing the I2C bus. Try setting the frequency to 100kHz:
i2c = machine.I2C(scl=machine.Pin(22), sda=machine.Pin(21), freq=100000)
i2c = machine.I2C(scl=machine.Pin(22), sda=machine.Pin(21), freq=100000)
Solution
Enthernet Code
Enthernet Code4mo ago
Thanks @RED HAT o checked if my sensor was initialized using the script you sent and it was but I after I changed the frequency to 100kHz it started working properly 👍, thanks once again
Want results from more Discord servers?
Add your server