Sony Arouje

a programmer's log

Posts Tagged ‘XBee

Farm Automation system based on Arduino and Raspberrypi

with 3 comments

Last two weeks, in my free time, I was working on a system to automate  Green house or an open field. The system designed using Arduino Nano and Raspberry Pi. The Arduino is used to read sensors and control devices and the Raspberry pi is the brain that decides what to do when an event detected by Arduino. All the systems communicates wirelessly via XBee.

In normal scenario in a farm we have to

  • Switch on the drip irrigation pump when the soil humidity is low.
  • Switch off when the soil is wet.
  • Switch on the Main motor that connects to a water source when the reservoir level goes down.
  • Switch off the main motor when the reservoir is full.
  • If it’s a Green house then monitor the humidity and control devices to increase or decrease the humidity. Also need to control temperature.

 

Below is a very ugly drawing I could come up : ), to explain the system.

image

 

Arduino based nodes

The nodes are connected to different Sensors like Soil Humidity, Temperature, Air Humidity, etc. Also the nodes can also switch on/Off drip irrigation motor, switch on/off Reservoir’s Solenoid valves, or control any hardware needed in the field.

Raspberry pi Brain

I developed this central/brain system in Nodejs. The system is very much generic and run based on configurations. So nothing is hardcoded. The XBee connected to the pi act as the coordinator and receive periodic sensor inputs from Ardunio connected in the field. This system can issue command to control devices based on the sensor inputs.

 

Let’s go through some of the scenarios to see how the system works.

Watering the plants: From the above picture you can see, there are 5 Arduino’s in the field sensing different parameters. For now lets think that they all reads the soil humidity. Say soil humidity value range from 0 to 100, where 0 is dry and 100 is fully wet. We need to switch on the drip irrigation motor when any of the sensor value is less than 20. Once all the sensor give a humidity value greater than 90 we need to switch off the motor.

As you can see the system need to take action based on the values coming from the sensor. Depending upon the crops these values can be changed. That’s where the Central Node js system comes into play.

In the central system, we can group the Sensor nodes and configure the triggering points. Also we can configure what to do when the triggering points reach. For e.g. in the above case we can say when the soil humidity of any sensor goes below 20, then send the Motor switch on command to the node sitting next to the Reservoir motor. To switch off the motor, the system needs approval from all the sensors, that means the motor will get switched off if all the nodes reported value is greater than 90.

Failover: What happens when a sensor node dies without sending soil humidity greater than 90 value, will the motor run whole day? No, the central system can be configured for that too, while configuring we can set up a timeout period. If the central system is not receiving high water level after a configured time, it automatically sends a Switch off command to the desired Arduino node to switch off the motor.

Filling Reservoir: From the above diagram, we can see there are two reservoirs and one Main motor. The main motor need to switch on to fill the Reservoir. Each reservoir is equipped with sensors to detect the High and Low water level. Also each water input is equipped with a solenoid valve. If the reservoir is high then the solenoid valve will close the input thus protect the reservoir from overflowing. Once all the reservoir get filled the system will switch off the Main motor before closing the last solenoid, other wise the pressure increase and can damage the Main motor.

The Arduino node will send a Water low when the water go down below a desired level. Then the central system will open the Solenoid before switching on the Main motor. The valve will open only for the reservoir where the water is low, rest all the valves will be closed.

If more than one Reservoir’s water is low then those valves will be open and the main pump will work until all the reservoir’s are filled. For e.g. say Reservoir A and B’s water level is low then both the valves will be open and switch on the main pump. A get filled and B is still not full then A’s valve will get closed. Once B is full the system will send Main pump switch off command then sends the command to close B’s valve.

 

System design

All the above scenarios are based on certain rules and all these rules are configurable. The central system is not aware of any rules. Based on the fields condition we need to configure it.

 

User can also see the activities in the farm via a dashboard. I haven’t designed any Dashboard UI yet.

 

Happy farming…

Written by Sony Arouje

February 17, 2016 at 6:16 pm

Communication between Raspberry Pi and Arduino using XBee

with 18 comments

Recently I was doing some experiments to establish a wireless communication between a Raspberry pi and Arduino. To establish wireless communication I used XBee Pro Series 2 from Digi International. The idea behind this test setup is to test, whether I can control devices like motor or read different sensors remotely.

One of the biggest advantage of using XBee is, you can find a lot of tutorials and libraries for any kind of system and programming languages. For this test app, I used Node js in RPi and C in Arduino.

Test Setup

XBee: I configured two xbee, one as Coordinator and another as Router. Both in API mode 2 (AP =2). I used XCTU to configure both the device. Only reason to choose API 2 is because the Arduino library I used only support API mode 2.

