Hallo SchimmerMedia-Forum,
ich benötige eure Hilfe.
Mein Ziel ist es "low-energy" ESP8266 Sensoren zu bauen, die deutlich Stromsparender als die Lösung mit ESPEasy und Tasmota sind. Aktuell habe ich mehrere Wemos D1mini (ESP8266) im Einsatz, worauf zum Teil ESPEasy und auch Tasmota läuft. Die D1minis sind mit DHT-11 (Temperatur und Feuchtigkeit) und zum Teil mit HC-SR04 Sensoren (Ultraschall Entfernung) versehen sind und fleißig Messwerte über MQTT schicken.
Leider Verbrauchen die Sensoren mir zu viel Energie, da die Sendezeit knapp 6 Sekunden beträgt, bis der Sensor wieder in den DeepSleep Modus geht.
Jetzt habe über den YouTuber Andreas Spiess ("guy with the swiss accent") erfahren, dass es eine deutlich stromsparende Methode gibt - ESPNow (Link). Leider kenne ich mich mit den Programmieren in Arduino und den Sketches leider nicht so aus.
Die Sketches (ESPNow_Master_ESP8266 und EspNow_Slave_ESP8266) von ihm habe ich zum laufen bekommen, sodass ein D1mini (Master) eine Testnachricht schickt, dabei knapp 300ms benötigt und ein anderer D1mini (Slave) die Daten empfängt und als MQTT-Message verschickt. Nur kann ich mit dem Aufbau der Sketche nicht so viel anfangen, dass ich Daten von mehreren Sensoren schicken und empfangen kann.
/*
* Author: Andreas Spiess, 2017
*
This sketch measures the time to send a ESP-Now message. It is a strip down of Anthony's sensor sketch
https://github.com/HarringayMakerSpace/ESP-Now
Anthony Elder
*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
extern "C" {
#include "user_interface.h"
#include <espnow.h>
}
// this is the MAC Address of the remote ESP server which receives these sensor readings
uint8_t remoteMac[] = {0x1A, 0xFE, 0x34, 0xD5, 0xFA, 0x39};
#define WIFI_CHANNEL 1
#define SLEEP_SECS 5 // 15 minutes
#define SEND_TIMEOUT 245 // 245 millis seconds timeout
#define MESSAGELEN 10
unsigned long entry;
// keep in sync with slave struct
struct __attribute__((packed)) SENSOR_DATA {
char testdata[MESSAGELEN];
} sensorData;
//BME280 bme280;
volatile boolean callbackCalled;
unsigned long entry1 = millis();
void setup() {
int i = 0;
Serial.begin(115200);
Serial.println();
Serial.println();
Serial.println("ESP_Now Controller");
Serial.println();
WiFi.mode(WIFI_STA); // Station mode for esp-now sensor node
WiFi.disconnect();
Serial.printf("This mac: %s, ", WiFi.macAddress().c_str());
Serial.printf("target mac: %02x%02x%02x%02x%02x%02x", remoteMac[0], remoteMac[1], remoteMac[2], remoteMac[3], remoteMac[4], remoteMac[5]);
Serial.printf(", channel: %i\n", WIFI_CHANNEL);
if (esp_now_init() != 0) {
Serial.println("*** ESP_Now init failed");
gotoSleep();
}
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
Serial.println(millis() - entry1);
unsigned long entry2 = millis();
esp_now_add_peer(remoteMac, ESP_NOW_ROLE_SLAVE, WIFI_CHANNEL, NULL, 0);
Serial.println(millis() - entry2);
unsigned long entry3 = millis();
esp_now_register_send_cb([](uint8_t* mac, uint8_t sendStatus) {
Serial.printf("send_cb, send done, status = %i\n", sendStatus);
callbackCalled = true;
});
Serial.println(millis() - entry3);
unsigned long entry4 = millis();
callbackCalled = false;
for (i = 0; i < MESSAGELEN; i++) sensorData.testdata[i] = '0';
sensorData.testdata[MESSAGELEN] = '\0';
}
void loop() {
uint8_t bs[sizeof(sensorData)];
memcpy(bs, &sensorData, sizeof(sensorData));
unsigned long entry = millis();
esp_now_send(NULL, bs, sizeof(sensorData)); // NULL means send to all peers
Serial.print("Time to send: ");
Serial.println(millis() - entry);
Serial.print("Overall Time: ");
Serial.println(millis() - entry1);
// Serial.print("Size: ");
// Serial.println(sizeof(bs));
ESP.deepSleep(0);
}
/*
void loop() {
if (callbackCalled || (millis() > SEND_TIMEOUT)) {
gotoSleep();
}
}
*/
void gotoSleep() {
// add some randomness to avoid collisions with multiple devices
int sleepSecs = SLEEP_SECS;// + ((uint8_t)RANDOM_REG32/2);
Serial.printf("Up for %i ms, going to sleep for %i secs...\n", millis(), sleepSecs);
ESP.deepSleep(sleepSecs * 1000000, RF_NO_CAL);
}
Alles anzeigen
/**
*
* Author: Andreas Spiess, 2017
*
This sketch receives ESP-Now message and sends it as an MQTT messge
It is heavily based on of Anthony's gateway setch sketch
https://github.com/HarringayMakerSpace/ESP-Now
Anthony Elder
*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <credentials.h>
extern "C" {
#include "user_interface.h"
#include <espnow.h>
}
//-------- Customise the above values --------
#define SENDTOPIC "ESPNow/key"
#define COMMANDTOPIC "ESPNow/command"
#define SERVICETOPIC "ESPNow/service"
/* Set a private Mac Address
* http://serverfault.com/questions/40712/what-range-of-mac-addresses-can-i-safely-use-for-my-virtual-machines
* Note: the point of setting a specific MAC is so you can replace this Gateway ESP8266 device with a new one
* and the new gateway will still pick up the remote sensors which are still sending to the old MAC
*/
uint8_t mac[] = {0x36, 0x33, 0x33, 0x33, 0x33, 0x33};
void initVariant() {
//wifi_set_macaddr(SOFTAP_IF, &mac[0]);
}
#ifdef CREDENTIALS
char *ssid = mySSID; // Set you WiFi SSID
char *password = myPASSWORD; // Set you WiFi password
#else
char *ssid = ""; // Set you WiFi SSID
char *password = ""; // Set you WiFi password
#endif
IPAddress server(192, 168, 177, 35);
// the X's get replaced with the remote sensor device mac address
const char deviceTopic[] = "ESPNOW/";
WiFiClient wifiClient;
PubSubClient client(server, 1883, wifiClient);
String deviceMac;
// keep in sync with ESP_NOW sensor struct
struct __attribute__((packed)) SENSOR_DATA {
char testdata[240];
} sensorData;
volatile boolean haveReading = false;
/* Presently it doesn't seem posible to use both WiFi and ESP-NOW at the
* same time. This gateway gets around that be starting just ESP-NOW and
* when a message is received switching on WiFi to sending the MQTT message
* to Watson, and then restarting the ESP. The restart is necessary as
* ESP-NOW doesn't seem to work again even after WiFi is disabled.
* Hopefully this will get fixed in the ESP SDK at some point.
*/
int heartBeat;
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();
Serial.println("ESP_Now Controller");
Serial.println();
WiFi.mode(WIFI_AP);
Serial.print("This node AP mac: "); Serial.println(WiFi.softAPmacAddress());
Serial.print("This node STA mac: "); Serial.println(WiFi.macAddress());
initEspNow();
Serial.println("Setup done");
}
void loop() {
if (millis()-heartBeat > 30000) {
Serial.println("Waiting for ESP-NOW messages...");
heartBeat = millis();
}
if (haveReading) {
haveReading = false;
wifiConnect();
reconnectMQTT();
sendToNodeRed();
client.disconnect();
delay(200);
ESP.restart(); // <----- Reboots to re-enable ESP-NOW
}
}
void initEspNow() {
if (esp_now_init()!=0) {
Serial.println("*** ESP_Now init failed");
ESP.restart();
}
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
esp_now_register_recv_cb([](uint8_t *mac, uint8_t *data, uint8_t len) {
deviceMac = "";
deviceMac += String(mac[0], HEX);
deviceMac += String(mac[1], HEX);
deviceMac += String(mac[2], HEX);
deviceMac += String(mac[3], HEX);
deviceMac += String(mac[4], HEX);
deviceMac += String(mac[5], HEX);
memcpy(&sensorData, data, sizeof(sensorData));
Serial.print("Message received from device: "); Serial.print(deviceMac);
Serial.println(sensorData.testdata);
Serial.println();
// Serial.printf(" Temp=%0.1f, Hum=%0.0f%%, pressure=%0.0fmb\n",
// sensorData.temp, sensorData.humidity, sensorData.pressure);
haveReading = true;
});
}
void wifiConnect() {
WiFi.mode(WIFI_STA);
Serial.println();
Serial.print("Connecting to "); Serial.print(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(250);
Serial.print(".");
}
Serial.print("\nWiFi connected, IP address: "); Serial.println(WiFi.localIP());
}
void publishMQTT(String topic, String message) {
Serial.println("Publish");
if (!client.connected()) {
reconnectMQTT();
}
client.publish(SENDTOPIC, message.c_str());
}
void reconnectMQTT() {
Serial.println(" Loop until we're reconnected");
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("Mailbox", "admin", "admin")) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish(SERVICETOPIC, "I am live");
// ... and resubscribe
// client.subscribe("inTopic");
} else {
Serial.print("failed, rc = ");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void sendToNodeRed() {
Serial.println(sensorData.testdata);
String payload = "{";
payload += "\"test\":\"" + String(sensorData.testdata);
payload += "\"}";
Serial.println(payload);
publishMQTT(SENDTOPIC,payload);
}
Alles anzeigen
Hat jemand gute bis sehr gute Kenntnisse und ein wenig Zeit, mich da zu unterstützen? Ich denke das man mit dieser Möglichkeit hier eine Menge "low-energy"-Sensoren bauen kann, die ggf. mit Knopfzellen versorgt werden und trotzdem lange halten.
Vielen Dank.
Gruß
Justin