Tags

, , , , , , , , , , ,

This is part of a series of articles on the general subject of audio signal processing from air to information.

Previous installments include:

In this installment, we document the source kit for the PDM to PCM to SPL demonstration in the ATTiny85 CPU.

Get Set

It shouldn’t be too difficult to build the demonstration firmware yourself. You’ll need to collect some tools, clone a copy of the project source repository, compile, and flash.

Tools

The firmware is built with avr-gcc, links with a customized C runtime library, and flashed to the CPU with avrdude, all of which are included in the WinAVR distribution. These tools can be installed separately, or as part of the Arduino IDE. Since we are using the Adafruit Trinket board, which is not covered by the official IDE package, it can make sense to install Adafruit’s customized version of the IDE instead, especially if you plan to play with the Trinket for other projects.

Either way, you will need avr-gcc, avr-objcopy, avr-objdump, avr-size, and avrdude to compile and flash the firmware.

The source code is maintained in a public Fossil repository, as described below. We strongly recommend fossil for version control, especially of small projects where it really shines. I’ve written about fossil before.

Actually building the project will require a version of make, and the included Makefile will assume that various common unix-like command line utilities (notably rm and cp) are in the path. If you are working on Linux, you likely already have what you need. On Windows, I still like the convenient native Win32 builds of many common Unix tools available from the GnuWin32 project. In particular, I tend to assume that Gnu’s make is used and have stopped overtly trying to write Makefiles that work with other flavors of make.

There isn’t a whole lot of external documentation in this project, but what documentation there is is written in the Markdown text markup language, translated to LaTeX for print with Pandoc, and converted to PDF with LuaLaTeX provided by the MikTeX distribution.

The Makefile includes rules for compiling Markdown text to PDF using pandoc, as well as rendering SVG to PNG using Inkscape.

Source Code Repository

All of the code supporting this demonstration is in a public fossil repository. This post documents work that was checked in as 0ad9cf14f3.

To play with this utility yourself, you will want to do some of the following:

  1. Get the latest version of fossil from fossil-scm.org
  2. Install it in Windows by simply putting fossil.exe in a folder on your PATH. You will be using it from a command prompt, so if you’ve edited the system PATH to do this, you will want to restart any open command prompts so they are current.
  3. Create a working folder somewhere. Inside your My Documents folder is fine. We’ll assume it is C:\Users\You\Documents\PDMStunts, but it really could be anywhere. Open a command window and cd to that folder.
  4. Clone the repository with a command like this: fossil clone http://chiselapp.com/user/rberteig/repository/PDMStunts pdmstunts.fossil
  5. Open the repository in some folder so you can see its content and work with it. The easiest folder to use is the one you are standing in right now, and that is both safe and reasonable: fossil open pdmstunts.fossil
  6. You now have a tree of files rooted in the current folder. The ATTiny folder has the stunt for the ATTiny85 running in a Trinket.

Later you will want to update that working copy to track changes made in the public repository. That is easy to do: with an open command window, cd into the working folder, then say fossil update.

Build it

Open a command prompt, and find your way to the folder where you cloned and opened the repository as described above and cd into the ATTiny folder. You will also want to modify your PATH so that the WinAVR tools are available. In addition, to make these instructions easier to copy and paste, I’ve modified my prompt.

You can put this configuration in a batch file, if you want, or you can modify the PATH settings in the registry to make the AVR toolchain be available to all your command prompts. Here’s an example of a suitable batch file. Change ARDUINOBASE to name the root folder of the Arduino IDE you installed, or bypass the IDE and set WINAVR to the root of the WinAVR package you installed:

@echo off
set ARDUINOBASE=C:\Path\To\Arduino\IDE\Installation
set WINAVR=%ARDUINOBASE%\hardware\tools\avr
PATH %PATH%;%WINAVR%\bin;%WINAVR%\utils\bin
prompt $CWinAVR$F$G$S

I see something like the following:

C:\Users\You\> cd Documents\PDMStunts\ATTiny
C:\Users\You\Documents\PDMStunts\ATTiny\> SetWinAVR.bat
(WinAVR)>
(WinAVR)> make
avr-gcc -c -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=attiny85 -DF_CPU=16000000L -MMD MicDemo.c
avr-gcc -g -Os -Wl,--gc-sections -mmcu=attiny85 -o MicDemo.elf MicDemo.o -L. -lm

avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 MicDemo.elf MicDemo.eep
avr-objcopy -O ihex -R .eeprom MicDemo.elf MicDemo.hex
avr-objdump -l -d MicDemo.elf >MicDemo.lst
avr-size --mcu=attiny85 -C MicDemo.elf
AVR Memory Usage
----------------
Device: attiny85

Program:    1122 bytes (13.7% Full)
(.text + .data + .bootloader)

Data:         18 bytes (3.5% Full)
(.data + .bss + .noinit)

(WinAVR)>

Flash it

With the Trinket connected to the PC by a USB cable, and with the needed USB drivers all installed as per the instructions, re-flashing the firmware is simple as long as you haven’t accidentally damaged the Trinket’s boot loader. The boot loader is pretty resilient, you would likely have to be attempting to write to the CPU’s internal flash to actually damage it, or completely misconfigure avrdude. The settings provided in avrdude.conf are based on the instructions from Adafruit and as long as the proper settings are preserved it should not be possible to overwrite the boot loader.

Note: Always unplug the servo before flashing the Trinket. The USB connection to the PC is implemented in the boot loader using two of the ATTiny85’s GPIO pins. One of those pins is wired to the microphone’s clock input, and the other is either the debug sonar output or the control signal to a hobby servo. Leaving the servo connected while flashing the firmware will at best confuse the servo causing abrupt arbitrary movements, and at worst could damage the servo.

Just before flashing, unplug the servo, then push the reset button on the trinket. The red LED will blink, and if a meter is connected the needle will wave back and forth as well. This indicates that the boot loader has noticed a PC is connected, and is waiting for it to start the transfer. During the transfer, the LED will blink and the needle wiggle. This is expected. When the transfer is complete, the boot loader will jump to the new firmware and the needle will start to indicate SPL again. At that time it is safe to plug the servo back in.

(WinAVR)> make flash 
(WinAVR)> make flash
avrdude -C avrdude.conf  -c usbtiny -p t85 -Uflash:w:MicDemo.hex:i

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e930b
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "MicDemo.hex"
avrdude: writing flash (1122 bytes):

Writing | ###                                                | 5% 0.04s
avrdude: 8 retries during SPI command
....
Writing | ##########################                         | 51% 0.42s
avrdude: 8 retries during SPI command
....
Writing | ################################################## | 100% 0.82s

avrdude: 1122 bytes of flash written
avrdude: verifying flash memory against MicDemo.hex:
avrdude: load data flash data from input file MicDemo.hex:
avrdude: input file MicDemo.hex contains 1122 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.12s

avrdude: verifying ...
avrdude: 1122 bytes of flash verified
avrdude: safemode: Fuses OK
avrdude done.  Thank you.

(WinAVR)>

The warnings about SPI retries are expected according to Adfruit:

When uploading, you will see a lot of avrdude: 8 retries during SPI command and similar warnings. THIS IS OK! Because of the way the ATtiny85 works, there’s a small delay when writing the new program to flash, and during that delay, it cannot save the data and also send USB data at the same time. This causes the USB reply to avrdude to be delayed and avrdude to spit out the retry alert.

Use it

As configured, the outputs are proportional to the logarithm of the sound pressure level. That means that in a quiet room, it will hear relatively quiet sounds. Try tapping on the table, and notice that the needle twitches by half a volt or so. Talk near it, and it will move further.

Connect a hobby servo and the servo horn will move clockwise with louder sounds. Probably. It is actually difficult to say anything absolute about hobby servos, as even their connector wiring is not well standardized. So when connecting your servo, look carefully and at the wiring and possibly even seek out technical documentation to verify that the wires are in the order shown on our schematic. And certainly don’t attach the servo to any mechanism before you’ve verified that it moves as expected.

Say “Boo!”, honk at it, set off an alarm, …

Connect the SPL output from the trinket pin B1 (called out as PWMOUT on the schematic) to any analog input on an Arduino, and sample it. The PWM base frequency is 1 kHz, so a stiff low-pass reconstruction filter is probably a good idea to read it as an analog signal, or you could detect the edges in the PWM waveform and directly measure the pulse duty cycle. Either way, the SPL is measured and the duty cycle updated at about 8 Hz, so sampling in the Arduino faster than 16 Hz but well less than 1 kHz is reasonable.

What Next?

More sophisticated processing of the PDM bit stream or more interesting processing of the PCM or SPL samples will require more computational power than the ATTiny85 provides, so we’ll move the SPL meter to a tiny ARM CORTEX-M0 processor that is 32-bit, runs faster, and is still inexpensive in small quantities.


(Written with StackEdit.)