Raspberry pi: connected Coordinator XBee to one of my RPi. You can see more about the connection in one of my earlier post.

Arduino Uno: connected the Router xbee to one of my Arduino. The connection is pretty simple as below.

  • XBee Rx –> Arduino Tx
  • XBee Tx -> Arduino Rx
  • XBee 3.3v-> Arduino 3.3v
  • XBee Gnd –>Arduino Gnd

 

Raspberry Pi Node js code

Modules used

  • xbee-api: npm install xbee-api
  • serialport: npm install serialport

 

var util = require('util'); var SerialPort = require('serialport').SerialPort; var xbee_api = require('xbee-api'); var C = xbee_api.constants; var xbeeAPI = new xbee_api.XBeeAPI({ api_mode: 2 }); var serialport = new SerialPort("/dev/ttyAMA0", { baudrate: 9600, parser: xbeeAPI.rawParser() }); var frame_obj = { type: 0x10, id: 0x01, destination64: "0013A200407A25AB", broadcastRadius: 0x00, options: 0x00, data: "MTON" }; serialport.on("open", function () { serialport.write(xbeeAPI.buildFrame(frame_obj)); console.log('Sent to serial port.'); }); // All frames parsed by the XBee will be emitted here xbeeAPI.on("frame_object", function (frame) { console.log(">>", frame); if(frame.data!== undefined) console.log(frame.data.toString('utf8')); });

 

 

Arduino Sketch

This sketch uses a XBee library, to add the library, goto Sketch->Include Library->Manage Libraries. From the window search for XBee and install the library. I am using Arduino IDE 1.6.7.

I use SoftwareSerial to establish serial communication with XBee, Pin 2 is Arduino Rx and Pin 3 is Arduino Tx.

 

#include <Printers.h> #include <XBee.h> #include <SoftwareSerial.h> unsigned long previousMillis = 0; const long interval = 4000; // the interval in mS XBee xbee = XBee(); // XBee's DOUT (TX) is connected to pin 2 (Arduino's Software RX) // XBee's DIN (RX) is connected to pin 3 (Arduino's Software TX) SoftwareSerial soft(2,3);// RX, TX Rx16Response rx16 = Rx16Response(); ZBRxResponse rx = ZBRxResponse(); XBeeAddress64 addr64 = XBeeAddress64(0x0013a200,0x407a25b5); char Buffer[128]; char RecBuffer[200]; void setup() { // put your setup code here, to run once: soft.begin(9600); Serial.begin(9600); xbee.setSerial(soft); } void print8Bits(byte c){ uint8_t nibble = (c >> 4); if (nibble <= 9) Serial.write(nibble + 0x30); else Serial.write(nibble + 0x37); nibble = (uint8_t) (c & 0x0F); if (nibble <= 9) Serial.write(nibble + 0x30); else Serial.write(nibble + 0x37); } void print32Bits(uint32_t dw){ print16Bits(dw >> 16); print16Bits(dw & 0xFFFF); } void print16Bits(uint16_t w){ print8Bits(w >> 8); print8Bits(w & 0x00FF); } void loop() { // put your main code here, to run repeatedly: xbee.readPacket(); if (xbee.getResponse().isAvailable()) { if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) { xbee.getResponse().getZBRxResponse(rx); if (rx.getOption() == ZB_PACKET_ACKNOWLEDGED) { // the sender got an ACK Serial.println("got ACK"); } else { // we got it (obviously) but sender didn't get an ACK Serial.println("not got ACK"); } Serial.print("Got an rx packet from: "); XBeeAddress64 senderLongAddress = rx.getRemoteAddress64(); print32Bits(senderLongAddress.getMsb()); Serial.print(" "); print32Bits(senderLongAddress.getLsb()); Serial.println(' '); // this is the actual data you sent Serial.println("Received Data: "); for (int i = 0; i < rx.getDataLength(); i++) { print8Bits(rx.getData()[i]); Serial.print(' '); } //Received data as string to serial Serial.println(' '); Serial.println("In string format"); for (int i = 0; i < rx.getDataLength(); i++) { if (iscntrl(rx.getData()[i])) RecBuffer[i] =' '; else RecBuffer[i]=rx.getData()[i]; } Serial.println(RecBuffer); String myString = String((char *)RecBuffer); if(myString=="MTON"){ Serial.println("Switching on Motor"); } else if(myString=="MTOFF"){ Serial.println("Switching off Motor"); } } //clear the char array, other wise data remains in the //buffer and creates unwanted results. memset(&RecBuffer[0], 0, sizeof(RecBuffer)); memset(&Buffer[0], 0, sizeof(Buffer)); } //Send a packet every 4 sec. unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { // save the last time you blinked the LED previousMillis = currentMillis; strcpy(Buffer,"RSLOW"); uint8_t payload[20]= "RSLOW"; // ZBTxRequest zbtx = ZBTxRequest(addr64,(uint8_t *)Buffer,sizeof(Buffer)); ZBTxRequest zbtx = ZBTxRequest(addr64,payload,sizeof(payload)); xbee.send(zbtx); } }

 

