Bonjour, bonsoir
J'ai un projet c'est de faire une poubelle communicante c’est-à-dire que le but ça serait que celle-ci collecte les déchets et grâce à un capteur ultrason qui retransmettra ses données sur une application pour aider les éboueurs une perte de temps, pour éviter de consommer trop je voudrais une fonction "mise en veille". C’est-à-dire que la poubelle fonctionnerait par exemple de 8h00 à 8h05 (le temps de transmettre l'état de la poubelle c'est à dire si elle est pleine ou pas) puis se remettre en veille jusqu’à par exemple 17h30 qui de même se rallumera pendant 5 minutes .
je sais que se sujet a été abordé pas mal de fois sur le forum mais étant débutant dans tout ce qui est Arduino cela me parait compliqué.
je me base sur ce code la :
//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)
{`Texte préformaté`
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
}
}
Une UNO consomme 6mA en veille, un capteur HC-SR04 15mA.
Le total : 21mA.
Il faudra donc 21mA * 24 = 504mAH par jour.
Une batterie de 2500mAH aura donc une autonomie de 5 jours !!!
D'une part, la UNO ne convient pas pour ce genre d'application (une PRO MINI serait préférable), d'autre part il faudrait alimenter le HC-SR04 seulement en cas de nécessité.
Alors pour vous épargner tout un blalbla a lire je n'ai pas cité tout les composants que mon groupe va utiliser mais je suis entrain de faire un bilan énergétique , et pour la batterie je suis tout a fait d'accord avec vous mais malheureusement je suis obligatoirement obligé de faire de la SIN (c'est ma filière) qui veut dire du code sur Arduino. Une pro mini serait plus adapté ?
L'exemple powerDownWakePeriodic est assez explicite : 1 ligne de code (ce qui fait beaucoup moins de blabla que le code posté dans la demande).
Ensuite il faut appeler cette ligne de code en boucle : X * 450 pour atteindre X heures.
/* Constantes pour les broches */
const byte TRIGGER_PIN = 3; // Broche TRIGGER
const byte ECHO_PIN = 2; // Broche ECHO
#include <Wire.h>
#include "rgb_lcd.h"
#include "LowPower.h"
rgb_lcd lcd;
/* Constantes pour le timeout */
const unsigned long MEASURE_TIMEOUT = 25000UL; // 25ms = ~8m à 340m/s
/* Vitesse du son dans l'air en mm/us */
const float SOUND_SPEED = 340.0 / 1000;
int a = 0;
/** Fonction setup() */
void setup() {
/* Initialise le port série */
Serial.begin(115200);
lcd.begin(16, 2);
lcd.print("hello, world!");
/* Initialise les broches */
pinMode(TRIGGER_PIN, OUTPUT);
digitalWrite(TRIGGER_PIN, LOW); // La broche TRIGGER doit être à LOW au repos
pinMode(ECHO_PIN, INPUT);
}
/** Fonction loop() */
void loop() {
a = 0;
while (a < 500000) {
/* 1. Lance une mesure de distance en envoyant une impulsion HIGH de 10µs sur la broche TRIGGER */
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
/* 2. Mesure le temps entre l'envoi de l'impulsion ultrasonique et son écho (si il existe) */
long measure = pulseIn(ECHO_PIN, HIGH, MEASURE_TIMEOUT);
/* 3. Calcul la distance à partir du temps mesuré */
float distance_mm = measure / 2.0 * SOUND_SPEED;
/* Affiche les résultats en mm, cm et m */
Serial.print(F("Distance: "));
Serial.print(distance_mm);
Serial.print(F("mm ("));
Serial.print(distance_mm / 10.0, 2);
Serial.print(F("cm, "));
Serial.print(distance_mm / 1000.0, 2);
Serial.println(F("m)"));
/* Délai d'attente pour éviter d'afficher trop de résultats à la seconde */
delay(1000);
lcd.begin(16, 2);
lcd.print(distance_mm*100/362);
lcd.print(" %");
for (int t=0; t<90; t++)
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
}
}
donc la mon code permet d'afficher le taux de remplissage sur un écran Arduino avec le mode veille
pensez vous que cela est bon ?
au passage, a est un int donc il doit être compris entre -32768 et +32767, tu ne peux donc pas le comparer à 500000. Par défaut les constantes sont considérées comme des entiers donc tu devrais écrire 500000L même si dans le contexte cela n'a aucun sens.
peux-tu expliquer pourquoi tu mets un delay(1000) pour faire juste derrière
for (int t=0; t<90; t++)
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
pense à faire ctrlT lorsque tu es dans l'IDE pour indenter correctement ton code
Merci de votre réponse, j'ai compris que le :
for (int t=0; t<90; t++) ne servais pas a grand chose mais comme dit si dessus, j'aimerais que l’Arduino se mette en veille mais que une certaine heure par exemple de 7h30h à 18h mais si je met que cette ligne de code tu penses que c'est bon LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); ?
Au contraire la boucle for permet d'augmenter le temps de veille.
Le CPU est réveillé toutes les 8s, c'est le temps maximum que l'on peut programmer pour un réveil par le timer. La boucle for multiplie donc ces 8s par le nombre de fois qu'elle est exécutée, dans ce cas 90 x 8 = 720s.
Si tu veux travailler avec des heures précisément, ce genre de système n'est pas viable car il va y avoir de la dérive assez rapidement. Il vaudrait mieux utiliser une RTC DS3231 par exemple. La RTC peut tourner alors que le CPU est en veille et elle est capable de gérer des alarmes
j'ai regardé et je vous rejoins sur le fait que ça pourrait être possiblement bien mieux pour ce type de projet, mais malheureusement mon lycée ne peut plus commander de composant ou de capteur
n'aurait-il pas moyen de le faire à partir de mon code ?
Je n'ai as dit que c'était impossible à partir de ton code. J'ai dit que ce serait imprécis et qu'il y aurait de la dérive sur le long terme.
Il suffit juste de calculer le nombre de fois qu'il faut exécuter la boucle for pour obtenir le temps qui t'intéresse.
Cette boucle fait 90 fois un cycle de veille de 8s donc 90 x 8 = 720s.
Si tu changes le nombre de fois que la boucle s'exécute tu peux changer la durée de la veille.
Qu'est-ce qui te bloque?
À mais d'accord j'ai cru que mon code n'était pas bon c'est pour ça désolé
Sinon désolé encore de te déranger mais pense tu que c'est possible de la remettre en veille après qu'elle est fait ses 720 s de veille. C'est est à dire que elle fait ça veille puis elle s'active 5 minutes puis se remet en veille ? Et si oui cela serait possible avec mon code ou pas ?