In­halts­ver­zeich­nis

Was ist passiert?

Erste Sichtung

Was war das Problem?

Was tun?

Software

Tag/Nacht-Unterscheidung

Firmware

Jetzt leuchtet sie wieder!


Was ist passiert?

Damals hat ein schöne Solarlampe hat den Geist aufgegeben. Ich schraube so etwas immer auf, vielleicht kann man es ja reparieren. Das hat hat auch geklappt. Nun ist die Lampe nach einem Sturm unters Auto geraten. Das hat eine erneute Reparatur notwendig gemacht. Das gibt mir die Gelegenheit, das Ganze ein wenig zu dokumentieren.

Erste Sichtung

Der erste Eindruck zeigte ein aufgeräumtes Innenleben.

Die Elektronik der Leuchte

Unter der Solarzelle befindet sich eine Platine und ein 600 mAh Li-Ion-Akku. Die Platine enthält einen Mikroprozessor, der die LEDs ansteuert. Die geschieht jeweils über einen Treibertransistor. Die Strombegrenzung für die LEDs geschieht über Vorwiderstände. Auf der Platine befanden sich ein BMC zum Schutz des Akkus, ähnlich wie hier. Alles ist in SMD-Technik ausgeführt.

Auf der LED-Leiste sind zwei RGB-LEDs, die parallel betrieben werden, eine gelbe und eine weiße LED. Die LED-Leiste ist mit einem Flachbandkabel und einem Stecker mit der Platine verbunden.

Was war das Problem?

Optisch konnte man keinen Fehler erkennen. Auch der Akku war voll geladen. Die Leiterbahnen konnte man auf der Platine gut verfolgen. Die Akkuspannung lag am μC und an den Treibertransistoren an. Damit konnte man Ausschließen, dass die Schalter (Ein/Aus- und Farbwahl) das Problem waren. Wenn man die Pins des μC, die zu den Treibtransistoren führten, mit einem Widerstand (10 kΩ) an den Pluspol des Akkus legte, leuchten auch die LEDs auf. Das deutet alles auf einen defekten Mikroprozessor hin.

Was tun?

Der Typ des µC war nicht zu beschaffen und wie hätte ich ihn programmieren sollen? In meiner Bastelkiste hatte ich noch einige ATtin45 und ATtiny85. Mir denen kenne ich mich aus.

Den defekten μC konnte ich ohne Beschädigung der Platine mit einem SMD-Entlötkolben auslöten.

SMD-Enlötkolben

Der Package-Typ des µC war SOP. So etwas kann man mit viel Gefühl auch noch per Hand verlöten. Auf die relevanten Pin-Anschlüsse des µC auf der Platine habe ich kurze Kabel angelötet, die auf der anderen Seite mit einer 8-poligen DIP-Fassung für einen ATtiny45 verbunden wurden.

ATtiny ersetzt original μC

Wenn man den ATtiny "normal", d.h. im eingebauten Zustand (In-System-Programming, ISP) programmieren möchte, kann der Reset-Pin nicht anderweitig benutzt werden. Wenn man ihn per Fuse als regulären I/O-Pin konfiguriert, ist anschließen nur noch eine Programm im HV-Modus möglich. Dabei wird Reset mit 12 V angesteuert. Das mag aber der Rest der Schaltung meist nicht. Von den 8 Pins bleiben somit 5 für die freie Verwendung übrig.

Ein Pin ist notwendig, um die Spannung zu messen, die die Solarzelle liefert. Hierdurch wird erfolgt die Tag/Nacht-Unterscheidung. Die Lampe soll schließlich nur bei Dunkelheit leuchten. Bleiben vier Pins für die Ansteuerung der (fünf) LEDs. Ich habe mich entschlossen, die weiße LED auszulassen. Verbleiben die Farben Rot, Grün, Blau und Gelb.

Software

Tag/Nacht-Unterscheidung

Die Lampe soll natürlich nur bei Dunkelheit brennen. Tagsüber soll der Akku geladen werden. Über den ADC des ATtiny wird die Spannung der Solarzelle abgegriffen, nicht direkt sondern auch hier wurde ein Pad des ehemaligen µC benutzt um reale Bedingungen zu schaffen.

