Hallo an alle Bastler und Hobbyprogrammierer! Ich habe hier mal ein kleines Projekt als Anregung bzw. zur Diskussion eingestellt. Es ist eine µC-basierte Steuerung für eine Solarlampe. An meinen Garten-Solarlampen hat mich schon immer gestört, dass der simple, diskret aufgebaute Step-Up Konverter ungeregelt ist, d.h. die Helligkeit mit sinkender Akkuspannung abnimmt. Inspiriert durch einen Artikel im ELV-Journal 3/2007 (SLS2) habe ich dann diese Steuerung entwickelt. Warum? Weil's Spaß macht und weil ich beim ELV-Teil nicht's am µC-Programm ändern kann! Einziger Nachteil: Die billigen LED-Treiber von Zetex sind schwer zu bekommen. Also dachte ich mir, dass ich die LED-Stromregelung einfach mit in den µC packe... bitte nicht schlagen, ich weiß, es gibt genug andere IC's dafür... aber ich habe dadurch einiges über DC-DC Konverter und deren Regelung gelernt! Ausserdem braucht sich meine Schaltung mit einem Wirkungsgrad von ca. 80% nicht gerade verstecken :-) Zu verbessern wären der Schalttransistor (ein low Uce,sat) und vielleicht die Schottky-Diode. Ich habe mich mich eben mit dem begnügen müssen, was die Bastelkiste so her gab! Das Projekt ist noch lange nicht fertig. So fehlt das eigentliche Feature: Die intelligente Verteilung der Akkuenergie, also Abschaltung der Lampe mitten in der Nacht, wenn's keiner braucht, dafür aber noch Energie übrig haben für den nächsten Morgen, etc. Ausserdem fehlen mir die Schwellwerte der Solarzellen-Spannung, zur An-/Abschaltung der Lampe. Muss ich erst noch messen. Dürfte aber eh' bei jeder Lampe etwas anders sein! Und zu guter Letzt muss das ganze auf 'ne eigene Platine drauf... Trotzdem denke ich, dass man sich hierbei einige Anregungen holen kann, insbesondere wenn man MSP430 programmieren will. Denn nahezu alle Funktionen des verwendeten MSP430F1232 habe ich sozusagen ausgereizt. Einige Features: - Verwendung eines 32,768kHz Quarzes als Referenz-Clock - periodischer Abgleich des internen DCO-Oscillators mit den 32,768kHz (Timer_A mit Capture) - Timer_A mit Compare-Registern zur Erzeugung einer PWM mit variablem Duty-Cycle - Synchronisierung der ADC-Messung mit der PWM - digitale PI-Regelung (LED-Strom) - versch. Messungen mit dem internen ADC10 - versch. Low-Power-Modi - Statemachine mit (zum Teil) interrupt-gesteuerten Zustandsänderungen Im Anhang sind der Schaltplan und die C-Sourcen, die ich mit IAR EW V3.42A (Kickstart) erstellt habe, sowie Flowcharts zum (hoffentlich) besseren Verständnis. Noch Fragen? Immer her damit! Außerdem würde ich mich natürlich über Anregungen, Hinweise und konstruktive Kritik freuen. Ansonsten viel Spaß damit. Gruß, Stefan P.S.: Ich glaube, es versteht sich von selbst, dass jeder diese Schaltung und das Programm verwenden darf. Es darf sich aber keiner beschweren, wenn irgend etwas nicht so funktioniert, wie er/sie sich das vorgestellt hat... sprich: ich übernehme dafür kein Haftung!
Läuft das Integral ErrSum nicht ziemlich schnell an seine Grenzen? Ich sehe gar keinen Timer oder Warteschleife, die das verhindert (wenn du die Regelung zu schnell aufrufst dann läuft der halt sehr schnell in die Grenzen)
Prinzipiell hast Du recht, in diesem speziellen Fall geht ErrSum allerdings nicht in die Begrenzung (zumindest nicht im Normalfall). Die Sollgröße ist ja 109 (= 8mA LED-Strom), d.h der Fehler Err kann auch nur max. 109 sein. Die Begrenzung für ErrSum ist 32767/4=8191. D.h. ich könnte den max. Fehler (Err=109) 75-mal in ErrSum aufsummieren, ohne in die Begrenzung zu kommen. Mein Abtast-/Regelintervall ist 2*85µs=170µs. Bei 75 Intervallen ergäbe das eine Regelungsdauer von 75*170µs=12,75ms. Der LED-Strom ist aber schon nach ca. 3ms eingeregelt -> genug Puffer :-) Oder anders: Wenn der LED-Strom auf den Sollwert eingeregelt ist, gilt: PWM = (32*Err + 4*ErrSum)/128, mit Err=0. Die Stellgröße ist dann PWM=42, d.h. ErrSum = PWM*128 / 4 = 1344 << 8191 Aber warum willst Du mit einem Timer oder Warteschleife einen Überlauf verhindern? Dann wäre doch das Abtastintervall nicht mehr konstant?
Kleiner Bug-Fix: > void Set_DCO (void) > { > ... > while (!(CCIFG & CCTL2)); > { > if(DCO_Timeout == 460) > WDTCTL = 0; > } > ... > while (!(CCIFG & CCTL2)); > { > if(DCO_Timeout == 460) > WDTCTL = 0; > } > ... > } Hinter while ((!(CCIFG & CCTL2)) natürlich das Semikolon weglassen!
geiler Fehler :) Meckert C gar nicht die { } Klammern an, die mit Semikolon keinen Sinn mehr ergeben?
Lupin wrote: > geiler Fehler :) > > Meckert C gar nicht die { } Klammern an, die mit Semikolon keinen Sinn > mehr ergeben? Die { } markieren nur einen Block der Belibig oft auftauchen darf... Da kann (und darf) der Compiler nicht "meckern"
> warum? Klammert doch nur einen Block
ja schon, aber der Block soll eben wärend der while-Schleife abgefragt
werden. Ansonsten könnte in while() eine Endlosschleife entstehen!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.