Dateien nach "/" hochladen

This commit is contained in:
2024-09-27 22:08:49 +02:00
parent 3a87a41d72
commit c40627db53
5 changed files with 653 additions and 0 deletions
+232
View File
@@ -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();
}
}
}
+71
View File
@@ -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
View File
@@ -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() {
}
+57
View File
@@ -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
View File
@@ -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">&nbsp;</td>
<td id="dry_time_left">&nbsp;</td>
</tr>
<tr>
<th>H2O</th>
<td id="max_water">&nbsp;</td>
<td id="wet_time_left">&nbsp;</td>
</tr>
<tr>
<th>Int dry</th>
<td id="moisture_interval">&nbsp;</td>
<td id="dry_since">&nbsp;</td>
</tr>
<tr>
<th>Hum %</th>
<td id="min_moisture">&nbsp;</td>
<td id="sensor_moisture_value">&nbsp;</td>
</tr>
<tr>
<th>Temp</th>
<td>&nbsp;</td>
<td id="temp0">&nbsp;</td>
</tr>
<tr>
<td colspan="3" id="message">&nbsp;</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>
)***";