Dateien nach "/" hochladen
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
/**
|
||||
* SALATMASCHINE
|
||||
*
|
||||
* Microcontroller
|
||||
|
||||
* ESP32 NodeMCU Module WLAN WiFi Development Board mit CP2102 (Nachfolgermodell zum ESP8266)
|
||||
* ESP32 NODEMCU Module WiFi Development Board with CP2102 (successor model for the ESP8266) Compatible with Arduino
|
||||
* Zusätzliche Boardverwalter URL eintragen:
|
||||
* https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json <- klappt nicht!
|
||||
* https://dl.espressif.com/dl/package_esp32_index.json <- alte Version
|
||||
* Open Boards Manager from Tools > Board menu and install esp32 platform (and do not forget to select your ESP32 board from Tools > Board menu after installation).
|
||||
* ESP32 Dev Module
|
||||
* Das ist aber ein ESP32-WROOM-DA Module
|
||||
* Partition Scheme "No OTA(1MB APP/3MB SPIFFS")
|
||||
*
|
||||
* Es braucht scheinbar auch noch den CP201x Universal Driver (09.06.2023)
|
||||
* https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tab=downloads
|
||||
* Installieren über Gerätetreiber -> Treiber aktualisieren -> auf Computer suchen
|
||||
*
|
||||
* Relais
|
||||
* HW-383 2-Channel-Relais
|
||||
*
|
||||
* OLED
|
||||
* AZ-Delivery 1.3" I²C OLED Display
|
||||
*
|
||||
* Temperatur
|
||||
* Dallas DS18B20
|
||||
*/
|
||||
int version = 20240927;
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "arduino_secrets.h"
|
||||
#include "pins.h"
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
// alle variablen hier als unsigned long
|
||||
// mit int gab es bei langen Perioden Überläufen
|
||||
unsigned long std_duration_interval = 1200000; // in ms
|
||||
unsigned long std_max_water = 6000; // in ms
|
||||
|
||||
bool useTemperature = false; // gibt es Sensoren bzw. sollen die ausgelesen werden?
|
||||
bool useHumidity = false; // gibt es Sensoren bzw. sollen die ausgelesen werden?
|
||||
bool useButtons = true; // gibt es Sensoren bzw. sollen die ausgelesen werden?
|
||||
bool useSalatserver = true; // gibt es Sensoren bzw. sollen die ausgelesen werden?
|
||||
bool useSalatdisplay = true; // gibt es Sensoren bzw. sollen die ausgelesen werden?
|
||||
|
||||
bool useDryWetTrigger = false;
|
||||
// int
|
||||
int minMoisture = 25; // bei weniger Feuchtigkeit wird gewässert
|
||||
|
||||
// der häufigere Intervall für die vom MoistureSensor gesteuerte (Wert ist unter minMoisture) dry-Phase
|
||||
// wird aus std_duration_interval errechnet
|
||||
unsigned long moisture_interval_divider = 3; // Zeit seit der letzten Wässerung in ms
|
||||
|
||||
unsigned long dry_since = 0; // Zeit seit der letzten Wässerung in ms
|
||||
unsigned long first_water = 0; // Zeitpunkt Start Waesserung in ms
|
||||
unsigned long last_water = 0; // Zeitpunkt letzte Waesserung in ms
|
||||
unsigned long max_water; // Dauer Wasser in ms
|
||||
unsigned long duration_interval; // Interval in ms
|
||||
bool pump_on = false; // Pumpe an
|
||||
|
||||
|
||||
unsigned long dry_time_left; // vebleibende Zeit bis Start Waesserung in ms
|
||||
unsigned long wet_time_left; // Vebleibende Zeit bis Ende Waesserung in ms
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
float uptime;
|
||||
|
||||
// Messzyklus für alle Sensoren
|
||||
unsigned long duration_interval_measure = 5000; // Interval in ms
|
||||
unsigned long last_measure = 0; // Zeitpunkt letzte Messung in ms
|
||||
|
||||
// Zyklus Display
|
||||
unsigned long duration_interval_display = 1000; // Interval in ms
|
||||
unsigned long last_display = 0; // Zeitpunkt letzte Messung in ms
|
||||
|
||||
const char* message = ""; // Meldungen für DB und Webseite
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
bool firstStep = true;
|
||||
String trigger = "wet";
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
#include "temperature.h"
|
||||
#include "humidity.h"
|
||||
#include "buttons.h"
|
||||
#include "salatserver.h"
|
||||
#include "display.h"
|
||||
#include "salatclient.h"
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void pumpOn() {
|
||||
// pumpe anschalten
|
||||
digitalWrite(relais, LOW);
|
||||
pump_on = true;
|
||||
|
||||
first_water = millis();
|
||||
last_water = 0;
|
||||
dry_since = 0;
|
||||
Serial.println("pumpON-Pumpe via Relais 1 an");
|
||||
// Pumpe an - LED aus
|
||||
digitalWrite(LED, LOW);
|
||||
|
||||
// Daten an serverExt senden via salatclient
|
||||
sendDataToExtern();
|
||||
}
|
||||
void pumpOff() {
|
||||
|
||||
digitalWrite(relais, HIGH);
|
||||
pump_on = false;
|
||||
|
||||
first_water = 0;
|
||||
last_water = millis();
|
||||
Serial.println("pumpOFF-Pumpe via Relais aus");
|
||||
// Pumpe aus - LED an
|
||||
digitalWrite(LED, HIGH);
|
||||
}
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("Salatmaschine startet");
|
||||
|
||||
// LED
|
||||
// LED geht nach dem ERSTEN MAL pumpen an ... vorher ist pump_on NULL
|
||||
pinMode(LED, OUTPUT);
|
||||
|
||||
// Relais
|
||||
pinMode(relais, OUTPUT);
|
||||
digitalWrite(relais, HIGH);
|
||||
// pinMode(relais_2, OUTPUT);
|
||||
// digitalWrite(relais_2, HIGH);
|
||||
pump_on = false;
|
||||
|
||||
// Initialwerte setzen
|
||||
max_water = std_max_water; // millis
|
||||
duration_interval = std_duration_interval; // millis
|
||||
last_water = millis(); // millis
|
||||
if (useButtons) {
|
||||
setupButtons();
|
||||
}
|
||||
if (useTemperature) {
|
||||
setupTemperature();
|
||||
}
|
||||
if (useHumidity) {
|
||||
setupHumidity();
|
||||
}
|
||||
if (useSalatdisplay) {
|
||||
setupDisplay();
|
||||
}
|
||||
if (useSalatserver) {
|
||||
setupSalatserver();
|
||||
}
|
||||
}
|
||||
void loop() {
|
||||
|
||||
|
||||
if (useButtons) {
|
||||
loopButtons();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Time is up - dies ist der große Intervall - Pumpe wird angeschaltet
|
||||
// Wässern auf jeden Fall, wenn der Intervall abgelaufen ist
|
||||
if ((millis() > (last_water + duration_interval)) && pump_on == false) {
|
||||
// pumpe anschalten
|
||||
pumpOn();
|
||||
}
|
||||
|
||||
|
||||
// Pumpe läuft ....
|
||||
if (pump_on == true) {
|
||||
wet_time_left = max_water - (millis() - first_water);
|
||||
// Pumpe abschalten, wenn genug gewässert
|
||||
if (millis() > (first_water + max_water)) {
|
||||
wet_time_left = 0;
|
||||
// Pumpe aus
|
||||
pumpOff();
|
||||
}
|
||||
} else {
|
||||
dry_time_left = (duration_interval - (millis() - last_water));
|
||||
dry_since = millis() - last_water;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sensoren auslesen
|
||||
*/
|
||||
if (millis() > (last_measure + duration_interval_measure)) {
|
||||
uptime = millis() / 1000;
|
||||
if (useTemperature) {
|
||||
getTemperature();
|
||||
}
|
||||
if (useHumidity) {
|
||||
getHumidity();
|
||||
}
|
||||
Serial.println("xxxxx");
|
||||
|
||||
Serial.print("uptime ");
|
||||
Serial.println(uptime / 1000);
|
||||
Serial.print("last_water ");
|
||||
Serial.println(last_water / 1000);
|
||||
Serial.print("duration_interval ");
|
||||
Serial.println(duration_interval / 1000);
|
||||
Serial.print("max_water ");
|
||||
Serial.println(max_water / 1000);
|
||||
Serial.print("dry_since ");
|
||||
Serial.println(dry_since / 1000);
|
||||
Serial.print("message ");
|
||||
Serial.println(message);
|
||||
|
||||
// je nach Feuchtigkeit - im kleinen Intervall (immer 1/3 vom großen Intervall)
|
||||
if ((moistureValuePercent < minMoisture) && useDryWetTrigger) {
|
||||
trigger = "dry";
|
||||
// duration_interval = std_duration_interval / moisture_interval_divider;
|
||||
|
||||
Serial.println("triggerDRY");
|
||||
} else {
|
||||
|
||||
Serial.println("triggerWET");
|
||||
trigger = "wet";
|
||||
// duration_interval = std_duration_interval;
|
||||
}
|
||||
|
||||
last_measure = millis();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (millis() > (last_display + duration_interval_display)) {
|
||||
if (useSalatdisplay) {
|
||||
loopSalatdisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Sendet Daten an den Internetserver
|
||||
|
||||
Complete project details: https://RandomNerdTutorials.com/esp32-https-requests/
|
||||
|
||||
Wifi secure connection example for ESP32 - Running on TLS 1.2 using mbedTLS
|
||||
Suporting the following chipersuites:
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384","TLS_DHE_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_AES_256_CCM","TLS_DHE_RSA_WITH_AES_256_CCM","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384","TLS_DHE_RSA_WITH_AES_256_CBC_SHA256","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA","TLS_DHE_RSA_WITH_AES_256_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8","TLS_DHE_RSA_WITH_AES_256_CCM_8","TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256","TLS_DHE_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_CCM","TLS_DHE_RSA_WITH_AES_128_CCM","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256","TLS_DHE_RSA_WITH_AES_128_CBC_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA","TLS_DHE_RSA_WITH_AES_128_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8","TLS_DHE_RSA_WITH_AES_128_CCM_8","TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA","TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA","TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA","TLS_DHE_PSK_WITH_AES_256_GCM_SHA384","TLS_DHE_PSK_WITH_AES_256_CCM","TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384","TLS_DHE_PSK_WITH_AES_256_CBC_SHA384","TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA","TLS_DHE_PSK_WITH_AES_256_CBC_SHA","TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_PSK_DHE_WITH_AES_256_CCM_8","TLS_DHE_PSK_WITH_AES_128_GCM_SHA256","TLS_DHE_PSK_WITH_AES_128_CCM","TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256","TLS_DHE_PSK_WITH_AES_128_CBC_SHA256","TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA","TLS_DHE_PSK_WITH_AES_128_CBC_SHA","TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256","TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_PSK_DHE_WITH_AES_128_CCM_8","TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA","TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA","TLS_RSA_WITH_AES_256_GCM_SHA384","TLS_RSA_WITH_AES_256_CCM","TLS_RSA_WITH_AES_256_CBC_SHA256","TLS_RSA_WITH_AES_256_CBC_SHA","TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384","TLS_ECDH_RSA_WITH_AES_256_CBC_SHA","TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384","TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384","TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA","TLS_RSA_WITH_AES_256_CCM_8","TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256","TLS_RSA_WITH_CAMELLIA_256_CBC_SHA","TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_RSA_WITH_AES_128_GCM_SHA256","TLS_RSA_WITH_AES_128_CCM","TLS_RSA_WITH_AES_128_CBC_SHA256","TLS_RSA_WITH_AES_128_CBC_SHA","TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256","TLS_ECDH_RSA_WITH_AES_128_CBC_SHA","TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256","TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA","TLS_RSA_WITH_AES_128_CCM_8","TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_RSA_WITH_CAMELLIA_128_CBC_SHA","TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_RSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA","TLS_RSA_PSK_WITH_AES_256_GCM_SHA384","TLS_RSA_PSK_WITH_AES_256_CBC_SHA384","TLS_RSA_PSK_WITH_AES_256_CBC_SHA","TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384","TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_RSA_PSK_WITH_AES_128_GCM_SHA256","TLS_RSA_PSK_WITH_AES_128_CBC_SHA256","TLS_RSA_PSK_WITH_AES_128_CBC_SHA","TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256","TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA","TLS_PSK_WITH_AES_256_GCM_SHA384","TLS_PSK_WITH_AES_256_CCM","TLS_PSK_WITH_AES_256_CBC_SHA384","TLS_PSK_WITH_AES_256_CBC_SHA","TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384","TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_PSK_WITH_AES_256_CCM_8","TLS_PSK_WITH_AES_128_GCM_SHA256","TLS_PSK_WITH_AES_128_CCM","TLS_PSK_WITH_AES_128_CBC_SHA256","TLS_PSK_WITH_AES_128_CBC_SHA","TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256","TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_PSK_WITH_AES_128_CCM_8","TLS_PSK_WITH_3DES_EDE_CBC_SHA","TLS_EMPTY_RENEGOTIATION_INFO_SCSV"]
|
||||
2017 - Evandro Copercini - Apache 2.0 License.
|
||||
*/
|
||||
|
||||
#include <WiFiClientSecure.h>
|
||||
|
||||
|
||||
// const char* serverExt = "www.yourserver.de"; // Server URL
|
||||
// const char* pathExt = "/path/to/script.php"; // Server URL
|
||||
|
||||
// root certificate authority, to verify the server
|
||||
// change it to your server root CA
|
||||
// SHA1 fingerprint is broken now!
|
||||
|
||||
// const char* shq_root_ca =
|
||||
// "-----BEGIN CERTIFICATE-----\n"
|
||||
// "LoremIpsum[...]\n"
|
||||
// "-----END CERTIFICATE-----\n";
|
||||
|
||||
// You can use x.509 client certificates if you want
|
||||
//const char* test_client_key = ""; //to verify the client
|
||||
//const char* test_client_cert = ""; //to verify the client
|
||||
|
||||
WiFiClientSecure client;
|
||||
|
||||
void sendDataToExtern() {
|
||||
|
||||
|
||||
client.setCACert(shq_root_ca);
|
||||
//client.setCertificate(test_client_cert); // for client verification
|
||||
//client.setPrivateKey(test_client_key); // for client verification
|
||||
|
||||
Serial.println("\nStarting connection to serverExt...");
|
||||
if (!client.connect(serverExt, 443))
|
||||
Serial.println("Connection failed!");
|
||||
else {
|
||||
Serial.println("Connected to serverExt!");
|
||||
// Daten zusammenstellen
|
||||
String jsonPayload = "{ \"version\":\"" + String(version) + "\",\"uptime\":\"" + String(uptime) + "\",\"trigger\":\"" + trigger + "\",\"duration_interval\":\"" + duration_interval + "\",\"dry_time_left\":\"" + dry_time_left + "\",\"max_water\":\"" + max_water + "\",\"wet_time_left\":\"" + wet_time_left + "\",\"dry_since\":\"" + dry_since + "\",\"min_moisture\":\"" + minMoisture + "\",\"sensor_moisture_value\":\"" + sensor_moisture_value + "\",\"temp0\":\"" + tempSensor[0] + "\",\"message\":\"" + message + "\" }" + '\n';
|
||||
Serial.println("JSON: " + jsonPayload);
|
||||
// Make a HTTP request:
|
||||
String request = "POST " + String(pathExt) + " HTTP/1.1\r\n" + "Host: " + String(serverExt) + "\r\n" + "Content-Type: application/json\r\n" + "Content-Length: " + jsonPayload.length() + "\r\n" + "\r\n" + jsonPayload;
|
||||
client.print(request);
|
||||
|
||||
while (client.connected()) {
|
||||
String line = client.readStringUntil('\n');
|
||||
Serial.println(line);
|
||||
if (line == "\r") {
|
||||
Serial.println("headers received");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if there are incoming bytes available
|
||||
// from the serverExt, read them and print them:
|
||||
while (client.available()) {
|
||||
char c = client.read();
|
||||
Serial.write(c);
|
||||
}
|
||||
|
||||
client.stop();
|
||||
}
|
||||
// nur einmal pro Wässerungsphase senden
|
||||
delay(max_water + 1000);
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
/*********
|
||||
https://circuits4you.com/2018/11/20/web-server-on-esp32-how-to-update-and-display-sensor-values/
|
||||
*********/
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
// Webserver
|
||||
// s. a.: https://lastminuteengineers.com/creating-esp32-web-server-arduino-ide/
|
||||
// https://randomnerdtutorials.com/esp32-async-web-server-espasyncwebserver-library/
|
||||
|
||||
// https://github.com/me-no-dev/ESPAsyncWebServer ESPAsyncWebServer-master.zip
|
||||
// Installieren über Sketch-Install ZIP Library ...
|
||||
// NICHT die aus der IDE-Library nehmen!
|
||||
|
||||
|
||||
// Load Wi-Fi library
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
//#include <WiFiClientSecure.h>
|
||||
|
||||
#include <HTTPClient.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <AsyncTCP.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <AsyncJson.h>
|
||||
#include "webPageSource.h"
|
||||
|
||||
|
||||
/**
|
||||
* VAR1 accessPointMode = true; ESP32 ist selber ein AccessPoint
|
||||
* VAR2 accessPointMode = false; Verbindung mit dem Heimnetz
|
||||
*/
|
||||
bool accessPointMode = false;
|
||||
|
||||
// VAR1 AccessPointMode
|
||||
const char *ssid = SECRET_AP_SSID;
|
||||
const char *password = SECRET_AP_PASSWD;
|
||||
/* Put IP Address details */
|
||||
IPAddress local_ip(192, 168, 3, 1);
|
||||
IPAddress gateway(192, 168, 3, 1);
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
|
||||
// VAR2 Wifi-Client
|
||||
const char *ssid2 = SECRET_SSID;
|
||||
const char *password2 = SECRET_PASSWD;
|
||||
|
||||
// Set web server port number to 80
|
||||
AsyncWebServer server(80);
|
||||
|
||||
// Current time
|
||||
unsigned long currentTime = millis();
|
||||
// Previous time
|
||||
unsigned long previousTime = 0;
|
||||
// Define timeout time in milliseconds (example: 2000ms = 2s)
|
||||
const long timeoutTime = 2000;
|
||||
|
||||
JsonObject root;
|
||||
void (*resetFunc)(void) = 0; //declare reset function @ address 0
|
||||
|
||||
void setupSalatserver() {
|
||||
|
||||
Serial.begin(9600);
|
||||
Serial.println();
|
||||
Serial.println("Booting Sketch...");
|
||||
if (accessPointMode == true) {
|
||||
// ESP32 as AccessPoint
|
||||
WiFi.softAP(ssid, password);
|
||||
WiFi.softAPConfig(local_ip, gateway, subnet);
|
||||
delay(100);
|
||||
Serial.println("Connecting to ");
|
||||
Serial.print(ssid);
|
||||
} else {
|
||||
|
||||
// ESP32 connects to your wifi -----------------------------------
|
||||
WiFi.mode(WIFI_STA); // Connect to your wifi
|
||||
|
||||
WiFi.begin(ssid2, password2);
|
||||
// Wait for WiFi to connect
|
||||
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
||||
Serial.print("waitForConnectResult...");
|
||||
//delay(3000);
|
||||
}
|
||||
|
||||
// If connection successful show IP address in serial monitor
|
||||
Serial.println("");
|
||||
Serial.print("Connected to ");
|
||||
Serial.println(ssid2);
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP()); // IP address assigned to your ESP
|
||||
}
|
||||
//----------------------------------------------------------------
|
||||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
int paramsNr = request->params();
|
||||
//Serial.println(paramsNr);
|
||||
|
||||
String s = webPageSource; // Read HTML contents
|
||||
if (paramsNr <= 0) {
|
||||
request->send(200, "text/html", s);
|
||||
} else {
|
||||
for (int i = 0; i < paramsNr; i++) {
|
||||
AsyncWebParameter const *p = request->getParam(i);
|
||||
//Serial.print("Param name: ");
|
||||
//Serial.println(p->name());
|
||||
//Serial.print("Param value: ");
|
||||
//Serial.println(p->value());
|
||||
//Serial.println("------");
|
||||
}
|
||||
if (request->hasParam("waterNow")) {
|
||||
buttonsWaterNow();
|
||||
Serial.println("Webserver: waterNow");
|
||||
//request->send(200, "text/plain", "waterNow received");
|
||||
request->send(200, "text/html", s);
|
||||
} else if (request->hasParam("resetAll")) {
|
||||
Serial.println("Webserver: resetAll");
|
||||
buttonsResetAll();
|
||||
//request->send(200, "text/plain", "resetAll received");
|
||||
request->send(200, "text/html", s);
|
||||
} else if (request->hasParam("waterLess")) {
|
||||
buttonsWaterLess();
|
||||
Serial.println("Webserver: waterLess");
|
||||
//request->send(200, "text/plain", "waterLess received");
|
||||
request->send(200, "text/html", s);
|
||||
} else if (request->hasParam("waterMore")) {
|
||||
buttonsWaterMore();
|
||||
Serial.println("Webserver: waterMore");
|
||||
request->send(200, "text/html", s);
|
||||
//request->send(200, "text/plain", "waterMore received");
|
||||
} else if (request->hasParam("intLess")) {
|
||||
buttonsIntLess();
|
||||
Serial.println("Webserver: intLess");
|
||||
request->send(200, "text/html", s);
|
||||
// request->send(200, "text/plain", "intLess received");
|
||||
} else if (request->hasParam("intMore")) {
|
||||
buttonsIntMore();
|
||||
Serial.println("Webserver: intMore");
|
||||
request->send(200, "text/html", s);
|
||||
// request->send(200, "text/plain", "intMore received");
|
||||
} else if (request->hasParam("readData")) {
|
||||
|
||||
AsyncJsonResponse *response = new AsyncJsonResponse();
|
||||
response->addHeader("Server", "ESP Async Web Server");
|
||||
root = response->getRoot();
|
||||
root["version"] = version;
|
||||
root["uptime"] = uptime;
|
||||
root["trigger"] = trigger;
|
||||
root["duration_interval"] = duration_interval;
|
||||
root["dry_time_left"] = dry_time_left;
|
||||
root["max_water"] = max_water;
|
||||
root["wet_time_left"] = wet_time_left;
|
||||
root["dry_since"] = dry_since;
|
||||
root["min_moisture"] = minMoisture;
|
||||
root["sensor_moisture_value"] = sensor_moisture_value;
|
||||
root["temp0"] = tempSensor[0];
|
||||
root["message"] = message;
|
||||
response->setLength();
|
||||
request->send(response); // request->send(200, "text/plain", "data"); //Send value only to client ajax request
|
||||
|
||||
|
||||
} else if (request->hasParam("resetArduino")) {
|
||||
resetFunc();
|
||||
}
|
||||
};
|
||||
});
|
||||
server.begin();
|
||||
}
|
||||
void loopSalatserver() {
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
// Temperatur
|
||||
#include <OneWire.h> // http://www.arduino.cc/playground/Learning/OneWire
|
||||
#include <DallasTemperature.h> // http://milesburton.com/index.php?title=Dallas_Temperature_Control_Library DS18B20
|
||||
// Define Pins
|
||||
#define TEMPERATURE_PRECISION 9
|
||||
OneWire oneWire(ONE_WIRE_BUS); // Einrichten des OneWire Bus um die Daten der Temperaturfühler abzurufen
|
||||
DallasTemperature sensors(&oneWire); // Bindung der Sensoren an den OneWire Bus
|
||||
DeviceAddress tempDeviceAddress; // Verzeichniss zum Speichern von Sensor Adressen
|
||||
int numberOfDevices; // Anzahl der gefundenen Sensoren
|
||||
float sensor[5][10] = { 0 };
|
||||
|
||||
float tempSensor[5] = { 0 };
|
||||
|
||||
|
||||
void setupTemperature() {
|
||||
// Temperatur
|
||||
Serial.println("Abfrage mehrerer Dallas Temperatur Sensoren");
|
||||
Serial.println("-------------------------------------------");
|
||||
|
||||
// Suche der Sensoren
|
||||
Serial.println("Suche Temperatur Sensoren...");
|
||||
sensors.begin();
|
||||
|
||||
sensors.setWaitForConversion(false);
|
||||
numberOfDevices = sensors.getDeviceCount();
|
||||
|
||||
Serial.print("Habe ");
|
||||
Serial.print(numberOfDevices, DEC);
|
||||
Serial.println(" Sensoren gefunden.");
|
||||
|
||||
// Setzen der Genauigkeit 9,10,11 oder 12bit
|
||||
for (int i = 0; i < numberOfDevices; i++) {
|
||||
if (sensors.getAddress(tempDeviceAddress, i)) {
|
||||
sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);
|
||||
Serial.print("Sensor ");
|
||||
Serial.print(i);
|
||||
Serial.print(" hat eine Genauigkeit von ");
|
||||
Serial.println(sensors.getResolution(tempDeviceAddress), DEC);
|
||||
sensors.requestTemperatures();
|
||||
}
|
||||
}
|
||||
}
|
||||
void getTemperature() {
|
||||
|
||||
for (int i = 0; i < numberOfDevices; i++) {
|
||||
|
||||
tempSensor[i] = sensors.getTempCByIndex(i);
|
||||
Serial.println("Messe Temperatur ");
|
||||
Serial.print("Sensor ");
|
||||
Serial.print(i);
|
||||
Serial.print(" in Celsius: ");
|
||||
Serial.println(tempSensor[i]);
|
||||
}
|
||||
// Auslesen für den nächsten Zyklus. Der Sensor braucht genügend Zeit. Wenn er nur 85 anzeigt, reicht die Spannne zum Auslesen nicht.
|
||||
sensors.requestTemperatures();
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
//============
|
||||
//Webpage Code
|
||||
//============
|
||||
String webPageSource = R"***(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name= "viewport " content= "width=device-width, initial-scale=1">
|
||||
<link rel= "icon " href= "data:, ">
|
||||
<style>
|
||||
html { font-family: Helvetica, Arial, sans-serif; display: inline-block; margin: 0px auto; text-align: center; font-size: 6vw; background-color: #333; color: white;}
|
||||
h1{font-size: 12vw;}
|
||||
.button {background-color: #8fc83b; font-size: 8vw; border-radius: 3vw; width: 90%; border: 4px solid black; color: white; padding: 0.5em 2em; text-decoration: none; font-weight: bold; margin: 0.25em auto; cursor: pointer;}
|
||||
.button1 {background-color: #85b3ee;}
|
||||
.button2 {background-color: #678cb3;}
|
||||
.button3 {background-color: #c80000;}
|
||||
#sensorData{ border: 1px solid #3333ff; width: 90%; margin: 1em auto; text-align: center;}
|
||||
table{width: 100%;border-collapse: collapse; border: 1px solid grey;}
|
||||
tr:nth-child(even){background-color: silver;}
|
||||
tr:nth-child(odd){background-color: lightgrey; }
|
||||
td:nth-child(1){width:50%;text-align: left;}
|
||||
td:nth-child(2),td:nth-child(3){width:25%; text-align: right;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Salatmaschine</h1>
|
||||
<p><span id="version"></span><br><span id="uptime"></span><br><span id="trigger"></span></p>
|
||||
<div id="sensorData">
|
||||
<table>
|
||||
<tr>
|
||||
<th>Int wet</th>
|
||||
<td id="duration_interval"> </td>
|
||||
<td id="dry_time_left"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>H2O</th>
|
||||
<td id="max_water"> </td>
|
||||
<td id="wet_time_left"> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Int dry</th>
|
||||
<td id="moisture_interval"> </td>
|
||||
<td id="dry_since"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Hum %</th>
|
||||
<td id="min_moisture"> </td>
|
||||
<td id="sensor_moisture_value"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Temp</th>
|
||||
<td> </td>
|
||||
<td id="temp0"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3" id="message"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<a href= "/?waterNow=1"><button class= "button button2">WASSER MARSCH</button></a>
|
||||
|
||||
<a href= "/?waterMore=1"><button class= "button button1">Wasser +1s</button></a>
|
||||
<a href= "/?waterLess=1"><button class= "button button1">Wasser -1s</button></a>
|
||||
<a href= "/?intMore=1"><button class= "button">Intervall +1min</button></a>
|
||||
<a href= "/?intLess=1"><button class= "button">Intervall -1min</button></a>
|
||||
|
||||
|
||||
<a href= "/?resetAll=1"><button class= "button button3" onclick="confirm('Echt? Really? Wirklich?!');">Reset auf Standardwerte</button></a>
|
||||
<a href= "/?resetArduino=1"><button class= "button button3" onclick="confirm('Echt? Really? WIRKLICH?!');">Reset Arduino</button></a>
|
||||
|
||||
|
||||
<script>
|
||||
setInterval(function() {
|
||||
// Call a function repetatively with x Second interval
|
||||
getData();
|
||||
}, 1000); //x*1000mSeconds update rate
|
||||
function getData(){
|
||||
var getSensorData = new XMLHttpRequest();
|
||||
getSensorData.onreadystatechange = function(){
|
||||
if(this.readyState == 4 && this.status == 200){
|
||||
//console.log(this.responseText);
|
||||
const obj = JSON.parse(this.responseText);
|
||||
//console.log(obj);
|
||||
let uptime;
|
||||
let suffix = 's';
|
||||
if(obj.uptime>86400){
|
||||
uptime = obj.uptime / 86400;
|
||||
suffix = 'd';
|
||||
}else if(obj.uptime>3600){
|
||||
uptime = obj.uptime / 3600;
|
||||
suffix = 'h';
|
||||
}else if(obj.uptime>60){
|
||||
uptime = obj.uptime / 60;
|
||||
suffix = 'm';
|
||||
}else{
|
||||
uptime = obj.uptime;
|
||||
}
|
||||
uptime = Math.round(uptime) + suffix;
|
||||
document.getElementById("version").innerHTML = 'v'+obj.version;
|
||||
document.getElementById("trigger").innerHTML = obj.trigger;
|
||||
document.getElementById("uptime").innerHTML = 'uptime '+uptime;
|
||||
document.getElementById("duration_interval").innerHTML = Math.round(obj.duration_interval / 1000);
|
||||
document.getElementById("dry_time_left").innerHTML = Math.round(obj.dry_time_left / 1000);
|
||||
document.getElementById("max_water").innerHTML = Math.round(obj.max_water / 1000);
|
||||
document.getElementById("wet_time_left").innerHTML = Math.round(obj.wet_time_left / 1000);
|
||||
|
||||
document.getElementById("dry_since").innerHTML = Math.round(obj.dry_since / 1000);
|
||||
document.getElementById("min_moisture").innerHTML = obj.min_moisture;
|
||||
document.getElementById("sensor_moisture_value").innerHTML = obj.sensor_moisture_value;
|
||||
document.getElementById("temp0").innerHTML = obj.temp0;
|
||||
document.getElementById("message").innerHTML = obj.message;
|
||||
console.log('got Data');
|
||||
|
||||
}
|
||||
}
|
||||
getSensorData.open("GET", "/?readData=1", true);
|
||||
getSensorData.send();
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
)***";
|
||||
Reference in New Issue
Block a user