Raspberry Pi and Arduino i2c communication using nodejs

Raspberry Pi i2c Master Writer  Arduino Slave Reader in nodejs
Using an Express Server

By: Jeramie Chew

// Introduction

This instruction set is designed for a user who already has a Raspberry Pi with nodejs and npm installed. It is important to point out that after installing nodejs and npm on your Raspberry Pi this turtorial is very simple. If you don’t have them installed you can follow instructions here to install nodejs and npm: http://www.instructables.com/id/Install-Nodejs-and-Npm-on Raspberry-Pi/ on your Raspberry Pi. This instruction set also requires the Arduino IDE, if you need to install it follow instructions here to install:https://www.arduino.cc/en/Main/Software.

// Inter-integrated Circuits (i2c)

Arduino i2c

Inter-integrated circuit(i2c) communication is a quick way to communicate between a master device and up to 127 slave devices quickly. I2c is used in robotics and many systems that require sensor data from an array of sensors. You can even use i2c to write data to devices. Some write data to i2c to move servos on cameras to achieve pan/tilt or to give commands to motors or leds.

I won’t be going too deep into the low level logic on i2c and want to provide a few simple tips for troubleshooting your i2c circuit.

1. Make sure that your wires have a solid connection.
2. Make sure your wires are functional.
3. Make sure you have proper power for your system.

These 3 errors are the biggest time consuming errors in i2c, without a working circuit
you won’t be able to detect when your lines go high or low, which means your i2c may
not work. i2c does not require for you to communicate via a web server but I am here to
show you that you can indeed send i2c commands via a web server, with very few steps.

 

// Supplies

1. Raspberry Pi (Zero W/2/3 with Raspberain or equivalent)
2. Breadboard(optional)
3. Jumper Wires(Female to Male or Male to Male)
4. Arduino(Nano/Uno)
5. 5V 2.5A Power Supply for System
6. Mouse——Keyboard——Monitor

                        • NOTE:
                           There are a number of ways to power your circuit. In this example I will        be the Arduino through Raspberry Pi GPIO. This is not recommended for
                           heavy use for you have risk to cause a problem with your Raspberry Pi.

//Setup

1.) Wiring your devices

Basic Setup

 

 

 

• NOTE:
   Make sure that you power and connect your Arduino to the correct pins on
   the Raspberry Pi. A minor mistake can be a catastrophe to your device.

2. In your Raspberry Pi terminal type this command to activate your i2c Bus

sudo raspi-config

3. Activate i2c on Pi

Follow this figure from left to right

 

 

 

 

4. Arduino IDE
Copy and paste the below code to your Arduino

// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>

void setup() {
Wire.begin(4); // join i2c bus with address 0x04
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}


void loop() {
//Serial.println("Arduino has i2c address 0x04");
delay(100);
}

void receiveEvent(int howMany) 
{
byte c[7];
while (1 < Wire.available()) {
// loop through all but the last
for (int i = 0; i < howMany; i++) {

c[i] = Wire.read(); // receive byte as a character
Serial.println(c[i]);
}
}
}

5. Check i2c Bus on Arduino
In your Raspberry Pi terminal type:

i2cdetect -r 1

  • Read the scary warning and type y and enter.

To avoid the scary warning you can always insert the -y flag

i2cdetect -r -y 1

Output of i2cdetect

i2c addresses are represented in hexadecimal. If you are unfamiliar with decimal to hexadecimal conversions follow this link to find a decimal to hexadecimal converter: http://lmgtfy.com/?q=decimal+to+hexadecimal+converter

 

//Express Server

Setting up an express server is very quick and easy. All you need is a basic text editorand one npm dependency.

1. Open terminal on the Raspberry Pi and type

mkdir myExpress

Then change directories to your newly created folder

cd myExpress

2. Initialize npm

npm init

You will recieve some prompts. You can press enter all the way through or fill out
the prompts. I will be using index.js.

          • Side Note:
             npm stands for “Node Package Manager” this platform gives us access to over
             400,000 API’s that are contributed by many open source developers.

3. Install Express into myExpress folder

While in terminal

npm install express --save

  • Note:
        all npm’s have to installed while you are in myExpress.

4. Create a new file titled index.js (any text editor)

If you do not have nano install nano onto your Pi by typing this into terminal

sudo apt-get install nano

Create a new file

nano index.js

We can now add the following code it our index.js file.

var express = require(’express’);

var app = express();
app.get(’/’, function (req, res) 
{
res.send(’Hello World!’);
});

app.listen(1868, function () 
{
console.log(’Example app listening on port 1868!’);
});

To exit press ctrl-x and follow the prompts

5. Run the Server

ensure you are still in the myExpress folder and tun this in terminal

node index.js

If you see “Example app listening on port 1868!” in your terminal your terminal you are successful this is where your website is http://localhost:1868/

6. Now to Send i2c commands to Arduino

Type this command in your myExpress folder

npm install i2c-bus --save

Add your i2c code to the index.js file

var express = require(’express’);
var app = express();
var i2c = require(’i2c-bus’);
var i2c_Bus = i2c.openSync(1);
var arduino_i2cAddress = 0x04;

//The Register is where we send our 1 to tell our slave to read or a 0 to send data to.
var arduino_Register = 0x00;

//We need to identify the size of our message we are sending to the slave. So that we can send //the end of transmission bit.
var arduino_Data_Length = 0x07;

//We use a Buffer to transport Binary Data
const buf0 = new Buffer([0,1,2,3,4,5,6]);

//This is What your Buffer should look like
console.log(buf0);

//Here is your i2c Write command
i2c_Bus.i2cWriteSync(arduino_i2cAddress,arduino_Data_Length,buf0);
while(i2c_Bus.i2cReadSync(arduino_i2cAddress, arduino_Data_Length , buf0);

Now run your server again

node index.js

If you see this you are successful

Success i2c via nodejs

// Conclusion

There you have it, you are sending an array that is loaded with 7 integers and are receiving it on an Arduino. There are many applications to this. I would recommend that you play around here at the base level are a few links to help you convert values. If you are having problems with this example you can always email me at Bot@osbotdrop.com and if I have time to support I will. Feel free to leave a comment on success and problems that you encounter

 

•https://nodejs.org/api/buffer.html#buffer_buffers_and_typedarray

            This is the Documentation for Buffers in nodejs.
          • https://www.npmjs.com/package/i2c-bus
            This is the Documentation for the i2c-bus npm we are using.
          • https://www.npmjs.com/package/express
             This is Documentation for the Express server we are using.

Leave a Reply

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