Added Reconnecting ability

This commit is contained in:
simon 2024-12-28 19:52:54 +01:00
parent 10d6898e43
commit 5a6b2d4e0e
2 changed files with 137 additions and 10 deletions

View File

@ -15,10 +15,18 @@ flash1:
sudo chmod o+rw /dev/ttyUSB1 sudo chmod o+rw /dev/ttyUSB1
idf.py flash -p /dev/ttyUSB1 idf.py flash -p /dev/ttyUSB1
flash2:
sudo chmod o+rw /dev/ttyUSB2
idf.py flash -p /dev/ttyUSB2
monitor0: monitor0:
sudo chmod o+rw /dev/ttyUSB0 sudo chmod o+rw /dev/ttyUSB0
idf.py monitor -p /dev/ttyUSB0 idf.py monitor -p /dev/ttyUSB0
monitor1: monitor1:
sudo chmod o+rw /dev/ttyUSB0 sudo chmod o+rw /dev/ttyUSB1
idf.py monitor -p /dev/ttyUSB1 idf.py monitor -p /dev/ttyUSB1
monitor2:
sudo chmod o+rw /dev/ttyUSB2
idf.py monitor -p /dev/ttyUSB2

View File

@ -17,6 +17,7 @@
#include <freertos/task.h> #include <freertos/task.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include "main.h" #include "main.h"
@ -28,6 +29,9 @@
#define TXD_PIN (GPIO_NUM_17) #define TXD_PIN (GPIO_NUM_17)
#define RXD_PIN (GPIO_NUM_16) #define RXD_PIN (GPIO_NUM_16)
#define CLIENT_TIMEOUT_MS 5000 // 5 Sekunden Timeout
#define CHECK_INTERVAL_MS 1000 // Jede Sekunde überprüfen
uint8_t broadcast_address[ESP_NOW_ETH_ALEN] = {0xFF, 0xFF, 0xFF, uint8_t broadcast_address[ESP_NOW_ETH_ALEN] = {0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF}; 0xFF, 0xFF, 0xFF};
#define IS_BROADCAST_ADDR(addr) \ #define IS_BROADCAST_ADDR(addr) \
@ -37,6 +41,7 @@ typedef enum {
BroadCastPage, BroadCastPage,
StatusPage, StatusPage,
PingPage, PingPage,
RegisterPage,
} CommandPages; } CommandPages;
typedef struct { typedef struct {
@ -51,10 +56,15 @@ typedef struct {
typedef struct { typedef struct {
} BroadCastPayload; } BroadCastPayload;
typedef struct {
bool familierClient;
} RegisterPayload;
typedef union { typedef union {
StatusPayload status_payload; StatusPayload status_payload;
PingPayload ping_payload; PingPayload ping_payload;
BroadCastPayload broadcast_payload; BroadCastPayload broadcast_payload;
RegisterPayload register_payload;
} PayloadUnion; } PayloadUnion;
typedef struct { typedef struct {
@ -74,12 +84,25 @@ typedef struct {
uint8_t macAddr[ESP_NOW_ETH_ALEN]; uint8_t macAddr[ESP_NOW_ETH_ALEN];
int rssi; int rssi;
bool isAvailable; bool isAvailable;
TickType_t lastSuccessfullPing;
} ClientInfo; } ClientInfo;
ClientInfo clients[19]; #define MAX_CLIENTS 19
ClientInfo clients[MAX_CLIENTS];
size_t numClients = 0; size_t numClients = 0;
size_t activeClients = 0;
bool hasMaster = false; bool hasMaster = false;
// return any inactive client field for new usage
int getNextFreeClientId() {
for (int i = 0; i < numClients; i++) {
if (!clients[i].isAvailable) {
return i;
}
}
return 0;
}
void add_peer(uint8_t *macAddr) { void add_peer(uint8_t *macAddr) {
esp_now_peer_info_t peerInfo = { esp_now_peer_info_t peerInfo = {
.channel = .channel =
@ -93,15 +116,44 @@ void add_peer(uint8_t *macAddr) {
if (result == ESP_OK) { if (result == ESP_OK) {
ESP_LOGI(TAG, "Peer added: %02X:%02X:%02X:%02X:%02X:%02X", macAddr[0], ESP_LOGI(TAG, "Peer added: %02X:%02X:%02X:%02X:%02X:%02X", macAddr[0],
macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]); macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
if (!IS_BROADCAST_ADDR(macAddr)) {
if (numClients >= MAX_CLIENTS) {
ESP_LOGW(TAG, "Cannot add more clients, maximum reached.");
return;
}
ClientInfo newClient = {}; ClientInfo newClient = {};
memcpy(newClient.macAddr, macAddr, ESP_NOW_ETH_ALEN); memcpy(newClient.macAddr, macAddr, ESP_NOW_ETH_ALEN);
newClient.isAvailable = true; newClient.isAvailable = true;
clients[numClients++] = newClient; newClient.lastSuccessfullPing = xTaskGetTickCount();
clients[getNextFreeClientId()] = newClient;
ESP_LOGI(TAG, "New client added.");
}
} else if (result == ESP_ERR_ESPNOW_EXIST) {
ESP_LOGW(TAG, "Peer already exists.");
// Überprüfen, ob der Client bereits existiert
for (int i = 0; i < numClients; i++) {
if (memcmp(clients[i].macAddr, macAddr, ESP_NOW_ETH_ALEN) == 0) {
ESP_LOGI(TAG, "Client found again, welcome back!");
clients[i].isAvailable = true; // Reaktiviere den Client
break;
}
}
} else { } else {
ESP_LOGE(TAG, "Failed to add peer: %s", esp_err_to_name(result)); ESP_LOGE(TAG, "Failed to add peer: %s", esp_err_to_name(result));
} }
} }
// UNSAFE ACCROSS THREADS BUT EZ TO USE
const char *MACtoString(uint8_t *macAddr) {
static char output[18]; // 17 Zeichen + 1 für Nullterminierung
sprintf(output, "%02X:%02X:%02X:%02X:%02X:%02X", macAddr[0], macAddr[1],
macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
return output;
}
BaseMessage MessageBuilder(CommandPages commandPage, PayloadUnion payload, BaseMessage MessageBuilder(CommandPages commandPage, PayloadUnion payload,
size_t payload_size) { size_t payload_size) {
BaseMessage message; BaseMessage message;
@ -134,7 +186,7 @@ void master_broadcast_task(void *param) {
void master_ping_task(void *param) { void master_ping_task(void *param) {
while (1) { while (1) {
for (size_t i = 0; i < numClients; ++i) { for (size_t i = 0; i < MAX_CLIENTS; ++i) {
if (clients[i].isAvailable) { if (clients[i].isAvailable) {
PingPayload payload = {}; PingPayload payload = {};
payload.timestamp = esp_timer_get_time(); payload.timestamp = esp_timer_get_time();
@ -167,15 +219,43 @@ void master_receive_callback(const esp_now_recv_info_t *esp_now_info,
ESP_LOGI(TAG, "Start: %lu, End: %lu, Diff: %lu, Ping: %lu", ESP_LOGI(TAG, "Start: %lu, End: %lu, Diff: %lu, Ping: %lu",
message->payload.ping_payload.timestamp, currentTime, diff, message->payload.ping_payload.timestamp, currentTime, diff,
diff / 1000); // ping in ms diff / 1000); // ping in ms
for (int i = 0; i < 20; i++) {
// Überprüfen, ob der Client existiert und die MAC-Adresse übereinstimmt
if (clients[i].isAvailable &&
memcmp(clients[i].macAddr, esp_now_info->src_addr,
ESP_NOW_ETH_ALEN) == 0) {
clients[i].lastSuccessfullPing = xTaskGetTickCount();
ESP_LOGI(TAG, "Updated client %d last ping time to %lu", i,
clients[i].lastSuccessfullPing);
break;
}
}
break; break;
case BroadCastPage: case BroadCastPage:
ESP_LOGI(TAG, "WILL REGISTER NEW DEVICE"); ESP_LOGI(TAG, "MASTER SHOULD NOT GET BROADCAST MESSAGE, is there another "
"master calling?");
break;
case RegisterPage:
ESP_LOGI(TAG, "WILL REGISTER DEVICE");
esp_now_peer_info_t checkPeerInfo; esp_now_peer_info_t checkPeerInfo;
esp_err_t checkPeer = esp_err_t checkPeer =
esp_now_get_peer(esp_now_info->src_addr, &checkPeerInfo); esp_now_get_peer(esp_now_info->src_addr, &checkPeerInfo);
switch (checkPeer) { switch (checkPeer) {
case (ESP_OK): case (ESP_OK):
ESP_LOGI(TAG, "CLIENT BEKANNT"); ESP_LOGI(TAG, "CLIENT BEKANNT");
for (int i = 0; i < 20; i++) {
// client in liste wiederfinden
if (!clients[i].isAvailable &&
memcmp(clients[i].macAddr, esp_now_info->src_addr,
ESP_NOW_ETH_ALEN) == 0) {
clients[i].isAvailable = true;
clients[i].lastSuccessfullPing = xTaskGetTickCount();
ESP_LOGI(TAG, "Updated client %d last ping time to %lu", i,
clients[i].lastSuccessfullPing);
break;
}
}
break; break;
case (ESP_ERR_ESPNOW_NOT_INIT): case (ESP_ERR_ESPNOW_NOT_INIT):
ESP_LOGI(TAG, "Not initalised"); ESP_LOGI(TAG, "Not initalised");
@ -190,6 +270,7 @@ void master_receive_callback(const esp_now_recv_info_t *esp_now_info,
default: default:
ESP_LOGI(TAG, "Unknown Message %i", checkPeer); ESP_LOGI(TAG, "Unknown Message %i", checkPeer);
} }
break; break;
default: default:
break; break;
@ -226,12 +307,18 @@ void client_receive_callback(const esp_now_recv_info_t *esp_now_info,
ESP_LOGI(TAG, ESP_LOGI(TAG,
"GOT BROADCAST MESSAGE ATTEMPTING TO REGISTER TO MASTER!"); "GOT BROADCAST MESSAGE ATTEMPTING TO REGISTER TO MASTER!");
add_peer(esp_now_info->src_addr); add_peer(esp_now_info->src_addr);
uint8_t data[] = "REGISTER ME DADDY"; replyMessage =
esp_now_send(esp_now_info->src_addr, data, strlen((const char *)data)); MessageBuilder(RegisterPage, *(PayloadUnion *)&message->payload,
sizeof(message->payload));
ESP_ERROR_CHECK(esp_now_send(esp_now_info->src_addr,
(uint8_t *)&replyMessage,
sizeof(BaseMessage)));
hasMaster = true; hasMaster = true;
} }
} }
break; break;
case RegisterPage:
break;
default: default:
ESP_LOGI(TAG, "GOT UNKONW MESSAGE"); ESP_LOGI(TAG, "GOT UNKONW MESSAGE");
break; break;
@ -248,6 +335,37 @@ void client_data_sending_task(void *param) {
} }
} }
void client_monitor_task(void *pvParameters) {
TickType_t timeout_ticks =
pdMS_TO_TICKS(CLIENT_TIMEOUT_MS); // Timeout in Ticks
TickType_t interval_ticks =
pdMS_TO_TICKS(CHECK_INTERVAL_MS); // Prüfintervall in Ticks
while (1) {
TickType_t now = xTaskGetTickCount(); // Aktuelle Zeit in Ticks
for (int i = 0; i < 20; i++) {
if (clients[i].isAvailable) {
TickType_t time_diff = now - clients[i].lastSuccessfullPing;
// Prüfen, ob der Client als "nicht verfügbar" markiert werden soll
if (time_diff > timeout_ticks) {
clients[i].isAvailable = false;
ESP_LOGW(
TAG,
"Client %d (MAC: %02X:%02X:%02X:%02X:%02X:%02X) is unavailable",
i, clients[i].macAddr[0], clients[i].macAddr[1],
clients[i].macAddr[2], clients[i].macAddr[3],
clients[i].macAddr[4], clients[i].macAddr[5]);
}
}
}
// Task für das Prüfintervall anhalten
vTaskDelay(interval_ticks);
}
}
void uart_read_task(void *param) { void uart_read_task(void *param) {
uint8_t *data = (uint8_t *)malloc(BUF_SIZE); uint8_t *data = (uint8_t *)malloc(BUF_SIZE);
int len = 0; int len = 0;
@ -323,6 +441,7 @@ void app_main(void) {
add_peer(broadcast_address); add_peer(broadcast_address);
xTaskCreate(master_broadcast_task, "MasterBroadcast", 4096, NULL, 1, NULL); xTaskCreate(master_broadcast_task, "MasterBroadcast", 4096, NULL, 1, NULL);
xTaskCreate(master_ping_task, "MasterPing", 4096, NULL, 1, NULL); xTaskCreate(master_ping_task, "MasterPing", 4096, NULL, 1, NULL);
xTaskCreate(client_monitor_task, "MonitorClientTask", 4096, NULL, 1, NULL);
init_uart(); init_uart();
} else { } else {
ESP_LOGI(TAG, "Started in Slavemode"); ESP_LOGI(TAG, "Started in Slavemode");