Over
the Air(OTA) Update of Nodemcu(esp8266) Using MQTT:
So what actually I'm going to do here, suppose I've
installed this system somewhere in a office for attendance of employees or may
be in school for attendance of student, now if I need to add more employees or
student then what I'll do I'll take the nodemcu and edit the code from system.
So this will be a huge problem, as I don't want to mess up with these things
like take out the nodemcu and connect to laptop or PC and update the code. So
what is the sollution? Here is the solution and that is we can update the code
Over-the-Air(OTA) without even touching the nodemcu. So this is really a cool
thing. So here I'll tell you how we can update the code Over-the-Air.
a)
Installation of LAMP Server and PHPMYADMIN:
First of all let us clear one thing that we are using
LAMP Server for this project. In case if you don't know what is LAMP, it is an
abbreviation of Linux, Apache, MySQL and PHP. So if you have windows or may be
MAC then you have to install WAMP and MAMP respectively.
So what we are explaining that is only for LAMP server:
and here are the steps for installing LAMP server
1. Install Apache
sudo apt-get install apache2
2. Install MySQL:
sudo apt-get install mysql-server
3. Install PHP:
sudo apt-get install php5 libapache2-mod-php5
4. Restart Server:
sudo /etc/init.d/apache2 restart
5. Check Apache http://localhost/ if you install these
steps successfully then you will get the apche page like the image above.
Here we are using PHPMYADMIN that is the web interface
of MySQL so for that you have to install that also and the command for that is:
sudo apt-get install phpmyadmin
b)
Installation of Arduino IDE:
You can download the latest Arduino IDE from this link:
Component
Used:
1)
Node MCU V3 : Node MCU is an open source IOT platform.
It includes firmware which runs on the ESP8266 Wi- Fi SoC from hardware which
is based on the ESP-12 module. The term "Node MCU" by default refers
to the firmware rather than the dev kits.
2)
RFID RC522 Reader with Tag: There are cheap RFID modules that can
read and write Mifare's tags and being sold at several web stores, like eBay
and included with many "starter kits" nowadays. Simply search
RFID-RC522 (MF-RC522). The microcontroller and card reader uses SPI for
communication (chip supports I2C and UART protocols but not implemented on
library). The card reader and the tags communicate using a 13.56MHz
electromagnetic field.
3) Jumper Wire
How
to Program NodeMCU Using Arduino IDE:
Step1:
Firstly open the Arduino IDE.
Step2:
Go to the File then click on preferences tab like
Figure 1.
Now you have to copy in the additional board manager
URL- http://arduino.esp8266.com/stable/package_esp8266... then click ok
Step
3:
Now go to the Tools then select Board Manager. open
window like figure 2. Just Scroll down on that window and search for esp8266 by
ESP8266 Community and then click on install button. Step4: Restart your Arduino
IDE Step5: Now goto Tools.
Circuit
Diagram:
Here are the connections of our circuit:
RFID-RC522NODE MCU
SDA(SS)-------------------------GPIO2---------D4
MOSI ----------------------------GPIO13--------D7
MISO ----------------------------GPIO12--------D6
SCK ----------------------------- GPIO14--------D5
GND -----------------------------GND
3.3V ------------------------------3.3V
RST ------------------------------not connected
IRQ -------------------------------not connected
Importing Necessary Library for NodeMCU:
Here we are using RFID RC522. So you have to import library.
Why
We Need MQTT:
Here we don't necessarily need MQTT. What is the
purpose of MQTT here that we want to make one toggle button in this case. So
when it will be 0 then our nodemcu will be in programming mode and if it is 1
then it will be in OTA mode. So if you want to update the installed nodemcu
just click the button and value will be 1, So here you can update the code and
then after successful update you can again click and make it 0 for programming
mode.
If you don't want to go with MQTT then you can chose
one push button as well which is connected to one gpio of nodemcu, but again
the problem is that button will always be there connected to nodemcu, and also
every time you need to press that button for making it OTA or programming mode.
So That's why we thought that we should go with some
soft toggle button and we can easily make that using MQTT.
How
to Use MQTT:
In this step I'm going to explain you about how we can
create Mqtt Dashboard. So for that we are using Adafruit Mqtt. The UI of
Adafruit IO is very user-friendly. So Step by step I'm going to explain you
about this. So you just follow the process.
Here
are the steps:
1. First you need to create account in io.adafruit.com
2. You will get the page like below, so fill these
details, now when you will sign in you will get the page like below
3. In this page in the top right corner you will get
some icons. From this you can click on 'Create a new block'. So from here you
can create toggle button.
As we have given the name Bulb1 for our toggle button.
When you will create that button then you need to give value 1 and 0 for for
High and Low respectively, remember these values are not a numeric value, these
are string values which we will convert to integer through our arduino code.
Code
of Project:
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include<SoftwareSerial.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <SPI.h>
#include <MFRC522.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
const char* ssid = "Your ssid name";
const char* password = "your ssid password";
int led = 16;
int flash = 0;
/************************* Adafruit.io Setup *********************************/
#define AIO_SERVER
"io.adafruit.com"
#define AIO_SERVERPORT
1883 // use 8883
for SSL
#define AIO_USERNAME
"Your Adafruit AIO Key"
#define AIO_KEY
"Your Adafruit AIO Password"
#define SS_PIN 2 //FOR RFID SS PIN BECASUSE WE ARE
USING BOTH ETHERNET SHIELD AND RS-522
#define RST_PIN 15
#define No_Of_Card 3
bool flag =0; // For selecting Mode
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER,
AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
Adafruit_MQTT_Subscribe Bulb1 =
Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Bulb1");
void MQTT_connect();
char server[] = "192.168.0.111"; //eg: 192.168.0.222
SoftwareSerial mySerial(8,9);
MFRC522 rfid(SS_PIN,RST_PIN);
MFRC522::MIFARE_Key key;
byte id[No_Of_Card][4]={
{44,153,22,219},
//RFID NO-1
{112,224,72,84},
//RFID NO-2
{151,94,80,84} //RFID
NO-3
};
byte id_temp[3][3];
byte i;
int j=0;
void setup() {
pinMode(led,OUTPUT);
pinMode(flash,INPUT);
pinMode(5,OUTPUT);
Serial.begin(115200);
Serial.println("Booting");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while
(WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
// Port
defaults to 8266
//
ArduinoOTA.setPort(8266);
// Hostname
defaults to esp8266-[ChipID]
//ArduinoOTA.setHostname("My ESP");
// No
authentication by default
//
ArduinoOTA.setPassword((const char *)"123"); // password
ArduinoOTA.onStart([]() {
digitalWrite(led,HIGH);
Serial.println("Start");
});
ArduinoOTA.onEnd([]() {
digitalWrite(led,LOW);
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error ==
OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if
(error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if
(error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if
(error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if
(error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
Serial.println("Ready");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
mqtt.subscribe(&Bulb1);
SPI.begin();
rfid.PCD_Init();
for(byte
i=0;i<6;i++)
{
key.keyByte[i]=0xFF;
}
// Connect to
WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while
(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the
server
//
server.begin();
Serial.println("Server started");
Serial.print(WiFi.localIP());
delay(1000);
Serial.println("connecting...");
}
void loop() {
MQTT_connect();
Adafruit_MQTT_Subscribe *subscription;
while
((subscription = mqtt.readSubscription(10))) {
if
(subscription == &Bulb1) {
Serial.print(F("Got_Bulb1: "));
Serial.println((char *)Bulb1.lastread);
uint16_t
num = atoi((char *)Bulb1.lastread);
flag= num;
}
}
if(flag==1) //
OTA mode
ArduinoOTA.handle();
else // normal
mode
{
abc();
}
}
void abc()
{
// Check if a
client has connected
int m=0;
if(!rfid.PICC_IsNewCardPresent())
return;
if(!rfid.PICC_ReadCardSerial())
return;
for(i=0;i<4;i++)
{
id_temp[0][i]=rfid.uid.uidByte[i];
delay(50);
}
for(i=0;i<No_Of_Card;i++)
{
if(id[i][0]==id_temp[0][0])
{
if(id[i][1]==id_temp[0][1])
{
if(id[i][2]==id_temp[0][2])
{
if(id[i][3]==id_temp[0][3])
{
Serial.print("your card no :");
for(int s=0;s<4;s++)
{
Serial.print(rfid.uid.uidByte[s]);
Serial.print(" ");
}
Serial.println("\nVALID");
Sending_To_DB();
j=0;
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1(); return;
}
}
}
}
else
{j++;
if(j==No_Of_Card)
{
Serial.println("inVALID");
Sending_To_DB();
j=0;
}
}
}
// Halt PICC
rfid.PICC_HaltA();
// Stop
encryption on PCD
rfid.PCD_StopCrypto1();
}
void MQTT_connect() {
int8_t ret;
// Stop if
already connected.
if
(mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... ");
uint8_t retries
= 3;
while ((ret =
mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if
(retries == 0) {
//
basically die and wait for WDT to reset me
while
(1);
}
}
Serial.println("MQTT Connected!");
}
void Sending_To_DB()
//CONNECTING WITH MYSQL
{
if
(client.connect(server, 80)) {
Serial.println("connected");
// Make a
HTTP request:
Serial.println("GET /rfid/rfid_read.php?allow="); //YOUR URL /rfid/rfid_read.php?allow
client.print("GET
/rfid/nodemcu_rfid/rfid_read.php?allow="); //YOUR URL /rfid/rfid_read.php?allow /var/www/html/rfid/rfid_read.php
if(j!=No_Of_Card)
{
Serial.println('1');
client.print('1');
}
else
{
Serial.println('0');
client.print('0');
}
Serial.println("&id=");
client.print("&id=");
for(int
s=0;s<4;s++)
{
Serial.println(rfid.uid.uidByte[s]);
client.print(rfid.uid.uidByte[s]);
}
client.print(" ");
//SPACE BEFORE HTTP/1.1
client.print("HTTP/1.1");
client.print("Host: ");
client.println(server);
client.println("Host: 192.168.0.111");//eg: 192.168.0.222
client.println("Connection: close");
client.println();
} else {
// if you
didn't get a connection to the server:
Serial.println("connection failed");
}
client.stop();
}
0 comments:
Post a Comment
if you have any doubt please let me know