Arduino and Pi in Harmony

The Arduino and Raspberry Pi both have their pros and cons. The Arduino has great IO with thousands of additional sensors and libraries but has limited RAM and processing speed. The Raspberry Pi on the other hand is a powerful minicomputer, but is somewhat limited in the IO department. In this project we will combine the forces of the Arduino and Raspberry Pi, to create the perfect harmony.

For this demo we will be making an Infrared Thermometer with web interface. The Arduino will connect to the Freetronics Infrared Thermometer module while the Raspberry Pi will act as the server with some python running on it to handle the server side code. I’ll be using the Pi Zero W, but any version of the Pi should work fine.

Download Project Source

Licensed under the MIT license, you have access to all the source code and schematics to build your own version


ADVERTISMENT


The Build

Parts needed

  • A Raspberry Pi variant
  • An Arduino variant
  • (optional) your favourite Arduino sensor to interface with

Hardware

The interface between the Arduino and Pi can be done via USB or through the GPIO pins.

USB

If your connecting over USB its simple. Just plug the Arduino into the Pi with the USB cable. Your serial port on the pi will most likely be:


/dev/ttyACM0

GPIO Serial

If the Arduino you are using doesn’t have USB, such as the Arduino Mini, or your using the ATMega or ATTiny microcontrollers and you don’t want to use an FTDI chip, then directly connecting over serial is the way to go. Remember to update the code to use the new serial port:


/dev/ttyAMA0

It’s important to remember that most Arduino and Pi’s run at different logic levels, with most Arduino’s running at 5 volts and the Pi running at 3.3. In that case you’ll need some sort of logic level conversion. To do this you can use a logic level converter such as this one from SparkFun or with a resistor divider to step-down the 5V logic of the Arduino TX to 3.3V on the Pi’s RX. The Arduino will survive with 3.3V coming into its RX. Hackaday has a good article on making 3.3 and 5 volt logic communicate.

Note: These examples use pins 4 and 5. Use this if your using a library such as SoftwareSerial, otherwise use pins 0 and 1 for hardware serial

Using a logic level converter
Serial connection with logic level converter module

Using a resistor divider
Serial connection with voltage divider

Sensors

How you connect the sensors to the Arduino is up to you. For this demo I’m using the Freetronics IR Module with my shield connected for easy connectivity.

IR Module connected to Arduino

Software

Arduino

This demo code for the Arduino is very simple. Get the data from the IR module and send it to the Pi. The data is encoded with a colon separating the data so that we can split the values out on the pi. If your connecting the Arduino directly to the Pi’s GPIO you may wish to use the SoftwareSerial library otherwise remember to disconnect the Arduino from the Pi before flashing the code.

Arduino IR Temperature

Arduino sender unit for IR thermometer


/*
 * Demo code for an arduino sensor sender unit
 * Sends back IR temperature and ambient temperature every second
 * over serial
 *
 * Project details at
 * prototypingcorner.io/projects/arduino-and-pi-in-harmony
 *
 * MIT License
 *
 * Copyright (c) 2018 Prototyping Corner
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "IRTemp.h"

static const byte PIN_DATA   = 4;
static const byte PIN_CLOCK  = 5;
static const byte PIN_AQUIRE = 6;
const int LED = 7;

static const TempUnit SCALE=CELSIUS;

IRTemp ir(PIN_AQUIRE, PIN_CLOCK, PIN_DATA);

void setup() {
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
}

void loop() {
  digitalWrite(LED, HIGH);
  float irtemp = ir.getIRTemperature(SCALE);
  float ambtemp = ir.getAmbientTemperature(SCALE);

  // IR:AMB format
  Serial.println(String(irtemp) + ":" + String(ambtemp));
  digitalWrite(LED, LOW);

  delay(1000);
}

Pi

Before continuing with the Pi software make sure you have set up your pi with the latest version of Raspbian.

Update Pi and install apache, python and flask


$ sudo apt update
$ sudo apt upgrade
$ sudo apt install apache2 libapache2-mod-wsgi python-setuptools python-serial python-flask

Install apache, python and flask

Test that apache was installed correctly by going to the IP address of the Pi

Default apache site

Installing the code

Get the code for this demo from the GitHub repository


$ git clone https://github.com/prototyping-corner/Arduino-and-Pi-in-Harmony.git

Create the new server directory and copy the code to it


$ sudo mkdir /var/www/server
$ sudo cp -a Arduino-and-Pi-in-Harmony/code/server/. /var/www/server/

Configure apache to use the new config


<VirtualHost *>
  WSGIDaemonProcess server user=pi group=www-data threads=5
  WSGIScriptAlias / /var/www/server/server.wsgi

  <Directory /var/www/server>
    WSGIProcessGroup server
    WSGIApplicationGroup %{GLOBAL}
    Order allow,deny
    Allow from all
    #Require all granted
  </Directory>
</VirtualHost>

Take down the default config


$ sudo a2dissite 000-default

Copy the new config to sites-available and enable it


$ sudo cp Arduino-and-Pi-in-Harmony/code/server.conf /etc/apache2/sites-available/
$ sudo a2ensite server

Make sure the mod_wsgi module is enabled


$ sudo a2enmod wsgi

And reload apache


$ sudo systemctl restart apache2

Now plug in the Arduino and visit raspberrypi.ip/demo
Demo webpage

This demo replaces the values in the output_template.html file with the values from the serial port. Refreshing this page will get the next set of values. Refreshing the page to get updated values isn’t a very user friendly experience so the JSON demo returns the values in the JSON format for use by client side code such as javascript to update DOM elements without need to refresh the entire page.

Demo JSON

This also enables more advanced features and graphics to be rendered client side such as graphs and charts.

If you get internal server errors take a look at the apache error log to find out what went wrong


$ sudo tail /var/log/apache2/error.log

Done

That’s it! Now you have a Python server that can communicate over serial to an Arduino. If you run into any problems let me know in the comments and I’ll try to help you out.

Support Prototyping Corner

Consider supporting Prototyping Corner by making a small contribution to our work or take a look at other ways to support us


Leave a Reply

Your email address will not be published. Required fields are marked *