Check-in [0ad9cf14f3]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fixed saved settings folder name, updated documentation.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0ad9cf14f3fd312af7e1af565490cf85fbf16888
User & Date: rberteig 2015-01-21 01:58:36
Context
2015-01-21
19:54
Added schematic of the ATTiny85 stunt. check-in: f617dc9d64 user: rberteig tags: trunk
01:58
Fixed saved settings folder name, updated documentation. check-in: 0ad9cf14f3 user: rberteig tags: trunk
01:37
Initial checkin of a working source kit for the ATTiny85 Demonstration. check-in: 995ad5da5c user: rberteig tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Name change from .fossil_settings/binary-glob to .fossil-settings/binary-glob.

Name change from .fossil_settings/crnl-glob to .fossil-settings/crnl-glob.

Added ATTiny/readme.txt.



























































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# PDM Microphone with an AVR ATTiny85

This is a demonstration of sampling audio data from a digital MEMS
microphone, delivered in PDM (Pulse Density Modulation) format at a 1
MHz sample rate.

This code is built entirely independently of the Arduino framework,
although it does run in an ATTiny85 on an Adafruit Trinket board which
was built to be used as an inexpensive and small Arduino.



# Usage

With the circuit wired up as described below, and firmware built and
loaded, the microphone will listen to the ambient sound, the firmware
will compute the sound pressure level, and a meter connected to pin
PB1 will indicate the SPL. The output voltage will be proportional to
the level measured in dB SPL.

If built with the hobby servo option, then a servo may be connected,
and the servo horn will move to a position related to the sound level.


# Hardware

## Components

The demonstration bread board uses a Knowles SPM0437HD4H-B microphone
and a 5V Adafruit Trinket board, along with some passive components.

Visible outputs are provided by the LED already present on the
Trinket, a 5V scale analog meter movement, and a small hobby servo.

Power is supplied by the USB cable that also supports flashing the
firmware.

The microphone is designed for operation at 3.3V. We could wire it
directly to a 3.3V ATTiny85, and there is a 3V model of the Trinket
that suits. However, running at 3V the ATTiny85 is limited to too low
a core clock to keep up with the computation required per 8 audio
bits.

For a bread board demonstration, resistor dividers are used to power
the mic and adjust the level of the clock drive. In a finished PCB,
those should be replaced by an actual 3.3V supply and level
translators. To make the bread board work, we had to drive the mic at
a higher than recommended voltage so that its data output would cross
the Vih threshold for the ATTiny85's input pins, which is 70% of Vcc
or 3.5V when running at 5V.

## Implementation

The Trinket is connected as follows:

Trinket   ATTiny         Usage
--------  ------------   ---------------------------
`B0`      `PB0/DI`       Mic data input to `USI`
`B1`      `PB1/DO/OC0B`  PWM Analog SPL Output
`B2`      `PB2/USCLK`    Mic clock input to `USI`
`B3`      `PB3`          Sonar, hobby servo (USB `D-`)
`B4`      `PB4/OC1B`     Mic clock output (USB `D+`)
`B5`      `PB5/RESET`    Reset button
`5V`                     Divider to Mic `VCC`
`GND`                    `GND` reference
`VBAT`                   N/C
`VBUS`                   Power to hobby servo

The clock output on pin `B4` is wired directly to `B2`, and passed
through a resistor divider to connect to the microphone's clock input.
The microphone's power supply is similarly divided from the Trinket's
regulated 5V output pin. The divider used in the bread board produces
about 4V, which is above the recommended operating range for the mic,
but still below its absolute max rating. The mic's data output pin is
observed to swing nearly all the way to the mic's Vcc level.

The microphone's clock is generated by Timer 1 based on the internal
64 MHz PLL. The clock output on `PB4` is wired to the `USI` clock
input on `PB2`, as well as to the microphone. Attempts to use a clock
generated by `Timer0` worked for driving the mic, but did not usefully
clock the `USI` peripheral.

The microphone's data is gathered on `PB0` which is the `DI` pin to
the `USI` peripheral. The `USI` provides an 8-bit shift register that
can be configured to capture input data on either clock edge, and
provide an interrupt once per 8 bits captured. That interrupt handler
will do all processing that must be done at the source sample rate,
and hand off to foreground code to finish the processing at the down
sampled rate and do something useful with the recovered audio.

