Table des matières:
2025 Auteur: John Day | [email protected]. Dernière modifié: 2025-01-13 06:57
Le sujet d'aujourd'hui concerne un test de distance avec un ESP32 avec antenne externe. Utilisons aujourd'hui deux modules: d'Espressif et TTGO. Vérifions ensuite le RSSI entre ces deux antennes ESP32, générons un graphique à partir de l'historique et écrivons un journal des valeurs dans un fichier.csv.
On a alors l'ESP32 Wrover en AP, et l'ESP32 de TTGO en Station. J'ai utilisé une antenne que j'ai prise sur un TP-Link légèrement plus grand et un autre routeur appelé antenne 9dbm. Je n'ai pas remarqué de différence entre les deux.
Enfin, les deux microcontrôleurs se connectent via socket et, à chaque envoi de paquets de données, nous imprimons sur un écran un graphique avec les barres qui indiquent le ratio de dbm.
Étape 1: montage du point d'accès avec Wrover
Étape 2: Assemblage de STATION avec TTGO
Étape 3: RÉSULTAT
Distance maximale avec 2x antennes externes: 315 mètres
Distance maximale avec antenne externe et interne: 157 mètres
Étape 4: Archiver LOG. CSV
J'ai enregistré les données sur une carte SD, avec des données en millis, dbm et la chaîne du package.
Étape 5: Bibliothèque Adafruit GFX
Dans l'IDE Arduino, allez dans Sketch-> Inclure la bibliothèque-> Gérer les bibliothèques…
Installer la bibliothèque Adafruit GFX
Étape 6: Bibliothèque Adafruit ST7735
Dans l'IDE Arduino, allez dans Sketch-> Inclure la bibliothèque-> Gérer les bibliothèques…
Installer Adafruit ST7735
Étape 7: Configuration des cartes
Restez à l'affût des différences:
Étape 8: AP.ino
Nous avons inclus les bibliothèques nécessaires et défini certains paramètres.
#include #include #include #include #include #include //Rede que o ESP criará. No Station deve ser igual #define SSID "RSSI_Test" #define PASSWORD "87654321" //Tempo de timeout para considerar a conexão pedida #define TIMEOUT 2000 //Largura e altura do display #define DISPLAY_WIDTH 160 #define DISPLAY_HEIGHT 128 //Configurações de cor, margem e tamanho do gráfico #define PLOT_COLOR ST77XX_GREEN #define PLOT_MARGIN 20 #define PLOT_SIZE (DISPLAY_HEIGHT - 2*PLOT_MARGIN) //Arquivo de log no SD #define FILE_PATH "/log.csv"
Nous définissons les broches, entre autres variables
//Les pinos affichent#define DISPLAY_DC 12 //A0 #define DISPLAY_CS 13 //CS #define DISPLAY_MOSI 14 //SDA #define DISPLAY_CLK 27 //SCK #define DISPLAY_RST 0 //Pino fait SDCard. Os pinos mosi, miso e sck são os nativos (23, 19 e 18 respectivement) #define SDCARD_CS 15 //Pixel onde o gráfico começa horizontalmente int currentX = PLOT_MARGIN; //Objeto responsável pelo display Adafruit_ST7735 display = Adafruit_ST7735(DISPLAY_CS, DISPLAY_DC, DISPLAY_MOSI, DISPLAY_CLK, DISPLAY_RST); //Criamos um server (qualquer porta válida serve contanto que o cliente use a mesma porta) WiFiServer server (80); //Variável para armazenar o cliente (pas de caso o ESP32 em modo station) conectado WiFiClient client; //Chaîne que recebemos do cliente Chaîne reçue; // RSSI enviado pelo cliente para este ESP32 long rssi = 0; //Faz o controle do temporizador (interrupção por tempo) hw_timer_t *timer = NULL; //Utilisé pour protéger les derniers std::vector rssiHistory;
Installer
void setup(){ Serial.begin(115200); setupAffichage(); //Inicializa o SD if (!SD.begin(SDCARD_CS)) { display.println("Erro ao inicializar lib SD!"); } //Cria un rede WiFi, inicializa o server e espera o cliente conectar setupWiFi(); serveur.begin(); waitForClient(); //Espera 3 segundos, limpa a tela e inicializa o Watchdog delay(3000); display.fillScreen(ST77XX_BLACK); display.setCursor(0, 0); setupWatchdog(); }
Configurer le Wi-Fi
//Cria um Access Point e configura o IPvoid setupWiFi() { display.println("Creating softAP " + String(SSID)); WiFi.disconnect(); WiFi.mode(WIFI_AP); WiFi.softAPConfig (adresse IP (192, 168, 0, 1), adresse IP (192, 168, 0, 1), adresse IP (255, 255, 255, 0)); WiFi.softAP (SSID, MOT DE PASSE); display.println("softAP " + String(SSID) + " créé !"); }
Affichage de configuration
//Initializa o display, muda a orientação e limpa a telavoid setupDisplay() { //Inicializa o display display.initR(INITR_BLACKTAB); //Rotaciona o conteúdo mostrado display.setRotation(3); //Pinta a tela de preto display.fillScreen(ST77XX_BLACK); }
attendreClient
void waitForClient(){ display.println("En attente du client"); //Aguarda o cliente conectar while(!(client = server.available())) { display.print("."); retard (500); } display.println("Client connecté"); //Tempo maximum que le client deve demorar pour le répondeur //antes de dizermos qu'un conexão foi perdida client.setTimeout(TIMEOUT); }
IRAM_ATTR resetModule et setupWatchdog
//função que o temporizador irá chamar, para reiniciar o ESP32void IRAM_ATTR resetModule(){ ets_printf("(watchdog) reiniciar\n"); esp_restart_noos(); //reinicia o chip } void setupWatchdog() { timer = timerBegin (0, 80, true); //timerID 0, div 80 //timer, callback, interruption de timerAttachInterrupt(timer, &resetModule, true); //timer, tempo (us), répétition timerAlarmWrite(timer, 10000000, true); timerAlarmEnable(timer); //capacité à interrompre }
Boucle
boucle vide() { timerWrite(timer, 0); //Reseta o temporizador (alimenta o watchdog) checkConnection(); // vérifier si vous pouvez vous connecter avec le client readFromClient(); //lê os dodos do cliente sendToClient(); //envia confirmação para o cliente plot(); //plus de graphique de l'historique de rssi log(); //salva um log no cartão SD }
vérifierConnexion
void checkConnection(){ //Se o cliente não estiver conectado if(!client.connected()) { //Limpa a tela e espera pelo cliente display.fillScreen(ST77XX_BLACK); display.println("Client déconnecté"); waitForClient(); } }
lireDeClient
void readFromClient(){ //Espera até o cliente enviar algo ou desconectar while(client.connected() && !client.available()) { delay(100); } //Se chegou aqui e ainda estiver conectado é porque possui algo para receber do cliente if(client.connected()) { receive = client.readStringUntil('\n'); //Lê o texto que o cliente enviou receive.remove(received.length()-1); //Supprimer o \n faire le rssi final = client.parseInt(); //Lê ou rssi que o cliente enviou clearText(); //Limpe ou texte display.setCursor(0, 0); // Déplacer le curseur vers le texte pour afficher display.println("RSSI: " + String(rssi)); //Mostra o RSSI pas d'affichage display.println("Reçu: " + reçu); //Mostra a mensagem recebida do cliente //Se a quantidade de barras do gráfico passou do limit apagamos o registro mais antigo if(rssiHistory.size() == (DISPLAY_WIDTH - 2*PLOT_MARGIN)/2) { rssiHistory.erase(rssiHistory.commencer()); } //Adiciona no final do histórico (mais recente) rssiHistory.push_back(rssi); } }
envoyerAuClient
void sendToClient(){ //Se o cliente estiver connecté enviamos de volta a mensagem com um OK if(client.connected()) { String envoi = reçu + " OK"; client.println(envoi); } }
terrain
void plot(){ //Coloca no ponto inicial e limpamos o gráfico currentX = PLOT_MARGIN; display.fillRect(PLOT_MARGIN, 2*PLOT_MARGIN, DISPLAY_WIDTH - 2*PLOT_MARGIN, DISPLAY_HEIGHT - 2*PLOT_MARGIN, ST77XX_BLACK); //Para cada valor do histórico fazemos o cálculo do tamanho da barra do gráfico, desenhamos e avançamos para o próximo for (int i = 0; i -120 ? map(rssiHistory, -120, 0, 0, PLOT_SIZE): 0; display.drawFastVLine(currentX, DISPLAY_HEIGHT - valeur, valeur, PLOT_COLOR); currentX += 2; } }
clearText et log
void clearText(){ //Limpa a area com o texto da mensagem vinda do cliente display.fillRect(0, 0, DISPLAY_WIDTH, 2*PLOT_MARGIN, ST77XX_BLACK); } void log() { //Abrimos ou arquivo para escrevermos no final dele File file = SD.open(FILE_PATH, FILE_APPEND); //Se não conseguimos ouvrir ou arquivo mostramos uma mensagem de erro if(!file) { Serial.println("Impossible d'ouvrir le fichier"); revenir; } //Gravamos uma linha com o tempo desde o boot, o rssi atual e a mensagem recebida String data = String(millis()) + ";" + Chaîne(rssi) + ";" + reçu; fichier.println(données); fichier.close(); }
Étape 9: Station.ino
Nous avons inclus les bibliothèques nécessaires et défini certains paramètres.
#include #include #include #include #include #include //Nome da rede que nos conectaremos. Criado pelo AP #define SSID "RSSI_Test" #define PASSWORD "87654321" #define HOST "192.168.0.1" //IP que foi configurado no setup do AP #define PORT 80 //Porta do sever. Qualquer porta válida contanto que seja igual nos dois arquivos //Tempo de timeout para considerar a conexão pedida #define TIMEOUT 2000 //Largura e altura do display #define DISPLAY_WIDTH 160 #define DISPLAY_HEIGHT 128 //Configurações de cor, margemáe tamanho do gr #define PLOT_COLOR ST77XX_GREEN #define PLOT_MARGIN 20 #define PLOT_SIZE (DISPLAY_HEIGHT - 2*PLOT_MARGIN) //Arquivo de log no SD #define FILE_PATH "/log.csv"
Nous définissons les paramètres qui impliquent l'affichage et la carte SD.
compte long = 0; //Contador de mensagens enviadaslong rssi = 0; //RSSI calculé Chaîne reçue; //Mensagem de confirmation que o AP nos envia //Pixel onde o gráfico começa horizontalmente int currentX = PLOT_MARGIN; //Utilisé pour connecter le serveur WiFiClient socket; #define DISPLAY_DC 12 //A0 #define DISPLAY_CS 13 //CS #define DISPLAY_MOSI 14 //SDA #define DISPLAY_CLK 27 //SCK #define DISPLAY_RST 0 //Pino do SDCard. Os pinos mosi, miso e sck são os nativos (23, 19 e 18 respectivement) #define SDCARD_CS 15 //Objeto responsável pelo display Adafruit_ST7735 display = Adafruit_ST7735(DISPLAY_CS, DISPLAY_DC, DISPLAY_MOSI, DISPLAY_CLRS); hw_timer_t *timer = NULL; //Faz o controle do temporizador (interrupção por tempo) //Utilizado para guardar os ultimos std::vector rssiHistory;
Installer
void setup(){ setupDisplay(); //Inicializa o SD if (!SD.begin(SDCARD_CS)) { display.println("Erro ao inicializar lib SD!"); } //Conecta pas de point d'accès criado pelo outtro ESP32 e conecta ao server setupWiFi(); connecter au serveur(); //Espera 3 segundos, limpa a tela e inicializa o Watchdog delay(3000); display.fillScreen(ST77XX_BLACK); display.setCursor(0, 0); setupWatchdog(); }
configurationAfficher
//Initializa o display, muda a orientação e limpa a telavoid setupDisplay() { //Inicializa o display display.initR(INITR_BLACKTAB); //Rotaciona o conteúdo mostrado display.setRotation(1); //Pinta a tela de branco display.fillScreen(ST77XX_BLACK); display.setTextColor(ST77XX_WHITE); }
configurationWiFi
//Conecta ao AP void setupWiFi() { WiFi.disconnect(); WiFi.mode(WIFI_STA); WiFi.begin (SSID, MOT DE PASSE); display.println("Connexion à " + Chaîne(SSID)); //Enquanto não estiver connecté à rede WiFi while (WiFi.status() != WL_CONNECTED) { delay(500); display.print("."); } display.println(""); display.print("Connecté à "); display.println(SSID); }
connecter au serveur
void connectToServer(){ display.println("Essayer la connexion socket"); //Espera une connexion avec le serveur while(!socket.connect(HOST, PORT)) { display.print("."); retard (500); } display.println(); display.println("Connecté!"); //Tempo maximum que le client deve demorar pour le répondeur //antes de dizermos qu'un conexão foi perdida socket.setTimeout(TIMEOUT); }
IRAM_ATTR resetModule et setupWatchdog
//função que o temporizador irá chamar, para reiniciar o ESP32void IRAM_ATTR resetModule(){ ets_printf("(watchdog) reiniciar\n"); esp_restart_noos(); //reinicia o chip } void setupWatchdog() { timer = timerBegin (0, 80, true); //timerID 0, div 80 //timer, callback, interruption de timerAttachInterrupt(timer, &resetModule, true); //timer, tempo (us), répétition timerAlarmWrite(timer, 10000000, true); timerAlarmEnable(timer); //capacité à interrompre }
boucle
boucle vide() { timerWrite(timer, 0); //Reseta o temporizador (alimenta o watchdog) checkConnection(); //vérifier la possibilité de connexion avec le serveur checkRSSI(); //vérification ou rssi plot(); //plus graphique de l'historique de rssi sendToServer(); //envia un mensagem avec un contador pour le serveur readFromServer(); //espera une confirmation du serveur log(); //salva um log no cartão SD delay(1000); //espera um segundo }
vérifierConnexion
void checkConnection(){ //Vérification d'une connexion avec AP if(WiFi.status() != WL_CONNECTED) { display.fillScreen(ST77XX_BLACK); display.setCursor(0, 0); display.println("WiFi déconnecté"); configurationWiFi(); retard(1000); } //vérifier une connexion avec socket if(!socket.connected()) { display.fillScreen(ST77XX_BLACK); display.setCursor(0, 0); display.println("Socket déconnecté"); connecter au serveur(); retard(3000); display.fillScreen(ST77XX_BLACK); } }
vérifierRSSI
void checkRSSI(){ //Vérification o RSSI rssi = WiFi. RSSI(); //Limpa o texto e mostra o RSSI pas d'affichage clearText(); display.setCursor(0, 0); display.print("RSSI: " + String(rssi)); //Se a quantidade de barras do graphique passou do limit apagamos o registro mais antigo if(rssiHistory.size() == (DISPLAY_WIDTH - 2*PLOT_MARGIN)/2) { rssiHistory.erase(rssiHistory.begin()); } //Adiciona no final do histórico (mais recente) rssiHistory.push_back(rssi); }
terrain
void plot(){ //Coloca no ponto inicial e limpamos o gráfico currentX = PLOT_MARGIN; display.fillRect(PLOT_MARGIN, 2*PLOT_MARGIN, DISPLAY_WIDTH - 2*PLOT_MARGIN, DISPLAY_HEIGHT - 2*PLOT_MARGIN, ST77XX_BLACK); //Para cada valor do histórico fazemos o cálculo do tamanho da barra do gráfico, desenhamos e avançamos para o próximo for (int i = 0; i -120 ? map(rssiHistory, -120, 0, 0, PLOT_SIZE): 0; display.drawFastVLine(currentX, DISPLAY_HEIGHT - valeur, valeur, PLOT_COLOR); currentX += 2; } }
envoyerVersServeur
void sendToServer(){ //Se connecter au serveur if(socket.connected()) { //Envia um hello com um contador, mostra no display e incrementa o contador Envoi de chaîne = "Bonjour " + String(count); display.setCursor(0, 10); display.println("Envoi: " + envoi); socket.println(envoi); socket.print(String(rssi)); compte++; } }
readFromServer
void readFromServer(){ //Espera até o server enviar algo ou desconectar while(socket.connected() && !socket.available()) { delay(100); } //Set algo para receber if(socket.available()) { //Faz a leitura, remove o \n do final e mostra no display receive = socket.readStringUntil('\n'); receive.remove(received.length()-1); display.println("Reçu: " + reçu); } }
clearText et log
void clearText(){ //Limpa a area com o texto da mensagem vinda do cliente display.fillRect(0, 0, DISPLAY_WIDTH, 2*PLOT_MARGIN, ST77XX_BLACK); } void log() { //Abrimos ou arquivo para escrevermos no final dele File file = SD.open(FILE_PATH, FILE_APPEND); //Se não conseguimos ouvrir ou arquivo mostramos uma mensagem de erro if(!file) { Serial.println("Impossible d'ouvrir le fichier"); revenir; } //Gravamos uma linha com o tempo desde o boot, o rssi atual e a mensagem recebida String data = String(millis()) + ";" + Chaîne(rssi) + ";" + reçu; fichier.println(données); fichier.close(); }
Étape 10: Fichiers
Téléchargez les fichiers:
INO