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.