Bridging the Raspberry Pi and the Arduino

Bridging the Raspberry Pi and the Arduino © GPL3+

Easily extend the Arduino capabilities to the Raspberry Pi 2 running Windows 10 IoT Core with C#.

  • 12,560 views
  • 10 comments
  • 38 respects

Components and supplies

Apps and online services

About this project

Introduction

I recently had a conversation with a colleague wanting to get into IoT. He was contemplating whether to buy a Raspberry Pi 2 or an Arduino Uno. He asked my opinion and I found I couldn't give him a clear answer.

Through my experience, I have come to understand that these two platofrms are not swappable. Both offer excellent advantages and disadvantages. In fact, they can easily be complementing platforms.

In a recent project I needed to use an Arduino to control some sensors and devices but the core of my project was based on the C# running on the Raspberry Pi. I found the excellent project posted by Christiano Faig titled "Arduino I2C communication with Raspi 2 WIOT" and was inspired. I immediately connected my Arduino Uno to my Raspberry Pi and was on my way.

In the project mentioned I knew exactly how I wanted to use my Arduino. I also knew, however, that I would most likely use this platform combination in future projects. I decided I needed to create a reusable library.

In this article I will share my library with you in the hope that you find it useful too.

C# Universal Library

Since the focus of this library is to control and Arduino from a Universal application running on the Raspberry Pi 2, I will start with the C# library.

Getting the Library

The library is available from two sources. The first, and easiest way to get the library is via NuGet. To install open the NuGet package console and enter

PM> Install-Package IoT.Arduino

The second way to get the library is to download the source code from GitHub and add it directly to your project. The GitHub link is included at the bottom of the page.

Using the Library

The first thing to do is to add the following using statement at the top of your source code file.

using Porrey.Uwp.IoT.Devices.Arduino;

Next, create an instance of the Arduino object and specify the address. The default is 0x04. The address can be changed by updating the Definitions.h file reloading your code to the Arduino.

Arduino arduino = new Arduino(0x04);

before using the library you need to initialize the connection. To do this call InitializeAsync.

await arduino.InitializeAsync();

Currently the library supports basic Arduino commands but will be updated regularly to incorporate more capabilities.

Here are some of the basic commands:

Set the output mode on a specific pin.

await arduino.PinModeAsync(9, ArduinoPinMode.Output);

Set the digital output value on a specific pin.

await arduino.DigitalWriteAsync(9, ArduinoPinValue.Low);

The commands currently implemented are:

Task<bool> PinModeAsync(byte pin, ArduinoPinMode pinMode) 

Maps to the pinMode(pin, mode) command.

Task<bool> DigitalWriteAsync(byte pin, ArduinoPinValue value)

Maps to the digitalWrite(pin, value) command.  

Task<ArduinoPinValue> DigitalReadAsync(byte pin) 

 Maps to the digitalRead(pin) command.

Task<bool> AnalogReferenceAsync(ArduinoAnalogReferenceType type)

Maps to the analogReference(type) command.  

Task<bool> AnalogWriteAsync(byte pin, byte value)

Maps to the analogWrite(pin, value) command.  

Task<ushort> AnalogReadAsync(byte pin)

Maps to the analogRead(pin) command.   

Task<bool> ToneAsync(byte pin, ushort frequency)

Maps to the tone(pin, frequency) command.  

Task<bool> ToneAsync(byte pin, ushort frequency, TimeSpan duration)

Maps to the tone(pin, frequency, duration) command.  

Task<bool> NoToneAsync(byte pin)

Maps to the noTone(pin) command.

Task<bool> ShiftOutAsync(byte dataPin, byte clockPin, ArduinoBitOrder bitOrder, byte value)

Maps to the shiftOut(dataPin, clockPin, bitOrder, value) command

Task<bool> EnableInterruptsAsync()

Maps to the interrupts() command

Task<bool> DisableInterruptsAsync()

Maps to the noInterrupts() command  

Task<byte[]> CustomCommandAsync(int registerId, byte[] data, int resultBufferSize)

Maps to any custom command added to the currently running Arduino sketch

Task<bool> BreatheLedAsync(byte pin, byte rate, byte step, byte offValue)

Cycles the intensity of a single color LED on the specified pin

Task<bool> NoBreatheLedAsync(byte pin)

