Преглед изворни кода

branch webserver config

webserver_config
agr пре 4 година
родитељ
комит
dfac643c9f
6 измењених фајлова са 528 додато и 1 уклоњено
  1. +9
    -0
      .cproject
  2. +15
    -0
      .project
  3. +183
    -0
      eepromsettings.cpp
  4. +38
    -0
      eepromsettings.h
  5. +175
    -1
      esp32MQTT.ino
  6. +108
    -0
      struct.h

+ 9
- 0
.cproject Прегледај датотеку

@@ -23,6 +23,9 @@
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/core/variant}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/PubSubClient/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/WiFi/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/Ethernet/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/SPI/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/EEPROM/src}&quot;"/>
</option>
<inputType id="io.sloeber.compiler.cpp.sketch.input.937136842" name="CPP source files" superClass="io.sloeber.compiler.cpp.sketch.input"/>
</tool>
@@ -32,6 +35,9 @@
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/core/variant}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/PubSubClient/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/WiFi/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/Ethernet/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/SPI/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/EEPROM/src}&quot;"/>
</option>
<inputType id="io.sloeber.compiler.c.sketch.input.1969354592" name="C Source Files" superClass="io.sloeber.compiler.c.sketch.input"/>
</tool>
@@ -41,6 +47,9 @@
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/core/variant}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/PubSubClient/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/WiFi/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/Ethernet/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/SPI/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/esp32MQTT/libraries/EEPROM/src}&quot;"/>
</option>
<inputType id="io.sloeber.compiler.S.sketch.input.132653342" name="Assembly source files" superClass="io.sloeber.compiler.S.sketch.input"/>
</tool>


+ 15
- 0
.project Прегледај датотеку

@@ -41,11 +41,26 @@
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/packages/esp32/hardware/esp32/1.0.4/variants/esp32</locationURI>
</link>
<link>
<name>libraries/EEPROM</name>
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/packages/esp32/hardware/esp32/1.0.4/libraries/EEPROM</locationURI>
</link>
<link>
<name>libraries/Ethernet</name>
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/libraries/Ethernet/2.0.0</locationURI>
</link>
<link>
<name>libraries/PubSubClient</name>
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/libraries/PubSubClient/2.7.0</locationURI>
</link>
<link>
<name>libraries/SPI</name>
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/packages/esp32/hardware/esp32/1.0.4/libraries/SPI</locationURI>
</link>
<link>
<name>libraries/WiFi</name>
<type>2</type>


+ 183
- 0
eepromsettings.cpp Прегледај датотеку

@@ -0,0 +1,183 @@
/*
* eepromsettings.c
*
* Created on: 14.05.2020
* Author: agr
*/

#include "eepromsettings.h"
#include "struct.h"

/**
* read_EEPROM_Settings function
* This function is used to read the EEPROM settings at startup
*
* Overview:
* - Set the PIN for the RESET-button to input and activate pullups
* - Load the stored data from EEPROM into the eeprom_config struct
* - Check if a config is stored or the reset button is pressed. If one of the conditions is ture, set the defaults
*/
void read_EEPROM_Settings() {
pinMode(RESET_PIN, INPUT);
digitalWrite(RESET_PIN, HIGH);

// read the current config
EEPROM_readAnything(0, eeprom_config);

// check if config is present or if reset button is pressed
if (eeprom_config.config_set != 1 || digitalRead(RESET_PIN) == LOW) {
// set default values
#ifdef DEBUG
Serial.println(eeprom_config.config_set);
Serial.println(digitalRead(RESET_PIN));
#endif

set_EEPROM_Default();
#ifdef DEBUG
Serial.println("write default config");
#endif
// write the config to eeprom
EEPROM_writeAnything(0, eeprom_config);
}
}

