Project tutorial
What you can do when a Raspberry Pi teams up with an Arduino

What you can do when a Raspberry Pi teams up with an Arduino

The ArduinoPi is a web-based controller for the Arduino using the Raspberry Pi.

  • 3,885 views
  • 0 comments
  • 5 respects

Components and supplies

About this project

The principal behind ArduinoPi

First a little clarification, the ArduinoPi isn’t really a library or a command set or an out of the box controller, its more a proof of concept using already know programming languages. If you want to use it be ready for some PHP, CSS, HTML, C++ and jQuery!

The principal is as follows: The Arduino is connected as a slave device, meaning it waits for a command, execute it and maybe return a value or something. Everything must be initiated from the web browser. A true slave device.

It’s also possible for the Arduino to execute its own program and the ArduinoPi can then be used as a controller to switch variables. For example I have an automatic light switching system but using the ArduinoPi controller and my web browser I’m able to manually override it. ## The command set of the ArduinoPi

The Arduino will check for a valid command. Every command starts with @ and ends with :, variables can be separated with a comma. Of course other commands can be added yourself, I’ve found that these are the basics and cover enough to make some interesting interfaces.

Basic Switch-port-high command
@6,255: 

This command is sent to the Arduino, for example this will switch port 6 high (255 = HIGH). The first value in this command must be between 0-99, which corresponds to the port number. Note that there is no checking so always see the port is set in OUTPUT mode and you are addressing the right port.

RGB Command

I’ve also added a RGB command for LEDs, this is a special command and is constructed as follows:

@101,245,23,0: 

The 101 indicates the special command mode and the following 3 values are just the RGB values. In my example setup I’ve added 3 RGB LEDs and they all get turned on to the right value using the RGB command.

Read Sensor Command

The last command is the sensor command. It will read an analog sensor value and return it to the PHP script.

@102,6: 

The 102 indicate a special command and the following value indicates the port that should be read using analogRead().

My test setup for the ArduinoPi

My test setup for the ArduinoPi

I’ve used the following components for testing various functions: 3 RGB LEDs + resistors and a light sensor. The example will work with the following configuration. The image does not contain the connection setup with level converter circuit from last time (to cut some space).

The Arduino code for ArduinoPi

the_arduino_code_for_arduinopi.c
The Arduino code for ArduinoPi

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

int ledstate = LOW;
String cmd;
bool cmdRec = false;
void setup()
{
    //Start the connection with the Raspberry Pi
    Serial1.begin(115200);
    // Start the connection with the Laptop
    Serial.begin(115200);
    for(int i=2; i <= 10; i++) {
        pinMode(i, OUTPUT);
    }
}

void loop()
{
    handleCmd();
}

void serialEvent1() {
    while(Serial1.available() > 0 && Serial1.writeable()) {
        char inByte = (char)Serial1.read();
        if(inByte == ':') {
            cmdRec = true;
            return;
        } else if(inByte == '@') {
            cmd = "";
            cmdRec = false;
            return;
        } else {
            cmd += inByte;
            return;
        }
    }
}

void handleCmd() {
    if(!cmdRec) return;

    int data[4];
    int numArgs = 0;

    int beginIdx = 0;
    int idx = cmd.indexOf(",");

    String arg;
    char charBuffer[16];

    while (idx != -1) {
        arg = cmd.substring(beginIdx, idx);
        arg.toCharArray(charBuffer, 16);

        // add error handling for atoi:
        data[numArgs++] = atoi(charBuffer);
        beginIdx = idx + 1;
        idx = cmd.indexOf(",", beginIdx);
    }
    // And also fetch the last command
    arg = cmd.substring(beginIdx);
    arg.toCharArray(charBuffer, 16);
    data[numArgs++] = atoi(charBuffer);

    // We just want to switch a port so lets change the values
    if(data[0] < 100) {
        execCmd(data);
    } else {
        execCmds(data);
    }
    cmdRec = false;
}

// Select just one port and enable it
void execCmd(int* data) {
    analogWrite(data[0], data[1]);
}

