Bonjour je voulais savoir si il était possible de ne faire tourner un programme sur une UNO que 2 fois par jour et êrte en veille le reste du temps
Merci pour vos réponses
oui
Exemple sur Atmel Studio en réglant certains registres et en activant les interruptions (lire le datasheet de l'atmega 328).
/*
* veille.cpp
*
* Created: 04/07/2020 21:26:20
* Author : Alexis
*/
#define F_CPU 8000000UL
//Librairies fournies par atmel
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sleep.h>
ISR(INT2_vect)
{
PORTB=0x80; // exemple d'une fonction non obligatoire d'interruption
_delay_ms(1000);
PORTB=0x00;
//reti();
}
int main(void)
{
DDRB=0xF0; //Mettre la moitié du port B en sortie, le reste en entrée
//MCUCSR|=(1<<ISC2); (Bit ISC2 pour le type d'interruption, front montant ou front descendant sur le pin INT2)
GICR|=(1<<INT2); (autoriser la requête d'interruption INT2)
sei(); (autorise les interruptions)
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Régler le registre MCUCR : mode de sommeil (SM0, SM1, SM2)
sleep_enable(); //(autorise le mode veille, selon le choix SM0...2) Sleep Enable à 1 dans le registre MCUCR
/* Replace with your application code */
while (1)
{
PORTB|=(1<<PB6); //clignoter une led
_delay_ms(1000);
PORTB=0x00;
_delay_ms(1000);
sleep_cpu(); // entre en veille, jusqu'à l'enclenchement d'une interruption fournie par certaines conditions comme INT, TWI ou UART, etc.
}
}
Code créé pour un atmega8535, il faut lire le datasheet et comprendre les différents registres.
Bonjour, sinon utiliser une librairie qui fait le boulot. Low-Power/Examples at master · rocketscream/Low-Power · GitHub
Bonjour je n'y connais absolument rien en programmation possible de m'en dire un peu plus.
Exécution du programme une fois le matin et une fois le soir.
Montage autonome ,panneau solaire + batterie,donc pas envie de rajouter d'horloge,pas envie d'un capteur quelconque pour le sortir du mode veille .
Ou peut-être lui dire dérouler le programme avec un intervalle de 12 heures
Bonjour je viens de trouver cela sur le forum
//Optimisation de la consommation
#include <avr/power.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
volatile int f_wdt = 1;
unsigned int tempo_desiree = 32; // mettre un multiple de 8, mais pas obligatoire
unsigned int compteur_reveil = 0;
unsigned int compteur_travail=0;
// Watchdog Interrupt Service est exécité lors d'un timeout du WDT
ISR(WDT_vect)
{
if (f_wdt == 0)
{
f_wdt = 1; // flag global }
}
}
// paramètre : 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms, 6=1 sec,7=2 sec, 8=4 sec, 9=8 sec
void setup_watchdog(int ii) {
byte bb;
int ww;
if (ii > 9 ) ii = 9;
bb = ii & 7;
if (ii > 7) bb |= (1 << 5);
bb |= (1 << WDCE);
ww = bb;
// Clear the reset flag
MCUSR &= ~(1 << WDRF);
// start timed sequence
WDTCSR |= (1 << WDCE) | (1 << WDE);
// set new watchdog timeout value
WDTCSR = bb;
WDTCSR |= _BV(WDIE);
}
void enterSleep(void) {
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode(); //Entre dans le mode veille choisi
//le micro passe en sommeil pour 8 secondes
// Le programme va reprendre ici après le timeout du WDT
sleep_disable(); // La 1ère chose à faire est de désactiver le mode veille
}
//************* SETUP *************
void setup() {
//Optimisation de la consommation
//power_adc_disable(); // Convertisseur Analog / Digital pour les entrées analogiques
//power_spi_disable();
//power_twi_disable();
// Si pas besoin de communiquer par l'usb
//power_usart0_disable();
//Extinction des timers, attention timer0 utilisé par millis ou delay
//power_timer0_disable();
//power_timer1_disable();
//power_timer2_disable();
setup_watchdog(9);
Serial.begin(57600);
}
//************* LOOP *************
void loop()
{
if (f_wdt == 1)
{
compteur_reveil++;
// Effectuer les mesures ici si sommeil = 8 secondes
Serial.print("reveil pour la ");
Serial.print(compteur_reveil,DEC);
if (compteur_reveil==1){Serial.println(" ere fois");}
else {Serial.println(" eme fois");}
// fin des mesures ici si sommeil = 8 secondes
if ((compteur_reveil*8)>= tempo_desiree)
{
compteur_travail++;
// Effectuer les mesures ici si sommeil >8 secondes
Serial.print("travail car il y a eu ");
Serial.print((compteur_reveil*8),DEC);
Serial.println(" secondes de sommeil ");
Serial.print("il y a ");
Serial.print((compteur_travail*32),DEC);
Serial.println(" secondes de fonctionnement ");
// fin des mesures ici si sommeil >8 secondes
compteur_reveil = 0;
}
delay(2000); //pour laisser le temps aux "serial.print" de se fairent
f_wdt = 0; // Ne pas oublier d'initialiser le flag, sinon pas de sommeil
enterSleep(); //Revenir en mode veille
}
}
Est-ce que cela peut répondre à mes attentes ?
Désolé de débute en programmation
Merci d'avance
Le microcontroleur est réveillé à chaque débordement du watchdog. Ce programme a été conçu pour réduire la consommation du microcontrôleur : on arrête certaines fonctionnalités et on active le mode veille.
Quelle est la réelle finalité de votre programme ?
Bonjour ,la finalité du programme est une porte de poulailler automatique et solaire donc à 150 mètre de ma maison dans un sous bois ,oui je sais pour du solaire, mais il y pas mal de zones de soleil.
D’où l’intérêt d'avoir un système économe.
Mon programme est à quelque chose prêt:
//int commande_ouvre = 5; // Déclaration broche Bouton fermeture
//int commande_ferme = 6; // Déclaration broche Bouton ouverture
int fin_de_course_porte_ouverte = 3; // Capteur fin de course haut
int fin_de_course_porte_fermee = 2; /// Capteur fin de course bas
int MotorPin1 = 13; // Déclaration broche IN1 L298P
int MotorPin2 = 11; // Déclaration broche IN2 L298P
int LuminositePin = A0; // Déclaration broche LDR
int Luminosite = 0; // Variable de la luminosité
int Seuil_Jour = 80; // Variable de luminosité seuil pour le jour
int Seuil_Nuit = 50; // Variable de luminosité seuil pour la nuit
int Tempo_luminosite = 5000; // Temporisation luminosité 10 secondes = 10000ms
boolean porte_fermee = false; //Déclaration variable porte fermée
boolean porte_ouverte = false; //Déclaration variable porte ouverte
boolean fdch = false; // Déclaration variable Fin de Course Porte Fermée
boolean fdcb = false; // Déclaration variable Fin de Course Bas
boolean etat_bp_ferme = false, etat_bp_ouvre = false; // Déclaration des variables bas et haut
boolean mem_fdch = false, mem_fdcb = false; // Déclaration des mémoires
boolean mem_mouvement = false; // Déclaration de la mémoire mouvement
boolean mem_lumiere = false; // Déclaration de la mémoire lumière
boolean mem_init = false; // Déclaration de la mémoire initialisation
boolean Detecte_lumiere = false; // Déclaration variable détection lumière
boolean Jour = true; // Déclaration variable Jour = 1 | Nuit = 0
boolean Initialisation = false; // Déclaration variable initialisation
// État d'activation de la tempo
boolean tempoActive = false;
// Temps à l'activation de la tempo
unsigned long tempoDepart = 0;
void setup() {
Serial.begin(9600); // Ouverture du port série et debit de communication fixé à 9600 bauds
//pinMode(commande_ferme, INPUT_PULLUP); // Déclaration entrée pull-up sur entrée BP haut
//pinMode(commande_ouvre, INPUT_PULLUP); // Déclaration entrée pull-up sur entrée BP bas
pinMode(fin_de_course_porte_ouverte, INPUT_PULLUP); // Déclaration entrée pull-up sur entrée Fin de course haut
pinMode(fin_de_course_porte_fermee, INPUT_PULLUP); // Déclaration entrée pull-up sur entrée Fin de course bas
pinMode(MotorPin1, OUTPUT); // Déclaration de la sortie A- Moteur
pinMode(MotorPin2, OUTPUT); // Déclaration de la sortie A+ Moteur
Lance_initialisation();
}
void Lance_initialisation() {
Fermer_porte_Initialisation();
}
void loop() {
Luminosite = analogRead(LuminositePin);
if (Initialisation) {
//Serial.println(Luminosite); // Affichage sur le moniteur série du texte
if (Luminosite >= Seuil_Jour)
{
Detecte_lumiere = true;
}
if (Luminosite <= Seuil_Nuit)
{
Detecte_lumiere = false;
}
if (Detecte_lumiere != mem_lumiere) {
tempoActive = true;
tempoDepart = millis();
Serial.println("La lumière lance tempo"); // Affichage sur le moniteur série du texte
}
if (Detecte_lumiere && tempoActive && ((millis() - tempoDepart) >= Tempo_luminosite))
{
Jour = true;
Serial.println("Il fait jour"); // Affichage sur le moniteur série du texte
tempoActive = false;
if (mem_fdcb == 1 && !porte_ouverte) {
Serial.println("oh");
Ouvrir_porte();
}
}
mem_lumiere = Detecte_lumiere;
if (!Detecte_lumiere && tempoActive && (millis() - tempoDepart) >= Tempo_luminosite)
{
Jour = false;
Serial.println("Il fait nuit"); // Affichage sur le moniteur série du texte
tempoActive = false;
if (mem_fdch == 1 && !porte_ouverte) {
Serial.println("je ferme la porte");
Fermer_porte();
}
}
mem_lumiere = Detecte_lumiere;
}
// etat_bp_ouvre = !digitalRead(commande_ouvre); // Inverse de la lecture sur entrée BP haut
// etat_bp_ferme = !digitalRead(commande_ferme); // Inverse de la lecture sur entrée BP bas
fdch = !digitalRead(fin_de_course_porte_ouverte); // Inverse de la lecture sur entrée Fin de course haut
if (fdch != mem_fdch) // Changement d'état du fin de course haut (front montant ou descendant)
{
if (fdch)
{
Serial.println("Porte ouverte !"); // Affichage sur le moniteur série du texte
}
if (!fdch)
{
Serial.println("Porte fermée !"); // Affichage sur le moniteur série du texte
}
}
mem_fdch = fdch; // Mémorisation du nouvel état du fin de course haut
//if (etat_bp_ferme != mem_h) // Changement d'état du bouton poussoir haut (front montant ou descendant)
//{
//Serial.println("Appui BP Haut"); // Affichage sur le moniteur série du texte
//if (etat_bp_ferme && !etat_bp_ouvre && !fdch && !porte_fermee) // Appui sur BP haut mais pas sur le bas
//{
// Fermer_porte(); // Lancer la fonction sens normal
//}
//}
//mem_h = etat_bp_ferme; // Mémorisation du nouvel état du bouton haut
//if (etat_bp_ouvre != mem_b) // Changement d'état du bouton poussoir bas (front montant ou descendant)
//{
//if (etat_bp_ouvre && !etat_bp_ferme && !fdcb && !porte_ouverte) // Appui sur BP bas mais pas sur le haut
//{
//if (!fdcb) {
//Ouvrir_porte();
//}
//}
//}
//mem_b = etat_bp_ouvre; // Mémorisation du nouvel état du bouton bas
}
void Fermer_porte_Initialisation() {
delay(5000);
while (!fdcb) {
digitalWrite(MotorPin1, LOW);
digitalWrite(MotorPin2, HIGH);
Serial.println("Initialisation porte fermée"); // Affichage sur le moniteur série du texte
fdcb = !digitalRead(fin_de_course_porte_fermee);
// etat_bp_ferme = !digitalRead(commande_ferme); // Inverse de la lecture sur entrée BP bas
if (fdcb)
{
Serial.println("Porte fermée"); // Affichage sur le moniteur série du texte
Arret();
mem_fdcb = true;
porte_fermee = true;
porte_ouverte = false;
Initialisation = true;
break;
}
}
}
void Fermer_porte() {
Serial.println(" on ferme");
while (fdcb) {
digitalWrite(MotorPin1, LOW);
digitalWrite(MotorPin2, HIGH);
Serial.println("Fermer porte"); // Affichage sur le moniteur série du texte
fdch = !digitalRead(fin_de_course_porte_fermee);
// etat_bp_ferme = !digitalRead(commande_ferme); // Inverse de la lecture sur entrée BP bas
if (fdch || etat_bp_ferme)
{
porte_fermee = true;
porte_ouverte = false;
Serial.println("Porte fermée"); // Affichage sur le moniteur série du texte
Arret();
break;
}
}
}
void Ouvrir_porte() {
Serial.println("ok");
while (!fdch) {
digitalWrite(MotorPin1, HIGH);
digitalWrite(MotorPin2, HIGH);
Serial.println("Ouverture de la porte"); // Affichage sur le moniteur série du texte
fdch = !digitalRead(fin_de_course_porte_ouverte);
// etat_bp_ferme = !digitalRead(commande_ferme); // Inverse de la lecture sur entrée BP haut
if (!fdcb || etat_bp_ouvre)
{
mem_fdch = true;
porte_fermee = false;
porte_ouverte = true;
Serial.println("Porte ouverte"); // Affichage sur le moniteur série du texte
Arret();
break;
}
}
}
void Arret() {
digitalWrite(MotorPin1, LOW);
digitalWrite(MotorPin2, LOW);
tempoActive = 0;
}
J'ai quelques retouche a faire pour qu'il tourne parfaitement.
Comment puis-je imbriquer les 2
Merci d'avance