PiicoDev Requests/Suggestions

Thought I better stop using PiicoDev that is owned by Core electronics.
It was originally just an example.
Shamelessly used the Adafruit code to check status and bits.
Code below. It uses too many variables and could be tidied up. But development …

"""
Honeywell Micro Pressure Sensor - MPR
Device in Standby Mode normally, send command, device enters Operating Mode, sensors pressure, when done flags EOC pin and Status byte.

Send 0xAA 0x00 0x00 to start reading.
Wait for status or EOC pin or at least 5ms.
Read 4 bytes, status, data 24:16, data 15:8, data 7:0
"""

from PiicoDev_Unified import *

compat_str = '\nUnified PiicoDev library out of date.  Get the latest module: https://piico.dev/unified \n'

_MPR = 0x18
MAXIMUM_PSI = 25
MINIMUM_PSI = 0

OUTPUT_MAX = 0xE66666
OUTPUT_MIN = 0x19999A

class Honeywell_MPR(object):     
    def __init__(self, bus=None, freq=None, sda=None, scl=None, addr=_MPR):
        try:
            if compat_ind >= 1:
                pass
            else:
                print(compat_str)
        except:
            print(compat_str)
        self.i2c = create_unified_i2c(bus=bus, freq=freq, sda=sda, scl=scl)
        self.addr = addr

    def read(self):
        self.i2c.writeto_mem(self.addr, 0x00, bytes([0xAA,0x00,0x00]))
        sleep_ms(10)
       
        while True:
            status = self.i2c.readfrom_mem(self.addr, 0x00, 1)
            sleep_ms(1)
            if not status[0] & 0x20:
                break

        data = self.i2c.readfrom_mem(self.addr, 0x00, 4)
        if data[0] & 0x01:
            raise RuntimeError("Internal math saturation")
        if data[0] & 0x04:
            raise RuntimeError("Integrity failure")

        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
from Honeywell_MPR import Honeywell_MPR
from PiicoDev_Unified import sleep_ms

sensor = Honeywell_MPR()

while True:
    pressure = sensor.read()
    print(str(pressure))
    sleep_ms(5000)
2 Likes

Did some testing by simulating values. The line that converts bytes to a long integer is incorrect, should be. reading = data[1] << 16 | data[2] << 8 | data[3]

Near lower limit, 0x28FF00

Near upper limit, 0xD8FF00

Cheers
Jim

2 Likes

Now I got the same message, casting the variable as a byte.

2 Likes

OK Another day…

Ooops! Yes of course - totally agree

Progress - downloaded your latest version of Honeywell_MPR… no errors… (but) no output…

So as Thonny only easily monitors top level (main) variables, I moved the driver code to top level,
And then added some progress print statements…

There is an error message from unified (I think) but not sure if it is just reporting a default value…

Anyways… we get stuck in a loop trying to read sensor status – either waiting for the sensor, or not actually reading the sensor(???) [not sure how to check for i2c bus traffic – unless there is some debug code “out there” somewhere?]

Best wishes,

Victor

latest code: (if this gets too big maybe need to .zip?)

# PiicoDev test script for SparkFun MicroPressure Sensor 10/Dec/2021
# Ported to Python Core-Electronics.au forums James46717 Victor153764

# from Honeywell_MPR import Honeywell_MPR >> code copied to main for test
from PiicoDev_Unified import *
from machine import Pin

# Honeywell_MPR insert >>
"""
Honeywell Micro Pressure Sensor - MPR
"""

# from PiicoDev_Unified import * >> comment out duplicate statement

compat_str = '\nUnified PiicoDev library out of date.  Get the latest module: https://piico.dev/unified \n'

_MPR = 0x18
MAXIMUM_PSI = 25
MINIMUM_PSI = 0

OUTPUT_MAX = 0xE66666
OUTPUT_MIN = 0x19999A

class Honeywell_MPR(object):     
    def __init__(self, bus=None, freq=None, sda=None, scl=None, addr=_MPR):
        try:
            if compat_ind >= 1:
                pass
            else:
                print(compat_str)
        except:
            print(compat_str)
        self.i2c = create_unified_i2c(bus=bus, freq=freq, sda=sda, scl=scl)
        self.addr = addr

    def read(self):
        print("read: start")
        self.i2c.writeto_mem(self.addr, 0x00, bytes([0xAA,0x00,0x00]))
        print("read: sensor initialised")
        sleep_ms(10)
       
        while True:
            print("read: get sensor status")
            status = self.i2c.readfrom_mem(self.addr, 0x00, 1)
            sleep_ms(200)
            if not status[0] & 0x20:
                break

        print("read: get sensor reading")
        data = self.i2c.readfrom_mem(self.addr, 0x00, 4)
        if data[0] & 0x01:
            raise RuntimeError("Internal math saturation")
        if data[0] & 0x04:
            raise RuntimeError("Integrity failure")

        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
# End of Honeywell_MPR insert <<

print("main: pi-pico LED on")
led = Pin(25, Pin.OUT)
led.on()
sensor = Honeywell_MPR() # instantiate sensor
print("main: Honeywell_MPR on pi-pico")

while True:
    # Print data
    print("main: sensor.read")
    pessure = sensor.read() # read all data from the sensor
    print("main: MPR Pessure =", pressure)
    sleep_ms(1000)
    led.toggle()

3 Likes

… with a second pico… >> https://github.com/jjsch-dev/pico_i2c_sniffer
:thinking:

3 Likes

Nice use of a Pi Pico, will link this for future reference.

2 Likes

i reckon it would be easy to make space 4 the audio jack and the dac chip om the board even if the socket was below the board

2 Likes