/**
* print_EEPROM_Settings() function
*
* This function is used for debugging the configuration.
* It prints the actual configuration to the serial port.
*/
#ifdef DEBUG
void print_EEPROM_Settings() {
Serial.print("IP: ");
for(int i = 0; i<4; i++) {
Serial.print(eeprom_config.ip[i]);
if (i<3) {
Serial.print('.');
}
}
Serial.println();

Serial.print("Subnet: ");
for(int i = 0; i<4; i++) {
Serial.print(eeprom_config.subnet[i]);
if (i<3) {
Serial.print('.');
}
}
Serial.println();

Serial.print("Gateway: ");
for(int i = 0; i<4; i++) {
Serial.print(eeprom_config.gateway[i]);
if (i<3) {
Serial.print('.');
}
}
Serial.println();

Serial.print("DNS Server: ");
for(int i = 0; i<4; i++) {
Serial.print(eeprom_config.dns_server[i]);
if (i<3) {
Serial.print('.');
}
}
Serial.println();

Serial.print("MQTT Server: ");
for(int i = 0; i<4; i++) {
Serial.print(eeprom_config.mqtt_server[i]);
if (i<3) {
Serial.print('.');
}
}
Serial.println();

Serial.print("MAC: ");
for (int a=0;a<6;a++) {
Serial.print(eeprom_config.mac[a],HEX);
if(a<5) {
Serial.print(":");
}
}
Serial.println();
Serial.print("MQTTserver Port: ");
Serial.println(eeprom_config.mqttserverPort);

Serial.print("Webserver Port: ");
Serial.println(eeprom_config.webserverPort);

Serial.print("USE DHCP: ");
Serial.println(eeprom_config.use_dhcp);

Serial.print(" DHCP renew every ");
Serial.print(eeprom_config.dhcp_refresh_minutes);
Serial.println(" minutes");

Serial.print("Config Set: ");
Serial.println(eeprom_config.config_set);

}
#endif

// #############################################################################################################################################################


/**
* renewDHCP() function
* Renew the DHCP relase in a given interval.
*
* Overview:
* - Check if interval = 0 and set it to 1
* - Check if renew interval is reached and renew the lease
*/
void renewDHCP(int interval) {
unsigned long interval_millis = interval * 60000;

if (interval == 0 ) {
interval = 1;
}
if (eeprom_config.use_dhcp==1) {
if((millis() - last_dhcp_renew) > interval_millis) {
last_dhcp_renew=millis();
dhcp_state = Ethernet.maintain();
}
}
}


/**
* setupNetwork() function
* This function is used to setupup the network according to the values stored in the eeprom
*
* Overview:
* - First of all read the EEPROM settings
* - Display a link to the ethernet setup
* - Check if DHCP should be used, if not create instaces of IPAddress for ip, gateway, subnet and dns_server
* - Invoke Ethernet.begin with all parameters if no dhcp is active (Ethernet.begin(mac, ip, dns_server, gateway, subnet);).
* - If DHCP is used invoke only with mac (Ethernet.begin(mac);) and display the ip on the serial console.
*/
void setupNetwork() {
read_EEPROM_Settings();

#ifdef DEBUG
print_EEPROM_Settings();
#endif

// byte mac[] = { eeprom_config.mac[0], eeprom_config.mac[1], eeprom_config.mac[2], eeprom_config.mac[3], eeprom_config.mac[4], eeprom_config.mac[5] };

if (eeprom_config.use_dhcp != 1) {
IPAddress ip(eeprom_config.ip[0], eeprom_config.ip[1], eeprom_config.ip[2], eeprom_config.ip[3]);
IPAddress gateway (eeprom_config.gateway[0],eeprom_config.gateway[1],eeprom_config.gateway[2],eeprom_config.gateway[3]);
IPAddress subnet (eeprom_config.subnet[0], eeprom_config.subnet[1], eeprom_config.subnet[2], eeprom_config.subnet[3]);
IPAddress dns_server (eeprom_config.dns_server[0], eeprom_config.dns_server[1], eeprom_config.dns_server[2], eeprom_config.dns_server[3]);
Ethernet.begin(eeprom_config.mac, ip, dns_server, gateway, subnet);
} else {
if (Ethernet.begin(eeprom_config.mac) == 0) {
Serial.print("Failed to configure Ethernet using DHCP");
}
Serial.println(Ethernet.localIP());
}
}
// END Network section #########################################################################################################################################

+ 38
- 0
eepromsettings.h Прегледај датотеку

@@ -0,0 +1,38 @@
/*
* eepromsettings.h
*
* Created on: 14.05.2020
* Author: agr
*/

#ifndef EEPROMSETTINGS_H_
#define EEPROMSETTINGS_H_

#include <Arduino.h>

#include <WiFi.h>
#include <PubSubClient.h>

#define RESET_PIN 9 //Connect a button to this PIN. If the button is hold, an the device is turned on the default ethernet settings are restored.


void read_EEPROM_Settings();

#ifdef DEBUG
void print_EEPROM_Settings();
#endif


/* START Network section #######################################################################################################################################
* Code for setting up network connection
*/
unsigned long last_dhcp_renew;
byte dhcp_state;

void renewDHCP(int interval);

void setupNetwork() ;



#endif /* EEPROMSETTINGS_H_ */

+ 175
- 1
esp32MQTT.ino Прегледај датотеку

@@ -1,6 +1,8 @@
#include <WiFi.h>
#include <PubSubClient.h>

//#include "struct.h"
#include "eepromsettings.h"

// Update these with values suitable for your network.
const char* ssid = "Andreas-Grabner.NET";
@@ -16,6 +18,76 @@ WiFiClient wifiClient;

