Преглед изворни кода

* ESP-NOW experiment with terminal-chat

Scott Powell пре 1 година
родитељ
комит
7bd7bfb14a

+ 20 - 0
examples/simple_secure_chat/main.cpp

@@ -7,9 +7,12 @@
   #include <SPIFFS.h>
 #endif
 
+#ifdef WRAPPER_CLASS
 #define RADIOLIB_STATIC_ONLY 1
 #include <RadioLib.h>
 #include <helpers/RadioLibWrappers.h>
+#endif
+
 #include <helpers/ArduinoHelpers.h>
 #include <helpers/StaticPoolPacketManager.h>
 #include <helpers/SimpleMeshTables.h>
@@ -263,7 +266,11 @@ protected:
 
 public:
 
+#ifdef WRAPPER_CLASS
   MyMesh(RadioLibWrapper& radio, mesh::RNG& rng, mesh::RTCClock& rtc, SimpleMeshTables& tables)
+#else
+  MyMesh(mesh::Radio& radio, mesh::RNG& rng, mesh::RTCClock& rtc, SimpleMeshTables& tables)
+#endif
      : BaseChatMesh(radio, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables)
   {
     // defaults
@@ -325,6 +332,8 @@ public:
     Serial.println("===== MeshCore Chat Terminal =====");
     Serial.println();
     Serial.printf("WELCOME  %s\n", _prefs.node_name);
+    mesh::Utils::printHex(Serial, self_id.pub_key, PUB_KEY_SIZE);
+    Serial.println();
     Serial.println("   (enter 'help' for basic commands)");
     Serial.println();
   }
@@ -513,7 +522,12 @@ public:
 
 StdRNG fast_rng;
 SimpleMeshTables tables;
+
+#ifdef WRAPPER_CLASS
 MyMesh the_mesh(*new WRAPPER_CLASS(radio, board), fast_rng, *new VolatileRTCClock(), tables);
