Zylonenauge Solar betreiben

Zur Weihnachtszeit 2019 probierte ich kurzerhand mit den übrig gebliebenen Zylonenaugen-Prototypen aus, ob diese mit zwei NiHM-Akkus hell genug leuchten um als Weihnachtsbeleuchtung am Fenster zu funktionieren. Zu meiner Überraschung leuchtete auch die Version mit blauen LED noch ausreichend hell. Im weiteren Verlauf experimentierte ich mit einem Solar-Ladegerät für NiMH-Accus von Würth Solar, das ursprünglich Walkman usw. betreiben sollte.
Tagsüber ist der µC im Schlafmodus, abends wacht er auf. Gesteuert wird dies über die Spannung der Solarzelle, die an PD2 (INT0) angeschlossen ist.

Warmweisse und blaue LED harmonieren sehr gut mit der Spannung zweier Akkus. Auch bei wenig Licht im Winter leuchten die LED bis zur Abschaltung am Morgen ausreichend hell. Allerdings werden die Akkus dabei nur wenig entladen, es besteht die Gefahr der Überladung am Tag in sonnenreichen Zeiten. Vergleiche Entladungsspannung NiHM-Akku mit Spannungs-Stromkennlinie blaue (weisse) LED siehe LEDKennlinie.
Bei einem Zylonenauge mit roten LED besteht die Chance den Akku mehr zu entladen.
Software
// ZylonenaugeSchneeanimationSolar V1.1 (c) Oliver Mezger 5.01.2020 #include <avr/io.h> #include <util/delay.h> #include <avr/sleep.h> unsigned char muster[]={0x78,0x74,0x72,0x71,0xb8,0xb4,0xb2, 0xb1,0xd8,0xd4,0xd2,0xd1,0xe8,0xe4,0xe2,0xe1}; ISR(INT0_vect){ // wenn es dunkel ist wird ISR ausgelöst GIMSK &= ~(1 << INT0); // Interrupt wieder abschalten PORTD |= 1<<PD0; // Beleuchtung einschalten } void enter_sleep(void){ PORTD &= ~(1<<PD0); GIMSK |= (1 << INT0); // Interrupt0 ermoeglichen MCUCR = (1<<SM0) | (1<<SE); // Schlafmodus auf PWR_Down sleep_mode(); // Schalfen schicken /* Aufgewacht! */ MCUCR = 0; } int main(){ DDRB=0xff; // PORTB auf Ausgang signed char musterz=0; // Position 0 char z=0,i; PORTD = 0b01111011; // Pullups an PD2 hat pullDown, PD0 an DDRD = 1; // PD0 als Ausgang sei(); while(1){ if(PIND&4) enter_sleep(); // wenn es hell ist schlafen else{ musterz=8+rand()%8; z=2+(rand()%32); for(i=0;i<=z;i++){ _delay_ms(30); } z=2+(rand()%16); while (musterz>=0){ PORTB=muster[musterz--]; for(i=0;i<=z;i++){ _delay_ms(20); } } PORTB=0; } } }
Die Eingänge des µC sind als Schmitt-Trigger ausgeführt und haben versorgungsspannungsabhängige Schaltschwellen.
Im Wachzustand läuft die Animation und der Zustand von PD2 wird überwacht. Bei Helligkeit wird dieser zu 1 und der Schlafmodus wird aktiviert. Zum Aufwachen wird Interrupt INT0 mit low-Pegel verwendet. Wird es dunkel, bekommt PD2 (INT0) low, dies löst den INT0-Interrupt aus. Beim Erwachen wird der dem sleep_mode() folgende Befehl ausgeführt.
Leuchtstern am Fenster mit "Booster"


