How to Fix "OSError: [Errno 5] EIO" in STM32 Water Quality Monitoring System?

Hello Guys I am trying to develop a real-time water quality monitoring system using an STM32 microcontroller, MicroPython, and various water quality sensors(pH sensor, Turbidity sensor)DS18B20. The system will use an AI model to predict water quality parameters such as pH, turbidity, and temperature, and display the results on an LCD screen. I have connected the pH sensor, turbidity sensor, and DS18B20 temperature sensor to the STM32, also connected the LCD screen to the STM32 using I2C. But am getting the error OSError: [Errno 5] EIO
5 Replies
Enthernet Code
Enthernet Code5mo ago
Here's my code
import machine
import time
from lcd import LCD
from ds18x20 import DS18X20
from onewire import OneWire
import tensorflow as tf

ow = OneWire(machine.Pin(12))
ds = DS18X20(ow)

def read_temperature():
roms = ds.scan()
ds.convert_temp()
time.sleep_ms(750)
for rom in roms:
return ds.read_temp(rom)

def read_ph():
return 7.0

def read_turbidity():
return 100

lcd = LCD(i2c_addr=0x27, i2c_bus=1)

def display_data(ph, turbidity, temperature):
lcd.clear()
lcd.putstr(f'PH: {ph:.2f}\n')
lcd.putstr(f'Turb: {turbidity:.2f} NTU\n')
lcd.putstr(f'Temp: {temperature:.2f} C')

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

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

def predict_water_quality(ph, turbidity, temperature):
interpreter.set_tensor(input_details[0]['index'], [[ph, turbidity, temperature]])
interpreter.invoke()
prediction = interpreter.get_tensor(output_details[0]['index'])
return prediction[0][0]

while True:
temperature = read_temperature()
ph = read_ph()
turbidity = read_turbidity()

if temperature is not None and ph is not None and turbidity is not None:
quality = predict_water_quality(ph, turbidity, temperature)
print(f"Water Quality Index: {quality}")
display_data(ph, turbidity, temperature)

time.sleep(5)

import machine
import time
from lcd import LCD
from ds18x20 import DS18X20
from onewire import OneWire
import tensorflow as tf

ow = OneWire(machine.Pin(12))
ds = DS18X20(ow)

def read_temperature():
roms = ds.scan()
ds.convert_temp()
time.sleep_ms(750)
for rom in roms:
return ds.read_temp(rom)

def read_ph():
return 7.0

def read_turbidity():
return 100

lcd = LCD(i2c_addr=0x27, i2c_bus=1)

def display_data(ph, turbidity, temperature):
lcd.clear()
lcd.putstr(f'PH: {ph:.2f}\n')
lcd.putstr(f'Turb: {turbidity:.2f} NTU\n')
lcd.putstr(f'Temp: {temperature:.2f} C')

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

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

def predict_water_quality(ph, turbidity, temperature):
interpreter.set_tensor(input_details[0]['index'], [[ph, turbidity, temperature]])
interpreter.invoke()
prediction = interpreter.get_tensor(output_details[0]['index'])
return prediction[0][0]

while True:
temperature = read_temperature()
ph = read_ph()
turbidity = read_turbidity()

if temperature is not None and ph is not None and turbidity is not None:
quality = predict_water_quality(ph, turbidity, temperature)
print(f"Water Quality Index: {quality}")
display_data(ph, turbidity, temperature)

time.sleep(5)

RED HAT
RED HAT5mo ago
@Enthernet Code the OSError: [Errno 5] EIO is typically an input/output error, which can be caused by several factors. Let's go through some likely solutions: Firstly, make sure that the I2C bus initialization is correct. The i2c_bus parameter in the LCD initialization should match the I2C bus number used in your setup. For example, if you're using I2C1, it should be i2c_bus=1, Also, verify that the I2C address (0x27) is correct for your LCD screen. You can use an I2C scanner script to detect the connected I2C devices and confirm their addresses. Here’s an example of an I2C scanner script:
import machine

i2c = machine.I2C(1, 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(1, 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])
RED HAT
RED HAT5mo ago
make sure there is enough delay between I2C operations to avoid bus collisions. You can add small delays using time.sleep_ms(10) between I2C operations.
Dark AI
Dark AI5mo ago
Since you are using multiple sensors and an LCD on the I2C bus, check if there are any conflicts or interference between devices. Sometimes, devices can cause issues if they are not properly initialized or if they have different voltage levels. Ensure all devices are operating at the same voltage level, preferably 3.3V for the STM32, Make sure the libraries for the sensors and the LCD are correctly installed and compatible with your MicroPython setup. Sometimes, library issues can cause unexpected errors and try isolating each sensor and the LCD to check if they work individually. This can help identify if a specific device is causing the issue.
Enthernet Code
Enthernet Code5mo ago
Thanks for the guidance @RED HAT @Dark AI i would implement the following corrections and give u guys feedback
Want results from more Discord servers?
Add your server