Ten luxmetr znám, pár věcí tam vidím špatně, ale nebude problém to napravit.
Začneme adresou zařízení. Vidím ve Vašem příkladu 0x23, takže předpokládám, že ADDR pin zařízení máte spojen s GND. Předně 0x23 není celá adresa - je to horních 7 bitů adresy obvodu. Vy ještě musíte dodat nejnižší bit, kterým říkáte, jestli budete číst (1) nebo zapisovat (0). Pro zápis povelu tedy potřebujete volat adresu 0x23 << 1 | 0 = 0x46, pro čtení budete volat 0x23 << 1 | 1 = 0x47.
Převodník, co máte, je dost katastrofa, protože se snaží zjednodušit práci s některými typy I2C zařízení na úkor obecné použitelnosti. Navíc si v "dokumentaci" volně zaměňují pojmy jako adresa, registr, offset. 0x55 je povel pro zařízení s interním datovým pointerem, což tento senzor není.
Tento senzor, stejně jako spousta dalších, se nějakým povelem zapne a pak už jen chrlí data. Pro nastavení senzoru tedy použijete povel převodníku 0x53 "Read/Write single byte for non-registered devices" a potom pro čtení budete volat 0x54 "Read multiple bytes without setting new address".
Takhle by to mělo vypadat nějak celé:
import serial
import time
ser = serial.Serial(port="/dev/ttyUSB0",
baudrate=19200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_TWO,
bytesize=serial.EIGHTBITS,
timeout=0.500,
)
ser.flushInput()
ser.flushOutput()
ADDR_BASE = 0x23 # nebo 0x5c pokud je ADDR pin HIGH
ADDR_READ = ADDR_BASE << 1 | 1
ADDR_WRITE = ADDR_BASE << 1
CMD_WRITE_1B = 0x53
CMD_READ_MULT = 0x54
LUX_RESOLUTION_1X = 0x10
LUX_RESOLUTION_4X = 0x13
# nastavení senzoru
ser.write(bytearray([CMD_WRITE_1B, ADDR_WRITE, LUX_RESOLUTION_1X]))
while True:
time.sleep(1)
# požádám převodník o 2 B
ser.write(bytearray([CMD_READ_MULT, ADDR_READ, 0x02]))
# přečtu je
raw = ser.read(2)
# interpretace bytů podle datasheetu
lx = (raw[1] << 8 | raw[0]) / 1.2
print("--> %.d lx" %(lx))