Scenario:
I have to build a timer relay for the solar system of a friend of mine.
- If the voltage exceeds a certain ammount then start timer.
when times expires then write GPIO high. - If the voltage falls short of a certain ammount then start timer.
when times expires then write GPIO low.
for learning purpouses I was wondering how difficult it was to add:
- local webserver with pushbutton at my frineds house (behind NAT)
- preferaby https if possible, if memory allows …
- integrate it to my HA over cloud / tunnel …
webserver (example):
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-web-server-outputs-momentary-switch/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#else
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const int output = 2;
// HTML web page
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>ESP Pushbutton Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { font-family: Arial; text-align: center; margin:0px auto; padding-top: 30px;}
.button {
padding: 10px 20px;
font-size: 24px;
text-align: center;
outline: none;
color: #fff;
background-color: #2f4468;
border: none;
border-radius: 5px;
box-shadow: 0 6px #999;
cursor: pointer;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
.button:hover {background-color: #1f2e45}
.button:active {
background-color: #1f2e45;
box-shadow: 0 4px #666;
transform: translateY(2px);
}
</style>
</head>
<body>
<h1>ESP Pushbutton Web Server</h1>
<button class="button" onmousedown="toggleCheckbox('on');" ontouchstart="toggleCheckbox('on');" onmouseup="toggleCheckbox('off');" ontouchend="toggleCheckbox('off');">LED PUSHBUTTON</button>
<script>
function toggleCheckbox(x) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/" + x, true);
xhr.send();
}
</script>
</body>
</html>)rawliteral";
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
AsyncWebServer server(80);
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed!");
return;
}
Serial.println();
Serial.print("ESP IP Address: http://");
Serial.println(WiFi.localIP());
pinMode(output, OUTPUT);
digitalWrite(output, LOW);
// Send web page to client
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/html", index_html);
});
// Receive an HTTP GET request
server.on("/on", HTTP_GET, [] (AsyncWebServerRequest *request) {
digitalWrite(output, HIGH);
request->send(200, "text/plain", "ok");
});
// Receive an HTTP GET request
server.on("/off", HTTP_GET, [] (AsyncWebServerRequest *request) {
digitalWrite(output, LOW);
request->send(200, "text/plain", "ok");
});
server.onNotFound(notFound);
server.begin();
}
void loop() {
}
and here and example for the relays:
# https://forum.arduino.cc/t/triggering-relays-with-a-voltage-sensor/1082239/7
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Define analog input
#define ANALOG_IN_PIN01 A0
#define ANALOG_IN_PIN02 A3
// Define output pins
#define Relay01 5
#define Relay02 6
#define Relay03 7
#define Relay04 8
#define Relay05 9
#define Relay06 10
#define Relay07 11
#define Relay08 12
// Floats for ADC voltage & Input voltage
float adc_voltage01 = 0.0;
float adc_voltage02 = 0.0;
float in_voltage01 = 0.0;
float in_voltage02 = 0.0;
// Floats for resistor values in divider (in ohms)
float R1 = 30000.0;
float R2 = 7500.0;
// Float for Reference Voltage
float ref_voltage = 5.0;
// Integer for ADC value
int adc_value01 = 0;
int adc_value02 = 0;
void setup()
{
// Setup Serial Monitor
Serial.begin(9600);
Serial.println("DC Voltage Test");
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
{
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
display.clearDisplay();
// Define digital pins as OUTPUT
pinMode(Relay01, OUTPUT);
pinMode(Relay02, OUTPUT);
pinMode(Relay03, OUTPUT);
pinMode(Relay04, OUTPUT);
pinMode(Relay05, OUTPUT);
pinMode(Relay06, OUTPUT);
pinMode(Relay07, OUTPUT);
pinMode(Relay08, OUTPUT);
}
void loop() {
// Read the Analog Input
adc_value01 = analogRead(ANALOG_IN_PIN01);
adc_value02 = analogRead(ANALOG_IN_PIN02);
// Determine voltage at ADC input
adc_voltage01 = (adc_value01 * ref_voltage) / 1024.0;
adc_voltage02 = (adc_value02 * ref_voltage) / 1024.0;
// Calculate voltage at divider input
in_voltage01 = adc_voltage01 / (R2 / (R1 + R2)) ;
in_voltage02 = adc_voltage02 / (R2 / (R1 + R2)) ;
//Activate Relays based on input voltage
if (in_voltage01 > 0.5 && in_voltage01 < 2){
digitalWrite(Relay01, LOW);
}
else{
digitalWrite(Relay01, HIGH);
}
if (in_voltage01 > 3 && in_voltage01 < 4.5){
digitalWrite(Relay02, LOW);
}
else{
digitalWrite(Relay02, HIGH);
}
if (in_voltage01 > 5.5 && in_voltage01 < 8){
digitalWrite(Relay03, LOW);
}
else{
digitalWrite(Relay03, HIGH);
}
if (in_voltage01 > 9){
digitalWrite(Relay04, LOW);
}
else{
digitalWrite(Relay04, HIGH);
}
if (in_voltage02 > 0.5 && in_voltage02 < 2){
digitalWrite(Relay05, LOW);
}
else{
digitalWrite(Relay05, HIGH);
}
if (in_voltage02 > 3 && in_voltage02 < 4.5){
digitalWrite(Relay06, LOW);
}
else{
digitalWrite(Relay06, HIGH);
}
if (in_voltage02 > 5.5 && in_voltage02 < 8){
digitalWrite(Relay07, LOW);
}
else{
digitalWrite(Relay07, HIGH);
}
if (in_voltage02 > 9){
digitalWrite(Relay08, LOW);
}
else{
digitalWrite(Relay08, HIGH);
}
// Print results to Serial Monitor to 1 decimal place
Serial.print("Input Voltage = ");
Serial.println(in_voltage01, 1);
//Display static text on OLED display
display.setCursor(2, 2);
display.setTextSize(1);
display.setTextColor(WHITE);
display.println("Input Voltage 1");
display.setCursor(2, 33);
display.setTextSize(1);
display.setTextColor(WHITE);
display.println("Input Voltage 2");
//Display voltage readings on OLED display
display.setCursor(50, 13);
display.setTextSize(2);
display.setTextColor(WHITE);
display.print(in_voltage01, 1);
display.println(" V");
display.setCursor(50, 44);
display.setTextSize(2);
display.setTextColor(WHITE);
display.print(in_voltage02, 1);
display.println(" V");
display.display();
delay(500);
display.clearDisplay();
}
questions:
- would a esp8266 also work?
- how to do MQTT over cloud, best options?
- are there any better code examples out there than mine?