Bonjour, je n'avais pas vu le message.
La page de code est vide.
Je mets ici la dernière mise à jour
/****fonctionne raccordé sur pin 11 ou sur + batt****
Trappe automatique poulallier à servomoteur
Alimenté par batterie et panneau solaire.
Ouverture dans la paroi : 200 X 200 mm
Trappe en tôle galva 250 X 300 mm, poids ~300 gr
Bras de levier alu de ~250 mm
Contrepoids du même poids que la trappe ~300 gr
Tige d'acier galva 2 mm, longueur en fonction des emplacements.
Le centre de gravité du contrepoids est désaxé pour que la trappe
guillotine reste bien en position haute quand elle est ouverte et
qu'elle ne puisse être remontée quand elle est fermée, blocage
par une vis en butée.
Principe visible sur cette vieille vidéo https://youtu.be/1Y_6Dzo9-Po
Batterie 2Ah 4.8 V (4 éléments LR14 ou LR6)
Résistance 10 ohms limitant le courant de charge à C/30
charge terminée : 68 mA en plein soleil
Charge mesurée par temps couvert : 15 mA
consommation en veille (led power et régulateur enlevés) : 7 µA
avec ou sans racordement sur pinPont
Résistance de 4,7 ohm en série avec le servo moteur limite la puissance
et évite le reboot en cas de blocage mécanique.
installer la librairie LowPowerLab/LowPower
actions du bouton
appui bref :
- premier appui : fermeture ou ouverture manuelle,
annulée au crépuscule ou lever du jour suivant.
- deuxième appui : annule le forçage
appui long > 3 secondes enregistre la valeur "crepuscule"
en EEPROM, en adresse 00.
Pour régler "crepuscule" sur PC : mettre en mode debug et
régler le potentiommètre de la "bread board" pour obtenir la valeur
souhaitée sur le moniteur série.
A l'aube et au crépuscule le retard est visualisé par un flash
de la led tout les 8 secondes. Environ 48 secondes ( 6 périodes
de veille)
Un flash à chaque réveil indique que la batterie est en charge.
Même trajet angulaire du sermoteur pour l'ouverture que fermeture :
150° de trajet d'angle commandé par
150 impulsions espacées de 20 ms = 3 secondes
Estimation de consommation du servo-moteur
vu sur oscilloscope :
0.75 V sur résistance de 0.5 ohm, 150 impulsions de 3 ms environ,
donne 1.5 A pendant 0,5 secondes = 0.2 mAh(max)
matin et soir = 0.4 mAh/jour + 0.2 mAh de mode veille = 0.6 mAh/jour
30 mn de ciel voilé suffit logiquement à recharger 1 journée de conso.
analogReference(INTERNAL);// 1.1 V coeff 0.00105
permet une mesure sure de la tension de batterie.
La pin 11 en entrée pendant la veille permet d'effacer la consommation
du pont de mesure alimentation batterie.
Résistance de charge à 10 ohm, permet une charge plus rapide
sans surcharge pour applications futures
*/
#include <EEPROM.h>
#include <Servo.h>
#include <LowPower.h>
//#define Debug // mode test et moniteur série
//* noms des broches entrées/sorties */
const byte pinBouton = 2;
const byte AlimServo = 3;
Servo monServo;// pin 4
const byte pinLed = 10; // led externe
const byte pinPont = 11;// commute le pont bat hors veille
const byte pinPV = A0; // tension panneau
const byte pinBat = A1; // tension batterie
//const byte pinILS = A2; // ILS 1 = trappe fermée
/* variables */
int addr = 0;
byte val; // crépuscule valeur numérique <1 octet en EEPROM
int vBat;// 1 M/ 220 k rapport 0,00593
byte batLed;
bool afBat = true; // autorise l'affichage de l'état de la batterie
// résistane 100 k à UPV; 22 k au moins
int UPV; // mesure de tension sur le panneau, rapport 0,00593
byte seuilNuit = 70; // seuil nuit 0.42 v;
int seuilJour = 337; // seuil jour 2 v;
byte retard = 0; // pour éviter les ouvertures ou fermetures intempestives
byte nbCycle = 5; // fois 8 secondes
bool ouvert; // 1 : trappe ouverte
volatile bool appuiBref = false;
bool manuel = false; // état fermeture manuelle forcée
unsigned long chrono = 0; // bouton, appui long
int dureeTravail = 4000; // fermeture normale 3 secondes
unsigned long chronoTravail = 0 ;
void setup()
{
// initialisation entree/sortie
// EEPROM.write(addr, seuilNuit );//première programmation
pinMode(pinBouton, INPUT_PULLUP);
//interruption par bouton poussoir
attachInterrupt(digitalPinToInterrupt(pinBouton), bouton, FALLING);
pinMode(AlimServo, OUTPUT);
monServo.attach(4);
pinMode(pinLed, OUTPUT);
pinMode(pinPV, INPUT);
pinMode(pinBat, INPUT);
pinMode(pinPont, OUTPUT);// alimente le pont batterie
analogReference(INTERNAL);// 1.1 V coeff 0.00105
//initialisation trappe :
seuilNuit = EEPROM.read(addr);
if (seuilNuit == 255)seuilNuit = 70; //eeprom vierge
UPV = analogRead(pinPV);// lit la tension du PV
vBat = analogRead(pinBat); // lit la tension de batterie
#ifdef Debug
Serial.begin(115200);
Serial.println ("Moniteur série validé") ;
Serial.print ("seuilNuit = ") ; Serial.print (seuilNuit) ;
Serial.print (" UPV = ") ; Serial.print (UPV) ;
Serial.print (" ouvert = ") ; Serial.print (ouvert) ;
Serial.print (" vBat = ") ; Serial.println (vBat) ;
delay(10);
#endif // Debug
// initialise la trappe en fonction du soleil
if (UPV >= seuilJour) {
ouvrir();
ouvert = true;
}
else {
fermer();
ouvert = false;
}
appuiBref = false;// en dernier sinon ça bug
}
void loop() {
// mise en veille
pinMode(pinPont, INPUT);// coupe le pont batterie
#ifdef Debug
LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); // mise en veille
#else
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); // mise en veille
#endif
// le réveil commence ici
pinMode(pinPont, OUTPUT);// active le pont batterie
UPV = analogRead(pinPV); // lit la tension aux bornes du PV
vBat = analogRead(pinBat);
#ifdef Debug
Serial.print (" UPV = ") ; Serial.print (UPV) ;
Serial.print (" vBat = ") ; Serial.print (vBat) ;
Serial.print (" ouvert = ") ; Serial.print (ouvert) ;
Serial.print (" manuel = ") ; Serial.print (manuel) ;
Serial.print (" appuiBref = ") ; Serial.print (appuiBref) ;
Serial.print (" retard = ") ; Serial.println (retard) ;
delay(10);
#endif // Debug
modemanuel(); // actions du bouton
if (UPV <= seuilNuit && ouvert)fermeture(); // attends la nuit
else if (UPV >= seuilJour && !ouvert)ouverture(); // attends le jour
else retard = 0;// et retour en veille
if ((UPV - vBat) > 32 )flash(); // indique batterie en charge (5 mA au minimum)
}// fin de loop
void bouton() {// appui bouton déclenche interruption
chrono = millis();// initialise le compteur
appuiBref = true; // autorisé si appui bref
}
void modemanuel()
{
while (!digitalRead(pinBouton))//tant que le bouton est appuyé
{
if (millis() - chrono > 3000) // bouton maintenu appuyé 3 secondes
{
sauvseuilNuit();// sauve en EEPROM
digitalWrite(pinLed, 1); delay(200);
digitalWrite(pinLed, 0); // acquit appuiLong
appuiBref = false; // annule l'appui bref
}
}//while
if (appuiBref) {
if (!manuel) {
if (ouvert) fermer();
else ouvrir();
manuel = true; // ouvert ou fermé de force
}
else { // désactive le mode
if (ouvert) ouvrir();
else fermer();
manuel = false;
}
appuiBref = false;
}//appuiBref
}
void ouverture() {
retard++;
flash();
if (retard > nbCycle) {
if (manuel) { // déjà ouvert manuellement
manuel = false;// annule le forçage
}
else ouvrir();
ouvert = true;
}
}
void ouvrir() {
digitalWrite(AlimServo, 0); // alimente le servomoteur
for (int i = 175; i >= 20; i--) {// 130°,
monServo.write(i);
delay(20); // trappe ouverte en 2.6 secondes
}
digitalWrite(AlimServo, 1);
retard = 0;
}
void fermeture() {
retard++;
flash();
if (retard > nbCycle) {
if (manuel) { // déjà fermé manuellement
manuel = false;// annule le forçage
}
else {
fermer();
}
ouvert = false;
}
}
void fermer() {
digitalWrite(AlimServo, 0);
for (int i = 20; i <= 175; i++) {
monServo.write(i);
delay(20);
}
digitalWrite(AlimServo, 1);
retard = 0;
}
void flash() {
digitalWrite(pinLed, 1); delay(10); digitalWrite(pinLed, 0);
}
void testBat() {// non utilisé
// 1 M au +, 220 k au - coeff 0.005817
vBat = analogRead(pinBat);
#ifdef Debug
Serial.print ("vBat = ") ;
Serial.println (vBat) ;
delay(10);
#endif // Debug
if (vBat <= 810)batLed = true; // faible < 4.8 V
else if (vBat > 810 && vBat < 945)
batLed = 2; // normal entre 4.7 et 5.4 V
else if (vBat >= 945)batLed = 3; // pleine charge > 5.4 V
for (int i = 0; i < batLed; i ++) {
digitalWrite(pinLed, 1); delay(20); digitalWrite(pinLed, 0);
delay(200);
}
}
void sauvseuilNuit() { // enregistre le seuil crépuscule
EEPROM.write(addr, UPV); // 0 à 254 0 à 1.35 V
seuilNuit = UPV;
}
Il suffit de tout sélectionner et coller le code précédent.
Image du circuit avec le logiciel Fritzing
La mise à jour :
220510maj.ino (8.8 KB)