Posts Tagged ‘Arduino’
Control AC/DC devices using Arduino
In forums I could see people asking how to switch on/off devices using Arduino. It’s a very simple approach using a relay module. In this post I will briefly explain how to do that.
Connecting Relay module to Arduino
Most of the relay module runs with 5 or 12v DC. Even if it’s 5v, never connect VCC of relay to Arduino. Always make sure Relay should powered from an external source. Most of the relay need more current (A) than Arduino can supply and might damage your Arduino. In the above diagram I used a battery (it should be a 12v battery, I couldn’t find 12v battery in fritzing) to as power source.
Here the Arduino and the Relay are powered from the battery. If you are powering Arduino separately via USB then remove the wire connecting to VIN of Arduino. Leave the GND connecting to Arduino as it is, all the connected devices needs common ground.
Relay need a trigger to switch on/off the connected device. If we supply high (5v) to INP pin of relay module the connected device will switch on, if we supply low then the device will get switched off. Here I connected D2 to INP pin of the relay. In code if we do digitalWrite to D2 with HIGH, the relay will get activated and LOW will deactivate the relay.
We can control AC or DC device using the relay. As you can see from the above diagram, the Relay is in series to the power supply going to the load. The wiring is very similar to a switch between a load and the power.
Connect Arduino to external EEPROM
Arduino has a tiny built in hard drive called EEPROM, in this area we can write data that should be available after power cycles. Unfortunately the size of this built in EEPROM is 512 byte for Atmega168 and 1kb for Atmega328. If our application is dealing with very small amount of data to persist then built in EEPROM is a good choice.
In some scenarios we might need to keep some logging info or any kind of data that needs more than 1kb then we need to go for external EEPROM. For this post I am using 24LC256, it can store 256kb of data. We can connect upto 8 ICs to a single Arduino by changing the voltage in A0, A1 and A2 pins.
Connection to Arduino
Here I connect A0 to A2 to GND and that gives me an address of 0x57.
VSS to GND, VCC to 5v, WP to GND, SCL to A5, SDA to A4
High on WP will disable writing, in my scenario I need to write, so I connect to GND.
Source Code
To deal with EEPROM reading and writing, I used a library called Extended Database Library (EDB). I also used the samples provided along with EDB but with some modifications.
#include <EDB.h> #include <Wire.h> #define disk 0x50 #define TABLE_SIZE 131072 // 1 device struct LogEvent { int id; int temperature; } logEvent; void writer(unsigned long address, byte data) { Wire.beginTransmission(disk); Wire.write((int)(address>>8)); Wire.write((int)(address & 0xFF)); Wire.write(data); Wire.endTransmission(); delay(5); } byte reader(unsigned long address) { byte rdata = 0xFF; Wire.beginTransmission(disk); Wire.write((int)(address>>8)); Wire.write((int)(address & 0xFF)); Wire.endTransmission(); Wire.requestFrom(disk,1); if(Wire.available()) rdata = Wire.read(); return rdata; } EDB db(&writer, &reader); void setup() { Serial.begin(9600); Wire.begin(); randomSeed(analogRead(0)); Serial.println("Creating db..."); EDB_Status result = db.create(2, TABLE_SIZE, (unsigned int)sizeof(logEvent)); if (result != EDB_OK) printError(result); Serial.println("Created db..."); createRecord(1); selectAll(); } void loop() { // put your main code here, to run repeatedly: } void createRecord(int recno) { Serial.println("Creating Records..."); logEvent.id = 1; logEvent.temperature = random(1, 125); EDB_Status result = db.insertRec(recno, EDB_REC logEvent); if (result != EDB_OK) printError(result); Serial.println("DONE"); } void selectAll() { for (int recno = 1; recno <= db.count(); recno++) { EDB_Status result = db.readRec(recno, EDB_REC logEvent); if (result == EDB_OK) { Serial.print("Recno: "); Serial.print(recno); Serial.print(" ID: "); Serial.print(logEvent.id); Serial.print(" Temp: "); Serial.println(logEvent.temperature); } else printError(result); } } void deleteAll() { Serial.print("Truncating table..."); db.clear(); Serial.println("DONE"); } void printError(EDB_Status err) { Serial.print("ERROR: "); switch (err) { case EDB_OUT_OF_RANGE: Serial.println("Recno out of range"); break; case EDB_TABLE_FULL: Serial.println("Table full"); break; case EDB_OK: default: Serial.println("OK"); break; } }
Happy coding…
Bluetooth Communication with Arduino
I am in the process of redesigning my Raspberry Pi based Aeroponic controller, in my new system I am using Arduino. This time I decided to use Bluetooth instead of WiFi to communicate between my mobile app and Arduino controller. Later I will write a different post explaining about the new design. In this post I will explain how to communicate to Arduino via Bluetooth.
Arduino Bluetooth connection
I bought a HC-05 Bluetooth module from Ebay, it’s a very low cost module. The connection is pretty simple. See the connection below. I am using Arduno Nano in my new design.
Connection Details
- Nano VCC to BT VCC
- Nano GND to BT GND
- Nano RXD to BT TXD
- Nano TXD to BT RXD
In my sketch I used Softserial and I assign D2 and D3 as RXD and TXD respectively.
I haven’t used the EN and KEY pin in the Bluetooth module. You might want to use EN pin, if you want to enter into AT mode to issue any commands to BT module.
Arduino Sketch
#include <SoftwareSerial.h> SoftwareSerial soft(2,3);// RX, TX void setup() { soft.begin(9600); Serial.begin(9600); } void loop() { if(soft.available()){ String serialData = soft.readString(); Serial.println(serialData); //echo bluetooth data to serial writeAck(); } } void writeAck(){ uint8_t payload[]="ACK|0|\n"; soft.write(payload,sizeof(payload)); }
It’s a very simple sketch to receive the data from Bluetooth module and echo to Serial, also send and Acknowledgment back to the caller.
You can test the program by issuing some text from Hyperterminal or any other similar app. I wrote an Android app to issue command via Mobile bluetooth.
Happy coding…
Farm Automation system based on Arduino and Raspberrypi
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.
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…
Communication between Raspberry Pi and Arduino using XBee
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….