Schéma de câblage récepteur :
Programme récepteur :
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <LoRa.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
const int buttonPE1 = 7; // BP PE1
const int buttonPE2 = 4; // BP PE2
int tempLabels1[] = {2,4,6,8};
int tempLabels2[] = {2,4,6,8};
int mesures1[72]; // les 32 dernieres mesures
int mesures2[72]; // les 32 dernieres mesures
int compteur1 = 0; // nombre de mesures prises jusqu'à présent
int compteur2 = 0; // nombre de mesures prises jusqu'à présent
unsigned long previousAutoSendPE1 = 0;
unsigned long previousPacketTime1 = 0;
const long autoSendIntervalPE1 = 43000;
const long retryInterval1 = 20000;
bool packetReceived1 = false;
unsigned long previousAutoSendPE2 = 0;
unsigned long previousPacketTime2 = 0;
const long autoSendIntervalPE2 = 107000;
const long retryInterval2 = 20000;
bool packetReceived2 = false;
unsigned long systemStartTime;
float temp_float1;
float temp_float2;
void setup() {
Serial.begin(9600);
pinMode(buttonPE2, INPUT_PULLUP);
pinMode(buttonPE1, INPUT_PULLUP);
if (!LoRa.begin(433E6)) {
Serial.println("Initialisation LoRa échouée.");
while (1);
}
LoRa.setTxPower(20);
delay (300);
Affichage ();
}
void loop() {
unsigned long currentMillis = millis();
//Si le LORA recoit un packet
if (LoRa.parsePacket()) {
String receivedData = LoRa.readString();
Serial.println("Recu :");
Serial.print(receivedData);
//DEBUT GESTION GRAPHIQUE COMBE**************************************************
if (receivedData.startsWith("RPE1:")) {
tcaselect(0);
String temp_extrait2 = receivedData.substring(6,11);
temp_float2 = temp_extrait2.toFloat();
packetReceived1 = true;
previousPacketTime1 = currentMillis;
Serial.println(temp_extrait2);
Serial.println("Conversion en float " + temp_extrait2);
display2.fillRect(75, 0, 25, 10, BLACK);
display2.setTextSize(0);
display2.setTextColor(WHITE);
display2.setCursor(75,0);
display2.println(temp_float2);
display2.display();
int nouvelleValeur2 = map(temp_float2 * 100, 800, 0, 16, 70);
if (compteur2 > 71) {
// l'écran est déjà rempli: on fait glisser le graphique vers la gauche
for (int i = 0; i < 71; i++) {
mesures2[i] = mesures2[i + 1];
}
mesures2[71] = nouvelleValeur2;
display2.clearDisplay();
//tracé de la courbe
for (int i = 1; i <= 71; i++) {
display2.drawLine(5.5+1.75 * (i - 1), mesures2[i - 1], 5.5+1.75 * i, mesures2[i], WHITE);
}
display2.setTextSize(0);
display2.setTextColor(WHITE);
display2.setCursor(32,0);
display2.println("COMBE:");
display2.display();
//Réaffichez les graduations le long de l'axe Y
for (int i = 0; i < 4; i++) {
int y = map(tempLabels2[i], 8, 0, 16, 70);
display2.setTextSize(1);
display2.setTextColor(WHITE);
display2.setCursor(0, y);
display2.print(tempLabels2[i]);
display2.display();
}
Trait3();
Trait4();
display2.setTextSize(0);
display2.setTextColor(WHITE);
display2.setCursor(75,0);
display2.println(temp_float2);
display2.display();
}
if ((compteur2 > 0) && (compteur2 <= 71)) {
// pas assez de mesures pour remplir tout l'écran: on ajoute notre nouvelle valeur
// au graphique déjà visible à l'écran
mesures2[compteur2] = nouvelleValeur2;
// on trace une droite reliant la mesure précédente à notre nouvelle mesure
display2.drawLine(5.5+1.75 * (compteur2 - 1), mesures2[compteur2 - 1],5.5+1.75 * compteur2, mesures2[compteur2], WHITE);
compteur2 = compteur2 + 1;
}
else if (compteur2 == 0) {
// c'est la première mesure: on la met en variable,
// mais on ne trace rien à l'écran, sauf le quadrillage
mesures2[0] = nouvelleValeur2;
compteur2 = compteur2 + 1;
}
}
//FIN GESTION GRAPHIQUE COMBE**************************************************
//DEBUT GESTION GRAPHIQUE GU SUD **************************************************
if (receivedData.startsWith("RPE2:")) {
tcaselect(1);
String temp_extrait1 = receivedData.substring(6,11);
temp_float1 = temp_extrait1.toFloat();
packetReceived2 = true;
previousPacketTime2 = currentMillis;
Serial.println(temp_extrait1);
Serial.println("Conversion en float " + temp_extrait1);
Serial.println(" ");
display1.fillRect(75, 0, 25, 10, BLACK);
display1.setTextSize(0);
display1.setTextColor(WHITE);
display1.setCursor(75,0);
display1.println(temp_float1);
display1.display();
int nouvelleValeur1 = map(temp_float1 * 100, 800, 0, 16, 70);
if (compteur1 > 71) {
// l'écran est déjà rempli: on fait glisser le graphique vers la gauche
for (int i = 0; i < 71; i++) {
mesures1[i] = mesures1[i + 1];
}
mesures1[71] = nouvelleValeur1;
display1.clearDisplay();
//tracé de la courbe
for (int i = 1; i <= 71; i++) {
display1.drawLine(5.5+1.75 * (i - 1), mesures1[i - 1], 5.5+1.75 * i, mesures1[i], WHITE);
}
display1.setTextSize(0);
display1.setTextColor(WHITE);
display1.setCursor(32,0);
display1.println("GU SUD:");
display1.display();
// Réaffichez les graduations le long de l'axe Y
for (int i = 0; i < 4; i++) {
int y = map(tempLabels1[i], 8, 0, 16, 70);
display1.setTextSize(1);
display1.setTextColor(WHITE);
display1.setCursor(0, y);
display1.print(tempLabels1[i]);
display1.display();
}
Trait1();
Trait2();
display1.setTextSize(0);
display1.setTextColor(WHITE);
display1.setCursor(75,0);
display1.println(temp_float1);
display1.display();
}
if ((compteur1 > 0) && (compteur1 <= 71)) {
// pas assez de mesures pour remplir tout l'écran: on ajoute notre nouvelle valeur
// au graphique déjà visible à l'écran
mesures1[compteur1] = nouvelleValeur1;
// on trace une droite reliant la mesure précédente à notre nouvelle mesure
display1.drawLine(5.5+1.75 * (compteur1 - 1), mesures1[compteur1 - 1],5.5+1.75 * compteur1, mesures1[compteur1], WHITE);
compteur1 = compteur1 + 1;
}
else if (compteur1 == 0) {
// c'est la première mesure: on la met en variable,
// mais on ne trace rien à l'écran, sauf le quadrillage
mesures1[0] = nouvelleValeur1;
compteur1 = compteur1 + 1;
}
}
//DEBUT GESTION GRAPHIQUE GU SUD **************************************************
}
//Envoie de PETOP1 avec le BP en pin 7
if (digitalRead(buttonPE1) == LOW) {
PE1();
}
//Envoie de PETOP2 avec le BP en pin 7
if (digitalRead(buttonPE2) == LOW) {
PE2();
}
// Envoi automatique PE1
if (currentMillis - previousAutoSendPE1 >= autoSendIntervalPE1) {
PE1();
previousAutoSendPE1 = currentMillis; // Met à jour le dernier temps d'envoi automatique
}
// Relancer la demande PETOP2 si aucun paquet n'est reçu après 20 secondes
if (!packetReceived1 && (currentMillis - previousPacketTime1 >= retryInterval1)&& (millis() - systemStartTime >= 43000)) {
PE1();
previousPacketTime1 = currentMillis;
}
// Envoi automatique PE2
if (currentMillis - previousAutoSendPE2 >= autoSendIntervalPE2) {
Serial.println(" ");
PE2();
previousAutoSendPE2 = currentMillis; // Met à jour le dernier temps d'envoi automatique
}
// Relancer la demande PETOP2 si aucun paquet n'est reçu après 20 secondes
if (!packetReceived2 && (currentMillis - previousPacketTime2 >= retryInterval2)&& (millis() - systemStartTime >= 107000)) {
PE2();
previousPacketTime2 = currentMillis;
}
LoRa.begin(433E6);
}
void PE1() {
//delay(200);
LoRa.beginPacket();
LoRa.print("PETOP1");
LoRa.endPacket();
delay(100);
Serial.println("PETOP1 envoyé !");
}
void PE2() {
//delay(200);
LoRa.beginPacket();
LoRa.print("PETOP2");
LoRa.endPacket();
delay(100);
Serial.println("PETOP2 envoyé !");
}
void Trait1 () {
// Définir les coordonnées de début et de fin du trait
int x1 = 10;
int y1 = 15;
int x2 = 128;
int y2 = 15;
// Dessiner le trait pointillé
for (int i = x1; i <= x2; i += 5) {
if ((i / 5) % 2 == 0) { // Alterner les segments de ligne pour créer l'effet pointillé
display1.drawLine(i, y1, min(i + 5, x2), y2, WHITE);
}
}
}
void Trait2 () {
// Définir les coordonnées de début et de fin du trait
int x1 = 10;
int y1 = 58;
int x2 = 128;
int y2 = 58;
// Dessiner le trait pointillé
for (int i = x1; i <= x2; i += 5) {
if ((i / 5) % 2 == 0) { // Alterner les segments de ligne pour créer l'effet pointillé
display1.drawLine(i, y1, min(i + 5, x2), y2, WHITE);
}
}
}
void Trait3 () {
// Définir les coordonnées de début et de fin du trait
int x1 = 10;
int y1 = 15;
int x2 = 128;
int y2 = 15;
// Dessiner le trait pointillé
for (int i = x1; i <= x2; i += 5) {
if ((i / 5) % 2 == 0) { // Alterner les segments de ligne pour créer l'effet pointillé
display2.drawLine(i, y1, min(i + 5, x2), y2, WHITE);
}
}
}
void Trait4 () {
// Définir les coordonnées de début et de fin du trait
int x1 = 10;
int y1 = 58;
int x2 = 128;
int y2 = 58;
// Dessiner le trait pointillé
for (int i = x1; i <= x2; i += 5) {
if ((i / 5) % 2 == 0) { // Alterner les segments de ligne pour créer l'effet pointillé
display2.drawLine(i, y1, min(i + 5, x2), y2, WHITE);
}
}
}
//Changement de chanel
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(0x70);
Wire.write(1 << i);
Wire.endTransmission();
Serial.println(i);
}
void Affichage () {
tcaselect(0);
display2.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display2.clearDisplay();
Trait3();
Trait4();
display2.setTextSize(0);
display2.setTextColor(WHITE);
display2.setCursor(32,0);
display2.println("COMBE:");
display2.display();
// GRADUATION GU SUD
for (int i = 0; i < 4; i++) {
int y = map(tempLabels1[i], 8, 0, 16, 70);
display2.setTextSize(1);
display2.setTextColor(WHITE);
display2.setCursor(0, y);
display2.print(tempLabels1[i]);
display2.display();
}
delay(500);
tcaselect(1);
display1.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display1.clearDisplay();
Trait1();
Trait2();
display1.setTextSize(0);
display1.setTextColor(WHITE);
display1.setCursor(32,0);
display1.println("GU SUD:");
display1.display();
// GRADUATION COMBE
for (int i = 0; i < 4; i++) {
int y = map(tempLabels2[i], 8, 0, 16, 70);
display1.setTextSize(1);
display1.setTextColor(WHITE);
display1.setCursor(0, y);
display1.print(tempLabels2[i]);
display1.display();
}
}
Schéma de câblage émetteurs :
Programme émetteurs : (Seul l'emitterID diffère entre mes programmes émetteurs)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LoRa.h>
#include <avr/wdt.h>
#define ONE_WIRE_BUS 15
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C lcd(0x27, 16, 2);
const String emitterID = "PE1:";
byte degreeSymbol[8] = {0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000};
unsigned long timer;
unsigned long previousMillis = 0; // variable pour stocker le dernier temps d'émission
const long interval = 1800000; // intervalle de 15 minutes en millisecondes
unsigned long lcdUpdateInterval = 2000; // intervalle de 10 secondes pour la mise à jour de l'écran LCD
unsigned long previousLCDUpdate = 0; // variable pour stocker le dernier temps de mise à jour de l'écran LCD
int nb=00;
int sv=0;
void setup()
{
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.createChar(0, degreeSymbol);
sensors.begin();
if (!LoRa.begin(433E6))
{
Serial.println("Initialisation LoRa échouée.");
lcd.setCursor(0, 0);
lcd.print("Echec LoRa");
while (1);
}
LoRa.setTxPower(20);
lcd.setCursor(0, 0);
lcd.print("INIT OK");
delay(500);
lcd.clear();
}
void loop()
{
unsigned long currentMillis = millis(); // obtenir le temps actuel
// Vérifier si une demande de température a été reçue
if (LoRa.parsePacket()){
String receivedData = LoRa.readString();
Serial.println("Message recu: " + receivedData);
// Si recoit "PETOP1", envoi de la temperature en reponse
if (receivedData.equals("RPETOP1")){
Serial.println("Demande RPETOP1 recu, envoie de la température");
delay(500);
sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);
// Envoyer la température en réponse à la demande
nb++;
LoRa.beginPacket();
delay(100);
LoRa.print(emitterID + " ");
delay(100);
LoRa.print(temp);
delay(100);
LoRa.print(" ");
delay(100);
LoRa.print(nb);
delay(100);
LoRa.endPacket();
delay(100);
Serial.println("temp envoyé");
LoRa.begin(433E6);
delay(500);
}
}
// Vérifier si 10 secondes se sont écoulées depuis la dernière mise à jour de l'écran LCD
if (currentMillis - previousLCDUpdate >= lcdUpdateInterval)
{
previousLCDUpdate = currentMillis; // sauvegarder le temps actuel
if (sv==1) {
sv=0;
}
else {
sv=1;
}
sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);
lcd.setCursor(0, 0);
lcd.print("Emetteur 1");
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(temp);
lcd.write(byte(0));
lcd.print("C");
lcd.print(" ");
lcd.print(sv);
// Serial.println("Écran LCD mis à jour avec la nouvelle température !");
}
if (millis() > 1800000) reboot();
}
void reboot() {
wdt_enable(WDTO_15MS); // activer le watchdog
while (1) {}; // et attendre ...
}
Vous avez l'ensemble de mon projet en espérant que cela vous permette de déceler le problème que je rencontre (le programme de mon relais est dans mon premier message)
Merci