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.


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: