Electronics, music, electronic music! general geekery


C# and Arduino: Reading Sensor Data

In my last posting I showed how to write a very basic C# console app and Arduino sketch to demonstrate serial communication between a PC app and Arduino. In this article we'll add sensors to expand further on the idea and introduce a few (hopefully) useful patterns for both the console app and the Arduino sketch. To complete this exercise you'll need:

Let's explore the new patterns introduced in the Cereal app and Arduino sketch.

A Life-Changing Eventhandler

Okay, maybe it's not quite that dramatic, but the event handler is a significant improvement since it lets the console app handle incoming serial data without tying up resources waiting for a response. Technically this is known as asynchronous behavior, and it has the effect of decoupling the code for sending the message from the code for receiving/processing incoming data. If your app could talk, it would say something like "I'm sending you a message now and you can respond whenever you want. Now if you'll excuse me I have other things to do." Then whenever data is received, the event handler processes it accordingly.

First we declare the event handler, which effectively binds it to the DataReceived event. Then we add the sp_DataReceived method, and add code to process the data:

In the preceding example the event handler does a little bit of cleanup on the incoming data by removing the opening "[", then prints the data to the console. The example is intentionally simple, but you can do lots of other tasks with the event handler, such as saving incoming data to a log file, or perhaps triggering some action when the value crosses a certain threshold.

Add a Sensor to the Mix

In order to do something vaguely useful, we will now walk through adding an ambient light sensor to get some readings of the, um, ambient lighting. If you are not familiar with the process of connecting things to Arduino, you are in for a real treat because it's FUN! There is a great tutorial for the light sensor which is very helpful for newbies (and old-bies like me) and includes a simple sketch that you can use to test things out. Note that this is where your soldering iron will come in handy for soldering the header pins to the breakout board. Also note that all of this code will work with any type of analog sensor.

Get Sensor Readings in Cereal

Upload the Light Sensor sketch to your Arduino, then launch Cereal. When you enter the "v" command, the Arduino should shoot back whatever the current reading is.

Send a Stream of Data

If sending a request for individual readings seems like a drag, you can set up the sketch to spew out a continuous stream of data. In the loop() section, there is a call to sendReading() which grabs the current reading and prints it to the serial port. Remove the comments so that it looks like this:

Now the Arduino sketch will send a new reading every 100 milliseconds. If you run Cereal now, you should see the values and not much else. If this is all you need, then that's great! This isn't ideal though, since we have not given ourselves a way to turn off the streaming. Luckily the code to do this is pretty simple.

Remember how the loop() runs the entire time the sketch is active? We'll add a flag called stream that will toggle whether the data is sent in a continuous stream. First let's add a new boolean variable for the flag:

Now we'll replace the original call to sendReading() with an if statement that will only call sendReading() if the 'stream' flag is set:

Finally, we'll update the switch statement in processCommands() with a new case, 's'.

Now when you run Cereal just type a lowercase 's' to toggle the continuous data stream.

You can get the complete updated code example here.

Who Turned Out the Lights?

The last thing we'll do is update the Arduino sketch so that it does something when the light level drops below a certain level. First, at the top of the sketch uncomment int led = 13;. This variable will help us to identify the default LED pin.

Next, add the following code to the loop():

As you can see, this code reads the current level from the light sensor, then turns on the LED and sends a short message over the serial port. That's pretty much it. I hope this tutorial has been enlightening, tinkering around with this stuff has been a great learning experience for me particularly around the various programming patterns that you can implement to make these gadgets do your bidding.


Make C# talk to Arduino!

I recently wrote a short tutorial about connecting an Arduino to a Lab of Things hub. If you're not familiar with Lab of Things (LoT), it's a platform for research using connected devices (think home automation and energy usage for example). Using LoT, a researcher can deploy and monitor sensors/devices in hundreds of locations. Because of what it is designed to do, LoT is fairly complex. In an attempt to keep my head from exploding I created a very simple C# console app called Cereal to test serial connections outside of the LoT platform code. In this tutorial we'll walk through a much simpler example to introduce the concepts without too much noise. In the next installment we'll cover some useful patterns for sending commands and handling sensor data. For now however we'll keep it simple, so let's get C# talking to Arduino.

Note: To complete this exercise you'll need Visual Studio (or other C# compatible IDE), an Arduino and the Arduino IDE.

The very first version of Cereal was as bare-bones simple as possible. To run SuperSimpleCereal, just create a new C# console app and paste in this code:

To accompany the super simple example, I adapted an equally simple Arduino sketch from the LoT Arduino example:

If you upload the sketch to your Arduino, then run the SuperSimpleCereal console app, you'll see the device ID string (as defined in the sketch) display in the console window. So now you can see just how simple it is to send and receive messages programmatically. Square brackets are used to delimit messages coming from the Arduino, which makes it easier to parse. You can change the console app to send "[L]" and see the other message. I like these examples because they're short and sweet, but there is clearly much more you can do (I'm thinking sensors). Stay tuned for the next installment where we'll take a closer look at Cereal.


Middle Aged Engineering Grum-P-Lab: connect and read sensor input

When I left off from Part 1, I had plugged the Teensy into the computer and loaded the flash program to make sure it works. The next phase involves loading Firmata onto the Teensy, and getting some sensor input into MaxMSP. Note that Firmata and MaxMSP are just two of many software possibilities. Other programs that are great for doing stuff with sensors include the free open-source PureData, and Processing applications.

To load Firmata onto Teensy, download and install the Teensy loader if you haven't already done so. Then, pick up the special Teensy version of Firmata from here. Follow the instructions for loading Firmata onto the Teensy and you're good to go.

For my first sensor I'm going with the pressure sensitive resistance pad. When you press on it, the resistance goes up! I have soldered it to the end of a 3.5mm male cable. One lead of the pressure pad is connected to the ground wire of the 3.5mm cable, and one to the positive wire (tip). You can ignore polarity for the pressure pad. This diagram shows the circuit (Teensy on the left, audio breakout on the right, pressure pad assembly is not shown - it's plugged into the breakout):

  • +5V to TIP
  • GND to GND (10k ohm resistor)
  • A0 (38) to GND

If you omit the +5V line all you'll get is noise. When I load the Max patcher and press the pressure pad, I can get a good signal. Woo-hoo! This could be set up to go to a pitch bender, bit crusher, purple spotlight, vacuum cleaner, or whatever. You can alter the response of the pressure sensor by placing other thin materials on top of it (if you're building it into something you will probably do this anyway). My feeling was that it tends to dampen the response a bit. This is good since at light pressure the reading is a bit jittery. Also you can play with the resistance on the +5V to change the high limit. 120k ohms worked for me but your mileage may vary. If you are building this into something a trimmer resistor might not be a bad idea here.

Here is a screenshot of the Max patcher. You can set it to print the analog values, and the other part flashes LED 6 for an easy way to make sure your serial connection is working.

And the code:


Introducing the Middle-Aged Engineering Grum-P-Lab

If you like the idea of controlling music and other stuff using sensors, then you will probably love the Oplab from Teenage Engineering. It's a really smart, inspiring piece of kit which takes physical input (taps, gestures, pressure, shaking, etc.) and outputs the resulting signals in USB, MIDI, and even control voltage, which you can plug in to your favorite electronic instrument or software. I love the idea of Oplab, but I can't justify spending $300 on it. I figure I can create a microcontroller-based sensor-oriented I/O system with an eye toward modularity, expandability, and ease of use. I'm thinking that once the initial work is complete, it should be something I can just reach for and use with a minimal amount of fiddling around.
For a microcontroller, I chose the Teensy++ over Arduino. It's also AVR-based, it's got more pins, it's native USB/HID/MIDI, it's smaller (fits on a breadboard) and it's cheaper. You can even program Teensy boards using the Arduino software if the C language isn't your thing. You can pick up a Teensy for a measly $16, $24 for the Teensy++. The regular Teensy actually has a few more analog ins than the Teensy++ so that's one thing to consider.
As for the sensors, I put together an assortment of items including a piezo disc for a percussion sensor, a pressure-sensitive resistor pad, an accelerometer, and an ambient light sensor. Those should be a good starting point. To make it modular, I am using standard 3.5mm audio connectors to connect the sensors. For cables I picked up some 3.5mm male to male connector cables (the kind you use to hook your iPod to a stereo). I'll cut those apart, and solder the sensors on, probably with some heat-shrink to make everything tidy. This approach will also transition nicely to an enclosure should that stage be reached. For now, everything takes place on a breadboard, which the Teensy++ plugs directly into. Since Teensy supports USB, you don't need to fuss with a power supply (of course it can run on batteries if needed).

What a nice collection of items! If only I had some sort of special container to store it all in, like maybe a tray or something.
In terms of software, my first choice is MaxMSP and the Maxuino library. Maxuino requires the Firmata library to work. I wrote about this a while back: Interfacing MaxMSP and Arduino. In a nutshell, you load Firmata onto your Teensy (or other Arduino-compatible). Maxuino communicates using the OSC protocol, and facilitates I/O from within MaxMSP. My initial step is to make sure Teensy works by following the instructions here. I got a blink, so far so good!!! Next step: get a sensor and send a signal into MaxMSP.


M-Audio Axiom 61 Mainboard Replacement

UPDATE: As it becomes more difficult to locate replacement parts for the keyboard, some may despair. But don't give up hope! I have stumbled across a brilliant solution (by a really smart dude). There may be a way to fix your mainboard, but it is rather technical and involves a bit of soldering and knowledge of how to flash an ARM 7 chip: It's a long thread, but I think it contains enough info to get the job done. If anyone tries this, please drop a note.

