Walka była nierówna ale się udało
Co ciekawe, musiałem zamienić kolejnością SUPLĘ i ESP-NOW w SETUP bo jak SUPLA była pierwsza to niby rozgłaszała sieć (dioda szybko migała), a sieci nie było widać na żadnym urządzeniu.
Dodałem też do mastera Relay który informuje o błędzie wysłania lub dostarczenia danych po ESP-NOW. Można podpiąć do tego jakąś diodę czy powiadomienie z Supli.
Master:
Code: Select all
#ifdef ARDUINO_ARCH_AVR
#error "This example is not supported on Arduino AVR"
#endif
#define BUTTON_CFG_RELAY_GPIO 0
#define STATUS_LED_GPIO 2
#define OUTPUT_GPIO 14
#define OUTPUT_GPIO_ERR 5
#define DS18B20_GPIO 4
#include <SuplaDevice.h>
#include <supla/storage/eeprom.h>
#include <supla/network/esp_wifi.h>
#include <supla/device/status_led.h>
#include <supla/storage/littlefs_config.h>
#include <supla/network/esp_web_server.h>
#include <supla/network/html/device_info.h>
#include <supla/network/html/protocol_parameters.h>
#include <supla/network/html/status_led_parameters.h>
#include <supla/network/html/wifi_parameters.h>
#include <supla/device/supla_ca_cert.h>
#include <supla/control/hvac_base.h>
#include <supla/clock/clock.h>
#include <supla/network/html/time_parameters.h>
#include <supla/network/html/hvac_parameters.h>
#include <supla/control/internal_pin_output.h>
#include <supla/events.h>
#include <supla/actions.h>
#include <supla/control/button.h>
#include <supla/control/virtual_relay.h>
#include <supla/sensor/DS18B20.h>
#include <supla/control/relay.h>
#include <supla/control/action_trigger.h>
#include <supla/network/html/device_info.h>
#include <supla/sensor/virtual_thermometer.h>
// ESP-NOW
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <espnow.h>
uint8_t broadcastAddress[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // Adres MAC drugiego Wemosa
bool delivery_error = false; // bit błędu odebrania danych
struct esp_now_message
{
bool relayState; // Przechowuje stan GPIO14
};
esp_now_message message_content;
size_t msg_size = sizeof(message_content);
void print_msg_info(uint8_t* mac_addr, uint8_t status)
{
if (status == ERR_OK)
{
delivery_error=false;
}
else
{
delivery_error=true;
}
}
Supla::ESPWifi wifi;
Supla::LittleFsConfig configSupla;
Supla::Eeprom eeprom;
Supla::Device::StatusLed statusLed(STATUS_LED_GPIO, true);
Supla::EspWebServer suplaServer;
// wykonywanie co czas w opóźnieniu
unsigned long aktualny_czas = 0UL;
unsigned long zapamietany_czas = 0UL;
unsigned long opoznienie = 5000UL;
Supla::Control::Relay *output_err = nullptr;
void setup() {
Serial.begin(115200);
// ESP-NOW
WiFi.mode(WIFI_STA);
if (esp_now_init() != ERR_OK)
{
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
esp_now_register_send_cb(print_msg_info);
if (esp_now_add_peer((uint8_t*)broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0) != ERR_OK)
{
Serial.println("Failed to add peer");
return;
}
pinMode(OUTPUT_GPIO, OUTPUT); // wyjście termostat
pinMode(OUTPUT_GPIO_ERR, OUTPUT); // wyjście błąd
new Supla::Html::DeviceInfo(&SuplaDevice);
new Supla::Html::WifiParameters;
new Supla::Html::ProtocolParameters;
new Supla::Html::StatusLedParameters;
new Supla::Clock;
new Supla::Html::TimeParameters(&SuplaDevice);
//eeprom.setStateSavePeriod(5000);
auto output = new Supla::Control::InternalPinOutput(OUTPUT_GPIO);
output_err = new Supla::Control::Relay(OUTPUT_GPIO_ERR);
auto hvac = new Supla::Control::HvacBase(output);
new Supla::Html::HvacParameters(hvac);
//DeviceAddress ds1addr = {0x28, 0x97, 0xD7, 0x06, 0x0A, 0x00, 0x00, 0x46};
//new Supla::Sensor::DS18B20(DS18B20_GPIO, ds1addr);
// wirtualny termometr do testów
auto t1 = new Supla::Sensor::VirtualThermometer;
t1->setValue(20);
hvac->setMainThermometerChannelNo(1);
hvac->setTemperatureHisteresisMin(20);
hvac->setTemperatureHisteresisMax(100);
hvac->setTemperatureAuxMin(1700);
hvac->setTemperatureAuxMax(3000);
hvac->setTemperatureHisteresis(30);
auto buttonCfgRelay =
new Supla::Control::Button(BUTTON_CFG_RELAY_GPIO, true, true);
SuplaDevice.setSuplaCACert(suplaCACert);
SuplaDevice.setSupla3rdPartyCACert(supla3rdCACert);
// start w trybie parowania bez przycisku
SuplaDevice.allowWorkInOfflineMode(0);
SuplaDevice.setLeaveCfgModeAfterInactivityMin(0);
SuplaDevice.begin();
}
void loop() {
SuplaDevice.iterate();
if (millis() - zapamietany_czas >= opoznienie ) {
zapamietany_czas = millis();
message_content.relayState = digitalRead(OUTPUT_GPIO);
uint8_t result_send = esp_now_send((uint8_t*)broadcastAddress, (uint8_t*)&message_content, msg_size);
if (result_send == ERR_OK && delivery_error == false)
{
Serial.println("Dane wysłane i odebrane");
output_err->turnOff();
}
if (result_send != ERR_OK || delivery_error == true)
{
Serial.println("Błąd wysyłania lub odbierania danych");
output_err->turnOn();
}
}
}
Slave (z internetów nic oprócz czasu wyłączenia nie zmieniałem):
Code: Select all
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <espnow.h>
// Definicja pinów
#define LED_BUILTIN_GPIO 2 // Wbudowana dioda LED
#define RELAY_GPIO 5 //przekaźnik
// Struktura danych do odbierania
struct esp_now_message
{
bool relayState;
};
esp_now_message message_content;
unsigned long lastReceiveTime = 0; // Czas ostatniego odbioru danych
const unsigned long timeout = 30000; // Czas (ms) do automatycznego wyłączenia LED
void print_received_msg(uint8_t* mac, uint8_t* incoming_data, uint8_t len) {
memcpy(&message_content, incoming_data, sizeof(message_content));
Serial.print("Bytes received: ");
Serial.println(len);
Serial.print("value: ");
Serial.println(message_content.relayState);
// Włącz lub wyłącz diodę LED wbudowaną w Wemos D1 Mini
digitalWrite(LED_BUILTIN_GPIO, message_content.relayState ? LOW : HIGH);
digitalWrite(RELAY_GPIO, message_content.relayState ? HIGH : LOW);
// Aktualizacja czasu ostatniego odbioru
lastReceiveTime = millis();
}
void setup() {
Serial.begin(115200);
// Ustawienie pinu diody LED jako OUTPUT
pinMode(LED_BUILTIN_GPIO, OUTPUT);
pinMode(RELAY_GPIO, OUTPUT);
digitalWrite(LED_BUILTIN_GPIO, HIGH); // Wyłączona domyślnie
digitalWrite(RELAY_GPIO, LOW); // Przekaźnik domyślnie wyłączony
// Ustawienie trybu Wi-Fi na station mode
WiFi.mode(WIFI_STA);
if (esp_now_init() != ERR_OK)
{
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_recv_cb(print_received_msg);
}
void loop() {
// W tej wersji loop() jest puste, bo ESP-NOW działa w tle
// Sprawdź, czy minęło 10 sekund od ostatniego odebrania danych
if (millis() - lastReceiveTime > timeout) {
digitalWrite(LED_BUILTIN_GPIO, HIGH); // Wyłącz diodę LED
digitalWrite(RELAY_GPIO, LOW); // Wyłącz przekaźnik
}
}