Disables the call to BreatheLed()

Task<bool> PulsePinAsync(byte pin, ArduinoPinValue value, TimeSpan onDuration TimeSpan offDuration)

Pulses a pin with the given fixed intervals. This is not intended as PWM. This could be used, for example, to flash an LED for status purposes

Task<bool> NoPulsePinAsync(byte pin)

Disables a call to PulsePin()

Future Items

I am currently working on a set of built-in RGB LED effects. Note with the current library you can set any color using the analogWriteAsync method.

As project needs come up I will add additional methods to the C# library as well as the corresponding Arduino code.

Arduino Code

Library

The library is a standard Arduino library that is installed to your Libraries folder. Simply download the zip and add it to the Arduino IDE using the "Add .Zip Library..." menu under Include Library in the Sketch menu.

To learn more about installing libraries see "Installing Additional Arduino Libraries".

Use this link to download the RPi2 Bridge library: Download Library

The library has detailed logging to the Serial device that can be enabled. Be ware that when enabling this option the application will use more memory and in some cases you may run out of memory to run your code.

See the Definitions.h file for parameters that can be changed. Any changes to this file will require a recompile and upload of the code.

Sketch

There are several samples sketches. The Standard sketch will get you up and running with the basic commands shown above. The Basic sketch is limited to the standard Arduino commands. If you need more advanced interaction use one of the other examples or build your own sketch with custom commands.

To load the various sketches use choose Examples in the File menu of the Arduino IDE and select Rpi2 Bridge and then select one of the sketches.

Advantages/Disadvantages

The greatest advantage to this is that you can get up and running quickly and utilize the Arduino in your C# code. Sensors that are very difficult use on the Raspberry Pi such as the DHT11/21/22 or your NeoPixels can now be used easily. Connect these sensors or devices to your Arduino as usual, load the libraries and then call the commands from the C# code to get them going.

Another advantage is that with the Arduino Bridge you can eliminate the need for extra devices such as a PWM for LED's or an ADC chip. The best "out of the gate" use I found was with the analog pins as well as the PWM ports since both of these are not available on the Raspberry natively (the one PWM port on the Raspberry Pi is not currently available under Windows 10 IoT Core).  

The biggest disadvantage to this approach is that it would be very easy is to under utilize the processing power on the Arduino and over use the processor on the Raspberry Pi. This is one of the reason I left room for custom commands. One of the sample sketches shows how to read the temperature and humidity from a DHT22 (will also work with DHT11). This custom command places the overhead of the specific timing requirements of this sensor on the Arduino instead of the Raspberry Pi. This sketch is called Dht22.ino.

Another disadvantage of this approach is that you lose some flexibility. For example, if you are reading a sensor using the shiftIn() command it would be very difficult to map this back to the Raspberry Pi through a single command. This approach will not fit every situation but will certainly make some previously impossible scenarios now possible.

Summary

This library is a great way to build on your existing hardware and not worry about whether to choose the Raspberry Pi or an Arduino. It enables both to be used seamlessly in a single project.

See Also:

For other ways to use the Arduino with Windows 10 and UWP applications.

Windows Remote Arduino

Windows Virtual Shields for Arduino

Arduino Wiring and UWP Lightning providers

Additional Information

I have tested this library on the Arduino Uno, the Adafruit Trinket Pro 5V and the Adafruit Trinket Pro 3V.

Code

C# Source Code
Look for the project called Porrey.Uwp.IoT.Devices.Arduino.

Comments

Similar projects you might like

Home Automation Using Raspberry Pi 2 And Windows 10 IoT

Project tutorial by Anurag S. Vasanwala

  • 297,270 views
  • 98 comments
  • 706 respects

Interfacing Arduino with Raspberry Pi

by Sankar Cheppali

  • 84,841 views
  • 9 comments
  • 25 respects

Home Automation system using Raspberry Pi

Project tutorial by Christian Kratky

  • 127,573 views
  • 34 comments
  • 404 respects

DHT Tiny Breakout for the Raspberry Pi

Project tutorial by Daniel Porrey

  • 6,152 views
  • 5 comments
  • 15 respects

DHT11 /DHT22 Temperature Sensor

Project tutorial by Daniel Porrey

  • 82,653 views
  • 106 comments
  • 133 respects
Add projectSign up / Login