Core 2 connecting with W5500 LAN to Firebase RTDB
-
I have a Core 2 with W5500 LAN module. For 10 days I have been trying in vain to connect to Firebase RTDB.
With WLAN I managed it 5 days ago... but that doesn't work now either! No idea why.
Both WIFI and Ethernet I tried the following templates: https://github.com/mobizt/Firebase-ESP-Client
Ethernet and WIFI work in simple tests.
-
WIFI works now again.. Firebase.reconnectWiFi(true); must be called AFTER Firebase.begin(&config, &auth);. With me this was somehow suddenly no longer so... probably because of a copy/paste error..`
so here my working WIFI code:
/**
- Created by K. Suwatchai (Mobizt)
- Email: k_suwatchai@hotmail.com
- Github: https://github.com/mobizt/Firebase-ESP-Client
- Copyright (c) 2022 mobizt
*/
/** This example will show how to authenticate as a user with Email and password.
*- You need to enable Email/Password provider.
- In Firebase console, select Authentication, select Sign-in method tab,
- under the Sign-in providers list, enable Email/Password provider.
- From this example, the user will be granted to access the specific location that matches
- the user uid.
- This example will modify the database rules to set up the security rule which need to
- guard the unauthorized access with the user Email.
*/
#include <M5Core2.h>
#include <WiFi.h>
#include <Firebase_ESP_Client.h>// Provide the token generation process info.
#include <addons/TokenHelper.h>// Provide the RTDB payload printing info and other helper functions.
#include <addons/RTDBHelper.h>/* 1. Define the WiFi credentials */
#define WIFI_SSID "WIFI_SSID"
#define WIFI_PASSWORD "WIFI_PASSWORD"/** 2. Define the API key
*- The API key (required) can be obtained since you created the project and set up
- the Authentication in Firebase console. Then you will get the API key from
- Firebase project Web API key in Project settings, on General tab should show the
- Web API Key.
- You may need to enable the Identity provider at https://console.cloud.google.com/customer-identity/providers
- Select your project, click at ENABLE IDENTITY PLATFORM button.
- The API key also available by click at the link APPLICATION SETUP DETAILS.
*/
#define API_KEY "API_KEY"/* 3. Define the user Email and password that already registerd or added in your project */
#define USER_EMAIL "USER_EMAIL"
#define USER_PASSWORD "USER_PASSWORD"/* 4. If work with RTDB, define the RTDB URL */
#define DATABASE_URL "DATABASE_URL" //<databaseName>.firebaseio.com or <databaseName>.<region>.firebasedatabase.app/** 5. Define the database secret (optional)
*- This database secret needed only for this example to modify the database rules
- If you edit the database rules yourself, this is not required.
*/
#define DATABASE_SECRET "DATABASE_SECRET"
/* 6. Define the Firebase Data object */
FirebaseData fbdo;/* 7. Define the FirebaseAuth data for authentication data */
FirebaseAuth auth;/* 8. Define the FirebaseConfig data for config data */
FirebaseConfig config;unsigned long dataMillis = 0;
int count = 0;void setup()
{
//M5.begin();
Serial.begin(115200);WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.print("Connecting to Wi-Fi"); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(300); } Serial.println(); Serial.print("Connected with IP: "); Serial.println(WiFi.localIP()); Serial.println(); Serial.printf("Firebase Client v%s\n\n", FIREBASE_CLIENT_VERSION); //config.signer.test_mode = true; /* Assign the api key (required) */ config.api_key = API_KEY; /* Assign the user sign in credentials */ auth.user.email = USER_EMAIL; auth.user.password = USER_PASSWORD; /* Assign the RTDB URL */ config.database_url = DATABASE_URL; /* In case the certificate data was used */ //config.cert.data = rootCACert; // Or custom set the root certificate for each FirebaseData object //fbdo.setCert(rootCACert); /* Or assign the certificate file */ /** From the test as of July 2021, GlobalSign Root CA was missing from Google server * as described above, GTS Root R1 (gsr1.pem or gsr1.der) can be used instead. * ESP32 Arduino SDK supports PEM format only even mBedTLS supports DER format too. * ESP8266 SDK supports both PEM and DER format certificates. */ //config.cert.file = "/gtsr1.pem"; //config.cert.file_storage = mem_storage_type_flash; // or mem_storage_type_sd fbdo.setResponseSize(4096); String base_path = "/UsersData/"; /* Assign the callback function for the long running token generation task */ config.token_status_callback = tokenStatusCallback; // see addons/TokenHelper.h /* Initialize the library with the Firebase authen and config */ Firebase.begin(&config, &auth); Firebase.reconnectWiFi(true); /** Now modify the database rules (if not yet modified) * * The user, <user uid> in this case will be granted to read and write * at the certain location i.e. "/UsersData/<user uid>". * * If you database rules has been modified, please comment this code out. * * The character $ is to make a wildcard variable (can be any name) represents any node key * which located at some level in the rule structure and use as reference variable * in .read, .write and .validate rules * * For this case $userId represents any <user uid> node that places under UsersData node i.e. * /UsersData/<user uid> which <user uid> is user UID. * * Please check your the database rules to see the changes after run the below code. */ String var = "$userId"; String val = "($userId === auth.uid)"; Firebase.RTDB.setReadWriteRules(&fbdo, base_path, var, val, val, DATABASE_SECRET); /** path for user data is now "/UsersData/<user uid>" * * The id token can be accessed from Firebase.getToken(). * * The refresh token can be accessed from Firebase.getRefreshToken(). */
}
void loop()
{// Firebase.ready() should be called repeatedly to handle authentication tasks. if (millis() - dataMillis > 5000 && Firebase.ready()) { dataMillis = millis(); String path = "/UsersData/"; path += auth.token.uid.c_str(); //<- user uid of current user that sign in with Emal/Password path += "/test/int"; Serial.printf("Set int... %s\n", Firebase.RTDB.setInt(&fbdo, path, count++) ? "ok" : fbdo.errorReason().c_str()); // You can use refresh token from Firebase.getRefreshToken() to sign in next time without providing Email and Password. // See SignInWithRefreshIDToken example. }
}
Now i will try again to connect with Ethernet W5500.. i come back later with more infos..
-
Ethernet still not working. I used the following code:
/**
- Created by K. Suwatchai (Mobizt)
- Email: k_suwatchai@hotmail.com
- Github: https://github.com/mobizt/Firebase-ESP-Client
- Copyright (c) 2022 mobizt
*/
/** This example shows the basic RTDB usage with external Client.
- This example used ESP32 and WIZnet W5500 (Etherner) devices which built-in SSL Client will be used as the external Client.
- For other non-espressif (ESP32 and ESP8266) devices, this SSL Client library can be used
- https://github.com/OPEnSLab-OSU/SSLClient
- Don't gorget to define this in FirebaseFS.h
- #define FB_ENABLE_EXTERNAL_CLIENT
*/
#include <WiFi.h>
#include <M5Core2.h>
#include <Firebase_ESP_Client.h>
#include "time.h"
#include <ESP32Time.h>//ESP32Time rtc;
ESP32Time rtc(3600); // offset in seconds GMT+1// Provide the token generation process info.
#include <addons/TokenHelper.h>// Provide the RTDB payload printing info and other helper functions.
#include <addons/RTDBHelper.h>//https://github.com/arduino-libraries/Ethernet
#include <Ethernet.h>// Include built-in SSL Client which supports other network interfaces
#include "sslclient/esp32/MB_ESP32_SSLClient.h"// You can use MB_ESP32_SSLClient.h in your ESP32 project in the same way as normal WiFiClientSecure
// For NTP time client
#include "MB_NTP.h"// For the following credentials, see examples/Authentications/SignInAsUser/EmailPassword/EmailPassword.ino
/* 1. Define the API Key */
#define API_KEY "KEY"/* 2. Define the RTDB URL */
#define DATABASE_URL "URL" //<databaseName>.firebaseio.com or <databaseName>.<region>.firebasedatabase.app/* 3. Define the user Email and password that alreadey registerd or added in your project */
#define USER_EMAIL "EMAIL"
#define USER_PASSWORD "PASSWORD"/* 4. Defined the Ethernet module connection */
//#define WIZNET_RESET_PIN 26 // Connect W5500 Reset pin to GPIO 26 of ESP32
#define WIZNET_CS_PIN 26 // Connect W5500 CS pin to GPIO 5 of ESP32
#define WIZNET_MISO_PIN 38 // Connect W5500 MISO pin to GPIO 19 of ESP32
#define WIZNET_MOSI_PIN 23 // Connect W5500 MOSI pin to GPIO 23 of ESP32
#define WIZNET_SCLK_PIN 18 // Connect W5500 SCLK pin to GPIO 18 of ESP32//WLAN
const char* ssid = "ssid";
const char* password = "password";/* 5. Define MAC */
uint8_t MAC[] = { 0x12, 0x12, 0x12, 0x12, 0x12, 0x12 };/* 6. Define IP (Optional) */
IPAddress IP(192, 168, 1, 233);
IPAddress DNS(8, 8, 8, 8);// Define Firebase Data object
FirebaseData fbdo;FirebaseAuth auth;
FirebaseConfig config;unsigned long sendDataPrevMillis = 0;
int count = 0;
volatile bool dataChanged = false;
EthernetClient basic_client;
MB_ESP32_SSLClient ssl_client;// For NTP client
EthernetUDP udpClient;MB_NTP ntpClient(&udpClient, "ch.pool.ntp.org" /* NTP host /, 123 / NTP port /, 0 / timezone offset in seconds */);
uint32_t timestamp = 0;
const char* ntpServer = "ch.pool.ntp.org";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;
int second;
int minute;
int hour;
int day;
int month;
int year;
struct tm timeinfo;void printLocalTime() {
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
M5.Lcd.print("Failed to obtain time");
return;
}
second = timeinfo.tm_sec;
minute = timeinfo.tm_min;
hour = timeinfo.tm_hour;
day = timeinfo.tm_mday;
month = timeinfo.tm_mon + 1;
year = timeinfo.tm_year + 1900;
weekday = timeinfo.tm_wday + 1;
rtc.setTime(second, minute, hour, day, month, year);
}void wifiNtpSetup() {
M5.Lcd.setTextSize(2); //Set the font size to 2. 设置字号大小为2
M5.Lcd.printf("\nConnecting to %s", ssid);
WiFi.begin(
ssid,
password); //Connect wifi and return connection status. 连接wifi并返回连接状态
while (WiFi.status() != WL_CONNECTED) { //If the wifi connection fails. 若wifi未连接成功
delay(500); //delay 0.5s. 延迟0.5s
M5.Lcd.print(".");
}
M5.Lcd.println("\nCONNECTED!");
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); //init and get the time. 初始化并设置NTP
printLocalTime();if (timestamp == 0) {
timestamp = ntpClient.getTime(2000 /* wait 2000 ms */);if (timestamp > 0) { Serial.print("timestamp:"); Serial.print(timestamp); } else { Serial.println("NTP Server via Ethernet nicht erreichbar !"); }
}
WiFi.disconnect(true); //Disconnect wifi. 断开wifi连接
WiFi.mode(WIFI_OFF); //Set the wifi mode to off. 设置wifi模式为关闭
delay(20);
M5.Lcd.println("\nWIFI OFF!");
}/*
void ResetEthernet()
{
Serial.println("Resetting WIZnet W5500 Ethernet Board... ");
pinMode(WIZNET_RESET_PIN, OUTPUT);
digitalWrite(WIZNET_RESET_PIN, HIGH);
delay(200);
digitalWrite(WIZNET_RESET_PIN, LOW);
delay(50);
digitalWrite(WIZNET_RESET_PIN, HIGH);
delay(200);
}
*/void networkConnection() {
SPI.begin(WIZNET_SCLK_PIN, WIZNET_MISO_PIN, WIZNET_MOSI_PIN, -1);
Ethernet.init(WIZNET_CS_PIN);
//Serial.begin(115200);//ResetEthernet();
Serial.println("Starting Ethernet connection...");
Ethernet.begin(MAC, IP, DNS);unsigned long to = millis();
while (Ethernet.linkStatus() == LinkOFF || millis() - to < 2000) {
delay(100);
}if (Ethernet.linkStatus() == LinkON) {
Serial.print("Connected with IP ");
Serial.println(Ethernet.localIP());
} else {
Serial.println("Can't connect");
}
}// Define the callback function to handle server status acknowledgement
void networkStatusRequestCallback() {// Set the network status
fbdo.setNetworkStatus(Ethernet.linkStatus() == LinkON);
}// Define the callback function to handle server connection
void tcpConnectionRequestCallback(const char* host, int port) {// You may need to set the system timestamp to use for
// auth token expiration checking.
Firebase.setSystemTime(rtc.getLocalEpoch());Serial.print("Connecting to server via external Client... ");
if (!ssl_client.connect(host, port)) {
Serial.println("Connection failed !");
return;
}
Serial.println("Connection established !");
}void setup() {
M5.begin();
wifiNtpSetup();
networkConnection();Serial_Printf("Firebase Client v%s\n\n", FIREBASE_CLIENT_VERSION);
/* Assign the basic Client (Ethernet) pointer to the basic Client */
ssl_client.setClient(&basic_client);/* Similar to WiFiClientSecure */
ssl_client.setInsecure();config.cert.file = "/gtsr1.pem";
config.cert.file_storage = mem_storage_type_flash;/* Assign the api key (required) */
config.api_key = API_KEY;/* Assign the user sign in credentials */
auth.user.email = USER_EMAIL;
auth.user.password = USER_PASSWORD;/* Assign the RTDB URL (required) */
config.database_url = DATABASE_URL;/* Assign the callback function for the long running token generation task */
config.token_status_callback = tokenStatusCallback; // see addons/TokenHelper.h/* fbdo.setExternalClient and fbdo.setExternalClientCallbacks must be called before Firebase.begin */
/* Assign the pointer to global defined external SSL Client object */
fbdo.setExternalClient(&ssl_client);/* Assign the required callback functions */
fbdo.setExternalClientCallbacks(tcpConnectionRequestCallback, networkConnection, networkStatusRequestCallback);Firebase.setDoubleDigits(5);
Firebase.begin(&config, &auth);
// Comment or pass false value when WiFi reconnection will control by your code or third party library
//Firebase.reconnectWiFi(true);
}void loop() {
// Firebase.ready() should be called repeatedly to handle authentication tasks.
if (Firebase.ready() && (millis() - sendDataPrevMillis > 15000 || sendDataPrevMillis == 0)) {
sendDataPrevMillis = millis();Serial_Printf("Set bool... %s\n", Firebase.RTDB.setBool(&fbdo, F("/test/bool"), count % 2 == 0) ? "ok" : fbdo.errorReason().c_str()); count++;
}
}Excerpt from Serial Monitor:
"
Token info: type = id token (GITKit token), status = on request
[V][ESP32_SSL_Client.cpp:402] stop_tcp_connection(): Cleaning SSL connection.
Connecting to server via external Client... [V][ESP32_SSL_Client.cpp:173] connect_ssl(): Seeding the random number generator
[V][ESP32_SSL_Client.cpp:185] connect_ssl(): Setting up the SSL/TLS structure...
[I][ESP32_SSL_Client.cpp:201] connect_ssl(): WARNING: Skipping SSL Verification. INSECURE!
[V][ESP32_SSL_Client.cpp:313] connect_ssl(): Setting hostname for TLS session...
[V][ESP32_SSL_Client.cpp:334] connect_ssl(): Performing the SSL/TLS handshake...
[E][ESP32_SSL_Client.cpp:61] _esp32_ssl_handle_error(): [connect_ssl():341]: (-1) UNKNOWN ERROR CODE (0001)
[E][MB_ESP32_SSLClient.cpp:217] connect(): MB_ESP32_SSLClient Error: upgrade connection, -1
[V][ESP32_SSL_Client.cpp:402] stop_tcp_connection(): Cleaning SSL connection.
Connection failed !
"This error indicates that there was an issue with the SSL/TLS handshake when trying to connect to an external server. The exact cause of this error is unknown, but it could be due to an incorrect SSL configuration, an expired/invalid certificate, or an issue with the network connection.
The NTP server is also not accessible via Ethernet. Therefore I connected the NTP with WLAN and synchronized timestamp with Firebase. The SSL/TLS connection still failed. I am running out of ideas. -
I have downloaded again the above code for a WLAN connection. It did not work!
The following error message appeared:
Token info: type = id token (GITKit token), status = on request
Token info: type = id token (GITKit token), status = error
Token error: code: -105, message: Client is not yet initializedAfter that i downgraded the library "Firebase Arduino Client Library for ESP8266 and ESP32" to 2.3.7 and after that i reinstalled 4.2.7 and it worked again. Why do i need to reinstall the lib to get it working?
-
-
Thanks to your steep pass it IT finally WORKS !!!
Here are a few more stumbling blocks to be aware of:
-
#define FB_ENABLE_EXTERNAL_CLIENT must be set for Ethernet connection. For WLAN it must be deactivated. Therefore WLAN worked again after reinstalling the lib as described above.
-
you need to define the GPIO´s for Core 2 as following in the code
-
trust_anchors URL => www.google.com seems to work as Firebase is a google product
-
#include <M5Core2.h> is NOT necessary => if you use it with M5.begin you need to delete Serial.begin(115200) => otherwise your CPU will crash => known issue also thanks to felmue
-
NTP server is not working => always returns 0 => seems to work without NTP
Here is the working code i use:
/**
- Created by K. Suwatchai (Mobizt)
- Email: k_suwatchai@hotmail.com
- Github: https://github.com/mobizt/Firebase-ESP-Client
- Copyright (c) 2022 mobizt
*/
/** This example shows the basic RTDB usage with external Client.
- This example used your Arduino device and WIZnet W5500 (Ethernet) device which SSLClient https://github.com/OPEnSLab-OSU/SSLClient
- will be used as the external Client.
- This SSLClient, https://github.com/OPEnSLab-OSU/SSLClient can't use in ESP8266 device due to wdt reset error.
- Don't gorget to define this in FirebaseFS.h
- #define FB_ENABLE_EXTERNAL_CLIENT
*/
#include <Firebase_ESP_Client.h>
// Provide the token generation process info.
#include <addons/TokenHelper.h>// Provide the RTDB payload printing info and other helper functions.
#include <addons/RTDBHelper.h>#include <Ethernet.h>
/* 1. Install SSLClient library */
// https://github.com/OPEnSLab-OSU/SSLClient
#include <SSLClient.h>/* 2. Create Trus anchors for the server i.e. www.google.com */
// https://github.com/OPEnSLab-OSU/SSLClient/blob/master/TrustAnchors.md
// or generate using this site https://openslab-osu.github.io/bearssl-certificate-utility/
#include "trust_anchors.h"// For NTP time client
#include "MB_NTP.h"// For the following credentials, see examples/Authentications/SignInAsUser/EmailPassword/EmailPassword.ino
/* 3. Define the API Key */
#define API_KEY "Key"/* 4. Define the RTDB URL */
#define DATABASE_URL "URL" //<databaseName>.firebaseio.com or <databaseName>.<region>.firebasedatabase.app/* 5. Define the user Email and password that alreadey registerd or added in your project */
#define USER_EMAIL "Email"
#define USER_PASSWORD "password"/* 6. Defined the Ethernet module connection */
#define WIZNET_RESET_PIN 19 // Connect W5500 Reset pin to GPIO 19 for Core 2
#define WIZNET_CS_PIN 26 // Connect W5500 CS pin to GPIO 26 for Core 2
#define WIZNET_MISO_PIN 38 // Connect W5500 MISO pin to GPIO 38 for Core 2
#define WIZNET_MOSI_PIN 23 // Connect W5500 MOSI pin to GPIO 23 for Core 2
#define WIZNET_SCLK_PIN 18 // Connect W5500 SCLK pin to GPIO 18 for Core 2/* 7. Define the analog GPIO pin to pull random bytes from, used in seeding the RNG for SSLClient */
const int analog_pin = 27; // Core 2 => GPIO 27 (Analog pin)/* 8. Define MAC */
uint8_t mac[] = { 0x12, 0x12, 0x12, 0x12, 0x12, 0x12 };/* 9. Define IP (Optional) */
IPAddress ip(192, 168, 1, 50);
IPAddress myDns(8, 8, 8, 8);// Define Firebase Data object
FirebaseData fbdo;FirebaseAuth auth;
FirebaseConfig config;unsigned long sendDataPrevMillis = 0;
int count = 0;
volatile bool dataChanged = false;
EthernetClient basic_client;
SSLClient ssl_client(basic_client, TAs, (size_t)TAs_NUM, analog_pin);
// For NTP client
EthernetUDP udpClient;MB_NTP ntpClient(&udpClient, "pool.ntp.org" /* NTP host /, 123 / NTP port /, 0 / timezone offset in seconds */);
uint32_t timestamp = 0;
void ResetEthernet() {
Serial.println("Resetting WIZnet W5500 Ethernet Board... ");
pinMode(WIZNET_RESET_PIN, OUTPUT);
digitalWrite(WIZNET_RESET_PIN, HIGH);
delay(200);
digitalWrite(WIZNET_RESET_PIN, LOW);
delay(50);
digitalWrite(WIZNET_RESET_PIN, HIGH);
delay(200);
}void networkConnection() {
Ethernet.init(WIZNET_CS_PIN);
ResetEthernet();
Serial.println("Starting Ethernet connection...");
Ethernet.begin(mac);
unsigned long to = millis();
while (Ethernet.linkStatus() == LinkOFF || millis() - to < 2000) {
delay(100);
}if (Ethernet.linkStatus() == LinkON) {
Serial.print("Connected with IP ");
Serial.println(Ethernet.localIP());
} else {
Serial.println("Can't connect");
}
}// Define the callback function to handle server status acknowledgement
void networkStatusRequestCallback() {
// Set the network statusfbdo.setNetworkStatus(Ethernet.linkStatus() == LinkON);
}// Define the callback function to handle server connection
void tcpConnectionRequestCallback(const char *host, int port) {// You may need to set the system timestamp to use for
// auth token expiration checking.if (timestamp == 0) {
timestamp = ntpClient.getTime(2000 /* wait 2000 ms */);
Serial.print("timestamp from NTP: ");
Serial.println(timestamp);if (timestamp > 0) { Firebase.setSystemTime(timestamp); Serial.print("Firebase => setSystemTime done"); }
}
Serial.print("Connecting to server via external Client... ");
if (!ssl_client.connect(host, port)) {
Serial.println("failed.");
return;
}
Serial.println("success.");
}void setup() {
SPI.begin(WIZNET_SCLK_PIN, WIZNET_MISO_PIN, WIZNET_MOSI_PIN, -1);
Serial.begin(115200);networkConnection();
Serial_Printf("Firebase Client v%s\n\n", FIREBASE_CLIENT_VERSION);
/* Assign the api key (required) */
config.api_key = API_KEY;/* Assign the user sign in credentials */
auth.user.email = USER_EMAIL;
auth.user.password = USER_PASSWORD;/* Assign the RTDB URL (required) */
config.database_url = DATABASE_URL;/* Assign the callback function for the long running token generation task */
config.token_status_callback = tokenStatusCallback; // see addons/TokenHelper.h/* fbdo.setExternalClient and fbdo.setExternalClientCallbacks must be called before Firebase.begin */
/* Assign the pointer to global defined external SSL Client object */
fbdo.setExternalClient(&ssl_client);/* Assign the required callback functions */
fbdo.setExternalClientCallbacks(tcpConnectionRequestCallback, networkConnection, networkStatusRequestCallback);Firebase.setDoubleDigits(5);
Firebase.begin(&config, &auth);
}void loop() {
// Firebase.ready() should be called repeatedly to handle authentication tasks.
if (Firebase.ready() && (millis() - sendDataPrevMillis > 15000 || sendDataPrevMillis == 0)) {
sendDataPrevMillis = millis();Serial_Printf("Set bool... %s\n", Firebase.RTDB.setBool(&fbdo, F("/test/bool"), count % 2 == 0) ? "ok" : fbdo.errorReason().c_str()); count++;
}
} -