Saturday, February 1, 2020

Blynk, ESP8266, XBEE


Blynk, ESP8266, XBEE

AIM

The aim of this experiment is to connect a smartphone app to an Arduino, through the internet. The phone could be anywhere in the world, connected to the internet. One Arduino device will be connected to a domestic Wifi (let’s call it “Home Controller”). This Home Controller will communicate to another Arduino device (let’s call it “Remote Controller”) through Xbee radio transmitters (up to about 3km distance). The final aim is to enable two-way communication between the Remote Controller and the smartphone app. The Smartphone app will be created with the Blynk software.
Example: a farm has a Wifi network in the farmhouse. 3km from the house there is a water cistern and a pump. From the smartphone, we want to see the level of the water in the cistern and start/stop the pump. We also want a feedback to see if the pump is actually running. With this system it’s easy to add more devices (pumps, motors, actuators, and sensors of any kind).


WHAT WE NEED

Obviously we need two arduino boards, breadboards, jumper wires, potentiometers, LED, power supplies. The usual stuff.

ESP8266

The ESP8266 is a low-cost Wi-Fi microchip with full TCP/IP stack and microcontroller capability produced by Shanghai-based Chinese manufacturer, Espressif Systems, compatible with IEEE 802.11 b/g/n Wi-Fi. Basically, it's a modem, but it can be programmed as a controller or server.
The ESP8266 can be programmed with AT commands through a serial interface. It cost about $3.

5V to 3.3V logic converter

The Arduino uses a 5V logic. The ESP8266 uses a 3.3V logic. A logic converter is necessary between them.

3.3V power supply

The arduino 3.3V pin doesn't supply enough power to the ESP8266. It needs a separate power supply. I'm using an adjustable step-down power supply module with LM2596 voltage regulator.

XBEE x2

To extend the range of the microcontrollers, I’m going to use Xbee transmitters. They send digital data using radio frequencies. To connect the Arduino to the XBee module you need an Arduino Wireless Shield. To connect the XBee module to the PC for modifying the settings you need a XBee Explorer board. They can be configured to create very complex mesh networks, but I don't need it now.
The XBee module I've chosen are: XBee PRO series 2. They use 50 mW power at 2.4 GHz frequency (legal in Australia). The range of this model is about 3 km outdoor.

WIRELESS SHIELD x2

To connect the XBEE to the Arduino board, you need a module called "wireless shield".

LCD Displays

I'm using one LCD display attached to each Arduino controller, just to see if they are working correctly and they are sending/receiving the right data. When the devices are working, the LCD displays could be removed. They are the usual 16x2 but one of them has a I2C interface, just so I learn how to use it.

BLYNK

Blynk is a crowdfunded smartphone app editor which can be used not only to create your apps, but also to write the code for the Arduino, in order to communicate with your apps. It’s compatible with many other controllers as well. For small projects like this one, it’s free. Find out more at www.blynk.cc.



LET’S DO IT

SETUP THE XBEEs

Each module has to be configured using the Explorer board and X-CTU, a free software distributed by Digi International. To communicate, the two modules have to use the same ID (the name of the network), and same baud speed; one have to be a coordinator and the other can be router, end device or both. In this case I set one as coordinator and the other one as a router.


ROUTER
COORDINATOR
SH
13A200
SH
13A200
SL
40AD4579
SL
40A8E58A
16bit
B7C
16bit
0
DH
13A200
DH
0
DL
40A8E58A
DL
FFFE

The router DL and coordinator SL are the same.The router DH and coordinator SH are the same.

Once they are installed on the wireless shield of the Arduino, they use the serial port. The USB connection of the PC uses the same port, so there's a switch on the shield: you must select “USB” when using serial to upload a sketch to the Arduino, and “MICRO” when using the XBee to send data.

WIRING

REMOTE CONTROLLER

The potentiometer simulates a water level sensor. The led simulates a pump. A pin reads the status of the led to send a feedback to the app (to show that the pump is actually running).


