@Victor153764 posted a request for a Python Port of driver code for the SparkFun MicroPressure Sensor SKU: SEN-16476. The Original post here.
We have been working through it and have come to the conclusion the PiicoDev Unified Library will not work. The library writes an address and then reads data, this causes the sensor to lock into busy mode.
The sensor is pretty simplistic; activating a pressure measurement and reading the data has a specific write command (the only command it has) and a read returns 4 bytes, status & 24 bit pressure measurement. The status byte can be read as a single byte as well.
I have developed a Class to access the sensor successfully using the machine
Library of the Pi Pico; read(address, bytes)
& write(address, bytes)
. These definitions simply read and write a number of bytes.
The class I2CUnifiedMachine(I2CBase):
is used to access the Pi Pico. It might be useful to add the following definitions to the class, allowing basic sensors like the Sparkfun one to work.
class I2CUnifiedMachine(I2CBase):
def readBytes(self, addr, numbytes):
return self.i2c.readfrom(addr, numbytes)
def writeBytes(self, addr, data):
self.i2c.writeto(addr, data)
return
Regards
Jim
PS This has taken us quite a few days to sort out. First to try and understand why the sensor was always busy and then to find a way to make it work. @Victor153764 & I have been communicating via private message so as not to clog the thread which we had hijacked; our discussion was in a completely different direction to the original post.
Setup of Pi Pico and Sensor:
Successful test of sensor:
Sensor Class:
"""
Honeywell Micro Pressure Sensor - MPR
Device in Standby Mode normally, send command, device enters Operating Mode,
sets busy bit, measures pressure, when done sets EOC pin high and clears busy bit.
Process takes about 5ms, wait at least 10ms.
Procedure:
Check busy bit if clear,
Send 0xAA 0x00 0x00 to start measureement,
Check for clear busy bit, EOC pin high or wait 10ms,
Read 4 bytes, 1=status, 2=data 24:16, 3=data 15:8, 4=data 7:0.
"""
from PiicoDev_Unified import *
from PiicoDev_Unified import sleep_ms
import utime
_MPR = 0x18
MAXIMUM_PSI = 25
MINIMUM_PSI = 0
BUSY_FLAG = 0x20
INTEGRITY_FLAG = 0x04
MATH_SAT_FLAG = 0x01
OUTPUT_MAX = 0xE66666
OUTPUT_MIN = 0x19999A
compat_str = '\nUnified PiicoDev library out of date. Get the latest module: https://piico.dev/unified \n'
class Honeywell_MPR(object):
def __init__(self, bus=0, freq=400000, addr=_MPR):
try:
if compat_ind >= 1:
pass
else:
print(compat_str)
except:
print(compat_str)
self.i2c = I2C(bus,freq)
self.addr = addr
def readStatus(self):
return self.i2c.readfrom(self.addr, 1)
def CheckBusy(self):
TimeStart = utime.ticks_ms()
status = self.readStatus()
Busy = True
while Busy:
status = self.readStatus()
if not (status[0] & BUSY_FLAG):
Busy = False
if utime.ticks_diff(utime.ticks_ms(), TimeStart) > 2000:
raise RuntimeError("Sensor Busy, cannot read")
utime.sleep_ms(100)
return
def read(self):
self.CheckBusy()
self.i2c.writeto(self.addr, bytes([0xAA,0x00,0x00]))
self.CheckBusy()
data = self.i2c.readfrom(self.addr, 4)
reading = data[1] << 16 | data[2] << 8 | data[3]
pressure = (reading - OUTPUT_MIN) * (MAXIMUM_PSI - MINIMUM_PSI)
pressure = (pressure / (OUTPUT_MAX - OUTPUT_MIN)) + MINIMUM_PSI
return pressure