micropython-mlx90614
micropython-mlx90614 copied to clipboard
OSError 5 when doing i2c.readfrom_mem
Board: Raspberry Pi Pico
Code:
import uos
import machine
import time
print(uos.uname())
print("Freq: " + str(machine.freq()) + " Hz")
i2c = machine.I2C(0, scl=machine.Pin(5), sda=machine.Pin(4))
print(i2c)
print("Available i2c devices: "+ str(hex(i2c.scan()[0])))
import ustruct
_REGISTER_TA = const(0x06) # ambient
_REGISTER_TOBJ1 = const(0x07) # object
_REGISTER_TOBJ2 = const(0x08) # object2
class MLX90614:
def __init__(self, i2c, address=0x5a):
self.i2c = i2c
self.address = address
_config1 = i2c.readfrom_mem(address, 0x25, 2)
_dz = ustruct.unpack('<H', _config1)[0] & (1<<6)
self.dual_zone = True if _dz else False
def read16(self, register):
data = self.i2c.readfrom_mem(self.address, register, 2)
return ustruct.unpack('<H', data)[0]
def read_temp(self, register):
temp = self.read16(register);
# apply measurement resolution (0.02 degrees per LSB)
temp *= .02;
# Kelvin to Celcius
temp -= 273.15;
return temp;
def read_ambient_temp(self):
return self.read_temp(_REGISTER_TA)
def read_object_temp(self):
return self.read_temp(_REGISTER_TOBJ1)
def read_object2_temp(self):
if self.dual_zone:
return self.read_temp(_REGISTER_TOBJ2)
else:
raise RuntimeError("Device only has one thermopile")
@property
def ambient_temp(self):
return self.read_ambient_temp()
@property
def object_temp(self):
return self.read_object_temp()
@property
def object2_temp(self):
return self.read_object2_temp()
sensor = MLX90614(i2c)
while True:
print(sensor.read_ambient_temp())
time.sleep(1)
Output:
(sysname='rp2', nodename='rp2', release='1.14.0', version='v1.14 on 2021-02-09 (GNU 10.2.0 MinSizeRel)', machine='Raspberry Pi Pico with RP2040')
Freq: 125000000 Hz
I2C(0, freq=399361, scl=5, sda=4)
Available i2c devices: 0x5a
Traceback (most recent call last):
File "<stdin>", line 63, in <module>
File "<stdin>", line 23, in __init__
OSError: 5
I've hit this OSError: 5
a few times now on different modules. Not sure exactly what is causing it.
Try switching to SoftI2C
. That fixes it for me on other boards.
Replace:
i2c = machine.I2C(0, scl=machine.Pin(5), sda=machine.Pin(4))
With:
i2c = machine.SoftI2C(scl=machine.Pin(5), sda=machine.Pin(4))
After re-reading the datasheet, it looks like your I2C freq is too high. Drop your 399361 to > 100000 and it should start working.
The maximum frequency of the MLX90614 SMBus is 100 KHz and the minimum is 10 KHz. 8.4.7 Timing specification - Page 21