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:


Handy Maxuino abstraction

If you like making Arduino talk to MaxMSP, there are few things as nice and simple as Maxuino. A while back I wrote about using Maxuino and Firmata, and included my own patch which I unfortunately named "Maxuino simplified". Looking at it now, it doesn't really simplify anything! It did help me with understanding how to use Maxuino, but that's about it. As I bust out my Arduino once again, I have done a bit of work to actually simplify using Maxuino in my patches (see the bottom of this post for the MaxMSP code). I encapsulated Maxuino into a patcher that you can load into a bpatcher object. The inlet accepts OSC messages to Maxuino, the output spits out messages from Maxuino. From the panel you can select a COM port and activate the Maxuino example GUIs since they do come in handy. Here is an action shot:

Another thing I do is use a coll to initialize my pin modes. Put your pin mode settings into the coll using this format:
1, /0/mode 1;
2, /38/mode 2;
3, /39/mode 2;

Connect the coll to the inlet of the Maxuino bpatcher and send a dump message to the coll.

Here is the MaxMSP code (copy to clipboard, open Max, select File, Open from clipboard). Be sure to install Maxuino into your Max search path.

Filed under: Arduino, MaxMSP No Comments

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.