A couple of years ago I bought myself an M-Audio Axiom 61 MIDI controller keyboard (first gen). It's a pretty nice little unit, and it provided me with some good usage until one day it decided to just plain not work anymore. I turned on the unit and all I got was a blank blue screen. A few forum searches later, I found some postings where other folks have had similar problems. The possibility of replacing the mainboard was mentioned more than once, and a particularly detailed posting from an Avid support tech revealed that the first generation had issues with the microcontroller failing due to an unspecified grounding issue. So I opened a ticket with Avid. Several fruitless exchanges later, I finally got the number for the Avid Spare Parts Department: (626) 610-2529, Monday–Friday, 9am – 5pm Pacific time. I ordered a new mainboard, and it cost about $47 with shipping. That's a heckuva lot cheaper than buying a new keyboard.

The old card was v04, the new one is listed as v06. Interestingly, on the old board the power regulator did not have a heat sink, but the new one does. My guess is that this is more prudence on the part of the engineers, since those little suckers can get pretty hot. I'm sure they made many other improvements as well, but I'm just banking on having it actually work. I prefer functional equipment.

I set up my work area with a couple of books upon which to rest the ends of the keyboard, to avoid stress on the panel elements. On my poor keyboard a few slider heads got snapped off while it was being stored in the closet, so I took this step to prevent further damage. I have some cups to collect various sizes of screws, masking tape and a sharpie to label the cable leads, and a couple of screwdrivers.

Before starting I took a digital snapshot of the mainboard, numbering each terminal to avoid confusion. I then labeled each cable with the corresponding number from the picture. I flipped the keyboard over, resting the ends on top of the books to keep the knobs and sliders from resting on the table. Man there are a lot of screws! There are a dozen medium-sized screws right down the middle, a dozen smaller ones in wells along the edges, and 10 deep wells on the back of the case. All of the screws need to come out in order to take the case apart (which you probably could have guessed but I mention it here anyway).

Once all of the screws were loose I grasped the unit firmly on each ends and inverted it face-up, employing gravity to get the screws out. A brand new nice guitar pick fell out too, because I'm special like that. I did this in a safe place so as to lose no screws. It's helpful to note which screws came from which holes, as there are four types in use. I flipped the board back over and set it face up on the worktable with the rear of the unit facing me. The top and bottom are connected by a bunch of ribbon cables which are taped. Also, the front fascia of the top lid (just beneath the front of the keys) is really thin and easy to break. I gently removed the tape and flipped the upper case away from the lower case, like opening a book. Note that the keys are part of a separate assembly, and can be shifted out of position. I left the keys sitting in the bottom half of the case and tried not to disturb them. Ebony and ivory should remain together in perfect harmony. The arrow in the next photo points to the mainboard.

Now it's time to label the cables according to the numbered photo of the mainboard. Yes, I know, all but three of them are different sizes. However, I prefer to err on the side of caution. Each terminal has a small slot to the side, which corresponds to a small "tab" on each side. I had to examine the replacement mainboard to get a better idea of how these fit. I used a small screwdriver to release the tabs on them. Note here that it is important to use caution and never force anything. Once the cables were disconnected, I unscrewed the old board, noting the ground wires on each corner (these will need to be reattached when mounting the new board). I had to slide the board back a bit, then it was easy to remove. Lastly, I removed the board's own ground wire from the chassis. Time to put in the new board.

When mounting the replacement board, I first set it in and slid the non-connector end into the case on the key side, as shown below. The connectors now need to be aligned into their mounting holes.

I found that it was easiest to angle the board up a little so that the tops of the connector jacks just fit under the tops of the mounting holes (it's a snug fit). I then slid the board forward a bit, and gently nudged it until all of the screw holes lined up. Note that the tops of the MIDI I/O ports will end up resting against the inside of the mounting area, they don't go under. The USB port and AC jack need a little cajoling however. When the screw holes line up it snapped into place and I could see that all of the holes were properly lined up.

I screwed in the replacement board, attaching the ground wires on the corners (the two ground holes have a little circle of copper around them). There is a ground wire that is attached to the replacement board. Mine was too short to reach the original attachment point, so I attached it to part of the metal frame that was closer. I used the diagram I made earlier to reconnect the ribbon cables to the terminals, double checking my work before closing the case, taking care that no cables got pinched. Then I flipped it back over and put all those screws back in. The big round-head phillips go into the 12 recessed holes on the back. The small screws with coarse theads fasten the front fascia (the thin part underneath the front of the keys). The small fine-threaded screws go into the recessed edge holes. The slightly longer coarse-threaded screws go into the deeply recessed holes on the back. The 1/2" lag bolts go into the titanium mounting bosses on either side. Just wanted to make sure you're paying attention.

Testing time!!! A number of Avid forum posters remarked that the Axiom 61 performs at its best when it has the maximum amount of USB power available at the port. If you think all USB ports supply the same quality of power, think again. Self-powered hubs (the kind that come with their own wall wart) are generally your best bet. I am going with the IOGear 7-port that is on my desk right now. And I am seeing the blue screen of LIFE this time! After using my Akai MPK25 continuously for several weeks, this feels so lush! The keys are pretty decent quality, and they have aftertouch too. I really like this keyboard and I'm so glad it's back on my desk! Now about those broken sliders. Hey, at least I have the Avid Spare Parts Department phone number. Then again there is always super glue.

Tagged as: , 38 Comments