#include <Wire.h>
#include <U8g2lib.h>
#include <WiFi.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include "config.h"
#define SW_VERSION "v22"
// Exemple pour un écran SSD1306 I2C 128x64
// === OLED Reset + Init ===
#define OLED_RST 16
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, 15, 4);
HardwareSerial SerialGNSS(2);
const IPAddress remoteIP(10, 0, 0, 186);
const int remotePort = 5000;
WiFiUDP udp;
// === Affichage d’un message sur 3 lignes max ===
void oledMessage(const char* line1, const char* line2,const char* line3 = nullptr) {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
if (line1) u8g2.drawStr(0, 16, line1);
if (line2) u8g2.drawStr(0, 32, line2);
if (line3) u8g2.drawStr(0, 48, line3);
u8g2.sendBuffer();
}
void setupWiFiAndOTA(const char* hostname) {
WiFi.mode(WIFI_STA);
if (USE_STATIC_IP) {
WiFi.config(LOCAL_IP, GATEWAY_IP, SUBNET_IP, DNS_IP);
}
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connexion WiFi...");
oledMessage("WiFi Connexion...", WIFI_SSID, "");
while (WiFi.status() != WL_CONNECTED) {
delay(500); Serial.print(".");
}
Serial.println("\nConnecté! IP: " + WiFi.localIP().toString());
// Affiche l'adresse IP sur l'OLED
String ipStr = WiFi.localIP().toString();
oledMessage("WiFi OK", ipStr.c_str(), "");
// OTA Config
ArduinoOTA.setHostname(hostname);
ArduinoOTA.onStart([]() {
oledMessage("OTA", "Mise à jour...", " ");
Serial.println("Mise à jour OTA en cours...");
});
ArduinoOTA.onEnd([]() {
oledMessage("OTA", "Terminee"," ");
Serial.println("OTA terminée !");
});
ArduinoOTA.onError([](ota_error_t error) {
oledMessage("OTA ERREUR"," "," ");
});
ArduinoOTA.begin();
oledMessage("OTA", "Disponible"," ");
}
void setup() {
Serial.begin(115200);
SerialGNSS.begin(115200, SERIAL_8N1, 13, 17);
// OLED reset
pinMode(OLED_RST, OUTPUT);
digitalWrite(OLED_RST, HIGH); delay(1);
digitalWrite(OLED_RST, LOW); delay(10);
digitalWrite(OLED_RST, HIGH); delay(1);
// Initialisation OLED U8g2
u8g2.begin();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(0, 12, "SW Version:");
u8g2.drawStr(0, 28, SW_VERSION);
u8g2.sendBuffer();
delay(3000); // Affiche la version 2 secondes
setupWiFiAndOTA("esp32-emetteur");
// Affiche l'IP locale
String ipStr = WiFi.localIP().toString();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(0, 12, "Sender IP:");
u8g2.drawStr(0, 28, ipStr.c_str());
u8g2.sendBuffer();
delay(3000);
// Affiche la remoteIP
String remoteStr = remoteIP.toString();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(0, 12, "Remote IP:");
u8g2.drawStr(0, 28, remoteStr.c_str());
u8g2.sendBuffer();
delay(3000);
}
uint32_t trameCount = 0; // compteur global
void loop() {
ArduinoOTA.handle();
static uint8_t buffer[1024];
static size_t idx = 0;
static size_t expectedLength = 0;
static bool syncing = false;
static uint32_t lastOled = 0;
while (SerialGNSS.available()) {
uint8_t b = SerialGNSS.read();
if (!syncing) {
if (b == 0xD3) {
idx = 0;
buffer[idx++] = b;
syncing = true;
trameCount++; // Incrémente le compteur à chaque nouvelle trame
// Affiche le compteur sur l'OLED toutes les 4 secondes
if (millis() - lastOled > 4000) {
char line2[24];
snprintf(line2, sizeof(line2), "Trames: %lu", trameCount);
oledMessage("RTCM3 RX", line2, "");
lastOled = millis();
}
}
} else {
buffer[idx++] = b;
if (idx == 3) {
expectedLength = ((buffer[1] & 0x03) << 8) | buffer[2];
if (expectedLength > 1000) {
syncing = false;
idx = 0;
}
}
if (idx == expectedLength + 6) {
udp.beginPacket(remoteIP, remotePort);
udp.write(buffer, idx);
udp.endPacket();
syncing = false;
idx = 0;
}
}
}
delay(1); // Laisse du temps au WiFi/OTA
}