Wednesday, October 5, 2016

Wireless buzzers

Wireless buzzers:

  • Designed in Autodesk Fusion 360
  • 3D printed with Ultimaker 2 using clear PLA (layer height 0.1)
    • Pieces are printed in sections and fastened with M3 inset nuts and bolts
    • Transparency of the filament is used to create a thin (0.3mm) viewing window for the OLED display inside. Heated glass printbed helps make the 3 layers smooth and clear.
    • Because 3D printed plastic has a fine layered pattern, this make it terrible for pieces to slide past each other while in same orientation. Therefore i've printed 3 "sliders" that are printed in a different orientation so the smooth glass facing side of the print is in contact with the walls of the moving button/top cap.
    • Once assembled, the button enclosure interlocks with itself. Top cap is captive by same bolts that hold sliders in place.
  • Electronics:
    • Adafruit Feather M0+ with RFM69HCW 900mhz module
    • Adafruit OLED Featherwing for control unit display
    • Misc small buttons, switches, LEDs, piezos, and wiring.
    • 2000mAh lithium polymer cell
  • Software:
    • Programmed in Arduino environment
    • LowPowerLabs RFM69 library
      • modified SendWithRetry() to delay by additional specified random time to desynchronize collision deadlocks.
    • RTC library for low power standby function of buzzer buttons between buzzes.
    • Adafruit OLED library
  • Interface Features
    • Display RSSI or battery level of each buzzer
    • Silent mode - no buzzing or lighting so the trivia host can call out who buzzed in first.
    • Automatic reset - optionally allow the buzzer to automatically reset the lockout after 5s or 10s so the host does not have to press the button so much.
    • Central reset button - reset the lockout so the buzzers can buzz again; long press to select auto-reset time 
    • Battery measurements are normalized to a standard li-poly discharge curve (binned  every 10% runtime) to give charge level reflective of runtime.
  • Future features
    • Auto power control - dial transmit power back to conserve power based on RSSI; already supported by RFM69 library but not used here as batteries are already so overwhelmingly large and transmissions are so short.
    • Battery disconnection alarm - if the device is plugged in without being switched on first, the battery will not charge. There may be a way to use some external electronics with pulldown resistors to detect if the battery is attached to warn the user that the battery is not charging.

 Installing the electronics on the base station.

 Oops i designed it backwards. Had to reprint this mirrored.
 Above: the original design with one large button. Nice and clicky with good unified tactile and auditory feedback but would not click reliably when clicked on the edge of the top buttoncap. Switched to a 3-button design instead. Also seen: the 3 sliders, to be bolted on the midsection sideways as an interface between the midsection and the top buttoncap.
 Fitting test for the midsection of the buzzer unit.

The underside features some air vents and the piezo speaker. Silicone feet.
ON/OFF switch and the charging port. The switch fully disconnects the battery when off to minimize discharge during storage. Unfortunately, this means that if the switch is OFF, the device will not charge. Additionally there is no easy way to detect if the battery is attached (unless I of measure the batt pin through a voltage divider). If I could, at least I can warn the user with an annoying buzz until the battery is connected.

Sunday, February 16, 2014

RPi programming troubles

So, a lot of progress has been made on the RPi front, though none of it good!

Setting up the I2C to be automatic, using a startup script:

GPIO code:

For some reason, PureData refuses to recognize the USB sound card and crashes every time. The sound card works when I play a sound clip in the terminal with aplay. Since the prospect of programming logic in PD is daunting at best and nightmarish at worse, I've decided to just go with python since all the code exists for it already. In python I've successfully programmed a key scan program to read all the GPIO buttons and report which buttons have been pressed on the I2C LCD.

HOWEVER. VNC viewer will not play nice with pygame! And so far pygame is the best candidate for sound manipulation with python. I'm not liking python anyways. Maybe its time to switch to Java? I'll have to learn I2C in Java because I won't have the sample code to rely on.

Saturday, January 18, 2014