PubSubClient client(wifiClient);

// Webserver
WiFiServer server(80);
String header;

// Auxiliar variables to store the current output state
String output26State = "off";
String output27State = "off";

// Assign output variables to GPIO pins
const int output26 = 26;
const int output27 = 27;

/* Store all string in the FLASH storage to free SRAM.
The P() is a function from Webduino.
*/
P(Page_start) = "<html><head><title>Web_EEPROM_Setup</title></head><body>\n";
P(Page_end) = "</body></html>";

P(Http400) = "HTTP 400 - BAD REQUEST";
P(Index) = "<h1>index.html</h1><br>This is your main site!<br>The code is found in the indexHTML() function.<br>You can add more sites if you need. Please see the well documented source code.<br><br>Use the following link to setup the network.<br><a href=\"setupNet.html\">NETWORK SETUP</a>";

P(Form_eth_start) = "<FORM action=\"setupNet.html\" method=\"get\">";
P(Form_end) = "<FORM>";
P(Form_input_send) = "<INPUT type=\"submit\" value=\"Set config\">";

P(Form_input_text_start) = "<input type=\"text\" name=\"";
P(Form_input_value) = "\" value=\"";
P(Form_input_size2) = "\" maxlength=\"2\" size=\"2";
P(Form_input_size3) = "\" maxlength=\"3\" size=\"3";
P(Form_input_end) = "\">\n";

P(MAC) = "MAC address: ";
P(IP) = "IP address: ";
P(SUBNET) = "Subnet: ";
P(GW) = "GW address: ";
P(DNS_SERVER) = "DNS server: ";
P(WEB_PORT) = "Webserver port (1-65535): ";
P(DHCP_ACTIVE) = "Use DHCP: ";
P(DHCP_REFRESH) = "Renew interval for DHCP in minutes (1 - 255): ";
P(MQTT_SERVER) = "MQTT server: ";
P(MQTT_PORT) = "MQTTserver port (1-65535): ";

P(Form_cb) = "<input type=\"radio\" name=\"23\" value=\"";
P(Form_cb_checked) = " checked ";
P(Form_cb_on) = ">On";
P(Form_cb_off) = ">Off";

P(br) = "<br>\n";

P(table_start) = "<table>";
P(table_tr_start) = "<tr>";
P(table_tr_end) = "</tr>";
P(table_td_start) = "<td>";
P(table_td_end) = "</td>";
P(table_end) = "</table>";

P(Config_set) = "<font size=\"6\" color=\"red\">New configuration stored! <br>Please turn off and on your Arduino or use the reset button!</font><br>";

P(DHCP_STATE_TIME) = "DHCP last renew timestamp (sec)";
P(DHCP_STATE) = "DHCP renew return code (sec)";


P(UPTIME) = "Uptime: ";

#ifdef USE_SYSTEM_LIBRARY
P(RAM_1) = "RAM (byte): ";
P(RAM_2) = " free of ";
#endif


void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
@@ -34,6 +106,11 @@ void setup_wifi() {
Serial.println(WiFi.localIP());
}

void setup_webserver() {
server.begin();
}


