Playing sound when object is within set distance of ultrasonic rangefinder (Maybe converting between MicroPython and CircuitPython?)

Hi All,

Desired Outcome
I am working on a project where I want to play a sound file whenever an object comes within 20cm of the ultrasonic range sensor.

I have purchased a couple of Pimoroni Pico Audio Packs (Pimoroni Pico Audio Pack (Line-Out and Headphone Amp) | PIM544 | Core Electronics Australia) for the sound playback.
I am able to play sound back using the Pimoroni Pico Audio Pack connected to a Raspberry Pi Pic, but when I connect the PiicoDev ultransoic rangefinder (PiicoDev Ultrasonic Rangefinder | Core Electronics Australia) to the build, the sound no longer plays (the script continues to run, but the sound is no longer playing).

I am using a male prototyping cable connected to the following female pins on the Raspberry Pi Pico:

  • Red: 3v3
  • Black: GND
  • Blue: SDA (GP8)
  • Yellow: SCL (GP9)

I am thinking that the issue may be with the Pimoroni Audio Pack using CircuitPython, and the Ultrasonic Rangefinder using Micropython. The Core Electronics page says the following about the Pimoroni Audio Pack:

Please note that Pico Audio Pack only currently works with the C/C++ Pico SDK! We have Micro Python support planned but it is not available yet.


  • In a general sense, does ‘No micropython support’ mean that it cannot be used with Micropython?

  • Is it possible to run either the Pimoroni Audio Pack using MicroPython or the Ultrasonic Rangerfinder using CircuitPython?

  • Would there be a better audio playback component to use for the project instead?

Thanks in advance,

Hey @Nathan243765 - It seems to me that the “simplest” way forward would be to read from the Ultrasonic Rangefinder directly in circuitpython. Of the two devices its certainly the simplest.
You can get the time-of-flight from the rangefinder by reading 2-bytes from register 0x05.

Like MicroPython, CircuitPython is very object-heavy. But if you can invoke a simple I2C read from Rangefinder (I2C address 0x35) at the range register (0x05) then you can ostensibly measure range without making a whole driver from scratch. I haven’t any experience with CircuitPython and so can’t give any simple examples on how you would do this - intuition tells me it ought to be a very simple process but eveything’s always simpler in hindsight.

Closing thoughts
If i were you i’d invest no more than a couple of hours trying to interface with the Ultrasonic Rangefinder in circuitpython directly, without any driver-writing faff. Just try to get a hello-world going where you can read the time of flight (μs) and convert that to a range.
If you can do that then you ought to be able to strap in the Audio Pack code without trouble.

Recommended reading:

PiicoDev Ultrasonic Rangefinder device source code and MicroPython Library.
Circuit Python I2C docs

Other questions

Not at all. It just means that nobody has taken the time to create a maker-friendly driver. From my own experience, it takes much much longer to create a useful driver than it does to design a circuit board.

Perhaps! See the Makerverse Audio Kit (MicroPython) and its constituent parts.

1 Like

Hi @Nathan243765

The DFR0768 MP3 player might be a different way to get your sound effects to play - it interfaces to the Pico via a UART connection… Here is my test code to step through a set of several effects - in Micropython but the code should easily port into C

from machine import Pin, UART
from PiicoDev_Unified import sleep_ms
import random

uart = UART(0, baudrate=115200, tx=Pin(12), rx=Pin(13))

durations = [0, 17, 10, 2, 2, 6, 2, 3 ]    # runtime + 1 second, no track 0

uart.write("AT\r\n")        # wakeup
uart.write("AT+PLAYMODE=3\r\n")    # single track mode

# play 10 random noises
for i in range(10):
    play = random.randint(1,7)          # pick a track 1 - 7 
    print("playing track ", play)       # show me
    c_num = "% s" % play                #   / itoa()
    s = "AT+PLAYNUM=" + c_num + "\r\n"  #  / build DFRobot command
    uart.write(s)                       # / and send it
    sleep_ms(durations[play]*1000)      # zzzzz

(code snip from testing my Borg Cube project)


1 Like