Skip to content

Commit

Permalink
add config
Browse files Browse the repository at this point in the history
  • Loading branch information
zivillian committed Jun 16, 2022
1 parent e06fe5d commit 0583112
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 29 deletions.
33 changes: 21 additions & 12 deletions include/config.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
#ifndef CONFIG_H
#define CONFIG_H
#include <Arduino.h>
#include <Preferences.h>
#define debugSerial Serial
#define modbusSerial Serial2
#define DEBUG

typedef struct {
unsigned int tcpPort;
bool enableRtuOverTcp;
unsigned long baud;
unsigned long serialConfig;
} config_type;

const config_type default_config = {
502,
false,
19200,
SERIAL_8E1
class Config{
private:
Preferences *_prefs;
int16_t _tcpPort;
unsigned long _baud;
uint32_t _serialConfig;
public:
Config();
void begin(Preferences *prefs);
uint16_t getTcpPort();
unsigned long getBaud();
uint32_t getSerialConfig();
void setTcpPort(uint16_t value);
void setBaud(unsigned long value);
uint8_t getDataBits();
void setDataBits(uint8_t value);
uint8_t getParity();
void setParity(uint8_t value);
uint8_t getStopBits();
void setStopBits(uint8_t value);
};
#ifdef DEBUG
#define dbg(x...) debugSerial.print(x);
Expand Down
2 changes: 1 addition & 1 deletion include/pages.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <ModbusClientRTU.h>
#include "config.h"

void setupPages(AsyncWebServer* server, ModbusClientRTU *rtu, ModbusBridgeWiFi *bridge);
void setupPages(AsyncWebServer* server, ModbusClientRTU *rtu, ModbusBridgeWiFi *bridge, Config *config);
void sendResponseHeader(AsyncResponseStream *response, const char *title);
void sendResponseTrailer(AsyncResponseStream *response);
void sendButton(AsyncResponseStream *response, const char *title, const char *action, const char *css = "");
Expand Down
77 changes: 77 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include "config.h"

Config::Config()
:_prefs(NULL)
,_tcpPort(502)
,_baud(9600)
,_serialConfig(SERIAL_8N1)
{}

void Config::begin(Preferences *prefs)
{
_prefs = prefs;
_tcpPort = _prefs->getUShort("tcpPort", _tcpPort);
_baud = _prefs->getULong("baud", _baud);
_serialConfig = _prefs->getULong("serialConfig", _serialConfig);
}

uint16_t Config::getTcpPort(){
return _tcpPort;
}

unsigned long Config::getBaud(){
return _baud;
}

uint32_t Config::getSerialConfig(){
return _serialConfig;
}

void Config::setTcpPort(uint16_t value){
if (_tcpPort == value) return;
_tcpPort = value;
_prefs->putUShort("tcpPort", _tcpPort);
}

void Config::setBaud(unsigned long value){
if (_baud == value) return;
_baud = value;
_prefs->putULong("baud", _baud);
}

uint8_t Config::getDataBits(){
return ((_serialConfig & 0xc) >> 2) + 5;
}

void Config::setDataBits(uint8_t value){
auto dataBits = getDataBits();
value -= 5;
value = (value << 2) & 0xc;
if (value == dataBits) return;
_serialConfig = (_serialConfig & 0xfffffff3) | value;
_prefs->putULong("serialConfig", _serialConfig);
}

uint8_t Config::getParity(){
return _serialConfig & 0x3;
}

void Config::setParity(uint8_t value){
auto parity = getParity();
value = value & 0x3;
if (parity == value) return;
_serialConfig = (_serialConfig & 0xfffffffc) | value;
_prefs->putULong("serialConfig", _serialConfig);
}

uint8_t Config::getStopBits(){
return (_serialConfig & 0x30) >> 4;
}

void Config::setStopBits(uint8_t value){
auto stopbits = getStopBits();
value = (value << 4) & 0x30;
if (stopbits == value) return;
_serialConfig = (_serialConfig & 0xffffffcf) | value;
_prefs->putULong("serialConfig", _serialConfig);
}
20 changes: 5 additions & 15 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "pages.h"

AsyncWebServer webServer(80);
config_type config;
Config config;
Preferences prefs;
ModbusClientRTU MBclient(modbusSerial);
ModbusBridgeWiFi MBbridge;
Expand All @@ -22,32 +22,22 @@ void setup() {
dbgln();
dbgln("[config] load")
prefs.begin("modbusRtuGw");
if (prefs.getBytesLength("settings") != sizeof(config_type))
{
dbgln("[config] no config found - using default");
config = default_config;
prefs.putBytes("settings", &config, sizeof(config_type));
}
else
{
dbgln("[config] config found - loading");
prefs.getBytes("settings", &config, sizeof(config_type));
}
config.begin(&prefs);
dbgln("[wifi] start");
WiFi.mode(WIFI_STA);
wm.autoConnect();
dbgln("[wifi] finished");
dbgln("[modbus] start");
modbusSerial.begin(config.baud, config.serialConfig);
modbusSerial.begin(config.getBaud(), config.getSerialConfig());
MBclient.setTimeout(1000);
MBclient.begin();
for (uint8_t i = 1; i < 248; i++)
{
MBbridge.attachServer(i, i, ANY_FUNCTION_CODE, &MBclient);
}
MBbridge.start(502, 10, 10000);
MBbridge.start(config.getTcpPort(), 10, 10000);
dbgln("[modbus] finished");
setupPages(&webServer, &MBclient, &MBbridge);
setupPages(&webServer, &MBclient, &MBbridge, &config);
AsyncElegantOTA.begin(&webServer);
webServer.begin();
dbgln("[setup] finished");
Expand Down
104 changes: 103 additions & 1 deletion src/pages.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "pages.h"

void setupPages(AsyncWebServer *server, ModbusClientRTU *rtu, ModbusBridgeWiFi *bridge){
void setupPages(AsyncWebServer *server, ModbusClientRTU *rtu, ModbusBridgeWiFi *bridge, Config *config){
server->on("/", HTTP_GET, [](AsyncWebServerRequest *request){
dbgln("[webserver] GET /");
auto *response = request->beginResponseStream("text/html");
Expand Down Expand Up @@ -43,6 +43,104 @@ void setupPages(AsyncWebServer *server, ModbusClientRTU *rtu, ModbusBridgeWiFi *
ESP.restart();
dbgln("[webserver] rebooted...")
});
server->on("/config", HTTP_GET, [config](AsyncWebServerRequest *request){
dbgln("[webserver] GET /config");
auto *response = request->beginResponseStream("text/html");
sendResponseHeader(response, "Config");
response->print("<form method=\"post\">");
response->print("<table>"
"<tr>"
"<td>"
"<label for=\"port\">TCP Port</label>"
"</td>"
"<td>");
response->printf("<input type=\"text\" id=\"port\" name=\"port\" value=\"%d\">", config->getTcpPort());
response->print("</td>"
"</tr>"
"<tr>"
"<td>"
"<label for=\"baud\">Modbus baud rate</label>"
"</td>"
"<td>");
response->printf("<input type=\"number\" min=\"0\" id=\"baud\" name=\"baud\" value=\"%d\">", config->getBaud());
response->print("</td>"
"</tr>"
"<tr>"
"<td>"
"<label for=\"data\">Modbus data bits</label>"
"</td>"
"<td>");
response->printf("<input type=\"text\" id=\"data\" name=\"data\" value=\"%d\">", config->getDataBits());
response->print("</td>"
"</tr>"
"<tr>"
"<td>"
"<label for=\"parity\">Modbus parity</label>"
"</td>"
"<td>");
response->printf("<select id=\"parity\" name=\"parity\" data-value=\"%d\">", config->getParity());
response->print("<option value=\"0\">None</option>"
"<option value=\"2\">Even</option>"
"<option value=\"3\">Odd</option>"
"</select>"
"</td>"
"</tr>"
"<tr>"
"<td>"
"<label for=\"stop\">Modbus stop bits</label>"
"</td>"
"<td>");
response->printf("<select id=\"stop\" name=\"stop\" data-value=\"%d\">", config->getStopBits());
response->print("<option value=\"1\">1 bit</option>"
"<option value=\"2\">1.5 bits</option>"
"<option value=\"3\">2 bits</option>"
"</select>"
"</td>"
"</tr>"
"</table>");
response->print("<button class=\"r\">Save</button>"
"</form>"
"<p></p>");
sendButton(response, "Back", "/");
response->print("<script>"
"(function(){"
"var s = document.querySelectorAll('select[data-value]');"
"for(d of s){"
"d.querySelector(`option[value='${d.dataset.value}']`).selected=true"
"}})();"
"</script>");
sendResponseTrailer(response);
request->send(response);
});
server->on("/config", HTTP_POST, [config](AsyncWebServerRequest *request){
dbgln("[webserver] POST /config");
if (request->hasParam("port", true)){
auto port = request->getParam("port", true)->value().toInt();
config->setTcpPort(port);
dbgln("[webserver] saved port");
}
if (request->hasParam("baud", true)){
auto baud = request->getParam("baud", true)->value().toInt();
config->setBaud(baud);
dbgln("[webserver] saved baud");
}
if (request->hasParam("data", true)){
auto data = request->getParam("data", true)->value().toInt();
config->setDataBits(data);
dbgln("[webserver] saved data");
}
if (request->hasParam("parity", true)){
auto parity = request->getParam("parity", true)->value().toInt();
config->setParity(parity);
dbgln("[webserver] saved parity");
}
if (request->hasParam("stop", true)){
auto stop = request->getParam("stop", true)->value().toInt();
config->setStopBits(stop);
dbgln("[webserver] saved stop");
}
request->redirect("/");
});
server->on("/favicon.ico", [](AsyncWebServerRequest *request){
dbgln("[webserver] GET /favicon.ico");
request->send(204);//TODO add favicon
Expand Down Expand Up @@ -82,6 +180,10 @@ void setupPages(AsyncWebServer *server, ModbusClientRTU *rtu, ModbusBridgeWiFi *
"}"
"table{"
"text-align:left;"
"width:100%;"
"}"
"input{"
"width:100%;"
"}"
);
response->addHeader("ETag", __DATE__ "" __TIME__);
Expand Down

0 comments on commit 0583112

Please sign in to comment.