SparkFun MicroPressure Sensor and PiicoDev Unified Python Library

@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:

image

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
11 Likes

Hi Jim,

Awesome work!

An older version of the Unified library did include the .readfrom call rather than readfrom_mem.
I beleive this was a change so that it would work for the LoPy4 as the ports for that function call isnt the same between all devboards, see @Michael and @Liam120347 's discussion over on this forum topic.

I’ll shoot a message through to the Engineering team to take a look at :smiley:
Liam.

5 Likes

Thank You @James46717 with your help in finding a solution…
and filling many of the gaps in my understanding on the topic of classes etc. along the way.

3 Likes

I am a RPI/Sensor beginner but I have set up a pico with a photo sensor and a buzzer.

I need to add a pressure sensor and wanted to check that the above should still work to allow me to add the Spark Fun micropressure sensor to my Pico?

Also, in the above photos how is the micropressure sensor connected to the Pico? Is it using the debug pins?

The Spark Fun Pressure Sensor has an I2C interface, the pic shows it connected to the I2C connector on the PiicoDev Expansion Board.

Features

  • Pressure Type: Absolute
  • Operating Pressure: 25psi (172.37kPa)
  • I2C Address: 0x18
  • Accuracy: ±0.25%
  • Voltage - Supply: 1.8V-3.6V
  • Port Size: Male - 0.1" (2.5mm) Tube
  • Port Style: Barbless
  • Maximum Pressure: 60psi (413.69kPa)
  • Compatible with a variety of liquid media
  • 2x Qwiic Connectors

Copy the Honeywell Micro Pressure Sensor class from a previous post.
Save it to the Pico as Honeywell_MPR_02.py

Regards
Jim

2 Likes

Thank you! Worked perfectly.

2 Likes