Als erstes habe ich den entsprechenden Pad und die Stromversorgung an den ATtiny angeschlossen. Dazu habe ich eine Software-RS232 eingebunden, die permanent den ADC-Wert ausgegeben hat. Eine LED (die gelbe, weil si relativ hell ist) habe ich ebenfalls angeschlossen.

 Ich hatte glücklicherweise noch eine zweite Lampe des gleichen Typs. Die habe ich neben meinen Testaufbau gestellt. Nun habe ich langsam die Rollladen herab gelassen, bis die noch funktionierende Lampe aufleuchtete. Den entsprechenden ADC-Wert habe ich als Einschaltspannung verwendet.

Im zweiten Schritt habe ich LED eingeschaltet und die Rollladen wieder hochgezogen, bis die funktionierende Lampe wieder ausging. Der zugehörige ADC-Wert markiert die Ausschaltspannung. Bei diesem Schritt muss auch das Gehäuse (zumindest lose) angebracht sein. Die Lichtreflexion an der Innenwand des Gehäuses liefert zusätzliches Licht und beeinflusst die Solarzellenspannung.

Das Ganze sollte man min. dreimal wiederholen um ordentliche Werte zu erhalten.

Firmware

Mit den Daten für die Ein- und Ausschaltspannung kann man nun eine passende Firmware für die Lampe schreiben. Erleichtert wurde das ganze durch das integrierte BMC. Man muss also keine Rücksicht auf Über- oder Tiefentladung des Akkus nehmen.

 Die Farbe der Lampe sollte von Tag zu Tag automatisch wechseln. Dazu gibt es ein Array mit den Pin-Codes (colors[]), das zur Ansteuerung der LEDs dient. Der Index zu diesem Feld wird im EEPROM gespeichert.

Es gibt zwei Gründe warum die Lampe ausgeht. Wenn die Akku-Ladung für die kurze Nacht im Sommer ausreicht, wird die Solarspannung, wenn es hell wird, wieder ansteigen und irgendwann die Ausschaltschwelle überschreiten. In diesem Fall verbleibt die Firmware in loop. Wenn die Ladung nicht reicht, wird das BMC den Akku abschalten. Wenn die Solarzelle dann tagsüber wieder etwas Strom geliefert hat und das BMC den Akku wieder frei gibt, erfährt der ATtiny einen PowerOn-Reset. Er steigt über setup wieder in das geschehen ein.

/*
 Name:		SolarLED.ino
 Created:	01.03.2024 14:08:09
 Author:	bieno
*/


EEMEM uint8_t lastColor = 0;
uint8_t color;

bool isNight = false;

/*
Vcc            Kabel rot
PB0 - rot RGB  Kabel orange
PB1 - grün RGB Kabel gelb Markierung grün
PB2 - blau RGB Kabel gelb Markierung blau
PB3 - ADC      Kabel weiß
PB4 - Yellow   Kabel gelb
PB5 - Reset 10 k an Vcc
GND            Kabel grün
*/

uint8_t colors[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, (1 << PB4) }; // Pins für die verschiedenen Farben
//                   Rot   Grün  R+G   Bblau B+R   B+G   Gelb
uint8_t colorMask = (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB4); // Maske für die benutzen Pins


void setup() {
   DDRB |= colorMask; // Pins auf Output

   color = eeprom_read_byte(&lastColor); // Letzte benutze Farbe auslesen
   if (color >= sizeof(colors)) {        // da ist etwa schief gelaufen ...
      color = 0;                         // ... von vorn beginnen.
      eeprom_write_byte(&lastColor, color);
   }
}


void loop() {
   int16_t res = analogRead(PB3); // Solarzellenspannung einlesen
   if (!isNight && res < 210) {   // Es wird Nacht
      isNight = true;
      color++;                    // nächste Farbe wählen und abspeichern
      if (color >= sizeof(colors))
         color = 0;
      eeprom_write_byte(&lastColor, color);
   }

   if (isNight && res > 410)   // Es wird wieder hell 
      isNight = false;

   if (isNight) 
      PORTB = (PORTB & ~(colorMask)) | colors[color]; // LEDs einschalten
   else
      PORTB &= ~(colorMask);            // LEDs ausschalten

   delay(1000); // Bis zur nächsten Durchlauf warten
}

Jetzt leuchtet sie wieder!

Nun musste ich nur noch die Bauteile wieder an der richtigen Stelle platzieren. Für den ATtiny war neben der Platine noch genügend Platz.

Alles wieder montiert

... und voilà, jetzt leuchtet sie wieder:

Jetzt leuchtet sie wieder