stefan
2017-11-24 20:56:52 UTC
Je n'utilise pas PWM en mode d'économie d'énergie. La sortie se comporte de manière erratique. Cela devrait être possible, je suppose. Voici un exemple de fonctionnement minimal:
/ * MWE: Impossible d'utiliser PWM dans aucun mode d'économie d'énergie. Un exemple de travail minimal (MWE) démontrant mon problème dans l'utilisation de PWM tout en économisant de l'énergie. Intention: contrôler une charge pour qu'elle soit allumée ou éteinte pendant de plus longues périodes (des heures, c'est-à-dire). La luminosité de la charge est définie par PWM. Câblage: + 5V | + ------------------ + | + 5V --- | Vin | | | Arduino | C | Pro Mini 9 | ----- / \ / \ / ---- B | < PN2222 | compatible | 1k E | (ATmega328) | | GND --- | GND | | + + ------------------ + LED | - | > < 1k > | | Implémentation GND: * Réglez le chien de garde pour provoquer une interruption à intervalles réguliers (dans ce MWE: 2s). Décompte des «cycles» (MWE: 2 ou 3) à chaque interruption du chien de garde. * Si `cycles` est égal à 0, basculer la sortie, définir une nouvelle valeur` cycles`. Le programme réel utilise 7200 cycles 8s pendant 16h avant la prochaine bascule. * Accédez à SLEEP_MODE_PWR_DOWN. Attendu: la charge attachée est allumée pendant 4 s, atténuée à 32/256. Puis éteint pendant 6s. Puis répétez. Observé: Dans la plupart des cas, il n'y a pas de sortie en mode veille, la LED ne clignote qu'avant de dormir. Mais parfois c'est allumé, alors
PWM semble être possible pendant le sommeil! Le programme réel (à partir duquel ce MWE est dérivé) utilise la luminosité réglable, se réveille du sommeil par des interruptions externes, stocke les brightnes dans l'EEPROM, ... * // * La définition de ce qui suit à 0 utilise `digitalWrite` au lieu de` analogWrite` démontrer que le chien de garde et la logique d'interruption fonctionnent réellement. * / # define USE_PWM 1 # include <avr / sleep.h> # include <avr / wdt.h> # define outputPin 9 // où la charge PWM est connectée # define onCycles 2 // nombre de cycles de surveillance à rester actif # define offCycles 3 / / nombre de cycles de surveillance pour rester éteintint luminosité = 32; // Cycle de service PWM au 1/256, si la charge est activée toggle = 1; // état marche / arrêt actuel de la charge PWM / * nombre de cycles de surveillance jusqu'à la prochaine bascule. Cela sera modifié dans le gestionnaire d'interruption de surveillance. * / volatile unsigned long wdt_cycles = onCycles; / * Gestionnaire d'interruptions Watchdog appelé lorsque le chien de garde expire, compte à rebours des cycles restants. Ne déborde pas. * / ISR (WDT_vect) {if (wdt_cycles > 0) wdt_cycles -;} void setup (void) {/ * Setup watchdog. Voir [1] p54, [2] * / cli (); // BEGIN désactiver interrompt MCUSR & = ~ (1<<WDRF); // pas de réinitialisation du système à l'expiration du délai de surveillance WDTCSR | = 1<<WDCE | 1<<WDE; // autorise la configuration du chien de garde WDTCSR = 1<<WDIE // active les interruptions | 1<<WDP2 | 1<<WDP1 | 1<<WDP0 // 2,0 secondes; wdt_reset (); // réinitialise la minuterie sei (); // END désactiver les interruptions / * Configurer les broches de sortie * / pinMode (outputPin, OUTPUT); # if USE_PWM analogWrite (outputPin, luminosité); # else digitalWrite (outputPin, toggle? HIGH: LOW); # endif} void loop (void) {if (wdt_cycles < 1) {toggle =! toggle; wdt_cycles = basculer? onCycles: offCycles; #if USE_PWM
analogWrite (outputPin, basculer? Luminosité: 0); # else digitalWrite (outputPin, basculer? HIGH: LOW); # endif} / * Heartbeat: Clignotement court de la LED intégrée. Cela vérifie que nous dormons et nous nous réveillons réellement. * / digitalWrite (LED_BUILTIN, HIGH); retard (50); digitalWrite (LED_BUILTIN, LOW); / * Je me suis endormi, voir [3]. Je veux `SLEEP_MODE_PWR_DOWN`, mais aucun des autres ne fonctionne. * / set_sleep_mode (// SLEEP_MODE_IDLE // SLEEP_MODE_ADC // SLEEP_MODE_PWR_SAVE // SLEEP_MODE_STANDBY SLEEP_MODE_PWR_DOWN); sleep_mode ();} / * Références [1] https://cdn.sparkfun.com/datasheets/Kits/doc8161.pdf [2] https://forum.arduino.cc/index.php?topic=63651.0 [3 ] https://playground.arduino.cc/Learning/ArduinoSleepCode * /