+#else
+MyMesh the_mesh(radio, fast_rng, *new VolatileRTCClock(), tables);
+#endif
 
 void halt() {
   while (1) ;
@@ -526,7 +540,11 @@ void setup() {
 
   if (!radio_init()) { halt(); }
 
+#ifdef WRAPPER_CLASS
   fast_rng.begin(radio.random(0x7FFFFFFF));
+#else
+  fast_rng.begin(rand());
+#endif
 
 #if defined(NRF52_PLATFORM)
   InternalFS.begin();
@@ -538,12 +556,14 @@ void setup() {
   #error "need to define filesystem"
 #endif
 
+#ifdef WRAPPER_CLASS
   if (LORA_FREQ != the_mesh.getFreqPref()) {
     radio.setFrequency(the_mesh.getFreqPref());
   }
   if (LORA_TX_POWER != the_mesh.getTxPowerPref()) {
     radio.setOutputPower(the_mesh.getTxPowerPref());
   }
+#endif
 
   the_mesh.showWelcome();
 

+ 83 - 0
src/helpers/esp32/ESPNOWRadio.cpp

@@ -0,0 +1,83 @@
+#include "ESPNOWRadio.h"
+#include <esp_now.h>
+#include <WiFi.h>
+
+static uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+static esp_now_peer_info_t peerInfo;
+static bool is_send_complete = false;
+static esp_err_t last_send_result;
+static uint8_t rx_buf[256];
+static uint8_t last_rx_len = 0;
+
+// callback when data is sent
+static void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
+  is_send_complete = true;
+  ESPNOW_DEBUG_PRINTLN("Send Status: %d", (int)status);
+}
+
+static void OnDataRecv(const uint8_t *mac, const uint8_t *data, int len) {
+  ESPNOW_DEBUG_PRINTLN("Recv: len = %d", len);
+  memcpy(rx_buf, data, len);
+  last_rx_len = len;
+}
+
+void ESPNOWRadio::begin() {
+  // Set device as a Wi-Fi Station
+  WiFi.mode(WIFI_STA);
+
+  // Init ESP-NOW
+  if (esp_now_init() != ESP_OK) {
+    ESPNOW_DEBUG_PRINTLN("Error initializing ESP-NOW");
+    return;
+  }
+
+  esp_now_register_send_cb(OnDataSent);
+  esp_now_register_recv_cb(OnDataRecv);
+
+  // Register peer
+  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
+  peerInfo.channel = 0;
+  peerInfo.encrypt = false;
+
+  // Add peer        
+  if (esp_now_add_peer(&peerInfo) == ESP_OK) {
+    ESPNOW_DEBUG_PRINTLN("init success");
+  } else {
+   // ESPNOW_DEBUG_PRINTLN("Failed to add peer");
+  }
+}
+
+void ESPNOWRadio::startSendRaw(const uint8_t* bytes, int len) {
+  // Send message via ESP-NOW
+  is_send_complete = false;
+  esp_err_t result = esp_now_send(broadcastAddress, bytes, len);
+  if (result == ESP_OK) {
+    ESPNOW_DEBUG_PRINTLN("Send success");
+  } else {
+    last_send_result = result;
+    is_send_complete = true;
+    ESPNOW_DEBUG_PRINTLN("Send failed: %d", result);
+  }
+}
+
+bool ESPNOWRadio::isSendComplete() {
+  return is_send_complete;
+}
+void ESPNOWRadio::onSendFinished() {
+}
+
+float ESPNOWRadio::getLastRSSI() const { return 0; }
+float ESPNOWRadio::getLastSNR() const { return 0; }
+
+int ESPNOWRadio::recvRaw(uint8_t* bytes, int sz) {
+  int len = last_rx_len;
+  if (last_rx_len > 0) {
+    memcpy(bytes, rx_buf, last_rx_len);
+    last_rx_len = 0;
+  }
+  return len;
+}
+
+uint32_t ESPNOWRadio::getEstAirtimeFor(int len_bytes) {
+  return 100;  // TODO
+}

+ 34 - 0
src/helpers/esp32/ESPNOWRadio.h

@@ -0,0 +1,34 @@
+#pragma once
+
+#include <Mesh.h>
+
+class ESPNOWRadio : public mesh::Radio {
+protected:
+  uint32_t n_recv, n_sent;
+
+public:
+  ESPNOWRadio() { n_recv = n_sent = 0; }
+
+  void begin() override;
+  int recvRaw(uint8_t* bytes, int sz) override;
+  uint32_t getEstAirtimeFor(int len_bytes) override;
+  void startSendRaw(const uint8_t* bytes, int len) override;
+  bool isSendComplete() override;
+  void onSendFinished() override;
+
+  uint32_t getPacketsRecv() const { return n_recv; }
+  uint32_t getPacketsSent() const { return n_sent; }
+  virtual float getLastRSSI() const override;
+  virtual float getLastSNR() const override;
+
+  float packetScore(float snr, int packet_len) override { return 0; }
+};
+
+#if ESPNOW_DEBUG_LOGGING && ARDUINO
+  #include <Arduino.h>
+  #define ESPNOW_DEBUG_PRINT(F, ...) Serial.printf("ESP-Now: " F, ##__VA_ARGS__)
+  #define ESPNOW_DEBUG_PRINTLN(F, ...) Serial.printf("ESP-Now: " F "\n", ##__VA_ARGS__)
+#else
+  #define ESPNOW_DEBUG_PRINT(...) {}
+  #define ESPNOW_DEBUG_PRINTLN(...) {}
+#endif

+ 25 - 0
variants/espnow_c3/platformio.ini

@@ -0,0 +1,25 @@
+
+; ----------- Generic ESP32-C3 ------------
+
+[env:Generic_C3_ESPNOW_terminal_chat]
+extends = esp32_base
+;board = esp32-c3-devkitm-1
+board = esp32-s3-devkitc-1
+build_flags =
+  ${esp32_base.build_flags}
+  -I variants/espnow_c3
+  -D MAX_CONTACTS=100
+  -D MAX_GROUP_CHANNELS=1
+  -D ESPNOW_DEBUG_LOGGING=1
+;  -D P_LORA_TX_LED=8
+  -D P_LORA_TX_LED=35
+  -D PIN_USER_BTN=0
+;  -D MESH_PACKET_LOGGING=1
+;  -D MESH_DEBUG=1
+build_src_filter = ${esp32_base.build_src_filter}
+  +<../examples/simple_secure_chat/main.cpp>
+  +<helpers/esp32/ESPNowRadio.cpp>
+  +<../variants/espnow_c3>
+lib_deps =
+  ${esp32_base.lib_deps}
+  densaugeo/base64 @ ~1.4.0

+ 11 - 0
variants/espnow_c3/target.cpp

@@ -0,0 +1,11 @@
+#include <Arduino.h>
+#include "target.h"
+
+ESP32Board board;
+
+ESPNOWRadio radio;
+
+bool radio_init() {
+  radio.begin();
+  return true;  // success
+}

+ 9 - 0
variants/espnow_c3/target.h

@@ -0,0 +1,9 @@
+#pragma once
+
+#include <helpers/ESP32Board.h>
+#include <helpers/esp32/ESPNOWRadio.h>
+
+extern ESP32Board board;
+extern ESPNOWRadio radio;
+
+bool radio_init();