void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
@@ -45,7 +122,7 @@ void reconnect() {
if (client.connect(clientId.c_str(),MQTT_USER,MQTT_PASSWORD)) {
Serial.println("connected");
//Once connected, publish an announcement...
client.publish("icircuit/presence/ESP32/", "hello world");
client.publish("ESP32/Heizung/Status/restart", "done");
// ... and resubscribe
client.subscribe(MQTT_SERIAL_RECEIVER_CH);
} else {
@@ -71,6 +148,7 @@ void setup() {
Serial.begin(115200);
Serial.setTimeout(500);// Set time out for
setup_wifi();
setup_webserver();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
reconnect();
@@ -82,8 +160,104 @@ void publishSerialData(char *serialData){
}
client.publish(MQTT_SERIAL_PUBLISH_CH, serialData);
}

void loop_webserver() {
WiFiClient client = server.available(); // Listen for incoming clients
if (client) { // If a new client connects,
Serial.println("New Client."); // print a message out in the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
header += c;
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();

// turns the GPIOs on and off
if (header.indexOf("GET /26/on") >= 0) {
Serial.println("GPIO 26 on");
output26State = "on";
digitalWrite(output26, HIGH);
} else if (header.indexOf("GET /26/off") >= 0) {
Serial.println("GPIO 26 off");
output26State = "off";
digitalWrite(output26, LOW);
} else if (header.indexOf("GET /27/on") >= 0) {
Serial.println("GPIO 27 on");
output27State = "on";
digitalWrite(output27, HIGH);
} else if (header.indexOf("GET /27/off") >= 0) {
Serial.println("GPIO 27 off");
output27State = "off";
digitalWrite(output27, LOW);
}

// Display the HTML web page
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
// CSS to style the on/off buttons
// Feel free to change the background-color and font-size attributes to fit your preferences
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
client.println(".button2 {background-color: #555555;}</style></head>");

// Web Page Heading
client.println("<body><h1>ESP32 Web Server</h1>");

// Display current state, and ON/OFF buttons for GPIO 26
client.println("<p>GPIO 26 - State " + output26State + "</p>");
// If the output26State is off, it displays the ON button
if (output26State=="off") {
client.println("<p><a href=\"/26/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/26/off\"><button class=\"button button2\">OFF</button></a></p>");
}

// Display current state, and ON/OFF buttons for GPIO 27
client.println("<p>GPIO 27 - State " + output27State + "</p>");
// If the output27State is off, it displays the ON button
if (output27State=="off") {
client.println("<p><a href=\"/27/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/27/off\"><button class=\"button button2\">OFF</button></a></p>");
}
client.println("</body></html>");

// The HTTP response ends with another blank line
client.println();
// Break out of the while loop
break;
} else { // if you got a newline, then clear currentLine
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}

void loop() {
client.loop();
loop_webserver();
if (Serial.available() > 0) {
char mun[501];
memset(mun,0, 501);


+ 108
- 0
struct.h Прегледај датотеку

@@ -0,0 +1,108 @@
/*
* struct.h
*
* Created on: 07.04.2020
* Author: agr
*/

#ifndef STRUCT_H_
#define STRUCT_H_



#include <PubSubClient.h>
#include <Ethernet.h>
#include <EEPROM.h>

struct config_t
{
byte config_set;
byte use_dhcp;
byte dhcp_refresh_minutes;
byte mac[6];
byte ip[4];
byte gateway[4];
byte subnet[4];
byte dns_server[4];
unsigned int webserverPort;
byte mqtt_server[4];
unsigned int mqttserverPort;
} eeprom_config;

void set_EEPROM_Default() {
eeprom_config.config_set=1; // dont change! It's used to check if the config is already set
eeprom_config.use_dhcp=1; // use DHCP per default
eeprom_config.dhcp_refresh_minutes=60; // refresh the DHCP every 60 minutes
// set the default MAC address. In this case its DE:AD:BE:EF:FE:ED
eeprom_config.mac[0]=0xDE;
eeprom_config.mac[1]=0xAD;
eeprom_config.mac[2]=0xBE;
eeprom_config.mac[3]=0xEF;
eeprom_config.mac[4]=0xFE;
eeprom_config.mac[5]=0xED;
// set the default IP address for the arduino. In this case its 192.168.1.97
eeprom_config.ip[0]=192;
eeprom_config.ip[1]=168;
eeprom_config.ip[2]=1;
eeprom_config.ip[3]=97;
// set the default GATEWAY. In this case its 192.168.1.1
eeprom_config.gateway[0]=192;
eeprom_config.gateway[1]=168;
eeprom_config.gateway[2]=1;
eeprom_config.gateway[3]=1;
// set the default SUBNET. In this case its 255.255.255.0
eeprom_config.subnet[0]=255;
eeprom_config.subnet[1]=255;
eeprom_config.subnet[2]=255;
eeprom_config.subnet[3]=0;

// set the default DNS SERVER. In this case its 192.168.1.1
eeprom_config.dns_server[0]=192;
eeprom_config.dns_server[1]=168;
eeprom_config.dns_server[2]=1;
eeprom_config.dns_server[3]=1;

// set the default Webserver Port. In this case its Port 80
eeprom_config.webserverPort=80;
// set the default MQTT SERVER. In this case its 192.168.1.35
eeprom_config.mqtt_server[0]=192;
eeprom_config.mqtt_server[1]=168;
eeprom_config.mqtt_server[2]=1;
eeprom_config.mqtt_server[3]=35;

// set the default MqttServer Port. In this case its Port 1883
eeprom_config.mqttserverPort=1883;

}

#define P(name) static const unsigned char name[]

int EEPROM_readAnything(int ee, config_t& value)
{
byte* p = (byte*)(void*)&value;
unsigned int i;
for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++);
return i;
}

int EEPROM_writeAnything(int ee, const config_t& value)
{
const byte* p = (const byte*)(const void*)&value;
unsigned int i;
for (i = 0; i < sizeof(value); i++)
EEPROM.write(ee++, *p++);
return i;
}

EthernetClient MQTTethClient;
PubSubClient MQTTclient(MQTTethClient);


#endif /* STRUCT_H_ */

Loading…
Откажи
Сачувај