ich hab eine Wetterstation (Temperatur, Feuchtigkeit, Luftdruck, Regen) die im 10-Minuten-Takt ihre Messwerte auf einen Webserver schickt - funktioniert alles.
Zusätzlich möchte ich, dass mein Arduino in dem Zeitraum dazwischen als Webserver fungiert und auf Anfrage die aktuellen Messwerte an einen Client als Webseite ausgibt.
Leider funktioniert das mal sehr gut, mal wieder gar nicht.
"Sehr gut" funktionierts wenn ich nur mit dem PC auf die Seite zugreife (die sich im Minutentakt aktualisiert).
"Gar nicht" funktionierts wenn ich mit dem Handy zugreife, dann bei offener Seite das Handy abschalte und es nochmals versuche. Dann ist der Server (bzw. die Seite) nicht mehr erreichbar.
Gelöst hab ich die wesentlichen Teile so:
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);
// wird für den HTTP-Post verwendet, nicht für den Webserver
WiFiClient client;
void setup()
{
// Start the server
Serial.print("Start WebServer ... ");
server.begin();
Serial.println("Success");
}
void loop()
{
// Abwicklung des HTTP-Post läuft alle 10 Minuten - ist hier im Detail nicht relevant, daher nur der andere Abschnitt:
// Check if a client has connected
// leave loop() if !client
WiFiClient client = server.available();
if (!client) {
return;
}
// Wait until the client sends some data
Serial.print(String(counter) + " New client connected ");
counter += 1;
// if client is not available, leave loop() after 10 sec
int start = millis();
while(!client.available()){
delay(1);
if(millis() - start >= 10000)
{
break;
}
}
client.flush();
// Prepare the response
String s = "response-string"
// Send the response to the client
client.print(s);
delay(1);
client.stop();
Serial.println("Client disonnected");
// The client will actually be disconnected
}
Ein Verdacht den ich jetzt habe ... ich benutze WiFiClient client; zweimal.
Einmal global - damit baue ich die Verbindung zum Server auf client.connect(host, httpPort) und poste meine Daten.
Und einmal in dem Abschnitt in loop() der mir den Webserver macht.
ja - selbst programmiert und die einzelnen Teile vorher zusammengesucht
Ist aber erst eine Version 0.9 - die Lesbarkeit lässt sich noch verbessern.
Grundsätzlich:
Das Ding läuft und alle 10 Minuten postet er die Daten an den Datenbankserver.
Dazwischen soll er sich einfach als Webserver verhalten und bei Bedarf den Client mit Daten versorgen:
Der Code ist leider zu lang für ein Posting hier - ich versuchs auf zweimal:
#include <dht.h>
#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>
dht DHT;
const char* ssid = "meinWLAN";
const char* password = "meinPW";
const char* versionID = "Arduino Environmental Project 0.9";
const char* typeID = "NodeMCU 1.0 (ESP-12E Module) DevKit V2";
//const char* typeID = "ESP8266 ESP-01";
const char* deviceID = "ESP001";
const char* location = "Garage";
const char* host = "10.0.0.100";
const int httpPort = 890;
unsigned long prev_millis = 0;
int counter = 0;
String ipaddress = "";
float Humidity_DHT11 = 0.0;
float Temperature_DHT11 = 0.0;
float Temperature_DS18B20 = 0.0;
float Pressure_BMP180 = 0.0;
float Temperature_BMP180 = 0.0;
float RainSensor = 0.0;
int SQLExec_Counter = 0;
// Inititate Barometric Sensor
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);
//Pin for DHT11 - equals D5 on NodeMCU
#define DHT11_PIN 14
//Pin for DS18B20 - equals D6 on NodeMCU
#define ONE_WIRE_BUS 12
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
WiFiClient client;
void setup() {
Serial.begin(115200);
delay(10);
// Set I2C parameters
// SDA = 0 Pin D3
// SDA = 2 Pin D4
Wire.begin(0, 2);
bmp.begin();
Serial.println("");
Serial.println("");
Serial.println(String(versionID));
Serial.println(String(typeID));
Serial.println(String(deviceID));
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to WLAN ");
Serial.println(ssid);
WiFi.begin(ssid, password);
Serial.print("Start at ");
uptime();
while (WiFi.status() != WL_CONNECTED) {
delay(50);
Serial.print(".");
}
Serial.println("");
Serial.print("Success at ");
uptime();
Serial.println("WiFi connected");
//Serial.println(WiFi.getNetworkInfo());
Serial.print ("Signal Strength: ");
Serial.println (WiFi.RSSI());
// Print the IP address
Serial.print("My IP is: ");
Serial.println(WiFi.localIP());
IPAddress myAddr = WiFi.localIP();
ipaddress = String(myAddr[0])+ "." +String(myAddr[1]) + "." +String(myAddr[2]) + "." +String(myAddr[3]);
// Start the server
Serial.print("Start WebServer ... ");
server.begin();
Serial.println("Success");
Serial.println();
Serial.println();
// Read DHT11 Sensor
DHT.read11(DHT11_PIN);
// Read DS18B20
sensors.requestTemperatures();
// Read BMP180
sensors_event_t event;
bmp.getEvent(&event);
// Read Rain-Sensor
RainSensor = analogRead(A0);
delay(2000);
Humidity_DHT11 = DHT.humidity;
Temperature_DHT11 = DHT.temperature;
Temperature_DS18B20 = sensors.getTempCByIndex(0);
if (event.pressure)
{
Pressure_BMP180 = event.pressure;
bmp.getTemperature(&Temperature_BMP180);
}
Serial.println("DHT11:\t\tHumidity: "+String(Humidity_DHT11)+" \t Temperature: "+String(Temperature_DHT11));
Serial.println("DS18B10:\t\t\t\t Temperature: "+ String(Temperature_DS18B20));
Serial.println("BMP180:\t\tPressure: "+String(Pressure_BMP180)+" \t Temperature: "+String(Temperature_BMP180));
Serial.println("RainSensor:\tRainValue: "+String(RainSensor));
}
void loop() {
// Establish WiFi if disconnected
if (WiFi.status() != WL_CONNECTED)
{
uptime();
Serial.println("WLAN Connection lost - try to reconnect ...");
WiFi.begin(ssid, password);
}
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
SQLExec_Counter = millis() - prev_millis;
// Falls es bei den Millis zu einem Überlauf kommt - rücksetzen auf 0
if (SQLExec_Counter < 0)
{
SQLExec_Counter = 0;
prev_millis = 0;
}
delay(100);
if (SQLExec_Counter > 600000)
//alle 10 Minuten werden Werte geschrieben
{
// Be the HTTP Client and POST data to SQL
SQLExec_Counter = 0;
prev_millis = millis();
Serial.println();
uptime();
Serial.println("Start reading environmental Parameters");
// Read DHT11 Sensor
DHT.read11(DHT11_PIN);
// Read DS18B20
sensors.requestTemperatures();
// Read BMP180
sensors_event_t event;
bmp.getEvent(&event);
// Read Rain-Sensor
RainSensor = analogRead(A0);
delay(2000);
Humidity_DHT11 = DHT.humidity;
Temperature_DHT11 = DHT.temperature;
Temperature_DS18B20 = sensors.getTempCByIndex(0);
if (event.pressure)
{
Pressure_BMP180 = event.pressure;
bmp.getTemperature(&Temperature_BMP180);
}
Gawan:
... Leider funktioniert das mal sehr gut, mal wieder gar nicht.
"Sehr gut" funktionierts wenn ich nur mit dem PC auf die Seite zugreife (die sich im Minutentakt aktualisiert).
"Gar nicht" funktionierts wenn ich mit dem Handy zugreife, dann bei offener Seite das Handy abschalte und es nochmals versuche. Dann ist der Server (bzw. die Seite) nicht mehr erreichbar.
...
Vorweg: Deinen Code habe ich mir nicht angeguckt.
Kannst Du beim Testen den Arduino im Blick haben?
Wenn ja: Baue testweise Zeilen ein, die die LED an Pin 13 leuchten lassen. Je nachdem, wo Du diese Zeilen einbaust, kannst Du eingrenzen, wo der Fehler genau auftritt. Wenn Du das weißt, ist die Fehlerbehebung wahrscheinlich nur noch ein Klacks.
Ja, im Notfall kann ich das machen.
Aber ich verstehe die Befehle im Detail nicht gut genug um überhaupt sagen zu können wie die Reaktion sein soll.
Ich hab wie gesagt den Code halt nach bestem Wissen und Gewissen zusammengesucht.
Mich verwirrt
das doppelte WiFiClient client;
WiFiClient client = server.available();
if (!client) {
return;
}
Damit prüfe ich ob der Arduino Webserver verfügbar ist !? Wozu !?
Oder prüfe ich da schon ob sich ein Client verbunden hat ?
Falls der Client nicht mehr verfügbar (while(!client.available())) ist erzwinge ich ein BREAK
Was aber wenn der Client genau nach dieser Schleife und dem Vorbereiten der Response aussteigt ?
Müsste ich da nicht erst kurz vor dem client.print(s) prüfen ?
Ich gehe aber davon aus, dass der Fehler im Webserver-Abschnitt auftaucht (der kurze Code im ersten Posting).
Daher meine Frage ob es da irgendeine Art von Best-Practice gibt.
Damit der Webserver die Client-Verbindungen zeitgerecht wieder kappt.