I need to change value in MLX96014 temperature sensors eeprom with raspberry pi and python. I can read its ram and eeprom without problems, but I cant write to it. Also every python MLX96014 library that I find dont have this function implemented for some reason. I tried to do this with arduino and it works great with this function:
void Adafruit_MLX90614::write16(uint8_t a, uint16_t v) {
// a is register address
// v value to write to eeprom
// _addr is device address (0x5a)
uint8_t pec;
uint8_t pecbuf[4];
pecbuf[0] = _addr << 1;
pecbuf[1] = a;
pecbuf[2] = v & 0xff;
pecbuf[3] = v >> 8;
pec = crc8(pecbuf, sizeof pecbuf);
Wire.beginTransmission(_addr); // start transmission to device
Wire.write(a); // sends register address to write
Wire.write(v & 0xff); // lo
Wire.write(v >> 8); // hi
Wire.write(pec); // pec
Wire.endTransmission(true); // end transmission
}
So I tried to rewrite this function in python:
import board
import busio as io
import adafruit_mlx90614
import time
from smbus2 import SMBus, i2c_msg
import crc8
import sys
i2c = io.I2C(board.SCL, board.SDA, frequency=100000)
mlx = adafruit_mlx90614.MLX90614(i2c)
buf = bytearray(4)
buf[0] = 0x5a<<1
buf[1] = 0x24
buf[2] = 0 & 0xff
buf[3] = 0 >>8
pec = crc8.crc8()
pec.update(buf)
pec = pec.hexdigest() # = 0x28
i2c.writeto(0x5a, bytes([0x24]), stop=False)
buffer = bytearray(3)
buffer[0] = 0 & 0xFF
buffer[1] = (0 >> 8) & 0xFF
buffer[2] = 0x28
i2c.writeto(0x5a, buffer, stop=True)
i2cbus = SMBus(1)
emissivity=i2cbus.read_word_data(0x5a,0x24)
print(emissivity) # prints 65535 which is default
Code executes without errors. i2c.writeto() returns "None". So what im missing there?
Edit:
I found this (link) in datasheet but it confuses me. In datasheet it says that write comand bit is low and read is high. But in example both operations uses low. Also it looks like im supposed to send 0xb4 byte instead of 0x5a, but where to put it in pyhton code? If I put it in i2c.writeto() first parameter then I get I/O error because module is on address 5a (i2cdetect shows that).
By the way, I dont have access to osciloscope right now.
I dont know exactly why provided python code doesnt work but I have tried other i2c library and it started working. Here is the code snippet:
import board
import busio as io
import crc8
import adafruit_mlx90614
import adafruit_bus_device.i2c_device as ada_i2c
import time
def change_emissivity(value,i2c):
new_emissivity=round(65535*value)
buf=bytearray(4)
buf[0]=0x24
buf[1]=0x00
buf[2]=0x00
buf[3]=0x28 # kai irasomi nuliai
device=ada_i2c.I2CDevice(i2c,0x5a)
with device:
device.write(buf)
time.sleep(0.01)
buf[0]=0x5a<<1
buf[1]=0x24
buf[2]=new_emissivity & 0xff
buf[3]=(new_emissivity >> 8) & 0xFF
pec=crc8.crc8()
pec.update(buf)
pec=int(pec.hexdigest(),base=16)
buf[0]=0x24
buf[1]=new_emissivity & 0xff
buf[2]=(new_emissivity >> 8) & 0xFF
buf[3]=pec
print(new_emissivity)
i2c = io.I2C(board.SCL, board.SDA, frequency=100000)
mlx = adafruit_mlx90614.MLX90614(i2c)
change_emissivity(0.8, i2c)
print("New emissivity: %.2f" %mlx._read_16(0x24))
while(True):
print("Ambient Temp: %.2f" %mlx.ambient_temperature
print("Object Temp: %.2f" %mlx.object_temperature
time.sleep(3)