Autotrigger 555 circuit for the Casio SK1!

The Casio SK1 has 3 voices which can be independently programmed and played together with a "auto play" button. By somehow triggering the auto play button rhythmically, then, we can create loops! The idea came from Casper's SK1 page (

What we need is an extended-duty astable circuit, as seen here: (
Calculations: Because I needed the circuit to trigger for loops, I need the timer to go off between 2 and 15 seconds. Any shorter or longer than that is not really useful for me. I also know that the POTs I can buy go up to 500K, and any larger than that would be expensive custom parts. That still leaves you with one degree of freedom, a relation between R1 and C. Looking at the available parts at the store, I determined R1 to be 5K, R2 to be a 500K pot, and C to be 33uF.
Using the falstad circuit simulator (, it works! The on time is about 250ms, and the off time goes up to about 15-20 seconds.

The idea is to use the 555 timer's output current to electronically spoof a press of the 'auto play' button. The buttons on the SK1 are scanned by the CPU: merely finding one of the two wires corresponding to the auto play button on the PCB and dumping current into it is not enough, the leads have to be connected at the exact time that the key is being scanned. We need a switch that puts current into the sensor line of the key only when both the 555 timer and the output line of the key are both simultaneously active.

At the time of original writing, I had some MPF-102s handy from the contact mic, so I used those thinking that it would be the same. It didn't work. I then used a power mosfet, which didn't work either because the SK1's button scan did not put enough voltage to fully flip the mosfet to either an on or off position. That was a diagnostic headache. Finally I came across a blog of a contemporary doing similar SK1 stuff who used a NPN (, so in the end I had to go with an NPN bipolar junction transistor and it finally worked! A red LED with a ballasting 1k resistor in parallel with the transistor on the 555 circuit serves as an indicator light.

Linear or Log pot? Using my new breadboard, turns out the linear taper gives me better control of the cycle time.

I am using a CMOS 555 chip, a PA 7555. Why CMOS? The LM555 was built in the 70s and draws dozens of mAs, which is way too much to run on batteries. The entire circuit above takes a bit less than 2mA to run. This current is drawn from the mic circuit of the SK1: off the proximal end of R113, VC on the schematics, and using the mic jack's ground trace as the ground (VL1). The timer itself resides on a piece of perfboard wedged under the mic.

The looping function does everything thought it would! It now repeatedly plays back programmed key sequences quite well. The accuracy of the timing requires very fine adjustments of the knob but it is reliable enough once it warms up after going through a couple cycles. Some outstanding issues: 1) a bit of added noise from the wire that connects the 555 output to the key spoofing transistor is audible when I switch on my line-in pass-through mod, 2) the pot for the timer knob is occasionally unpredictable, 3) when the auto-play button is triggered, any sustained notes being played stop.

Video of the looping sk1 in action to come soon! It's quite fun to play with!

Sunday, December 15, 2013

Contact mic

So a friend suggested that I should build a contact mic out of a pizeo disc speaker. So, built me one of these pre-amp circuits last Thursday:

Shown here is an earlier version, I later added a longer, thinner wire between the disc and the preamp, so the disc could be silly puttied to something without the amp getting in the way. Works really well! My prior experience with analogue semiconductor use had left me expecting a tempermental, finicky result, but it turned out ok! It's really great for picking up the shuffling noises of lentils tumbling in Tupperware.

Thursday, December 12, 2013

Hardware mostly completed!

How was i going to access the raspberry pi once i closed the case up and tightened all the screws? I had to add a power socket and a ethernet jack. The ethernet jack I desoldered from an old ethernet card i had in a box of junk, and cut a section of ethernet cable, and the mini USB jack i got off a pair of silent disco headphones i found on the street once. For structural integrity i surface soldered the jack onto a piece of perfboard and wedged it between structural components of the case. The power leads were soldered according to the following schematic:, with this as an example: (except i soldered ground to the 0 ohm resistor R51 instead of diode D17.

This is the final product. Everything was glue-gunned into place. The RasPi is screwed into the bottom half of a RasPi case which i glue-gunned to the spell and math case. Hopefully there isn't too much EM interference from the ethernet cable and the I2C interface onto the audio jacks, but we'll have to see.

Running the demo python program for the LCD. I am controlling everything via ethernet cable!
Regret: I took off the original red sticker where the red button is (and in the process destroyed it). Should've kept it. Maybe i'll make my own custom sticker to put there.

1) make the usb sound card work!
2)Program a python script to set up the membrane keyboard!
3) Consider putting more buttons in that white space or maybe a sticker!
4) Program the PureData looper patch!

Sunday, December 8, 2013

Setting up software, I2C, Python

Setting up the software, I2C, Python

I had to completely re-image my RasPi because i messed up a config file. So, might as well document the installation process!

1) Installed Raspbian. Configured it to boot to command line, with minimal memory to graphics.
2) Installed TightVNC. Instructions from This setup is so that the RasPi has internet access, and I can access it from my laptop. For a setup where i connect directly to the RasPi with an ethernet cable but without internet access, the following instructions can be used:
3) Install PureData.
4) Install Python to interface with GPIO and I2C interfaces:
Python is the officially supported language and offers pretty good speed on the GPIO, according to the benchmarks at Maybe once i figure out what i'm doing i'll switch to wiringPi, but for now Python is a nice language to use with lots of sample code.

For I2C: I'm using Adafruit's own python demo code.
The P5 header on the raspberry pi is not enabled by default, and needs to be configured before it can be used. Somebody posted a quick python program to do that configuration at
It also does not have a built in pull-up resistor on the two data pins, which are necessary for a I2C interface (see The I2C interface sends data by pulling the two pins low, and without the pull-up, the device is not even visible to the I2C driver (giving me a good ESD scare). Therefore I built my own pull-up resistors onto the external IC of the LCD shield. I used two 56K resistors soldered directly from the data lines to the 3.3V line.

For GPIO: I'm using the python rpi.gpio library. Here is my membrane keyboard / pushbutton interface. This is by far the most delicate thing I've tried to solder so far, and it's probably the most fragile part of the entire endeavor, so if this breaks, i'll etch my own PCB. I've decided not to use the keys on the I2C interface after all because the GPIO is much faster and supports interrupts so I don't have to poll them in a loop.
Also pictured: extension plugs with screw mounts for the USB dongle's 3.5mm jacks. That way, the attachment is more sturdy. The red pushbutton gives a nice tactile click and will be used to trigger record/stop.

Next steps: Configuring the USB audio to work, putting it all together structurally, and actually coding the damn thing! I'll be accessing the RasPi through TightVNC on my laptop from now on!

Saturday, December 7, 2013

The Raspberry Pi

An update on the Raspberry Pi Looper

This week in pictures:

Trimming the original LCD display frame so the Adafruit LCD unit can fit. The dremel at 35,000 RPM simply melts through the plastic with minimal dust, but the molten blobs of resolidified plastic have to be scraped off afterwards.

A piece of CD jewel case cover provides a perfect pane of protection against dust and fingerprints for the LCD.

All the components placed in their approximate final locations in the case. The board resting at a slant must be cut to make way for a structural support strut of the original case. Left: the PCB I will cut to allows interfacing with the membrane keyboard. Still deciding on the placement of buttons on the case though.

A "Leaning header of Pi5a" I soldered onto the Raspberry Pi board. This was originally an unpopulated header which can serve as a second I2C interface; you can see from the previous picture that the leaning header is not present in the original board. I chose to add this so it would not interfere with my use of the P1 GPIO pins. From 

The I2C interface complete! Originally the blue board and the LCD screen are supposed to be stacked, and the entire thing is supposed to be stacked on top of the Pi. But due to the constraints of the case, I had to separate them and connect them with the blue wires and create the P5 header. Lots of soldering involved. Pin out reference from

Coming soon: The GPIO membrane keyboard system.