devnull69
05.11.2020, 08:46
Ich habe einen Arduino-Sketch aufgesetzt, der über WiFi auf Firebase zugreifen soll und zusätzlich HTTPS-Requests starten soll. Ich nutze ein ESP8266-12F Modul (AZ Delivery D1 mini NodeMCU)
ESP8266 Board Version 2.7.4
FirebaseArduino Version 0.3 (von 2018, gibt es da etwas Neueres, das ich nicht finden konnte?) zusammen mit ArduinoJson Version 5.13.1
ODER FirebaseESP8266 Version 3.0.2
Für die Firebase-Zugriffe habe ich sowohl FirebaseArduino als auch FirebaseESP8266 ausprobiert, beide haben aber mit der Situation ihre Probleme:
In setup() öffne ich die WiFi-Verbindung, und in loop() greife ich auf Firebase zu, um eine Liste von 10-Zeichen-Strings zu holen. Von diesen gibt es ca. 160 in der Datenbank, die genaue Anzahl kenne ich aber vorher nicht. Bis zu diesem Punkt funktionert auch alles prima. Ich kann mir sogar in einer Schleife die gesammelten String-Keys anschauen.
Aber sobald ich dann eine HTTPS-Client-Verbindung aufbaue
WiFiClientSecure client;
client.setInsecure(); // to avoid fingerprint stuff
if(!client.connect()) {
Serial.println("connection failed");
} else {
... // hier steht dann client.print("GET ......")
}
kommt es entweder zu "connection failed" oder aber zu Soft WDT Resets.
Wenn ich eine HTTPS-Client-Verbindung zu den gleichen URLs ohne vorherigen Firebase-Zugriff aufbaue, dann funktionieren diese prima!
Was möchte ich eigentlich machen? Für jeden der 10-Zeichen-Strings aus Firebase möchte ich eine HTTPS-Verbindung zu einem Server aufbauen, wobei die URL diesen String enthält. Von diesem Server hole ich mir Infos (einen weiteren String), den ich dann in Firebase bei dem String-Key speichern möchte.
Außerdem habe ich noch ein SSD1306 OLED an meinem ESP8266 angeschlossen.
Codeaufbau:
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WiFiClientSecureBearSSL.h>
#include <WiFiClient.h>
#include <Wire.h>
#include <SSD1306.h>
#include <FirebaseESP8266.h>
#define FIREBASE_HOST "xxxxxxxxxxxxxxxxxxxxxxx"
#define FIREBASE_AUTH "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
#define OLED_ADDRESS 0x3C //you may need to change this, this is the OLED I2C address.
SSD1306 display(OLED_ADDRESS, D2, D1);
ESP8266WiFiMulti WiFiMulti;
FirebaseData firebaseData;
...
void setup() {
...
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("aaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbb");
while(WiFiMulti.run() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
...
}
void loop() {
WiFiClientSecure client;
client.setInsecure();
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.reconnectWiFi(true);
firebaseData.setBSSLBufferSize(3072, 512);
firebaseData.setResponseSize(3072);
if(Firebase.get(firebaseData, "/my/path")){
Serial.print("Read object of type ");
Serial.println(firebaseData.dataType());
FirebaseJson& json = firebaseData.jsonObject();
size_t len = json.iteratorBegin();
String key, value = "";
int type = 0;
String buffer[len];
for (size_t i = 0; i < len; i++)
{
json.iteratorGet(i, type, key, value);
buffer[i] = key;
}
json.iteratorEnd();
delay(500);
// check single IDs
for(size_t i = 0; i < len; i++) {
String url = "/" + buffer[i];
if (!client.connect(host, httpsPort)) { // the problems happen here
Serial.println("connection failed");
} else {
...
}
client.stop();
}
}
}
Gibt es in dem Code ein grundlegendes Problem, das zu dieser Situation führt? Ich weiß zum Beispiel, dass ich Strings vermeiden sollte ... habe aber zu wenig Erfahrung mit hardwarenaher Programmierung eines speicherlimitierten Systems in C++ ;)
Vielleicht habt ihr Hinweise, wie ich beispielsweise die Liste der Keys nicht als String[] sondern speicherschonender ablegen und nutzen kann?
ESP8266 Board Version 2.7.4
FirebaseArduino Version 0.3 (von 2018, gibt es da etwas Neueres, das ich nicht finden konnte?) zusammen mit ArduinoJson Version 5.13.1
ODER FirebaseESP8266 Version 3.0.2
Für die Firebase-Zugriffe habe ich sowohl FirebaseArduino als auch FirebaseESP8266 ausprobiert, beide haben aber mit der Situation ihre Probleme:
In setup() öffne ich die WiFi-Verbindung, und in loop() greife ich auf Firebase zu, um eine Liste von 10-Zeichen-Strings zu holen. Von diesen gibt es ca. 160 in der Datenbank, die genaue Anzahl kenne ich aber vorher nicht. Bis zu diesem Punkt funktionert auch alles prima. Ich kann mir sogar in einer Schleife die gesammelten String-Keys anschauen.
Aber sobald ich dann eine HTTPS-Client-Verbindung aufbaue
WiFiClientSecure client;
client.setInsecure(); // to avoid fingerprint stuff
if(!client.connect()) {
Serial.println("connection failed");
} else {
... // hier steht dann client.print("GET ......")
}
kommt es entweder zu "connection failed" oder aber zu Soft WDT Resets.
Wenn ich eine HTTPS-Client-Verbindung zu den gleichen URLs ohne vorherigen Firebase-Zugriff aufbaue, dann funktionieren diese prima!
Was möchte ich eigentlich machen? Für jeden der 10-Zeichen-Strings aus Firebase möchte ich eine HTTPS-Verbindung zu einem Server aufbauen, wobei die URL diesen String enthält. Von diesem Server hole ich mir Infos (einen weiteren String), den ich dann in Firebase bei dem String-Key speichern möchte.
Außerdem habe ich noch ein SSD1306 OLED an meinem ESP8266 angeschlossen.
Codeaufbau:
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WiFiClientSecureBearSSL.h>
#include <WiFiClient.h>
#include <Wire.h>
#include <SSD1306.h>
#include <FirebaseESP8266.h>
#define FIREBASE_HOST "xxxxxxxxxxxxxxxxxxxxxxx"
#define FIREBASE_AUTH "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
#define OLED_ADDRESS 0x3C //you may need to change this, this is the OLED I2C address.
SSD1306 display(OLED_ADDRESS, D2, D1);
ESP8266WiFiMulti WiFiMulti;
FirebaseData firebaseData;
...
void setup() {
...
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("aaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbb");
while(WiFiMulti.run() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
...
}
void loop() {
WiFiClientSecure client;
client.setInsecure();
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.reconnectWiFi(true);
firebaseData.setBSSLBufferSize(3072, 512);
firebaseData.setResponseSize(3072);
if(Firebase.get(firebaseData, "/my/path")){
Serial.print("Read object of type ");
Serial.println(firebaseData.dataType());
FirebaseJson& json = firebaseData.jsonObject();
size_t len = json.iteratorBegin();
String key, value = "";
int type = 0;
String buffer[len];
for (size_t i = 0; i < len; i++)
{
json.iteratorGet(i, type, key, value);
buffer[i] = key;
}
json.iteratorEnd();
delay(500);
// check single IDs
for(size_t i = 0; i < len; i++) {
String url = "/" + buffer[i];
if (!client.connect(host, httpsPort)) { // the problems happen here
Serial.println("connection failed");
} else {
...
}
client.stop();
}
}
}
Gibt es in dem Code ein grundlegendes Problem, das zu dieser Situation führt? Ich weiß zum Beispiel, dass ich Strings vermeiden sollte ... habe aber zu wenig Erfahrung mit hardwarenaher Programmierung eines speicherlimitierten Systems in C++ ;)
Vielleicht habt ihr Hinweise, wie ich beispielsweise die Liste der Keys nicht als String[] sondern speicherschonender ablegen und nutzen kann?