Multiplexer vs ADC

As I’ve been preparing to build a test circuit using the CD4051 multiplexer, I’ve realized that a multiplexer isn’t an ADC. The CD4051 is an 8:1 multiplexer meaning that the Raspberry Pi will select which of the 8 inputs to select to read from the 1 output. That’s fine and dandy if all I want to do is to check whether a drum pad has been hit. It’s a 1 or a 0 for on off.

However, if I want to determine velocity ( how hard the pad has been hit ), I need to be able to measure voltage too. This is why I need the ADC.

I still have the MCP3008 ADC chip from my previous circuitry. So, what I’m planning to do is to connect the output from the CD4051 to one of the inputs on the MCP3008, select the CD4051 input using 3 GPIO pins and then permanently select the single input on the MCP3008 and measure the voltage.

At least, that’s the theory. First step is to get the Raspberry Pi talking to the CD4051 in the first place. I’ve laid the groundwork down by making sure I understand exactly which GPIO pins to assign to be the A/B/ C input select on the CD4051. Next, I’ll build up the circuit for the drum input using the LM324 op-amp.

 

Like a phoenix from the flames….

It’s been a (very long) while since I did anything with this.

I’ve been focussing on the code to get a MIDI event from my binary to Logic Pro X and I took a long break between iterations 🙂