Burn the sketch to Arduino.

Testing

Run node js code in RPi and you start receiving the frames from Arduino.

 

 

Happy coding….

Written by Sony Arouje

January 21, 2016 at 12:06 am

Connecting XBee to Raspberry pi

with 19 comments

Last one week I was doing some research in RF communication and controlling devices using RF. So what am I going to control here, I wanted to control the water pump running in my hydroponic reservoir without running wires from my raspberry pi. This way I can extend my hydroponic system to more balconies without buying extra RPi, a single RPi will send a switch on/off command and the RF client will switch on/off the motor via a relay. Also I don’t need to setup a wifi network in my controller RPi’s.

My research for RF communication platform leads to Zigbee protocol and XBee component. XBee is a very popular Zigbee complaint product from Digi. For my testing I got two XBee Pro S2 and two XBee explorer. The explorer I bought uses USB to A/B cable, if you are buying it make sure buy A/B cable as well. You will get micro usb explorer as well.

To configure the XBee’s I use the X-CTU software from Digi, you can download it free from Digi’s website. I use the Legacy X-CTU for configuring my modules and Next Generation X-CTU for issuing commands. Configuration is pretty simple and so many sites will walk you through it. I configure my XBee’s as shown below. One XBee act as Coordinator and enabled API mode and another XBee act as router and enabled Router AT.

XBee Coordinator

  • Modem: XBP24-ZB
  • Function Set: ZIGBEE CORDINATOR API
  • PAN: <set a pan id, say 123>
  • Destination Address Low: FFFF

XBee Router

  • Modem: XBP24-ZB
  • Function Set: ZIGBEE ROUTER AT
  • PAN: <set a pan id, say 123>
  • Destination Address Low: 0000

I left all other settings as default.

Connecting to Raspberry pi

For testing I connected the XBee coordinator to my computer and XBee Router to my RPi. In RPi I created a simple node app to send some text message to coordinator. Below diagram will show you, how I connected Router XBee to my RPi. Here we use serial communication between RPi and XBee. RPi has only one set of serial communication pin and by default it’s configured for console I/O, there are so many tutorial out there to free it up and I use one from them.

connection_diagram_bb

image developed using Fritzing

I connected the XBee directly using jumper wires, the above diagram is just for illustration for that I use the breadboard.

Connect RPi 3.3 volt to XBee 3.3 volt pin, Ground to XBee ground, Rx to Xbee Tx (Data Out), Tx to XBee Rx (Data In).

Sending some data from Router Xbee to Coordinator

Now I wanted to send some data from Router XBee connected to my RPi  to the coordinator connected to my Computer.

I created a small app using node js, below is the code. To run the code we have to install two node modules.

  • xbee-api: npm install xbee-api
  • serialport: npm install serialport
var util = require('util');
var SerialPort = require('serialport').SerialPort;
var xbee_api = require('xbee-api');

var C = xbee_api.constants;

var xbeeAPI = new xbee_api.XBeeAPI({
    api_mode: 1
});

var serialport = new SerialPort("/dev/ttyAMA0", {
    baudrate: 9600,
    parser: xbeeAPI.rawParser()
});

serialport.on("open", function () {
    var frame_obj = {
        type: 0x10, 
        id: 0x01, 
        destination64: "0013A200407A25A7",
        broadcastRadius: 0x00,
        options: 0x00, 
        data: "Hello world" 
    };
    
    serialport.write(xbeeAPI.buildFrame(frame_obj));
    console.log('Sent to serial port.');
});

serialport.on('data', function (data) {
    console.log('data received: ' + data);
});


// All frames parsed by the XBee will be emitted here
xbeeAPI.on("frame_object", function (frame) {
    console.log(">>", frame);
});

 

When I run the above node app, I can see the data receiving in my Coordinator’s X-CTU app. I could also send a Remote AT (0x17) command to the router to one of the Digital pin and could turn On/Off a LED.

Seems like the communication is working fine. Let’s see what I can come up next.

 

download

Scan using your mobile phone and access/share the post from your phone.

Written by Sony Arouje

December 20, 2014 at 6:07 pm

Posted in Raspberry Pi

Tagged with , ,

%d bloggers like this: