Hallo,
ich habe eine Powerled Steuerung entworfen, die auf Basis eines Buck
Converters funktioniert.
Es werden drei 3W LEDs gesteuert. Die LEDs sind in Reihe geschalten und
werden mit 12V versorgt.
Daten der LED:
-If = 700mA
-Uf = 3,4V ... 4V
Die Regelung übernimmt ein ATTINY13A.
Die Helligkeit ist über ein Poti einstellbar von 0-100%.
Da liegt nun auch das Problem, soblad der LED Strom 150mA unterschreitet
flackert das Licht, bei bestimmten Poti Stellungen. Darüber funktioniert
die Steuerung tadelos.
Ich vermute stark das es an der eher dürftig programmierten Regelung
liegt.
Hat einer eine Idee wie man die Regelung verbessern könnte?
C-Code und Schaltplan liegen im Anhang.
Vielen Dank im Voraus für die Antworten,
ruebe
Ohne dein Programm genau zu analysieren: Bist du dir sicher, dass
bootup() reentrant ist? Eigentlich muss man das dem Compiler extra
sagen.
Und selbst, wenn es so definiert ist: Bei bestimmten Kombinationen aus
Soll und Ist ruft sich bootup() immer wieder selbst im Kreis auf.
Die bootup funktion habe ich selbst geschrieben, ist kein bootloader
oder ähnliches.
Sie dient ledigilich dazu die LEDs langsam zu starten da sonst der strom
überschwingt.
Der Name war vielleicht etwas unglücklich gewählt^^
ruebe schrieb:> Schalplan.PNG
Das bezeichnest du als Schaltplan? Da sind Linien durch die Symbole
gezeichnet, es fehlen Werte und ein FET sieht auch irgendwie anders aus
in einem Schaltplan.
Nur kurz deinen Code überflogen, aber das sieht schon viel zu
kompliziert aus. Nimm mal den Elko parallel zur LED raus (ich denke mal
der soll parallel liegen, wird aus deinem "schaltplan" nicht ersichtlich
;-)).
Das du den Strom noch über einen Tiefpass schickst verhindert natürlich
auch eine vernünftige Regelung.
Die Regelung würde ich einfach so schnell wie möglich machen mit festen
Grenzen für die PWM (duty cycle z.B. max. 50% oder so - nur damit beim
Experimentieren nichts kaputt geht).
Am besten ADC und PWM mit gleicher Frequenz laufen lassen, Tiefpass am
AD Eingang auch auf diese Frequenz ausgelegt, damit du am Tiefpass quasi
immer den Strom der vergangenen Periode siehst um den duty cycle für die
nächste einstellen zu können.
Auch das Mitteln mehrerer ADC messungen bringt nichts, entweder filtert
man richtig (mit einem echten zeitlichen Bezug der Messungen zueinander,
damit man die Grenzfrequenz des Filters weiss) oder man lässt es gleich.
@Marius
Ich muss dir recht geben, dass Schaltplan und Code nur zweckmäßig sind
:-)
Den Tiefpass benötige ich,da ich den Mittelwert des Stromes einlesen
möchte. Denn ich habe nur bei durchgeschaltetem Mosfet einen Stromfluss
durch den Shunt.
Der ADC läuft schon so schnell wie laut Datenblatt möglich.
Der Elko parallel zur LED sollte zur Glättung dienen, ich werde ihn aber
mal rausnehmen und schauen obs hilft.
@lpg
Das sieht interessant aus. Werde ich bei Gelegenheit mal auspropieren.
ruebe schrieb:> Die bootup funktion habe ich selbst geschrieben, ist kein bootloader> oder ähnliches.
Hast du gelesen und verstanden, was ich geschrieben habe?
Deine Routine, gekürzt:
//Fährt beim einschalten der LED sanft auf Sollwert
uint8_t bootup(uint16_t soll)
{
[...];
{
[...]
if((OCR0A > (OCRMAX/4))&& (ist<10) && (i > 100))
{
bootup(soll);
}
[...]
}
return ist;
}
Siehst du nun, wie sich die Routine wieder selbst aufruft? Ist das
gewollt? Hoffentlich nicht, denn das führt ins Chaos.
Vorsicht beim programmieren! Wenn du den Programmer anschliesst, muss
auf jeden Fall die Power-LED raus sein, denn MOSI wird den FET mit
durchsteuern. Wenns irgendwie geht, nimm eine andere, weniger
verfängliche Pinbelegung.
Abgesehen vom etwas merkwürdigen 82µF Wert - ist der ganz nahe am MC?
Und setzt da noch einen 100nF hin gegen PWM Spitzen. Ein 10nF am ADC
Eingang schadet auch nicht.
@Georg
ok da habe ich dich missverstanden :)
aber das die Routine sich aufruft ist gewollt. Dieser Fall tritt ein
wenn die Leitung zu den LEDs unterbrochen ist.
@Matthias
Direkt am µC sitzt noch ein 100nF Kondensator, den ich aber bei der
Erstellung des Schatplans vergessen habe.
Die mit der Pinbelegung war anders nicht möglich. Ich benötige für die
LEDs entweder den OC0A (MOSI) oder den OC0B (MISO) Ausgang.
Marius S. schrieb:> Das bezeichnest du als Schaltplan?
Nein! ruebe bezeichnet es als "Schalplan"... ;-)
ruebe schrieb:> aber das die Routine sich aufruft ist gewollt. Dieser Fall tritt ein> wenn die Leitung zu den LEDs unterbrochen ist.
Hoffentlich ist dein Stack groß genug...
Was passiert denn bei einem Funktionsaufruf und bei einem Rücksprung?
Und wass passiert bei 1000 Funktionsaufrufen ohne Rücksprung?
ruebe schrieb:> Darüber funktioniert die Steuerung tadelos.
Glaube ich nicht. Kannst du mal Bauteilwerte in die Schaltung schreiben
(Widerstände, Mosfet, ...)?
> die auf Basis eines Buck Converters funktioniert.
Wo sind da nochmal die LEDs angeschlossen? Für mich sieht das eher nach
einer vermurksten Boost-Architektur aus.
Schaltregler haben idR. einen Eingangskondensator und einen
Ausgangskondensator. Ich kann mindestens einen davon in deinem Konzept
nicht entdecken...
Lothar Miller schrieb:>> aber das die Routine sich aufruft ist gewollt. Dieser Fall tritt ein>> wenn die Leitung zu den LEDs unterbrochen ist.> Hoffentlich ist dein Stack groß genug...> Was passiert denn bei einem Funktionsaufruf und bei einem Rücksprung?> Und wass passiert bei 1000 Funktionsaufrufen ohne Rücksprung?
ok das versteh ich nicht :)
darf man eine funktion nicht wieder aufrufen??
Lothar Miller schrieb:>> Darüber funktioniert die Steuerung tadelos.> Glaube ich nicht. Kannst du mal Bauteilwerte in die Schaltung schreiben> (Widerstände, Mosfet, ...)?
Ich habe den Schaltplan mal in LTSpice gezeichnet.
Habe zwar kein Oszi um genauer nachzumessen, aber soweit ich es
beurteilen kann funktioniert die Schaltung.
Die LEDs leuchten gleichmäßig und es bleibt alles kühl :)
Also wenn die Funktion sich selbst immer wieder Aufruft ( wenn ich mich
recht entsinne wird das auch "rekursiv" genannt) dann wird jedes mal auf
dem Atack die aktuellen Informationen durch push und pop (im genrierten
Assembler-Code) auf den stack geschoben und nach Lothars Szenario dann
1000mal und dabei kann es dr dann passieren das der Stack überläuft...
verbessert mich bitte falls ich falsch liege...
Heinrich nölte:
>ach ja und schön wäre es wenn du den Schaltplan wirklich einmal schön>machst, damit man besser versteht was da zu drinne ist
Guck Dir einen Schaltplan von einem koreanischen Fahrzeug an, dann hast
Du Grund zur Klage.
Heinrich schrieb:> dann wird jedes mal auf dem Atack die aktuellen Informationen durch push> und pop (im genrierten Assembler-Code) auf den stack geschoben
Beim Funktionaufruf wird nur gepusht. Und nach ein paar Aufrufen
hintereinander ist der Stack voll, und es werden dann irgendwelche
Variablen oder Werte überschreiben, die da gerade im Speicher liegen.
Und ab dieser Stelle kann dann eigentlich alles passieren.
ruebe schrieb:> Ich habe den Schaltplan mal in LTSpice gezeichnet.
Der sieht jetzt aber schon ein wenig anders aus...
> Die LEDs leuchten gleichmäßig und es bleibt alles kühl :)
Aber dein Design ist eine EMV-Schleuder. Denn mindestens zwischen Vcc
und GND muss ein Kondensator. Und in deinem Spice-Aufbau ist der
tatsächlich drin...
BTW:
> drei 3W LEDs ... in Reihe geschalten ... mit 12V versorgt.> Daten der LED: -Uf = ... 4V
Da bleibt evtl. nicht mehr viel über. Dein Spice-Modell mif Uf = 9,6V
ist da irgendwie "unterdimensioniert". Na gut, in der Simulation ist die
Versorgungsspannung ja auch 20V. Und auch die anderen Bauteile sind im
Plan und in der Simulation irgendwie anders (Spule, Kondensator,
Shunt)...
Das nimmt mich jetzt auch wunder:
Eine Funktion die sich selbst aufruft ist Murks, das ist mir klar. Aber
wäre das nicht ein fall für ein goto? Oder schreibt man die Funktion in
eine schleife aus der man rausspringt (break;) wenns fertig ist?
Sean Goff schrieb:> Eine Funktion die sich selbst aufruft ist Murks
Nicht unbedingt. Aber man muss wissen, was man tut...
> Aber wäre das nicht ein fall für ein goto?
Wer ein goto verwendet, hat sein Softwarekonzept noch nicht ganz fertig
gedacht...
Lothar Miller schrieb im Beitrag
>> Aber wäre das nicht ein fall für ein goto?> Wer ein goto verwendet, hat sein Softwarekonzept noch nicht ganz fertig> gedacht...
Weshalb denn? Mit gotos ist man doch sehr flexibel? Ich selbst benutze
es zwar nicht, aber es gab es auch schon, dass ich mir einen simplen
sprung gewünscht hätte.
Sean Goff schrieb:> Mit gotos ist man doch sehr flexibel?
Genau darum: beliebig flexibel. Oder anders gesagt: man kann den
Sofwareablauf nicht mehr nachvollziehen. Krass ausgedrückt: ein GOTO ist
der erste Schritt zur Kündigung. Es sei denn, du hast eine unheimlich
gute Ausrede...
Lothar Miller schrieb:> Der sieht jetzt aber schon ein wenig anders aus...
inwiefern? Das einzige was in dem EAGLE Schaltplan fehlt sind die
PowerLEDs (werden an Klemmen angeschlossen) und der Kondensator an der
Versorgungsspannung. Den habe ich mir gespart, da ich nur einen kurzen
weg zu einer 12V Autobatterie habe :)
Lothar Miller schrieb:> Da bleibt evtl. nicht mehr viel über. Dein Spice-Modell mif Uf = 9,6V> ist da irgendwie "unterdimensioniert". Na gut, in der Simulation ist die> Versorgungsspannung ja auch 20V. Und auch die anderen Bauteile sind im> Plan und in der Simulation irgendwie anders (Spule, Kondensator,> Shunt)...
Es muss ja auch nicht viel übrig bleiben, an meinem Shunt habe ich einen
Spannungsabfall von höchstens 0,35V.
Die Messungen haben gezeigt dass ich ab einer Versorgungsspannung von
~11V den maximalen LED Strom erhalte.
Und selbst wenn die Versorgung auf 10V abfällt geben die LEDs noch schön
hell...
naja mit dem LED Model komme ich ziemlich nahe an die Daten der LEDs ran
700mA*2,5Ohm+9,6V = 11,35V.
Die Schaltung erfüllt ihren Zweck und da diese nur in einem Bauwagen
verbaut ist reicht das allemal :)
Das einzige Problem ist der Code, ich stecke noch in den Kinderschuhen
was programmieren betrifft.
Gbit es auch Probleme wenn ich die Bootup Funktion in main immer wieder
aufrufe also so:
bootup:
nur mal zur Anmerkung
Was sollen denn die ganzen volatile bei deinen lokalen variablen im
main?
Es ist zwar schon so, dass ein vergessenes volatile einem einige Stunden
Fehlersuche bescheren kann, aber einfach alles damit zu deklarieren
macht auch keinen Sinn!
Dann schalt doch gleich die Compiler Optimierung aus.
Apropos Optimierung:
Bei deiner Mittelwertbildung der ADC Werte in bootup
(ADC_Read(IST_PIN,1)+ADC_Read(IST_PIN,1)+ADC_Read(IST_PIN,1)+ADC_Read(IS
T_PIN,1))/4;
Hast Du schon überprüft, ob die ADC_Read tatsächlich 4 mal aufgerufen
wird?
Ich weis es jetzt nicht, könnte aber evlt. wegoptimiert werden, dann
funktioniert dein Filter nicht.
nobi schrieb:> Hast Du schon überprüft, ob die ADC_Read tatsächlich 4 mal aufgerufen> wird?
Den Assembler Code habe ich mir nicht angeschaut, aber der Strom steigt
auf den richtigen Wert an. Daher dachte ich das es funktioniert.
Um das zu messe habe ich in die Schleife der Bootup Funtkon eine sehr
hohe delay Zeit eingefügt und einfach den aktuellen Strom gemessen.
nobi schrieb:> Es ist zwar schon so, dass ein vergessenes volatile einem einige Stunden> Fehlersuche bescheren kann, aber einfach alles damit zu deklarieren> macht auch keinen Sinn!
Anfangs waren diese ohne volatile. Ich habe es irgendwann davor
geschrieben als ich versuchte das flackern wegzubekommen.
Habe vergessen es wieder zu entfernen^^
Aber an der Funktion und an der Programmgröße hat sich nichts wesentlich
verändert^^
Hat aber am
habe die hälfte vergessen^^
Wenn man die Compileroptimierung abschaltet passt das Programm nicht
mehr auf den Chip.
Von dem her optimiert er schon noch einiges^^
Kenne mich aber zu wenig aus um zu sagen wo etwas optimiert wird und wo
es dann Probleme gibt^^
Du solltest Die optimierung ja auch nicht wirklich ausschalten,
Ich wollte damit nur sagen, alles mit volatile zu implementieren
verhindert, dass der Compiler gewisse optimierungen durchführt, und es
macht schon Sinn sich Gedanken zu machen, wo man es braucht und wo
nicht.
Hast Du dir in deiner Spice Simulation mal den Verlauf von Vadc
angeschaut?
wenn Du die Spannung als Messgröße für den Strom nimmst dann ist es
reiner Zufall, was dabei rauskommt (auch bei 4fach mittelung)
nobi schrieb:> Hast Du dir in deiner Spice Simulation mal den Verlauf von Vadc> angeschaut?> wenn Du die Spannung als Messgröße für den Strom nimmst dann ist es> reiner Zufall, was dabei rauskommt (auch bei 4fach mittelung)
Du hast recht in der Simualtion habe ich bei C3 ausversehen 4.7nF
anstatt der verbauten 4.7µF eingetragen.