Bonjour à tous , j'arrive tout doucement à la fin de mon projet mais j'ai encore 2 problèmes sur lesquels je me casse beaucoup la tête et pour lesquels je n'arrive pas à trouver de solutions adéquates, peut-être que vous aurez des idées.
LE PROJET:
Le but est d'ouvrir et fermer une fenêtre , un peu le même principe qu'une porte de poulailler. Donc je dois piloter, avec une télécommande, mon moteur ( DC 24V 12W) pour qu'il puisse ouvrir ou fermer la fenêtre avec certaines commandes de sécurité, etc... Comme principe , lorsque l'utilisateur appuie sur le Bouton "A" , la porte s'ouvre et sur Bouton "B" la porte se ferme. Le tout sur batteries rechargeables ( 24 V 3Ah) car cette fenêtre est montable et démontable en permanence.
Tout est fonctionnel mais voici les 2 soucis :
- La portée de communication de mon récepteur est médiocre. J'utilise pour le moment ce type de récepteur en 433 Mhzs à qui j'envoie des données avec ce type de télécommande.
Récepteur : récepteur
Télécommande : Télécommande
En effet, pour le moment , j'ai une porté d'environs 4m. et j'aimerais pouvoir communiquer à une portée de 40 -50m.
- Je n'ai pas assez d'autonomie de batterie , mon automate tient pour le moment 2 jours et après ça, les batteries sont trop déchargées pour pouvoir refermer la fenêtre en cas de besoin. Tout ça est du aux différents modules installés sur l'arduino pour la communications, la sécurité, pilotage du moteur, etc.. Dans l'idéal , l'automate devrait pouvoir tenir 1 semaine à 10 jours. Dans cet esprit, je comptais mettre mon arduino en mode veille dès que l'utilisateur aterminé une commande. Et pour sortir de ce mode veille , faire une interruption externe grâce au signal envoyé par la télécommande. En gros, l'utilisateur appuie sur un des boutons, l'arduino se réveille et ensuite l'utilisateur peut faire sa commande jusqu'à ce que le programme remette en veille l'arduino et ainsi économise énormément de batterie.
Pour le moment et avec ce récepteur , les Pins n'envoies que des "DATA" et je ne peux pas faire une interruptions avec ça.
C'est pour ça que je viens vers vous et demande si vous connaissez un moyen de communication ( bluetooth, Radio fréquence,... consommant le moins possible) qui permettrait d'augmenter considérablement la portée du signal et de plus permettrait d'agir comme interruption externe ?
Les modules wifi et infrarouges ne sont pas possibles dans cette application. Et j'ai essayé les modules LoRa mais ceux-ci coûtent trop cher et ont une application avec une portée trop importante pour la simple application que je fais.
Voici le code que j'utilise pour mes tests si ça peut vous aider:
#include <RCSwitch.h>
#include "EmonLib.h" // Inclure la bibliothèque pour le capteur ACS712 et la lecture de courant
#include <EEPROM.h>
#include <virtuabotixRTC.h>// inclure la bibliothèque de l'horloge RTC DS1302
#define ENA 10
#define INA 12
virtuabotixRTC myRTC(4, 5, 6); // définir l'horloge RTC DS1302
// SCLK -> 4, I/O -> 5, CE -> 6
// CLK -> 4 , DAT -> 5, Reset -> 6
RCSwitch mySwitch = RCSwitch();// définir la télécommande
// Data -> 2
EnergyMonitor emon1; // définition de la classe Energymonitor
const int analogInPin = A2; // Broche analogique utilisée pour la lecture de tension
const int courantPin = A0; // broche analogique utilisée pour lire le courant
// Valeurs des boutons de la première télécommande
unsigned long boutonA_1 = 12451858;
unsigned long boutonB_1 = 12451860;
// Valeurs des boutons de la deuxième télécommande
unsigned long boutonA_2 = 10813458;
unsigned long boutonB_2 = 10813460;
bool ouverture = false; // Indique si l'ouverture a été effectuée
bool fermeturefinale = false; // Indique lorsque la fermeture fianle du au seuil de tension a été effectué.
// variables pour la lecture de la tension de la batterie
float tensionBatterie = 0.0;// définition de la variable Tension batterie
float voltageDividerRatio = 6.0; // rapport de division de tension (10k / (2k + 10k))
float seuilTension = 22.0; // Seuil de tension en volts
// Variables pour la lecture du courant
float seuilCourant = 2.0; // Seuil de courant en ampères
// Variables pour l'heure
int address_day = 0;
int address_month = address_day + sizeof(int);
int address_year = address_month + sizeof(int);
int address_hours = address_year + sizeof(int);
int address_minutes = address_hours + sizeof(int);
int address_seconds = address_minutes + sizeof(int);
// Les différentes fonctions appelées dans le programme
// Fonction pour lire la tension de la batterie
float lireTensionBatterie() {
int sensorValue = analogRead(analogInPin); // Lecture de la valeur analogique
float tensionBatterie = sensorValue * (5.0 / 1023.0) * voltageDividerRatio; // Calcul de la tension réelle
return tensionBatterie;
}
// Fonction pour lire le courant
double lireCourant() {
double courant = emon1.calcIrms(1480); // Passer une valeur à calcIrms pour spécifier le nombre d'échantillons
return courant;
}
void sauvegarderheure(){
EEPROM.put(address_day, myRTC.dayofmonth);
EEPROM.put(address_month, myRTC.month);
EEPROM.put(address_year, myRTC.year);
EEPROM.put(address_hours, myRTC.hours);
EEPROM.put(address_minutes, myRTC.minutes);
EEPROM.put(address_seconds, myRTC.seconds);
}
//fonction pour afficher l'heure
void afficherheure(){
EEPROM.get(address_day, myRTC.dayofmonth);
EEPROM.get(address_month, myRTC.month);
EEPROM.get(address_year, myRTC.year);
EEPROM.get(address_hours, myRTC.hours);
EEPROM.get(address_minutes, myRTC.minutes);
EEPROM.get(address_seconds, myRTC.seconds);
Serial.print("Date / Heure de la fermeture définitive: ");
Serial.print(myRTC.dayofmonth);
Serial.print("/");
Serial.print(myRTC.month);
Serial.print("/");
Serial.print(myRTC.year);
Serial.print(" ");
Serial.print(myRTC.hours);
Serial.print(":");
Serial.print(myRTC.minutes);
Serial.print(":");
Serial.println(myRTC.seconds);
}
// Fonction pour avancer
void avancer() {
unsigned long startTime = millis(); // utillisation d'une fonction non bloquante pour ouvrir la fenêtre d'environs 18o mm
digitalWrite(INA, HIGH); // Avancer
analogWrite(ENA, 255);
while (millis() - startTime < 7000) { //( 25 secondes = 180 mm)
double courant = lireCourant(); // Lecture du courant
Serial.println(courant); // juste pour debuggage
// Vérifier si le courant dépasse le seuil
if (courant >= seuilCourant) {
// Arrêter complètement le moteur pour éviter la surcharge
analogWrite(ENA, 0); // arrêt
Serial.println("Alerte : Courant de surcharge détecté. Le moteur est arrêté.");
ouverture = true;
return; // Sortir de la fonction reculer() si le courant dépasse le seuil
}
}
analogWrite(ENA, 0);
ouverture = true;
}
// Fonction pour reculer
void reculer() {
digitalWrite(INA, LOW); // Reculer
analogWrite(ENA, 255);
while (true) {
double courant = lireCourant(); // Lecture du courant
Serial.println(courant); // juste pour débuggage
// Vérifier si le courant dépasse le seuil
if (courant >= seuilCourant) {
// Arrêter complètement le moteur pour éviter la surcharge
analogWrite(ENA, 0); // arrêt
myRTC.updateTime();
sauvegarderheure();
Serial.println("Alerte : Courant de surcharge détecté. Le moteur est arrêté.");
ouverture = false;
return; // Sortir de la fonction reculer() si le courant dépasse le seuil
}
}
}
void setup() {
pinMode(ENA, OUTPUT); // Pin de vitesse
pinMode(INA, OUTPUT); // Pin de direction
Serial.begin(9600); // Initialisation de la communication série
mySwitch.enableReceive(0); // Activer la réception sur le pin 0
// Initialisation de l'instance de la classe EnergyMonitor pour mesurer le courant
emon1.current(courantPin, 30); // La valeur 30 représente la sensibilité du capteur (185mV/A pour l'ACS712)
if (Serial){
afficherheure();
}
}
void loop() {
while(!fermeturefinale){
tensionBatterie = lireTensionBatterie(); // Lecture de la tension de la batterie
//Serial.println(tensionBatterie); // juste pour débuggage
if (tensionBatterie <= seuilTension) {
// Effectuer un dernier retour avant d'arrêter la boucle
reculer();
fermeturefinale = true;
}
if(fermeturefinale){
return;
}
if (mySwitch.available()) {
unsigned long valeurTelecommande = mySwitch.getReceivedValue();
if (!ouverture) {
if (valeurTelecommande == boutonA_1 || valeurTelecommande == boutonA_2) {
double courant = lireCourant(); // Lecture du courant
Serial.println(courant); // juste pour débuggage
avancer();
}
}
else {
if (valeurTelecommande == boutonB_1 || valeurTelecommande == boutonB_2) {
double courant = lireCourant(); // Lecture du courant
Serial.println(courant); // juste pour débuggage
reculer();
myRTC.updateTime();
sauvegarderheure();
Serial.print("Date / Heure de la fermeture définitive: ");
Serial.print(myRTC.dayofmonth);
Serial.print("/");
Serial.print(myRTC.month);
Serial.print("/");
Serial.print(myRTC.year);
Serial.print(" ");
Serial.print(myRTC.hours);
Serial.print(":");
Serial.print(myRTC.minutes);
Serial.print(":");
Serial.println(myRTC.seconds);
//delay(300000); // éviter que l'utilisateur joue trop avec les télécommandes , délais de 5 minutes
}
mySwitch.resetAvailable();
}
}
}
while(fermeturefinale){
analogWrite(ENA, 0); // arrêt
}
}
Merci beaucoup d'avance !