However, I have succeeded. I’ve put the code on GitHub ( http://github.com/ravelox/pimidi.git ).

The next step is to build a circuit again. I’ve found a different approach that will mean I don’t need to guess when the drums are hit. Information is at http://www.pjrc.com/tech/midi-drums/sch-ana1.html

What’s the (decimal) point ?

So guess who read the capacitance incorrectly ?

4.7uF is *not* the same as 4.7nF. Like I suspected, I’m using a capacitor that’s too big for the job. So, I’ve ordered some nano-Farad capacitors.

I played around with replacing the 1M ohm resistor with a variable potentiometer and that allows me to “tune” the signal a little more so that I can make the circuit more or less sensitive.

I think I also need to change the algorithm that’s sampling the data because it has some problems where it’s still measuring the decay (which should go away once the right capacitor is in place) but it’s also displaying the same measurement in a short period of time (milliseconds ?).

I did have it so that the measurement is only done when the delta between the current reading and the last one was positive ( an increase ) but that doesn’t allow for when I go from a hard hit (high number) to a light tap ( low number ). I figure that if the capacitor was smaller, the voltage will be held for a shorter amount of time and will drop to zero quicker meaning that sampling a positive delta will always be an intended event. TIme will tell. I’m just waiting for the postman now.

It's Alive !

It’s Alive !

The Circuit

I actually got the circuit wired up again and, somehow, it seemed to work this time. I saw a voltage change with small taps and large hits so the next step was to connect the ADC (MCP3008) and the Pi Cobbler (GPIO cable connector).

So, I consulted the project at http://learn.adafruit.com/reading-a-analog-in-and-controlling-audio-volume-with-the-raspberry-pi/overview and wired up the GPIO pins to the ADC per their instructions.

I also took the python script from the same project and hacked it to remove the audio volume stuff.

It was during my initial test that I found I had connected the GPIO cable the wrong way round on the Pi which meant that nothing worked. My first thought was that I’d broken something but I pulled everything out and did a quick LED test ( see https://projects.drogon.net/raspberry-pi/gpio-examples/tux-crossing/gpio-examples-1-a-single-led/ ) which proved that none of the GPIO pins were responding as they should have done. So, I took the case apart, turned the cable around and reassembled everything. This time, the LED test worked as I expected (cue a quick Gangnam across the living room to celebrate ).

After wiring the ADC up again, it was a success as this video shows:

 

Next to do is to remove the capcitor to see if I can get the slope to decay much quicker.

Information burst

More reading, more changes of mind.

As my requirements for this MIDI interface are limited only to sending notes, I came to the realisation that I don’t need to handle journals inbound to me and the only journal I need to create outbound is a Chapter N for NOTE ON/OFF events. After playing with reference implementation and copying most of the sample code from the RFC, I’ve taken it all out again and I’m starting from scratch. The RFC code isn’t the best example of a Chapter N journal so I need to go over the details again and translate the concept. I’m sure it’s relatively simple, I just need to wrap my head around it (I’m a bear of little brain).

I have 2 binaries right now. The first is a simple Avahi registration app that publishes host and port 5004 and the name of the service (_apple-midi._udp). The second listens on the ports for events. The listener app is correctly unpacking the Apple MIDI events. I did clean up some segfaults when the OS X MIDI app ends the session ( by sending a BY event ). I’m debating whether I want to handle just 1 session or multiple.

On the hardware side, having got a little bored of starting at C code, I spent some money at Radio Shack and other places to get capacitors, resistors, diodes and also some 3.5mm audio inputs that are breadboard combatible.

I did some reading up on how to handle the drum pad inputs. As the teardown showed, it’s a piezo trigger and, according to the internet, that requires some special handling.

The following pages are useful information: http://petervieth.com/projects/midi-drum-pad/ and http://leucos.lstilde.org/wp/2009/06/piezo-transducer-signal-conditioning/

They show the circuits needed to handle a piezo input.

Here’s my problem right now. I built the circuit using the info from Peter Vieth’s page and, if I connect up my multimeter, I can see there is a change in voltage when I hit a pad but it’s very small. Some of the many questions I have is whether I’m supposed to be seeing such a small voltage change ( which I saw when I first tested the pad a couple of months ago ). In some cases, with light hits, I don’t see a change at all.

I connected the drum pads back up to the controller they came with and they play fine. Light hits are registering so I know I haven’t broken anything ( hard to do seeing as it’s a piezo trigger ). The controller uses a 9v DC input and I’ve hooked my circuit to a 9v battery but see little change.

The other question I have is whether I’m actually using my multimeter correctly or if I should even be seeing anything register with a multimeter. The info on the Leucos site shows some good data using an oscilloscope but I don’t want to get into that at my stage of life ( $$$ ).

 

I guess more reading is in order. I have some work colleagues that are part of Noisebridge (www.noisebridge.net) and they have sessions on a Monday  which helps members learn about circuits’n’stuff so I may check them out.

Slight change of code

Well, the original intention was to use pybonjour and dpkt but it got a little complex when I actually read through the RTP-MIDI RFC ( http://tools.ietf.org/html/rfc4695 ) and got to the section on journals.

I’m hoping that the reference code at http://www.cs.berkeley.edu/~lazzaro/rtpmidi/ will achieve what I need. I’ve looked it over and can see that there is specific handling of SIP packets.

SIP is used by standard implementations but Apple ( in their infinite wisdom ) uses their own protocol. So, I’ve written some C code to handle pack and unpack of buffers into data structures and vice-versa. This will be a replacement for the SIP code in the reference. My test code works with each buffer I’ve taken from packet captures. It unpacks into a data structure and I can then pack that data structure into a new buffer that matches what I read originally. A quick valgrind leak check shows that I’m not leaking memory 🙂

Now that I’m switching to C, I needed to look at avahi (http://avahi.org/ ) to register the service instead of pybonjour. There is a simple client example at http://avahi.org/download/doxygen/client-publish-service_8c-example.html which I will modify to my own requirements.

The sample uses a polling loop which never returns control to the calling program so I either have to run it in a thread ( which I don’t really want to do ) or to poll at regular intervals. Regular intervals works better because I also need to check the inbound UDP ports for RTP and AppleMIDI events. It also means that I can create a listening socket of some kind to receive input events from any other code I write to read the GPIO data from the interface.

Good job I have a few days off this week 🙂

Little things please little minds

I ran the register_service.py script at the same time as the following UDP listener:

#!/usr/bin/python
import socket
HOST='192.168.0.226'
PORT=5004
s = socket.socket( socket.AF_INET , socket.SOCK_DGRAM )
s.bind( (HOST, PORT ) )
buffer = s.recv(1024)
print buffer.encode('hex')

The service shows up in the Audio MIDI setup. When I connected to that server, the output was:

ffff494e00000002663348739ec3dbe341433700

which matched up with expectations !

I’m looking at DPKT ( http://code.google.com/p/dpkt/ ) to help me construct the data packets in Python seeing as I really don’t have the energy to play around with bytes.

I needed to create a parser for the initial Apple MIDI conversation.

import dpkt
class COMMAND(dpkt.Packet):
 __hdr__ = (
 ('signature', 'H', 0),
 ('command', '2s', 0),
 ('version', 'I', 2),
 ('initiator', 'I', 0),
 ('sender_ssrc', 'I', 0),
 ('name', '4s', ''),
 )

However, I need to look into the fact that name can be any length and is null-terminated. DPKT works on fixed lengths.

Hello, hello ?

More information is in the Wireshark dissector for Apple MIDI at http://anonsvn.wireshark.org/wireshark/trunk/epan/dissectors/packet-applemidi.c

Intial packet capture shows that the Audio Midi software makes the initial invitation:

Apple Network-MIDI Session Protocol
 Signature: 0xffff
 Command: Invitation (0x494e)
 Protocol Version: 2
 Initiator Token: 0x6b8b4567
 Sender SSRC: 0x1c037394
 Name: AC7

To which the application replies:

Apple Network-MIDI Session Protocol
 Signature: 0xffff
 Command: Invitation Accepted (0x4f4b)
 Protocol Version: 2
 Initiator Token: 0x6b8b4567
 Sender SSRC: 0xa3a202f2
 Name: Ravelox iPad

The commands are IN and OK.

The Initiator Token is a value that is randomly generated by the session initiator and is used throughout the conversation, the Sender SSRC is generated by each side and remains the same.

Playing with hardware

Playing with hardware

My original multimeter failed me. It wasn’t either the battery or the fuse so I revisited Radio Shack and $21 later, I got a new one.

The drum pad just houses a trigger.

IMG_0644

 

So I wired a drum pad and a drum pedal to a 9v battery and attempted to measure the voltage:

The pad seems to vary in voltage when it’s hit. It doesn’t fluctuate when it’s not hit.  I’m quite willing to accept that wiring up a 9v battery is less than ideal here but it’s indicative of the fact I *will* need the ADC.

The drum pedal really acts as a switch so an ADC isn’t required here.