#include <ESP8266WiFi.
h>
#include <ESP8266WebServer.h>
#include "ModbusMaster.h"
#include <SoftwareSerial.h>
#include <EEPROM.h>
#include <ModbusIP_ESP8266.h>
#include <WiFiClient.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>
#include <ESP8266Ping.h>
#define MAX485_RE_NEG D2 //4 // RS485 has a enable/disable pin to transmit or receive
data. Arduino Digital Pin 2 = Rx/Tx 'Enable'; High to Transmit, Low to Receive
#define RX_RS485 D1 //5 //
#define TX_RS485 D4 //2 //
#define Slave_ID 6
#define BT_RESET 0
const char* ssidAP = "DWS2";
const char* passwordAP = "12345678";
char* ssid = "DWS";
char* password = "12345678";
int ModbusTCP_port = 502;
int j, capnhat, startserver;
uint16_t csdh_0, csdh_1, csdh_2, csdh_3, csdh_4;
unsigned long csdh;
unsigned long csdhtmp;
// Set web server port number to 80
ESP8266WebServer server(80);
ESP8266HTTPUpdateServer httpUpdater;
const char* host = "esp8266-webupdate";
IPAddress apIP(192, 168, 1, 1);
char ssidc[30];//Stores the router name for IOT
char passwordc[30];//Stores the password for IOT
int ip_group = 0; //sets what number set of the IP address we are collecting. 5 in total
String string_IP = ""; //temporarily stores a IP group number
String header;
String loimodbus1, loimodbus2, loimodbus;
uint16_t data[10];
//Creating the input form
const char INDEX_HTML[] =
"<!DOCTYPE HTML>"
"<html>"
"<head>"
"<meta content=\"text/html;\" charset=\" ISO-8859-1\" http-equiv=\"content-type\">"
"<meta name=\"viewport\" content=\"width = device-width, initial-scale = 1.0, maximum-
scale = 1.0, user-scalable=0\">"
"<title>Config</title>"
"<style>"
"body {"
"background-color: #fff;"
"font-family: Arial, Helvetica, Sans-Serif;"
"Color: #000000;"
"}"
"form{"
"float: left;"
"width: 100%;"
"margin-bottom: 30px;"
"}"
"div{"
"padding: 10px 0;"
"}"
"h1{"
"font-size: calc(100vw / 9);"
"text-align: center;"
"}"
"label{"
"font-size: calc(100vw / 13);"
"font-weight: bold;"
"}"
"input{"
"height: calc(100vw / 13);"
"width: calc(100% - 30px);"
"font-size: calc(100vw / 26);"
"padding: 0 10px;"
"display: block;"
"}"
"input[type=\"submit\"], input[type=\"reset\"]{"
"float: left;"
"width: 50%;"
"height: calc(100vw / 10);"
"border: none;"
"}"
"input[type=\"submit\"]{"
"background: #2196F3;"
"}"
"</style>"
"</head>"
"<body>"
"<h1>DOWASEN - AP</h1>"
"<form action=\"/\" method=\"post\">"
"<div>"
"<label>SSID:</label>"
"<input maxlength=\"30\" name=\"ssid\">"
"</div>"
"<div>"
"<label>Password:</label>"
"<input maxlength=\"30\" name=\"Password\">"
"</div>"
"<div>"
"<label>IP:</label>"
"<input maxlength=\"15\" name=\"IP\">"
"</div>"
"<div>"
"<label>Gateway:</label>"
"<input maxlength=\"3\" name=\"GW\">"
"</div>"
"<div>"
"<input type=\"submit\" value=\"Send\"/>"
"<input type=\"reset\">"
"</div>"
"</FORM>"
"</body>"
"</html>";
//save
byte IP1 = 192;
byte IP2 = 168;
byte IP3 = 5;
byte IP4 = 5;
word port = 0;
IPAddress subnet(255, 255, 255, 0);
word adrmem = 0;
bool fl_AP = false;
bool fl_reset = false;
bool cmd_reset = false;
ModbusMaster modbus;
SoftwareSerial swSer(RX_RS485, TX_RS485);
unsigned long lastmn = 0;
unsigned long lastkn = 0;
unsigned long lastpower = 0;
unsigned long lastping = 0;
unsigned long lastkeep = 0;
int countping = 0;
const IPAddress remote_ip(192, 168, 5, 1);
byte ByteArray[260];
unsigned int MBHoldingRegister[10];
ModbusIP mb;
void preTransmission()
digitalWrite(MAX485_RE_NEG, HIGH); //Switch to transmit data
void postTransmission()
{
digitalWrite(MAX485_RE_NEG, LOW); //Switch to receive data
byte AP_count = 0;
void handleRoot1() {
server.send(200, "text/plain", loimodbus1 + " - " + loimodbus2);
void setup() {
EEPROM.begin(512);//Starting and setting size of the EEPROM
ESP.wdtDisable();
pinMode(BT_RESET, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(MAX485_RE_NEG, OUTPUT);
digitalWrite(MAX485_RE_NEG, LOW);
ESP.wdtFeed();
fl_AP = false;
uint8_t ip[] = { IP1, IP2, IP3, IP4 };
uint8_t gateway[] = { IP1, IP2, IP3, 1 };
uint8_t subnet[] = { 255, 255, 255, 0 };
lastkn = millis();
lastpower = millis();
IOT();
AP_count = 0;
while ((WiFi.status() != WL_CONNECTED) and (AP_count < 30)) {
AP_count = AP_count + 1;
delay(500);
ESP.wdtFeed();
if (AP_count >= 30 ) {
fl_AP = true;
if (fl_AP == true) {
ESP.wdtFeed();
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
WiFi.softAP(ssidAP, passwordAP);
server.on("/", handleRoot);
server.onNotFound(handleNotFound);
server.begin();
else {
ESP.wdtFeed();
mb.slave();
mb.addHreg(0, 0);
mb.addHreg(1, 0);
mb.addHreg(2, 0);
mb.addHreg(3, 0);
mb.addHreg(4, 0);
mb.addHreg(5, 0);
startserver = 0;
ESP.wdtFeed();
swSer.begin(9600);
modbus.begin(Slave_ID, swSer);
// Callbacks allow us to configure the RS485 transceiver correctly
modbus.preTransmission(preTransmission);
modbus.postTransmission(postTransmission);
lastkeep = millis();
MDNS.begin(host);
httpUpdater.setup(&server);
server.begin();
MDNS.addService("http", "tcp", 80);
// server.on("/", handleRoot1);
startserver = 1;
ESP.wdtFeed();
int cn = 0;
void loop() {
capnhat = mb.Hreg(3);
if (capnhat == 1)
server.handleClient();
MDNS.update();
}
if (millis() < lastkn)
lastkn = millis();
if (millis() < lastpower)
{
lastpower = millis();
if (fl_AP == true) {
server.handleClient();
// ChkAP();
else {
if ((millis() - lastkn > 15000) )
lastkn = millis();
ReadRS485Slave();
if ((millis() - lastmn > 5000) )
lastmn = millis();
Readmn();
}
ESP.wdtFeed();
mb.task();
delay(10);
if ((millis() - lastpower > 900000) or (countping > 20))
{
ESP.restart();
while (1) {};
}
bool getResultMsg( uint8_t result)
String tmpstr2 = "\r\n";
switch (result)
{
case modbus.ku8MBSuccess:
Serial.println("Đọc RS485 thành công!");
return true;
break;
case modbus.ku8MBIllegalFunction:
tmpstr2 += "Illegal Function";
break;
case modbus.ku8MBIllegalDataAddress:
tmpstr2 += "Illegal Data Address";
break;
case modbus.ku8MBIllegalDataValue:
tmpstr2 += "Illegal Data Value";
break;
case modbus.ku8MBSlaveDeviceFailure:
tmpstr2 += "Slave Device Failure";
break;
case modbus.ku8MBInvalidSlaveID:
tmpstr2 += "Invalid Slave ID";
break;
case modbus.ku8MBInvalidFunction:
tmpstr2 += "Invalid Function";
break;
case modbus.ku8MBResponseTimedOut:
tmpstr2 += "Response Timed Out";
break;
case modbus.ku8MBInvalidCRC:
tmpstr2 += "Invalid CRC";
break;
default:
tmpstr2 += "Unknown error: " + String(result);
break;
}//
return false;
void Readmn()
{
Serial.println("Đang đọc dữ liệu RS485...");
modbus.preTransmission(preTransmission);
modbus.postTransmission(postTransmission);
ESP.wdtFeed();
uint8_t result = modbus.readHoldingRegisters(1, 0, 1); //đọc địa chỉ thiet bi 1, tai o nho 0, 1
dữ liệu
ESP.wdtFeed();
if (getResultMsg( result))
data[0] = modbus.getResponseBuffer(0);
mb.Hreg(2, data[0]);
}
else
{
delay(500);
result = modbus.readHoldingRegisters(1, 1, 1);
if (getResultMsg( result))
data[0] = modbus.getResponseBuffer(0);
mb.Hreg(2, data[0]);
void ReadRS485Slave()
{
modbus.preTransmission(preTransmission);
modbus.postTransmission(postTransmission);
ESP.wdtFeed();
uint8_t result = modbus.readHoldingRegisters(1, 272, 4); //đọc địa chỉ thiet bi 1, tai o nho 0,
1 dữ liệu
ESP.wdtFeed();
if (getResultMsg( result))
{
for (j = 0; j < 4; j++)
data[j] = modbus.getResponseBuffer(j);
csdh_0 = reform_uint16_2_float32(data[1], data[0]) * 100;
mb.Hreg(0, csdh_0);
csdh_1 = reform_uint16_2_float32(data[3], data[2]) * 100;
mb.Hreg(1, csdh_1);
ESP.wdtFeed();
modbus.preTransmission(preTransmission);
modbus.postTransmission(postTransmission);
data[0] = 1;
data[1] = 1;
delay(500);
result = modbus.readInputRegisters(1, 2, 2); //đọc địa chỉ thiet bi 1, tai o nho 0, 1 dữ liệu
ESP.wdtFeed();
if (getResultMsg( result))
for (j = 0; j < 2; j++)
data[j] = modbus.getResponseBuffer(j);
mb.Hreg(4, data[0]);
mb.Hreg(5, data[1]);
}
}
float reform_uint16_2_float32( uint16_t vt1, uint16_t vt2)
uint16_t w0, w1;
w0 = word(lowByte(vt1), highByte(vt1));
w1 = word(lowByte(vt2), highByte(vt2));
return doifloat(w0, w1);
float doifloat(uint16_t u1, uint16_t u2)
{
uint32_t num = ((uint32_t)u1 & 0xFFFF) << 16 | ((uint32_t)u2 & 0xFFFF);
float numf;
memcpy(&numf, &num, 4);
return numf;
int ip_convert(String convert) {
int number;
if (convert.toInt()) {
number = convert.toInt();
string_IP = "";
return number;
} else {
return 400;
}
//Reads a string out of memory
String read_string(int l, int p) {
String temp;
for (int n = p; n < l + p; ++n)
{
if (char(EEPROM.read(n)) != ';') {
if (isWhitespace(char(EEPROM.read(n)))) {
//do nothing
} else temp += String(char(EEPROM.read(n)));
} else n = l + p;
}
return temp;
void handleRoot() {
if (server.hasArg("ssid") && server.hasArg("Password") && server.hasArg("IP") &&
server.hasArg("GW") ) { //If all form fields contain data call handelSubmit()
handleSubmit();
else {//Redisplay the form
server.send(200, "text/html", INDEX_HTML);
void handleSubmit() { //dispaly values and write to memmory
String response = "<p>The ssid is ";
response += server.arg("ssid");
response += "<br>";
response += "And the password is ";
response += server.arg("Password");
response += "<br>";
response += "And the IP Address is ";
response += server.arg("IP");
response += "</P><BR>";
response += "<H2><a href=\"/\">go home</a></H2><br>";
server.send(200, "text/html", response);
//calling function that writes data to memory
write_to_Memory(String(server.arg("ssid")), String(server.arg("Password")),
String(server.arg("IP")), String(server.arg("GW")));
delay(1000);
while (1) {};
//Write data to memory
/**
We prepping the data strings by adding the end of line symbol I decided to use ";".
Then we pass it off to the write_EEPROM function to actually write it to memmory
*/
void write_to_Memory(String s, String p, String i, String g) {
s += ";";
write_EEPROM(s, 0);
p += ";";
write_EEPROM(p, 100);
i += ";";
write_EEPROM(i, 200);
g += ";";
write_EEPROM(g, 220);
EEPROM.commit();
}
//write to memory
void write_EEPROM(String x, int pos) {
for (int n = pos; n < x.length() + pos; n++) {
EEPROM.write(n, x[n - pos]);
}
//Shows when we get a misformt or wrong request for the web server
void handleNotFound()
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
message += "<H2><a href=\"/\">go home</a></H2><br>";
server.send(404, "text/plain", message);
void IOT() {
//reading the ssid and password out of memory
delay(3000);
String string_Ssid = "";
String string_Password = "";
string_Ssid = read_string(30, 0);
string_Password = read_string(30, 100);
string_Password.toCharArray(passwordc, 30);
string_Ssid.toCharArray(ssidc, 30);
//Reading IP information out of memmory
int ip_Info[5];//holds all converted IP integer information
for (int n = 200; n < 216; ++n)
if (char(EEPROM.read(n)) != '.' && char(EEPROM.read(n)) != ';') { //
string_IP += char(EEPROM.read(n));
} else if (char(EEPROM.read(n)) == '.') { //if(char(EEPROM.read(n))=='.')
ip_Info[ip_group] = ip_convert(string_IP);
ip_group++;
} else if (char(EEPROM.read(n)) == ';') {
ip_Info[ip_group] = ip_convert(string_IP);
ip_group++;
n = 217;
string_IP = "";
string_IP = read_string(4, 220);
ip_Info[ip_group] = ip_convert(string_IP);
//configuring conection parameters, and connecting to the WiFi router
IPAddress IOT_ip(ip_Info[0], ip_Info[1], ip_Info[2], ip_Info[3]); // defining ip address
IPAddress IOT_gateway(ip_Info[0], ip_Info[1], ip_Info[2], ip_Info[4]); // set gateway to
match your network
//IPAddress subnet(255, 255, 255, 0); // set subnet mask to match your network
WiFi.config(IOT_ip, IOT_gateway, subnet);
WiFi.begin(ssidc, passwordc);
delay(1000);