// For advanced function like switch all the leds in RGB
void execCmds(int* data) {
    switch(data[0]) {
    case 101:
        // first the red part of the RGB
        // for me 4,7,10
        analogWrite(4, data[1]);
        analogWrite(7, data[1]);
        analogWrite(10, data[1]);
        // green: 3, 6, 9
        analogWrite(3, data[2]);
        analogWrite(6, data[2]);
        analogWrite(9, data[2]);
        // blue: 2, 5, 8
        analogWrite(2, data[3]);
        analogWrite(5, data[3]);
        analogWrite(8, data[3]);
        break;

    case 102:
        // request analog readout!
        int sensor = analogRead(data[1]);
        Serial1.println(sensor);
    }
}

The Arduino code for ArduinoPi

SerialEvent1 gets called every time data is available on the Serial1 interface, the function will check for a valid command, if it found a valid command (meaning it starts with @ and ends with :) it will switch the Boolean value cmdRec to true, in the loop function we always call handleCmd(); now the cmdRec is set so we process the command. The while loop will split out the values and save them in the data array. Because we also need the last command we repeat the same stuff out of the while loop once more, I should fix that btw.

If the first value has a number lower than 100 we turn the port on with the second value as second parameter, else we process it like a special command. I’ve used a switch so you can add your own special commands as needed.

Github

Hover Example

Hover Example

The Hover example works as follows, we add a jQuery hover handler over all the buttons. If the user moves over the button we request the value of the button, this value corresponds with the port we want to switch. We then send an ajax call to a PHP script that will handle the communication with Arduino and sending the right command. For a value we use 255. When the mouse leaves the button we do the same but use the value 0 to turn it off.

Hover Example

hover_example.c
Hover Example

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