`Timer0` is configured for a PWM output on pin `PB1`, providing an
output signal to convey the measured sound level. The PWM hardware
allows the output to vary from 0% to 100% of Voh in 256 steps.

Pin `BP3` is configured as an output and used for either debug sonar
or as a hobby servo drive to demonstrate making something move when
scared by a loud noise. In the bread board, the servo's power is drawn
from `VBUS`, and care must be taken not to require too much current
for the servo motor. 

The Trinket provides a button on the `PB5/RESET` signal to restart its
boot loader for easy firmware updates from a PC over the USB cable.
Although the ATTiny85 does allow for a configuration fuse to be
programmed to allow `PB5` to be used for general purpose I/O, that
capability was not needed for this demonstration. 

The Trinket board also connects pins `PB3` and `PB4` to the USB `D-`
and `D+` signals, along with suitable clamping, protection, and a pull
up resistor signaling to the USB host port that the Trinket wants to
be a Low Speed device. This is used by its boot loader for
implementing a flash programmer. 

Note that any hobby servo must not be connected to `PB3` when the
Trinket is booting while connected to a PC or it will interact (badly)
with the USB signaling and potentially cause mechanical damage to the
servo mechanism. 


# Firmware Overview

The sound signal is encoded by the microphone in pulse density
modulation, and delivered at one sample per clock. `Timer1` is
configured to create a 1 MHz clock for the purpose.

The PDM signal is captured by the `USI` shift register and delivered
to the firmware 8 bits at a time via the `USI` overflow interrupt.

Through a pair of CIC filter structures, each 128 one-bit PDM
samples will be down converted to a single signed 14-bit PCM sample.
Starting from the 1 MHz source clock, the PCM sample rate is then
7812.5 Hz.

The PCM samples will be fed into an RMS calculation, which is a fair
proxy for SPL at the microphone. The RMS level will be used to adjust
the PWM output level, allowing a connected device to measure the
average voltage on pin `PB1` and convert that measurement to ambient
SPL at our microphone.

If configured, a hobby servo control signal is generated by software
taking advantage of the 125 kHz `USI` overlow interrupt to implement the
servo signal timing.

We know the mic itself is specified to convert a 94 dB 1Hz tone into
-26 dBFS in its PDM bit stream. By recovering a 15 bit PCM sample, we
can in principle measure a 90 dB range, topping out at 0 dBFS or 120
dB SPL. The exact scale and offset between dB SPL and modulation of
the PWM output is TBD.


# Project Files and Tools

## Tools

The firmware is built by [GCC][], targeting the AVR family CPU cores.
The bread board was tested with the version of [`avr-gcc`][avr-gcc]
included in the [Arduino IDE][arduino-ide], but a separate
installation should work as well. It does depend on the [AVR
libc][avr-libc] port, but does not depend on any Arduino files or
features.

[gcc]: http://gcc.gnu.org/
[avr-gcc]: http://gcc.gnu.org/wiki/avr-gcc
[avr-libc]: http://www.nongnu.org/avr-libc/
[arduino]: http://arduino.cc/
[arduino-ide]: http://arduino.cc/en/Main/Software

The bread board was built and tested around the Adafruit [Trinket][]
board, based on the ATTiny85 CPU. Adafruit supplies a customized
edition of the Arduino IDE that not only includes the USB drivers
needed to program the Trinket with `avrdude`, but also includes the
needed tweaks and patches to a stock Arduino IDE to use it for
developing code targeting the Trinket board.

[trinket]: http://learn.adafruit.com/introducing-trinket/introduction

Outside of the Arduino IDE, the best way to get all of the AVR
targeted tools is through the [WinAVR][] project. WinAVR provides a
suite of pre-built open source software development tools for the AVR
platform that run on Windows. 

[winavr]: http://winavr.sourceforge.net/

Firmware programming over USB is performed by `avrdude`, again found
in the Arduino IDE but also available separately. The Trinket
bootloader requires some specific modifications to the stock
configuration of `avrdude`, a working configuration file is included
in the build project. If a different programmer is used for firmware
flashing, then suitable changes will need to be made to the Makefile.

It would also be a good idea to have a collection of developer tools
that target Windows, along with utilities like Gnu Make. The [MinGW][]
project is a good source of builds of GCC and related tools for
building on Windows for Windows. There are also projects like
[GnuWin32][] that provide other Gnu utilities ported to run on
Windows. 

