0% found this document useful (0 votes)
7 views19 pages

Include

The document is an Arduino sketch for an ESP8266-based device that implements a web server for configuring WiFi settings and communicates with Modbus devices over RS485. It includes functions for handling HTTP requests, reading and writing data to EEPROM, and managing Modbus communication. The code sets up a web interface for users to input their WiFi credentials and IP settings, and it handles various Modbus operations to read data from connected devices.

Uploaded by

mrchubom
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views19 pages

Include

The document is an Arduino sketch for an ESP8266-based device that implements a web server for configuring WiFi settings and communicates with Modbus devices over RS485. It includes functions for handling HTTP requests, reading and writing data to EEPROM, and managing Modbus communication. The code sets up a web interface for users to input their WiFi credentials and IP settings, and it handles various Modbus operations to read data from connected devices.

Uploaded by

mrchubom
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

#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);

You might also like