#include <SPI.h> // Uniquement la bibliothèque SPI standard
#include <ESP32Servo.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// Initialisation de l'OLED sur l'adresse 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
#define LORA_NSS 7
#define LORA_RST 1
#define LORA_BUSY 2
#define LORA_DIO1 3 // Pin d'interruption connectée à DIO1 du SX1262
#define LORA_SCK 4
#define LORA_MISO 5
#define LORA_MOSI 6
Servo servo1;
Servo servo2;
const int servo1Pin = 18; // Pin PWM
const int servo2Pin = 19; // Pin PWM
volatile bool messageRecu = false;
// Fonction appelée immédiatement quand DIO1 monte
void IRAM_ATTR handleLoraInterrupt() {
messageRecu = true;
}
void setup() {
// Initialisation de l'I2C avec les pins de l'ESP32-C3
Wire.begin(8, 9);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(INVERSE);
display.setCursor(0, 10);
display.println("LoRa System Ready");
display.display();
Serial.begin(115200);
while(!Serial) delay(10);
// 1. Force la pin en PULLDOWN pour éviter les signaux flottants
pinMode(LORA_DIO1, INPUT_PULLDOWN);
// 2. Un petit délai pour laisser la pin se stabiliser
delay(100);
// 3. Attache l'interruption (syntaxe recommandée)
attachInterrupt(LORA_DIO1, handleLoraInterrupt, RISING);
// ... le reste de ton code (SPI, Servos) ...
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_NSS);
// Initialisation des servos
ESP32PWM::allocateTimer(0);
servo1.setPeriodHertz(50);
servo1.attach(servo1Pin, 500, 2400);
servo2.setPeriodHertz(50);
servo2.attach(servo2Pin, 500, 2400);
Serial.println("Systeme pret et interruptions configurees.");
}
void loop() {
// Sécurité : Si l'interruption a échoué mais que la pin est HAUTE
if (digitalRead(LORA_DIO1) == HIGH) {
messageRecu = true;
}
if (messageRecu) {
messageRecu = false;
// Paramètres SPI sécurisés
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
waitIfBusy();
digitalWrite(LORA_NSS, LOW);
delayMicroseconds(100);
// Séquence de lecture robuste
SPI.transfer(0x00); // Réveil de la puce
uint8_t cmd = SPI.transfer(0x00); // Lecture de la commande
waitIfBusy();
digitalWrite(LORA_NSS, HIGH);
SPI.endTransaction();
// Filtrage des commandes valides
if (cmd >= 0x01 && cmd <= 0x03) {
Serial.print(">>> Commande LoRa valide détectée : 0x0");
Serial.println(cmd, HEX);
if (cmd == 0x01) {
Serial.println("Action : V1-OUVERT / V2-FERME");
servo1.write(0);
servo2.write(0);
}
else if (cmd == 0x02) {
Serial.println("Action : V1-FERME / V2-OUVERT");
servo1.write(180);
servo2.write(360);
}
else if (cmd == 0x03) {
display.clearDisplay();
display.println("SECURITE - TOUT FERME");
display.display();
Serial.println("Action : SECURITE - TOUT FERME");
servo1.write(0);
servo2.write(0);
}
// On attend que les servos finissent leur course avant de réécouter
delay(2000);
}
}
}
void waitIfBusy() {
while (digitalRead(LORA_BUSY) == HIGH) {
delay(1); // On attend que la puce soit prête
}
}