HOME CONTROLLER

This LCD display uses the SDA/SCL pins. ESP8266 uses Serial1 (TX1,RX1). In the logic shifter, the 3.3V reference ("LV" pin) is attached to the 3.3V of the Arduino, not to the 3.3V power supply. If you attach it to the power supply it will give you intermittent faults.


TEST THE ESP8266

Because the pins of the ESP8266 don't fit in a breadboard, I had to build a connector.
The following steps are just to check if the ESP is working.
To setup amd test an ESP8266 through the Arduino, you have to upload and empty sketch from the Arduino IDE. Connect TX1 Arduino pin to ESP TX pin and RX1 Arduino pin to ESP RX pin. Connect GPIO-0 to GND (just for setup).
Open the serial monitor in the Arduino IDE. Select baud rate 115200 and "Both NL & CR". Now you can send AT commands to the ESP.
When the ESP is powered up, the blue led blinks quickly 3 times then stays off, the red led stays on. If not, you have a connector problem. Check your wiring.

Through the serial monitor, send "AT". You should receive "OK".
Send "AT+CWLAP", it will list the available AP (access point, or wifi).
Send "AT+CWJAP="ssid","pswd"" with your wifi name and password, it will connect to your wifi. "AT+CWQAP" will disconnect from wifi.

The default baud rate is 115200. Leave it as it is.
When you finished, remove the GPIO-0 pin from ground, and connect TX to RX1 and RX to TX1 (as in the wiring diagram).

BLYNK

I’m using the Blynk app to create a smartphone app. It’s an easy graphical editor and it doesn’t require any coding. You can download the Blynk app from Google Playstore. Create an account and design your app.
You will receive an authorization code by email.
Download the Blynk library from here. Unzip it and copy to the Arduino library folder.
Copy the Blynk example code for the Arduino from herePaste it in the Arduino IDE, change authorization token, SSID and password of your Wifi.
You need more than one serial: one is for the USB communication to your PC, one is for the ESP8266. Some boards have multiple serial pins (hardware serial), others have only one, so you have to enable software serial and assign 2 pins to it. I’m using a Mega with multiple hardware serial so I deleted the software serial part of the code.
Upload it to your board. When you open the serial monitor, the Blynk code will start connecting to the Wifi and it will give you confirmation through serial monitor.




ARDUINO CODING

REMOTE CONTROLLER

This is easy: 2 inputs (value of the potentiometer and the status of the led), 1 output (start/stop the pump). Everytime a 1 is received through serial, the pump is toggled (on/off). A string is created with the values and sent to serial. The values are also displayed on the LCD. A delay is needed to avoid buffer overflow in the receiver.


#include <LiquidCrystal.h>
LiquidCrystal lcd(26, 27, 28, 29, 30, 31);
boolean pump = false;

void setup(){

pinMode(8, OUTPUT);
pinMode(7, INPUT);
Serial.begin(9600);
lcd.begin(16,2);
}

void loop() {

  if(Serial.available() > 0) {
  int bla = Serial.parseInt();
    if (bla==1) pump = !pump; 
    }
  digitalWrite(8,pump);
  float sensor = analogRead(0);
  int value = sensor / 1024 * 100;
  
  String dataStringWater = "";
    dataStringWater += "Water:";
    dataStringWater += " ";
    dataStringWater += value;
    dataStringWater += " ";
    dataStringWater += "%";
  String dataStringPump = "";
    dataStringPump += "Pump:";
    dataStringPump += " ";
    dataStringPump += (digitalRead(7));
  Serial.print (value);
  Serial.print ("/");
  Serial.println (digitalRead(7));
  
  lcd.clear();
  lcd.print(dataStringWater);
  lcd.setCursor(0,1);
  lcd.print(dataStringPump);

  delay(1000);
}


After you upload the code, remember to switch the wireless shield to "micro".

HOME CONTROLLER

This one is a bit harder. It will receive 2 values over serial (water level, pump status). The function Serial.parseInt() is used to get those values out of the serial string.
The Blynk program will start running when a serial monitor is open. If you want it to run by itself you have to delete the line "#define BLYNK_PRINT Serial".
Because I'm using a I2C LCD, I need to include the libraries Wire.h and LiquidCrystal_I2C.h. Also you have to find out the address of that I2C device. To do that upload and run this code. Now you can enter the address value.
I have multiple hardware serial so I deleted the software serial bit.
I had few problems in reading the values from the serial string until I added:
 "while(Serial.available())  Serial.read();
  delay(500);"
That cleans the buffer and avoid messy readings.
The BLYNK_WRITE() function has to stay out of the void loop().

//#define BLYNK_PRINT Serial

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x3F, 16, 2);

char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxx";
char ssid[] = "xxxxxxxxxxxxxxxxxx";
char pass[] = "xxxxxxxxxxxxxxxxx";

// Hardware Serial on Mega, Leonardo, Micro...
#define EspSerial Serial1

// or Software Serial on Uno, Nano...
//#include <SoftwareSerial.h>
//SoftwareSerial EspSerial(2, 3); // RX, TX

#define ESP8266_BAUD 115200

ESP8266 wifi(&EspSerial);

void setup() {
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  EspSerial.begin(ESP8266_BAUD);
  delay(10);
  Blynk.begin(auth, wifi, ssid, pass);
}

void loop() {

  int value = Serial.parseInt();
  int pump = Serial.parseInt();
  while(Serial.available())
  Serial.read();
  delay(500);
  
  String dataStringWater = "";
    dataStringWater += "Water:";
    dataStringWater += " ";
    dataStringWater += value;
    dataStringWater += " ";
    dataStringWater += "%";
  String dataStringPump = "";
    dataStringPump += "Pump:";
    dataStringPump += " ";
    dataStringPump += pump;

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(dataStringWater);
  lcd.setCursor(0,1);
  lcd.print(dataStringPump);
  
  Blynk.run();
  Blynk.virtualWrite( V1, value);
  Blynk.virtualWrite( V2, pump);
}

BLYNK_WRITE(V5) {
// Assigning incoming value from pin V5 to a variable
 int pinValue = param.asInt(); 
 Serial.println(pinValue);
}

After you upload the code, remember to switch the wireless shield to "micro".


CONCLUSIONS

The project was successful, but it took longer than expected. I encountered several issues described below:

Issues

The 3.3V output of the Arduino doesn’t deliver enough power to the ESP8266. The Arduino provides up to 40mA, The ESP needs 250mA. I had to buy a separate power supply with voltage regulator. But when the 3.3V LV pin on the logic shifter was supplied from the 3.3V power supply, I had intermittent faults of connectivity. I solved it by connecting the 3.3V LV pin of the logic shifter to the 3.3V pin of the Arduino, and only connect the 3.3V power supply to the power pins of the ESP8266. Remember: if the ESP8266 blue led doesn't blink 3 times at startup, there's something wrong, probably in the wiring.
The Serial.parseInt() function was reading the wrong values sometimes. I fixed it by adding while(Serial.available()) Serial.read(); and delay(500); to clean the buffer.


Learning contents

During the development of the project and the research stage I learned about:
·         Frequency allocation and power limits (EIRP) in Australian Standards
·         Domestic router setup for static IP addresses
·         Wi-Fi modules and controllers (ESP8266)
·         Interface between different logics (5V, 3.3V, USB to serial), logic shifter and converter
·         Create a 2 way comms network with Xbee (2.4GHz)
·         Use multiple serial ports and set up virtual ports in the Arduino controller
·         Soldering and desoldering (some boards required modification or basic assembly)
·         Building pin header connectors using proper tools (wire stripper, crimping tool)
·         Building a smartphone app using an editor (Blynk)
·         Multiple power supplies of different voltages and current capabilities
·         I2C serial standard