Introduction

I was doing some debugging of house alarm wiring and kept having to look at resistence readings while opening and closing doors, and realised that a speaking ohmeter could be almost useful - and would be an execuse to buy and play with a Raspberry Pi Pico

All the code is available here as a Tar or on on Gitlab

My build of OhMy

Audio out

The audio is PWM’d onto GPIO16 (at the bottom of the PICO).

Audio amp

I use the following audio output amp, it’s very meh, but is audible, and is from scrapbox components.


5V VBus      -------------------------------
(USB, top pin                              |
on Pico)                               8ohm, 2W
                                       speaker
                                           |
                                   R2 -----*
                                   |       |
                                   |       C
GPIO 16      --- R1 ---- C1--------*----B    Q1
                                           E
                                           |
             ------------------------------


R1 = 330ohm
R2 = 2.2k
C1 = 42uf
Q1=  2n3904 (Looking at the flat front, that's EBC)

Perhaps I could drop R1 further, but I think that’s about 10mA and the pads are specd for 12?

Ohmeter

We run a series of ranges, each is driven off a separate GPIO pin and consists of a resistor where all the resistors are commoned. I drive a single GPIO at a time and measure the result using the ADC.


GPIO18  ----[  1M  ]  -----|
GPIO19  ----[100k  ]  -----|
GPIO20  ----[ 10k  ]  -----|
GPIO21  ----[  1k  ]  -----|
                           |
GPIO26  -------------------*--
                             |
                           Rtest
                             |
AGND26  ---------------------*

The pin table is in ohmeter.c and there are constants for ADC values corresponding to open and shorts. There are some heuristics for switching to the next range down:

I see a lot of noise on the ADC, and don’t really get anywhere near the 12 bits, or even effective 8 bits promised. One way I improve that is to turn off the PWM sound during the reading; I ramp it up to 255 and back down to 128 before playing the next sound. The ramp removes any click. Making it 255 means PWM is solid on, so there should be no switching noise.

Implementation

Some notes on the innards.

Sound

See sound.c

The sound uses the PWM output module; I run it as a simple 256 step setup; at 125MHz input that gets me just under 500k PWMs per second.

I then DMA sound samples into the PWM’s cc register to change the level; note I found 8 bit DMA to that doesn’t work, so ended up stretching the samples to 32 bit (two copies of 16) and DMA 32 bit.

The samples are chained together with a set of control blocks (sound_cbs) with some helpers for adding sound to the list.

I couldn’t get the IRQ/NULL notification for the end of the chain to work, so I spin on the read location. Hmm.

Speech and samples

scripts/mimicaudio uses the mimic speech synth to generate each word, and sox with some python to turn it into a C source file and header.

(I did wonder about incorporating mimic or the libraries it uses rather than taking whole words, but I realised this was simpler).

Numbers

I wrote a simple integer to words parser (see numberspeaker.c) it’s actually overkill for this.

TODO

(c)David Alan Gilbert 2021

mail: fromwebpage@treblig.org irc: penguin42 on libera.chat | matrix: penguin42 on matrix.org | mastodon: penguin42 on mastodon.org.uk

My home page