IKEA a fabriqué une lampe à fonctionnement solaire. La lampe dispose d'un petit module Panneau Solaire/Batteries (3xNiMH). On peut ensuite clipser ce module sur la lampe (qui est à base de 3 LEDs haute puissance) pour qu'elle fonctionne à l'énergie captée par le panneau solaire. Quand il y a du soleil, le panneau solaire recharge les 3 batteries (en passant, le circuit de charge est pourri: les 3 batteries sont en série et il n'existe aucun système de régulation de fin de charge… l'horreur) qui se déchargeront plus tard dans les LEDs (en passant, la lampe ne dispose non plus de circuit de régulation de décharge: en gros, si vous laissez votre lampe allumée pendant une semaine, au revoir les 3 piles NiMH (le module piles/panneaux solaires ne dispose que d'une diode et d'un fusible - je suppose imposé légalement pour éviter que les batteries explosent en cas de court circuit -.
Le problème avec cette superbe lampe, c'est que c'est des LEDs haute puissance. Et comme tout le monde sait, les LEDs haute puissance sont vraiment puissantes… On va donc mettre en place un petit système qui nous permettra de réguler l'intensité lumineuse de notre lampe.
Nous avons deux choix possibles:
Notre système sera donc composé d'un microcontroleur (dans notre cas, un petit Attiny13) qui sera relié en entrée à deux boutons (intensité + et intensité -). Il sera aussi relié en sortie à un transistor (dans notre cas un 2N2222) vu que la lampe consomme ~ 100mA@4V (ce qui est impossible à fournir directement en sortie du µC).
Le programme du µC sera vraiment très simple. En gros, il va générer un signal PWM (cyclique carré) à sa sortie. Avec les boutons + et -, on pourra changer le rapport cyclique de notre signal PWM de sortie. On peut aussi envisager de sauvegarder dans l'EEPROM du µC la valeur du signal cyclique pour pouvoir la retrouver directement une fois la lampe rallumée.
Le schéma du montage:
Le signal PWM (En haut: sortie du µC; en bas: tension aux bornes des LEDs):
Le prototype:
Le circuit dans la lampe:
Une vidéo est disponible ici: http://www.youtube.com/watch?v=lyg1QQ1XCvo
Voici le code source, en license “libre” bien entendu:
/* * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * <frank[ASCII:64]villaro-dixon.eu> wrote this file. As long as you retain this * notice, you can do whatever you want with this stuff. If we meet some day, * and you think this stuff is worth it, you can buy me a beer in return. * Frank Villaro-Dixon * ---------------------------------------------------------------------------- */ /* VARIATEUR DE LUMIÉRE *Un programme tout simple qui fait varier la lumière *Grace à la sortie PWM de l'attiny13 *En appuyant sur PB1 et PB2 à la fois, on *déclenche une séquence SOS *Schémas sur wiki.villaro-dixon.eu */ #define F_CPU 10000000UL #include <util/delay.h> #include <avr/io.h> #define OC0A PB0 #define BOUTON_PLUS PB1 #define BOUTON_MOINS PB2 void S() { OCR0A = 0xFF; _delay_ms(10); OCR0A = 0; _delay_ms(15); OCR0A = 0xFF; _delay_ms(10); OCR0A = 0; _delay_ms(15); OCR0A = 0xFF; _delay_ms(10); OCR0A = 0; _delay_ms(50); } void O() { OCR0A = 0xFF; _delay_ms(50); OCR0A = 0; _delay_ms(10); OCR0A = 0xFF; _delay_ms(50); OCR0A = 0; _delay_ms(10); OCR0A = 0xFF; _delay_ms(50); OCR0A = 0; _delay_ms(30); } void SOS() { while(1) { S();O();S(); _delay_ms(400); } } int main(void) { //On déclare tous les ports, PWM, etc... { DDRB = 0; PORTB = 0; DDRB |= (1<<OC0A); // OC0A (PB0) en sortie DDRB |= (0<<BOUTON_PLUS); // Le bouton en entrée DDRB |= (0<<BOUTON_MOINS); PORTB |= (1<<BOUTON_PLUS); // On ajoute les pull-ups internes aux boutons PORTB |= (1<<BOUTON_MOINS); TCCR0B = 0; TCCR0A = (1<<WGM00)|(1<<WGM01); TCCR0A |= (1<<COM0A1); TCCR0B |= (1<<CS00); } OCR0A = 0x50; while(1) { if(!bit_is_set(PINB, BOUTON_PLUS) && bit_is_set(PINB, BOUTON_MOINS) && (OCR0A < 0xFF)) { _delay_ms(5); OCR0A++; if(OCR0A == 0xFE) { OCR0A = 0x00; _delay_ms(10); OCR0A = 0xFF; } } if(!bit_is_set(PINB, BOUTON_MOINS) && bit_is_set(PINB, BOUTON_PLUS) && (OCR0A > 0)) { _delay_ms(5); OCR0A--; } if((!bit_is_set(PINB, BOUTON_MOINS)) && (!bit_is_set(PINB, BOUTON_PLUS))) //"Easter egg" { SOS(); } //if(compteur >= 0xFF)compteur = 0xFF; //if(compteur < 0)compteur = 0; } return 0; }
Discussion