// ZylonenaugeSchneeanimationSolar V1.2 (c) Oliver Mezger 6.01.2020 // 4MHz externer Schwinger B.O.D. bei 1,8V #include <avr/io.h> #include <util/delay.h> #include <avr/sleep.h> #define KEYREADER (~PIND&0x70)>>4 // Einlesen, invertieren, maskieren zurecht schieben unsigned char keyOld = 0; // alter Tasten-Zustand unsigned char keyEnter,keyExit; // gedrueckte und losgelassene Tasten volatile unsigned int zeit=0; // zaehlt 0,1ms runter in my_delay void my_delay(unsigned int z){ // 0,1 ms zeit=z; while(zeit); } void keyCheck(){ // Tastaturabfrage mit Flankendedektion unsigned char keyTest,tmp; keyEnter = 0, keyExit = 0; keyTest = KEYREADER; // Einlesen if (keyOld != keyTest){ // hat sich was getan my_delay(100); // Prellen abwarten tmp = KEYREADER; // noch mal Einlesen if (tmp == keyTest){ // ist es stabil? keyEnter = (~keyOld) & keyTest; // steigende Flanke !alt und neu keyExit = keyOld & (~keyTest); // fallende Flanke alt und !neu keyOld = keyTest; } } } unsigned char muster[]={0x78,0x74,0x72,0x71,0xb8,0xb4,0xb2,0xb1,0xd8, 0xd4,0xd2,0xd1,0xe8,0xe4,0xe2,0xe1}; unsigned char booster = 0; // Pulsbreite = 2µs*booster ISR(INT0_vect){ // wenn es dunkel ist wird ISR ausgelöst GIMSK &= ~(1 << INT0); // Interrupt wieder abschalten PORTD &= ~(1<<PD0); // Beleuchtung einschalten } ISR(TIMER0_COMPA_vect){ // Interrupt Service Routine unsigned char level; zeit--; if(booster){ asm volatile ("sbi 0x12,1"); // sbi PORTD,1 for(level=0;level<booster;level++) asm volatile ("nop"); asm volatile ("cbi 0x12,1"); // cbi PORTD,1 } } void enter_sleep(void){ PORTD |= 1<<PD0; // Beleuchtung ausschalten GIMSK |= (1 << INT0); // Interrupt0 ermoeglichen MCUCR = (1<<SM0) | (1<<SE); // Schlafmodus auf PWR_Down sleep_mode(); // Schalfen schicken /* Aufgewacht! */ MCUCR = 0; } int main(){ DDRB=0xff; // PORTB auf Ausgang signed char musterz=0; // Position 0 char z=0,i,up=0; PORTD = 0b01111000; // Pullups an PD2 hat pullDown, PD0 an DDRD = 3; // PD0 und PD1 als Ausgang TCCR0A |= 1<<WGM01; // Timer im CTC-Mode TCCR0B |= 2; // Vorteiler 1: Phi/1; 2: Phi/8; 3: Phi/64; 4: Phi/256; 5: Phi/1024 TIMSK |= 1<<OCIE0A; // Timer/Counter0 Output Compare Match A Interrupt Enable OCR0A = 49; // Wert bei dem der Timer wieder auf 0 gesetzt wird sei(); while(1){ if(PIND&4) enter_sleep(); // wenn es hell ist schlafen else{ keyCheck(); // Maske,NLogik if(keyEnter&1){ // Taste0 gedrueckt? if(booster>0)booster--; } if(keyEnter&2){ // Taste1 gedrueckt? if(booster<15)booster++; } musterz=8+rand()%8; z=2+(rand()%32); for(i=0;i<=z;i++){ my_delay(300); } z=2+(rand()%16); while (musterz>=0){ PORTB=muster[musterz--]; for(i=0;i<=z;i++){ my_delay(200); } } PORTB=0; if(up){ // Helligkeit veraendern booster++; if (booster>=10){ up=0; } } else{ if (booster>0) booster--; else up=1; } } } }
Der Booster
Die Akkus werden nicht gut entladen, daher soll ein "Booster" für den notwendigen Verbrauch sorgen. Ein Step-Up Wandler erhöht die Spannung, die Pulsweitenmodulation (PWM) wird per Software realisiert. Damit können nicht so hohe Frequenzen > 50 kHz wie mit der Timer-Hardware erzeugt werden, gewählt wurden: 4MHz Systemtakt mit externem Keramikschwinger, 10 kHz ISR-Aufruf. In der ISR wurde zwecks Zeitoptimierung Inlineassembler verwendet. Jede 100µs wird die Induktion für eine Zeit von 0..30µs (einstellbar in der Variablen booster) mit PD1 gegen GND geschaltet und dabei aufgeladen. Die gespeicherte Energie wird dann an die Lichterkette abgegeben, dabei die Spannung erhöht. Längere Ladezeiten ton würden die Spule in die Sättigung führen, dabei steigt der Strom an, ohne mehr Energie zu speichern, oder den maximalen Strom des Transistors überschreiten. Experimentel wurde eine Induktion von 4,7mH als geeignet ermittelt.
Hier sollten Formeln stehen! Denkfaul empirisch ermittelte Werte statt dessen...
Dimensionierung von Schaltnetzteilen
Cool, die Berechnung bei Dr. Heinz Schmidt-Walter passen gut zu meinen ermittelten Werten!
Ein paar Ströme
Bei Helligkeit im Schlafmodus: 0,04 mA
Volle Pulle Booster bei vollem Akku: 30 mA
Stromverbrauch: 2,5V: 4..22mA; 2,7V: 8..26mA
Unter 1,8V im B.O.D-Zustand: 0,2 mA
Gesammelte Informationen
Verschiedene Solarzellen (z.T aus Gartenlampen)
Gemessen mit 100 W Glühlampe und 1000 Lux Beleuchtungsstärke wurden die Lehrlaufspannung und der Kurzschlusstrom.
Bezeichnung | Spannung in V | Strom in mA |
---|---|---|
Würth Solar | 4,5 | 49 |
Gartenleuchte | 2 | 19,3 |
Gartenleuchte | 4,3 | 25 |
Gartenleuchte | 4,4 | 18 |
LED Spannungs-Strom-Kennlinie
Preiswerte LED-Lichterketten mit 24 LED.
Schaltschwellen der Eingänge
Interrupteingang soll als Spannungswächter für die Helligkeit der Solarzelle dienen. Die Eingänge sind mit Schmitt-Triggern versehen aus den Diagrammen des Datenblatts können die Schaltschwellen entnommen werden. Bei 2,6V Batteriespannung low: 1,05V high: 1,3V