Shallow Thoughts : tags : electronics
Akkana's Musings on Open Source Computing and Technology, Science, and Nature.
Thu, 28 Sep 2017
Someone at our makerspace found a fun Halloween project we could do
at Coder Dojo: a
sensing pumpkin that laughs evilly when anyone comes near.
Great! I've worked with both PIR sensors and ping rangefinders,
and it sounded like a fun project to mentor. I did suggest, however,
that these days a Raspberry Pi Zero W is cheaper than an Arduino, and
playing sounds on it ought to be easier since you have frameworks like
ALSA and pygame to work with.
The key phrase is "ought to be easier".
There's a catch: the Pi Zero and Zero W don't
have an audio output jack like their larger cousins. It's possible to
get analog audio output from two GPIO pins (use the term "PWM output"
for web searches), but there's a lot of noise. Larger Pis have a built-in
low-pass filter to screen out the noise, but on a Pi Zero you have to
add a low-pass filter. Of course, you can buy HATs for Pi Zeros that
add a sound card, but if you're not super picky about audio quality,
you can make your own low-pass filter out of two resistors and two capacitors
per channel (multiply by two if you want both the left and right channels).
There are lots of tutorials scattered around the web about how to add
audio to a Pi Zero, but I found a lot of them confusing; e.g.
tutorial on Pi Zero sound has three different ways to edit the
system files, and doesn't specify things like the values of the
resistors and capacitors in the circuit diagram (hint: it's clearer if you
download the Fritzing file, run Fritzing and click on each resistor).
There's a clearer diagram in
PWM Audio Guide, but I didn't find that until after I'd made my own,
so here's mine.
- 2 x 270 Ω resistor
- 2 x 150 Ω resistor
- 2 x 10 nF or 33nF capacitor
- 2 x 1μF electrolytic capacitor
- 3.5mm headphone jack, or whatever connection you want to use to
And here's how to wire it:
(Fritzing file, pi-zero-audio.fzz.)
This wiring assumes you're using pins 13 and 18 for the left and right
channels. You'll need to configure your Pi to use those pins.
Add this to /boot/config.txt:
Once you build your circuit up, you need to test it.
Plug in your speaker or headphones, then make sure you can play
anything at all:
If you need to adjust the volume, run
use the up and down arrow keys to adjust volume. You'll have to press
up or down several times before the bargraph actually shows a change,
so don't despair if your first press does nothing.
That should play in both channels. Next you'll probably be curious
whether stereo is actually working. Curiously, none of the tutorials
address how to test this. If you
you'll see names like Front_Left.wav, which might lead you to
might play only on the left. Not so: it's a recording of a voice
saying "Front left" in both channels. Very confusing!
Of course, you can copy a music file to your Pi, play it (omxplayer
is a nice commandline player that's installed by default and handles
MP3) and see if it's in stereo. But the best way I found to test
audio channels is this:
speaker-test -t wav -c 2
That will play those ALSA voices in the correct channel, alternating
between left and right.
(MythTV has a good
of how to use speaker-test.
Not loud enough?
I found the volume plenty loud via earbuds, but if you're targeting
something like a Halloween pumpkin, you might need more volume.
The easy way is to use an amplified speaker (if you don't mind
putting your nice amplified speaker amidst the yucky pumpkin guts),
but you can also build a simple amplifier.
Here's one that looks good, but I haven't built one yet:
One Transistor Audio for Pi Zero W
Of course, if you want better sound quality, there are various places
that sell HATs with a sound chip and line or headphone out.
[ 15:49 Sep 28, 2017
More hardware |
permalink to this entry |
Mon, 04 Sep 2017
My new book is now shipping! And it's being launched via a terrific Humble
Bundle of books on electronics, making, Raspberry Pi and Arduino.
Humble Bundles, if you haven't encountered them before, let you pay
what you want for a bundle of books on related subjects. The books are
available in ePub, Mobi, and PDF formats, without DRM, so you can read
them on your choice of device. If you pay above a certain amount,
they add additional books. My book is available if you pay $15 or more.
You can also designate some of the money you pay for charity.
In this case the charity is Maker Ed,
a crowdfunding initiative that supports Maker programs primarily
targeted toward kids in schools. (I don't know any more about them
than that; check out their website for more information.)
Jumpstarting the Raspberry Pi Zero W is a short book,
with only 103 pages in four chapters:
- Getting Started: includes tips on headless setup and the Linux
- Blink an LED: includes ways to blink and fade LEDs from the shell
and from several different Python libraries;
- A Temperature Notifier and Fan Control: code and wiring
instructions for three different temperature sensors (plus humidity
and barometric pressure), and a way to use them to control your house
fan or air conditioner, either according to the temperature in the room
or through a Twitter command;
- A Wearable News Alert Light Show: wire up NeoPixels or DotStars
and make them respond to keywords on Twitter or on any other web page
you choose, plus some information on powering a Pi portably with batteries.
All the code and wiring diagrams from the book, plus a few extras, are
available on Github, at my
Raspberry Pi Zero
Book code repository.
To see the book bundle, go to the
& Programming Humble Bundle and check out the selections.
My book, Jumpstarting the Raspberry Pi Zero W, is available if
you pay $15 or more -- along with tons of other books you'll probably
also want. I already have Make: Electronics and it's one of the
best introductory electronics books I've seen, so I'm looking forward
to seeing the followup volume. Plus there are books on atmospheric and
environmental monitoring, a three-volume electronic components
encyclopedia, books on wearable electronics and drones and other cool stuff.
I know this sounds like a commercial, but this bundle really does look
like a great deal, whether or not you specifically want my Pi book,
and it's a limited-time offer, only good for six more days.
[ 13:21 Sep 04, 2017
More writing |
permalink to this entry |
Sat, 04 May 2013
I've written about how to
small DC motors with an Arduino, in order to
a little toy truck around.
But an Arduino, while great at talking to hardware, isn't very powerful.
It's easy to add simple sensors to the truck so it can stop before hitting
the wall; but if I wanted to do anything complicated -- like, say,
image processing with a camera -- the Arduino really isn't enough.
Enter Raspberry Pi. It isn't a super-fast processor either, but it's
fast enough to run Linux, Python, and image processing packages like
A Raspberry-Pi driven truck would be a lot more powerful: in theory,
I could make a little Mars Rover to drive around my backyard.
If, that is, I could get the RPi driving the car's motors.
Raspberry Pi, sadly, has a lot of limitations as a robotics platform.
It's picky about input voltages and power; it has no analog inputs,
and only one serial port (which you probably want to use for a console
if you're going to debug your robot reliably).
But my biggest concern was that it has only one pulse-width modulation
(PWM) output, while I needed two of them to control the car's two motors.
It's theoretically possible to do software PWM on any pin -- but
until recently, there were no libraries supporting that.
Until recently. I've been busy for the last month or two and haven't
been doing much RPi experimenting. As I got back into it this week, I
discovered something delightful: in the widely available python library
Software PWM is available starting with 0.5.2a.
Getting the right RPi.GPIO
Just what I'd been wanting! So I got an LED and resistor and plugged
them into a breadboard.
I ran a black wire from the RPi's pin 6, ground, to the short LED pin,
and connected the long pin via the resistor to the RPi's pin 18
(GPIO 24) (see the
peripherals for the official GPIO pin diagrams).
With the LED wired up, I
in my serial cable, powered up the RPi with its Raspbian SD card,
and connected to it with
screen /dev/ttyUSB0 115200.
I configured the network to work on my local net and typed
sudo apt-get install python-rpi.gpio
to get the latest version. It got 0.5.2a-1. Hooray!
I hurried to do a test:
pi@raspberrypi:~$ sudo python
Python 2.7.3 (default, Jan 13 2013, 11:20:46)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import RPi.GPIO as GPIO
>>> GPIO.setup(24, GPIO.OUT)
>>> led = GPIO.PWM(24, 100)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'PWM'
Whoops! But Raspbian said it was the right version ...
I checked again with
aptitude show python-rpi.gpio --
yep, 0.5.2a-1. Hmph!
After some poking around, I discovered that help(GPIO),
after printing out an interminable list of exception classes,
eventually gets to this:
VERSION = '0.5.1a'
In other words, Rapsbian is fibbing: that package that Raspbian says
is version 0.5.2a-1 is actually version 0.5.1a.
(This is the sort of thing that makes Raspberry Pi such a joy to work with.
Yes, that's sarcasm.)
Okay. Let's try removing that bogus Raspbian package and getting it from
apt-get remove python-rpi.gpio
pip install --upgrade RPi.GPIO
Then I tried the same test as before. Success!
And now I was able to set the LED to half brightness:
I was able to brighten and dim the LED at will:
I played with it a little while longer, then cleaned up:
If you're experimenting with RPi.GPIO's PWM, you'll want to check
out this useful 2-part tutorial:
What about motors?
So PWM works great for LEDs. But would it drive my little robotic car?
I unplugged my LED and wired up one of the
motor drivers circuits I'd wired up for the Arduino. And it worked
just as well! I was able to control the motor speed using ChangeDutyCycle().
I'll write that up separately, but I do have one caveat:
GPIO.cleanup(), for some reason, sets the pin output to HIGH.
So if you have your car plugged in and sitting on the ground when you
run cleanup(), it will take off at full speed.
I recommend testing with the car on a stand and the wheels off the ground.
Update: the motor post is up now, at
two DC motors with a Raspberry Pi.
[ 21:00 May 04, 2013
More hardware |
permalink to this entry |
Sat, 11 Jun 2011
Every now and then I think it might be handy to have some sort of
display on the Arduino ... something a little more detailed than
an LED that either blinks or doesn't.
Adafruit's 2-line LCD text display comes with a great
tutorial, but it's quite heavy, and includes a backlight I
don't need. I wanted something more minimal.
The local surplus store always has
lots of cheap LCDs, but they unfortunately tend to be unlabeled, so
you can't tell which pin is which.
But the other day I spied a very lightweight little display for $2.95
that actually had a label on it, so I grabbed it, figuring I'd be able
to get the pinout from google. It said:
Alas, googling produced no useful information for any of those numbers.
Foiled again! It might as well have been unlabeled!
Wait -- let's not give up quite so quickly.
Shield tutorial says most parallel displays have either 14 or 16 pins,
while this one has 15. That's close, at least ... but comparing the
two Ada tutorials, I could see that the pin assignments for the two
displays were completely different even though both were 16-pin.
I wasn't going to get pin assignments there.
Searching for just
densitron 15-pin lcd found
lots of displays that clearly weren't this one. But apparently a lot of
them were similar to a display called an LM50. Perhaps mine used that
So I tried it, and it worked with only a little experimentation.
Here's the pinout:
|LCD pin ||Function ||Arduino pin
|1 ||Gnd ||Gnd
|2 ||+5 V ||+5 V
|3 ||Contrast ||pot
|4 ||RS ||7
|5 ||RW ||Gnd
|6 ||EN ||8
|7 ||D0 ||
|8 ||D1 ||
|9 ||D2 ||
|10 ||D3 ||
|11 ||D4 ||9
|12 ||D5 ||10
|13 ||D6 ||11
|14 ||D7 ||12
|15 ||(nonexistent backlight)
Or I can use the nice cable with the 8x2 connector that came with the
display, which maps to these functions:
|1 = Gnd ||Contrast ||RW ||D0 ||D2 ||D4 ||D6 ||
|+5V ||RS ||EN ||D1 ||D3 ||D5 ||D7 ||
The Arduino LiquidCrystal library works just fine with it, using
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
in the Liquid Crystal
Works great! I went back and grabbed another $3 display.
So the moral is, even a complete hardware klutz shouldn't give up too easily:
with the right web search terms and a little fiddling, you might just
get it to work after all.
Update: apparently something has changed in the LiquidCrystal library,
and you now need a trick to get this to work. Specifically, to see
the rightmost 8 characters, you need to call
lcd.setCursor(40, 0). See this discussion:
showing only first 8 characters (lcd.setCursor(0,1) not working).
[ 20:25 Jun 11, 2011
More hardware |
permalink to this entry |
Mon, 27 Oct 2008
I wrote in my OSCON report a few months back that I came home from the
conference with an Arduino
microcontroller kit and just enough knowledge and software to make
LEDs blink. And so it sat, for a month or two, while I tried to come
up with some reason I desperately needed a programmable LED blinker
(and time to play with it).
But it turned out I actually did have a practical need for a
customizable programmable gizmo. One of the problems with
flying is that you're so focused on keeping track of which plane
is yours that it's tough to keep track of how long you've gone on
the current battery. You don't want to fly a lithium-polymer battery
until it gets so weak you notice the drop in power -- that's really
bad for the battery. So you need a timer.
My transmitter (a JR 6102) has a built-in timer, but it's hard to use.
As long as you remember to reset it when you turn on the
transmitter, it displays minutes and seconds since reset.
Great -- so all I need is somebody standing next to me who can
read it to me. Looking away from the sky long enough
to read the timer is likely to result in flying into a tree, or worse.
(The new uber-fancy transmitters have programmable beeping
timers. Much more sensible. Maybe some day.)
I could buy a kitchen timer that dings after a set interval, but
what's the fun of that? Besides, I could use some extra smarts
that kitchen timers don't have.
Like audible codes for how long I've flown, so I can make my own
decision when to land based on how much throttle I've been using.
Enter the Arduino. Those digital outputs that can make an LED
blink work just dandy for powering a little piezo beeper, and it turns
out the Atmel ATmega168 has a built-in clock, which you can read
So I wired up the beeper to pin 8 (keeping an LED on pin 13 for
debugging) and typed up a trivial timer program,
It gives a couple of short beeps when you turn it on (that's so you
know it's on if you can't see it), then gives a short beep at 9
minutes, a long one at 10, shorter one at 11, and thereafter gives
(minutes MOD 10) beeps, i.e. two for 12, three for 13 and so forth.
Fun and easy, and it works fine at the field once I worked out a way
to carry it (it's in a camera bag hanging on my belt, with the beeper
outside the bag so I can hear it).
Fun! It could use better codes, and a pause switch (for when I land,
fiddle with something then go back up on the same battery).
Of course, in the long run I don't actually want to devote my only
Arduino kit to being a glorified stopwatch forever. I have further
plans to address that, but that's for a later posting ...
[ 13:10 Oct 27, 2008
More tech/hardware |
permalink to this entry |