$(".hover-light > button").hover(function () {
        var port = $(this).val();
        $.post("php-ajax/cmd.php?mode=hover", {port:port, value:255});
    }, function () {
        var port = $(this).val();
        $.post("php-ajax/cmd.php?mode=hover", {port:port, value:0});

Color Picker

Color Picker

The color picker works as follows. The user selects the desired color the RGB LEDs should produce and then click on the big square. An AJAX request is then made to a PHP page that will send the special command 101 with the right values for red, green and blue.

Color Picker

color_picker.c
Color Picker

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

$("#swatch").click(function () {
    var red = $("#red").slider("value");
    var green = $("#green").slider("value");
    var blue = $("#blue").slider("value");
    $.post("php-ajax/cmd.php?mode=picker", {red:red, green:green, blue:blue});

Basic Sensor Display

Basic Sensor Display

This has nothing to do with the Arduino, but remember my light measurements? I always had trouble displaying them and I’ve included an example how you can display graphs really easy using this tool. It’s really useful for offline measurements that are saved on a SD card and then need to be represented in a browser.

Live Sensor Data

Live Sensor Data

This will execute live measurements. A PHP cron job needs to be setup to run every minute as follows. 

The PHP script will execute a measurement and save the value in a JSON file. On the client side we refresh the graph every minute with an Ajax call. I’ve also include two buttons to clear the log or request your own value.

Live Sensor Data

live_sensor_data.c
Live Sensor Data

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

root@raspberrypi:/home/pi# crontab -e
* * * * * php /opt/www/php-ajax/cron.php

ArdunioPi Web-ased Controller using Raspberry Pi and Arduino

Conclusion

I gave a bare bone, alpha release of my ArduinoPi controller. This example can be expanded all the way and check the Github source, I’ve added a lot of comments to get people started.

There is one big limitation, the server (Raspberry Pi) always has to request data from the Arduino. It’s not possible to send data from the Arduino to the Raspberry Pi and then magically update the browser. When using for example Processing, it is possible to have a more live connection and build an interface in JAVA. But this web interface is accessible for any smartphone or laptop (assuming you don’t run IE6).

Original Post

http://www.fritz-hut.com/2012/08/31/arduinopi-web-based-controller-for-arduino//

Code

the_arduino_code_for_arduinopi.cC/C++
the_arduino_code_for_arduinopi.c
int ledstate = LOW;
String cmd;
bool cmdRec = false;
void setup()
{
    //Start the connection with the Raspberry Pi
    Serial1.begin(115200);
    // Start the connection with the Laptop
    Serial.begin(115200);
    for(int i=2; i <= 10; i++) {
        pinMode(i, OUTPUT);
    }
}

void loop()
{
    handleCmd();
}

void serialEvent1() {
    while(Serial1.available() > 0 && Serial1.writeable()) {
        char inByte = (char)Serial1.read();
        if(inByte == ':') {
            cmdRec = true;
            return;
        } else if(inByte == '@') {
            cmd = "";
            cmdRec = false;
            return;
        } else {
            cmd += inByte;
            return;
        }
    }
}

void handleCmd() {
    if(!cmdRec) return;

    int data[4];
    int numArgs = 0;

    int beginIdx = 0;
    int idx = cmd.indexOf(",");

    String arg;
    char charBuffer[16];

    while (idx != -1) {
        arg = cmd.substring(beginIdx, idx);
        arg.toCharArray(charBuffer, 16);

        // add error handling for atoi:
        data[numArgs++] = atoi(charBuffer);
        beginIdx = idx + 1;
        idx = cmd.indexOf(",", beginIdx);
    }
    // And also fetch the last command
    arg = cmd.substring(beginIdx);
    arg.toCharArray(charBuffer, 16);
    data[numArgs++] = atoi(charBuffer);

    // We just want to switch a port so lets change the values
    if(data[0] < 100) {
        execCmd(data);
    } else {
        execCmds(data);
    }
    cmdRec = false;
}

// Select just one port and enable it
void execCmd(int* data) {
    analogWrite(data[0], data[1]);
}

// For advanced function like switch all the leds in RGB
void execCmds(int* data) {
    switch(data[0]) {
    case 101:
        // first the red part of the RGB
        // for me 4,7,10
        analogWrite(4, data[1]);
        analogWrite(7, data[1]);
        analogWrite(10, data[1]);
        // green: 3, 6, 9
        analogWrite(3, data[2]);
        analogWrite(6, data[2]);
        analogWrite(9, data[2]);
        // blue: 2, 5, 8
        analogWrite(2, data[3]);
        analogWrite(5, data[3]);
        analogWrite(8, data[3]);
        break;

    case 102:
        // request analog readout!
        int sensor = analogRead(data[1]);
        Serial1.println(sensor);
    }
}
hover_example.c
hover_example.c
$(".hover-light > button").hover(function () {
        var port = $(this).val();
        $.post("php-ajax/cmd.php?mode=hover", {port:port, value:255});
    }, function () {
        var port = $(this).val();
        $.post("php-ajax/cmd.php?mode=hover", {port:port, value:0});
color_picker.c
color_picker.c
$("#swatch").click(function () {
    var red = $("#red").slider("value");
    var green = $("#green").slider("value");
    var blue = $("#blue").slider("value");
    $.post("php-ajax/cmd.php?mode=picker", {red:red, green:green, blue:blue});
live_sensor_data.c
live_sensor_data.c
root@raspberrypi:/home/pi# crontab -e
* * * * * php /opt/www/php-ajax/cron.php

Comments

Similar projects you might like

Home Automation Using Raspberry Pi 2 And Windows 10 IoT

Project tutorial by Anurag S. Vasanwala

  • 318,862 views
  • 101 comments
  • 767 respects

Home Automation using Raspberry Pi 2 (Windows 10 IoT Core)

Project tutorial by Christian Kratky

  • 139,773 views
  • 34 comments
  • 443 respects

Raspberry Pi and Arduino Laptop

Project tutorial by Dante Roumega

  • 31,602 views
  • 9 comments
  • 93 respects

Arduino / Raspberry Pi Internet Radio

Project tutorial by Anthony Kelly

  • 14,837 views
  • 2 comments
  • 36 respects

Raspberry Pi NFC Clothes Tracker

Project tutorial by Arduino “having11” Guy

  • 3,460 views
  • 0 comments
  • 4 respects
Add projectSign up / Login