mirror of
https://github.com/okalachev/flix.git
synced 2026-06-28 05:56:44 +00:00
Improve ESP-NOW connection
Implement auto-pairing. Make key optional. Remove re-sends. Add command for uploading proxy to makefile.
This commit is contained in:
@@ -18,6 +18,10 @@ dependencies .dependencies:
|
|||||||
arduino-cli lib install "MAVLink"@2.0.25
|
arduino-cli lib install "MAVLink"@2.0.25
|
||||||
touch .dependencies
|
touch .dependencies
|
||||||
|
|
||||||
|
upload_proxy: .dependencies
|
||||||
|
arduino-cli compile --fqbn $(BOARD) tools/espnow-proxy
|
||||||
|
arduino-cli upload --fqbn $(BOARD) -p "$(PORT)" tools/espnow-proxy
|
||||||
|
|
||||||
gazebo/build cmake: gazebo/CMakeLists.txt
|
gazebo/build cmake: gazebo/CMakeLists.txt
|
||||||
mkdir -p gazebo/build
|
mkdir -p gazebo/build
|
||||||
cd gazebo/build && cmake ..
|
cd gazebo/build && cmake ..
|
||||||
|
|||||||
+1
-1
@@ -46,7 +46,7 @@ const char* motd =
|
|||||||
"wifi - show Wi-Fi info\n"
|
"wifi - show Wi-Fi info\n"
|
||||||
"ap <ssid> <password> - setup Wi-Fi access point\n"
|
"ap <ssid> <password> - setup Wi-Fi access point\n"
|
||||||
"sta <ssid> <password> - setup Wi-Fi client mode\n"
|
"sta <ssid> <password> - setup Wi-Fi client mode\n"
|
||||||
"espnow <mac> - setup ESP-NOW peer\n"
|
"espnow <mac> [<key>] - setup ESP-NOW peer\n"
|
||||||
"mot - show motor output\n"
|
"mot - show motor output\n"
|
||||||
"log [dump] - print log header [and data]\n"
|
"log [dump] - print log header [and data]\n"
|
||||||
"cr - calibrate RC\n"
|
"cr - calibrate RC\n"
|
||||||
|
|||||||
+11
@@ -6,6 +6,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <ESP32_NOW_Serial.h>
|
||||||
|
|
||||||
const float ONE_G = 9.80665;
|
const float ONE_G = 9.80665;
|
||||||
extern float t;
|
extern float t;
|
||||||
@@ -46,6 +47,16 @@ void splitString(String& str, String& token0, String& token1, String& token2) {
|
|||||||
if (token2.c_str() == NULL) token2 = "";
|
if (token2.c_str() == NULL) token2 = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simplified ESP-NOW Serial without tx buffering and resends
|
||||||
|
class ESPNOWSerial : public ESP_NOW_Serial_Class {
|
||||||
|
public:
|
||||||
|
using ESP_NOW_Serial_Class::ESP_NOW_Serial_Class;
|
||||||
|
void onSent(bool success) override {} // disable resends
|
||||||
|
size_t write(const uint8_t *data, size_t len) override {
|
||||||
|
return ESP_NOW_Peer::send(data, len); // pure send without buffering
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Rate limiter
|
// Rate limiter
|
||||||
class Rate {
|
class Rate {
|
||||||
public:
|
public:
|
||||||
|
|||||||
+22
-7
@@ -9,19 +9,22 @@
|
|||||||
#include <MacAddress.h>
|
#include <MacAddress.h>
|
||||||
#include <ESP32_NOW_Serial.h>
|
#include <ESP32_NOW_Serial.h>
|
||||||
#include "Preferences.h"
|
#include "Preferences.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
extern Preferences storage; // use the main preferences storage
|
extern Preferences storage; // use the main preferences storage
|
||||||
|
|
||||||
const int W_DISABLED = 0, W_AP = 1, W_STA = 2, W_ESPNOW = 3;
|
const int W_DISABLED = 0, W_AP = 1, W_STA = 2, W_ESPNOW = 3;
|
||||||
int wifiMode = W_AP;
|
int wifiMode = W_AP;
|
||||||
|
|
||||||
int wifiLongRange = 0;
|
int wifiLongRange = 0;
|
||||||
int udpLocalPort = 14550;
|
int udpLocalPort = 14550;
|
||||||
int udpRemotePort = 14550;
|
int udpRemotePort = 14550;
|
||||||
int espnowChannel = 6;
|
|
||||||
IPAddress udpRemoteIP = "255.255.255.255";
|
IPAddress udpRemoteIP = "255.255.255.255";
|
||||||
|
|
||||||
WiFiUDP udp;
|
WiFiUDP udp;
|
||||||
ESP_NOW_Serial_Class espnow(NULL, 0, WIFI_IF_AP);
|
|
||||||
|
ESPNOWSerial espnow(NULL, 0, WIFI_IF_AP);
|
||||||
|
ESPNOWSerial espnowBroadcast(ESP_NOW.BROADCAST_ADDR, 0, WIFI_IF_AP);
|
||||||
|
int espnowChannel = 6;
|
||||||
|
|
||||||
void setupWiFi() {
|
void setupWiFi() {
|
||||||
print("Setup Wi-Fi\n");
|
print("Setup Wi-Fi\n");
|
||||||
@@ -37,8 +40,12 @@ void setupWiFi() {
|
|||||||
WiFi.mode(WIFI_AP);
|
WiFi.mode(WIFI_AP);
|
||||||
WiFi.setChannel(espnowChannel);
|
WiFi.setChannel(espnowChannel);
|
||||||
espnow.setChannel(espnowChannel);
|
espnow.setChannel(espnowChannel);
|
||||||
espnow.addr(MacAddress(storage.getString("ESPNOW_PEER_MAC", "").c_str()));
|
espnow.addr(MacAddress(storage.getString("ESPNOW_PEER_MAC", "FF:FF:FF:FF:FF:FF").c_str()));
|
||||||
|
String key = storage.getString("ESPNOW_PEER_KEY", "");
|
||||||
|
espnow.setKey(key.isEmpty() ? nullptr : (const uint8_t *)key.c_str());
|
||||||
espnow.begin();
|
espnow.begin();
|
||||||
|
espnowBroadcast.setChannel(espnowChannel);
|
||||||
|
espnowBroadcast.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
WiFi.setSleep(false); // disable power save
|
WiFi.setSleep(false); // disable power save
|
||||||
@@ -47,6 +54,8 @@ void setupWiFi() {
|
|||||||
void sendWiFi(const uint8_t *buf, int len) {
|
void sendWiFi(const uint8_t *buf, int len) {
|
||||||
if (espnow) {
|
if (espnow) {
|
||||||
espnow.write(buf, len);
|
espnow.write(buf, len);
|
||||||
|
static Rate discovery(2);
|
||||||
|
if (discovery) espnowBroadcast.write((const uint8_t *)"flix", 4); // broadcast message to help finding this device
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +85,7 @@ void printWiFiInfo() {
|
|||||||
print("Max packet size: %d\n", ESP_NOW.getMaxDataLen());
|
print("Max packet size: %d\n", ESP_NOW.getMaxDataLen());
|
||||||
print("MAC: %s\n", WiFi.softAPmacAddress().c_str());
|
print("MAC: %s\n", WiFi.softAPmacAddress().c_str());
|
||||||
print("Peer MAC: %s\n", MacAddress(espnow.addr()).toString().c_str());
|
print("Peer MAC: %s\n", MacAddress(espnow.addr()).toString().c_str());
|
||||||
|
print("Encrypted: %d\n", espnow.isEncrypted());
|
||||||
print("Channel: %d\n", espnow.getChannel());
|
print("Channel: %d\n", espnow.getChannel());
|
||||||
} else if (WiFi.getMode() == WIFI_MODE_AP) {
|
} else if (WiFi.getMode() == WIFI_MODE_AP) {
|
||||||
print("Mode: Access Point (AP)\n");
|
print("Mode: Access Point (AP)\n");
|
||||||
@@ -103,14 +113,19 @@ void printWiFiInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void configWiFi(int mode, const char *first, const char *second) {
|
void configWiFi(int mode, const char *first, const char *second) {
|
||||||
if (mode == W_AP) {
|
MacAddress mac;
|
||||||
|
if (mode == W_AP && strlen(first) > 0 && strlen(second) >= 8) {
|
||||||
storage.putString("WIFI_AP_SSID", first);
|
storage.putString("WIFI_AP_SSID", first);
|
||||||
storage.putString("WIFI_AP_PASS", second);
|
storage.putString("WIFI_AP_PASS", second);
|
||||||
} else if (mode == W_STA) {
|
} else if (mode == W_STA && strlen(first) > 0 && strlen(second) >= 8) {
|
||||||
storage.putString("WIFI_STA_SSID", first);
|
storage.putString("WIFI_STA_SSID", first);
|
||||||
storage.putString("WIFI_STA_PASS", second);
|
storage.putString("WIFI_STA_PASS", second);
|
||||||
} else if (mode == W_ESPNOW) {
|
} else if (mode == W_ESPNOW && mac.fromString(first)) {
|
||||||
storage.putString("ESPNOW_PEER_MAC", first);
|
storage.putString("ESPNOW_PEER_MAC", first);
|
||||||
|
storage.putString("ESPNOW_PEER_KEY", strlen(second) == ESP_NOW_KEY_LEN ? second : "");
|
||||||
|
} else {
|
||||||
|
print("Invalid configuration\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
print("✓ Reboot to apply new settings\n");
|
print("✓ Reboot to apply new settings\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,16 +7,25 @@
|
|||||||
#include <ESP32_NOW_Serial.h>
|
#include <ESP32_NOW_Serial.h>
|
||||||
#include <MacAddress.h>
|
#include <MacAddress.h>
|
||||||
#include <MAVLink.h>
|
#include <MAVLink.h>
|
||||||
|
#include <Preferences.h>
|
||||||
|
#include "../../flix/util.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
const int CHANNEL = 6;
|
const int CHANNEL = 6;
|
||||||
|
char key[ESP_NOW_KEY_LEN + 1] = {0}; // with trailing null
|
||||||
|
|
||||||
ESP_NOW_Serial_Class espnow(NULL, CHANNEL, WIFI_IF_AP);
|
Preferences storage;
|
||||||
MacAddress peerMac;
|
|
||||||
volatile bool peerFound = false;
|
std::vector<ESPNOWSerial *> peers;
|
||||||
|
|
||||||
void onNewPeer(const esp_now_recv_info_t *info, const uint8_t *data, int len, void *arg) {
|
void onNewPeer(const esp_now_recv_info_t *info, const uint8_t *data, int len, void *arg) {
|
||||||
peerMac = info->src_addr;
|
if (len != 4 || memcmp(data, "flix", 4) != 0) return; // check if discovery message
|
||||||
peerFound = true;
|
|
||||||
|
Serial.printf("New peer: " MACSTR "\n", MAC2STR(info->src_addr));
|
||||||
|
ESPNOWSerial *link = new ESPNOWSerial(info->src_addr, CHANNEL, WIFI_IF_AP);
|
||||||
|
link->begin();
|
||||||
|
link->setKey((const uint8_t *)key);
|
||||||
|
peers.push_back(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
@@ -25,22 +34,28 @@ void setup() {
|
|||||||
WiFi.setSleep(false);
|
WiFi.setSleep(false);
|
||||||
WiFi.setChannel(CHANNEL);
|
WiFi.setChannel(CHANNEL);
|
||||||
|
|
||||||
// while (!WiFi.AP.started()) {
|
|
||||||
// delay(100);
|
|
||||||
// }
|
|
||||||
|
|
||||||
ESP_NOW.onNewPeer(onNewPeer, NULL);
|
ESP_NOW.onNewPeer(onNewPeer, NULL);
|
||||||
ESP_NOW.begin();
|
ESP_NOW.begin();
|
||||||
|
|
||||||
while (!peerFound) {
|
storage.begin("espnow-proxy");
|
||||||
Serial.printf("MAC: %s, waiting for peer...\n", WiFi.softAPmacAddress().c_str());
|
if (!storage.isKey("key")) {
|
||||||
delay(1000);
|
generateRandomKey();
|
||||||
|
storage.putString("key", key);
|
||||||
}
|
}
|
||||||
Serial.printf("Peer found: %s\n", peerMac.toString().c_str());
|
strcpy(key, storage.getString("key").c_str());
|
||||||
|
|
||||||
espnow.addr(peerMac);
|
// Discover the first peer
|
||||||
espnow.setChannel(CHANNEL);
|
while (peers.empty()) {
|
||||||
espnow.begin();
|
Serial.printf("espnow %s %s\n", WiFi.softAPmacAddress().c_str(), key);
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateRandomKey() {
|
||||||
|
const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*-_+=";
|
||||||
|
for (int i = 0; i < ESP_NOW_KEY_LEN; i++) {
|
||||||
|
key[i] = chars[random(0, strlen(chars))];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
@@ -57,16 +72,17 @@ void loop() {
|
|||||||
mavlink_status_t status;
|
mavlink_status_t status;
|
||||||
if (mavlink_parse_char(MAVLINK_COMM_0, (uint8_t)b, &msg, &status)) {
|
if (mavlink_parse_char(MAVLINK_COMM_0, (uint8_t)b, &msg, &status)) {
|
||||||
int len = mavlink_msg_to_send_buffer(buf, &msg);
|
int len = mavlink_msg_to_send_buffer(buf, &msg);
|
||||||
// ESP_NOW.write(buf, len);
|
for (ESPNOWSerial *link : peers) {
|
||||||
espnow.write(buf, len);
|
link->write(buf, len);
|
||||||
// espnow.send(buf, len);
|
}
|
||||||
// esp_now_send(peerMac, buf, len);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send from ESP-NOW to serial
|
// Send from ESP-NOW to serial
|
||||||
int len = espnow.read(buf, sizeof(buf));
|
for (ESPNOWSerial *link : peers) {
|
||||||
if (len > 0) {
|
int len = link->read(buf, sizeof(buf));
|
||||||
Serial.write(buf, len);
|
if (len > 0) {
|
||||||
|
Serial.write(buf, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user