[mingw]: http://www.mingw.org/
[gnuwin32]: http://gnuwin32.sourceforge.net/

Of course it would also be handy to have at least one scripting
language you are comfortable with installed and happy on your Windows
box. A language like [Lua][], Perl, or Python will make constructing
code that creates lookup tables, code that creates state machines,
code that models possible algorithm choices, and similar
meta-programming utilities easier. I use Lua for the purpose, but your
mileage may vary.

[lua]: http://www.lua.org/

It is also good practice to have and use a source code control system.
Cheshire currently uses and recommends [Fossil][]. Git, Mercurial,
Subversion, and many others also exist and provide the same broad
features. We recommend Fossil for its ease of use, lack of ceremony,
and impressive track record.

[fossil]: http://www.fossil-scm.org/

This documentation 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. 

  [pandoc]: http://johnmacfarlane.net/pandoc/index.html
  [pdf]: http://www.adobe.com/pdf/
  [miktex]: http://www.miktex.org

## Files

The project includes the following files:

`avrdude.conf`
  ~ Configuration for `avrdude`.
`Makefile`
  ~ Project description for GNU make.
`MicDemo.c`
  ~ The firmware.
`readme.txt`
  ~ This document.

Build products of the firmware include:

`MicDemo.elf`
  ~ Firmware executable along with symbols and other metadata. This is
    the output of the linker, and is converted to Intel HEX format by
    `avr-objcopy`, disassembled by `avr-objdump`, and analyzed by
    `avr-size` once created.
`MicDemo.hex`
  ~ Firmware executable image in Intel HEX format to be flashed to
    the ATTiny85. 
`MicDemo.lst`
  ~ Assembly listing with references to the C source line numbers
    allowing easy inspection of generated code for various C
    constructs. This is handy for checking that lookup tables did get
    correctly built for placement in the program memory space, for
    example.

As long as WinAVR is installed and you have `...WinAVR\bin` and
`...WinAVR\utils\bin` on your PATH at a command prompt, (and Gnu Make as
well, probably from `...GnuWin32\bin`) you should be able to build the
project with the command `make`. If you have the USB drivers for the
Trinket installed, then `make flash` will build the firmware if
needed, then run `avrdude` to download it to the ATTiny85.



# References

## Microphones

 *  Way too much detail about how to actually design and build a MEMS
    microphone, including die photos and detailed characterization of a
    microphone built for this dissertation: 
    http://etd.fcla.edu/UF/UFE0017526/martin_d.pdf

 *  MEMS at Wikipedia:
    http://en.wikipedia.org/wiki/Microelectromechanical_systems 

 *  PCM: http://en.wikipedia.org/wiki/Pulse-code_modulation

 *  PDM: http://en.wikipedia.org/wiki/Pulse-density_modulation

## dB and Sound

 *  dB: http://en.wikipedia.org/wiki/Decibel

 *  SPL: http://en.wikipedia.org/wiki/Sound_pressure_level


## Filters

 *  http://en.wikipedia.org/wiki/Cascaded_integrator-comb_filter


## Test Instruments

 *  A reference sound field of 1 kHz sine wave at 94 dB(A) or 114
    dB(A) is available from several vendors in the form of a device
    that slips over the microphone housing, typically supplied with
    adaptors for 1/2" and 1" microphone bodies. Use of such a
    calibrator with this board would require mounting a suitable
    housing around the PDM mic. See this device from Reed, the SC-05,
    as typical for this class of calibrator. http://amzn.com/B008S0OVR2

Changes to readme.txt.

1
2
3
4
5
6


7
8
9
10


# PDM Audio Stunts

This is a collection of implementations of stunts with PDM audio
bitstreams, supporting articles written for [our Words from Cheshire
blog][words]. Check the blog for posts describing each stunt.



# License

The code in this repository is licensed under the MIT license. See
license.txt for the full statement of license.








>
>




>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# PDM Audio Stunts

This is a collection of implementations of stunts with PDM audio
bitstreams, supporting articles written for [our Words from Cheshire
blog][words]. Check the blog for posts describing each stunt.

  [words]: http://curiouser.cheshireeng.com/

# License

The code in this repository is licensed under the MIT license. See
license.txt for the full statement of license.