[Bascom] Soft-PWM und Uart Problem

  • Hi Leute.


    Ich mach noch mal einen neuen Thread auf. Zwar gleiches Projekt, aber neues Problem.


    Ich versuche immer noch einen µC per PC zu steuern. Klappt auch inzwischen wunderbar!!
    Da ich allerdings 9 PWM Kanäle benötige, blieb mir keine andere Wahl als Software PWM zu benutzen.


    Beides für sich funktioniert auch tadellos. Meine Soft-PWM macht genau das was sie machen soll und meine Uart Empfang macht auch genau das was er machen soll.
    Nur wenn ich beides zusammen bringe, kommt es zu Problemen.


    Ich schicke per Uart 9 Zahlenwerte für die Led-Helligkeit betrennt durch ein Leerzeichen. Schicke ich einfache Zahlenwerte ( 1 2 3 4 5 6 7 8 9 ) klappt alles.
    Sobald ich aber höhere Werte wie ( 100 100 100 100 100 100 100 100 100 ) schicke, kommt es zu Empfangsstörungen.
    Ich häng euch mal die Zeilen aus dem Terminal mit dran, damit ihr seht was ich meine:

    Ich häng euch auch noch mal meinen Bascom Code mit dran.


    Hat irgendwer nen Tipp woran das liegen kann ??
    Ps.: Die Timer hab ich auch schon ausgetauscht. Egal ob Timer0 oder Timer2 es kommt der selbe Fehler


    Danke für die Hilde und viele Grüße
    Philipp





  • Hi Flipp86,


    doch, Du hast eine andere Wahl, als Software-PWM einzusetzen.
    Für PWM gibt es spezielle ICs, die LED-Treiberstufen gleich integriert haben. Die schließt man einfach per I2C oder SPI an den Atmel an und freut sich, was der dann plötzlich alles kann, ohne sich anstrengen zu müssen!


    Eine Weichware-PWM beschäftigt den Controller permanent, und alles, was dazwischen funkt, sorgt für Flackern. Oder (umgekehrt) die serielle Datenübertragung kommt aus dem Takt. Oder ...
    Weichware-PWM ist böse! Ist das Werk von finsteren Mächten! Sie verursacht Schlafmangel, schlechte Laune und Eheprobleme!

  • naja, bei Dir vielleicht... ;) - ich z.B. bin gar nicht verheiratet... :D


    auch gibt es hier im Forum etliche Projekte mit SW-PWM, vom 3-Kanal-Controller mit Fernbedienung über 3-Kanal-DMX-Receiver, 12-Kanal-DMX-Receiver, 24-Kanal-PWM-Dimmer mit USB-Ansteuerung und nebenbei DMX-Ausgabe bis zum 30-Kanal-DMX Dimmer, die *alle* problemlos laufen ohne dass was flackert oder ein RC5-Befehl verloren geht oder die Datenübertragung aus dem Takt kommt... Hier mal ne Matrix, die mit diesen 30-Kanal-SW-PWM-Receivern angesteuert wird...


    klar, oft ist es sinnvoller, einen eigenen PWM-LED-Treiber einzusetzen, aber dieses generelle "Urteil" über SW-PWM kann man so einfach nicht stehen lassen :!:

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

  • OhhhKeehh, ich nehme das mal staunend zur Kenntnis.
    Die 306Hz PWM-Frequenz bei 24 Kanälen sind ja schon ziemlich ordentlich.


    Mal davon abgesehen, dass ich eine PWM bis etwa 1kHz noch als flimmernd wahrnehme, gerade bei niedrigen bis mittleren Helligkeitswerten. Das war bei mir aber auch die Grenze dessen, was ich mit 'nem AVR noch hinbekommen habe, in Weichware; schneller schaffte ich es nicht, wenn der AVR auch noch Nebenaufgaben erledigen soll.


    Ein befreundeter Ing. Nachrichtentechnik und meine Wenigkeit haben mal zusammen 'nen Daddelautomaten entwickelt.
    Ich machte den größten Teil der Hardware, mein Freund die Software (in C). Trotz meines Protestes sollte die Schaltung keine Hardware-PWM bekommen, um die Kosten zu senken. Hinterher war mein Freund verzweifelt am Optimieren der Software, bis man so einigermaßen mit dem Ergebnis leben konnte, ohne dass serieller Datenempfang großartig zu sichtbarem Flimmern führte. Und der Mann versteht sein Handwerk.


    Für meine Wahrnehmung war die PWM-Frequenz am Ende zwar störend gering, aber anscheinend fiel das sonst keinem auf.


    Ich baue aber auch Lauflichter für Schausteller. Da kommt nicht selten Bewegung mit ins Spiel.
    Lahme PWM geht da gar nicht, sonst "malen" die bewegten LEDs gepunktete Linien in die Luft.
    Aber wie man das in Weichware in den Griff kriegen sollte, mit 'nem lahmen AVR, wäre mir persönlich schleierhaft.


    PWM unter 1kHz kommt mir grundsätzlich nicht ins Haus, weil ich es einfach störend finde.
    Wenn man direkt drauf blickt fällt es nicht auf, aber aus den Augenwinkeln heraus flimmert es halt (zumindest in meiner Wahrnehmung).
    Jedanfalls danke für die informativen Beispiele, Pesi!

  • Ja, wie schon gesagt, kommt's halt auch immer auf die Umstände drauf an...


    klar, wenn man direkt in die LED schaut, und die sich auch noch bewegt, fällt das Flimmern sehr viel stärker auf, als wenn man mit ner PWM-gedimmten LED was beleuchtet.


    Ich bin da auch "empfindlich", mich nerven z.B. viele PWM-gedimmten Auto-Rücklichter, wo manch anderer gar kein Flimmern sieht... aber wenn man ne Fläche/Objekt/Zimmer mit 244 Hz PWM beleuchtet, finde ich es OK...


    und es kommt eben auch drauf an, was der AVR sonst noch alles machen muss - wenn der nen kompletten Spielautomaten steuert sind natürlich keine 30 PWM-Kanäle mehr drin, aber bei den verlinkten Beispielen muss er ja ausser der PWM nur noch Daten empfangen und evtl. umsortieren, bzw. selbst Effekte erzeugen (der Controller).


    Natürlich wird der Ing. sein Handwerk verstehen, keine Frage, aber es macht auch noch nen kleinen Unterschied, ob man in C oder asm programmiert, auch bei optimalen Compiler-Einstellungen kommt halt bei C oft mehr Code raus, als wenn man das gleich in asm schreibt.


    hier z.B. (die Beispiele), die DMX-Empfangsroutine braucht gerade mal (müsste ich abzählen, wenn's genauer sein soll) ca. 20-30 Takte - es kann also der Aufruf der PWM-Routine max. 30 Takte verzögert werden.


    ein PWM-Durchlauf ist ja 255 Aufrufe, irgendwo da werden die LEDs ein- bzw. ausgeschaltet, der verzögerte Aufruf fällt nur dann in's Gewicht, wenn es gerade das Segment ist, in dem sich an der LED was ändert - also wenn sie z.B. auf 128 eingestellt ist, und der Aufruf 100 kommt verzögert, dann macht das überhaupt nix.


    dieser worst case, also dass die Empfangs-ISR genau ein paar Takte vor der PWM-ISR aufgerufen wird, und dann noch bei nem Segment, wo sich an der LED was ändert, kommt halt statistisch gesehen höchst selten vor, und auch wenn das mal passiert, fällt es nicht auf, wenn die LED dann halt mal 20 Takte länger an ist, als sie sein soll...


    Und Lauflichter für Schausteller würde ich natürlich auch nicht mit SW-PWM steuern, da würde ich gleich so fertige "Digitale Pixel" mit WS2801, TM1804, LPD6803, etc. drin nehmen, alleine schon wegen dem Preis und der Verkabelung... ;)


    EDIT: Wenn's um ein paar Kanäle (3-9) geht, die man bei ner Schaltung mit AVR noch gedimmt braucht, wäre auch BCM eine Alternative, da kommt man bei 8 Bit und 20 MHz Takt dann auch auf ne Frequenz im 2-stelligen kHz-Bereich...

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

    Einmal editiert, zuletzt von Pesi ()

  • Hallo Pesi, was ist "BCM"?



    flipp86:
    Ich glaube ich weiß, wo Dein Problem liegt.


    Versuche doch mal, die seriellen Daten immer nur Byte für Byte abzuholen.
    Trifft ein serielles Byte ein, löst das einen Interrupt aus. In der Interrupt-Routine werden dann nur zwei Sachen gemacht:


    1) Das eine Byte wird in ein Byte-Array gestopft.
    2) Arraypointer inkrementieren.


    Also nix mit Buffer und so, sondern bei seriellem Interrupt immer nur ein einzelnes Byte "zu Fuß" abholen, statt die Sache Bascom zu überlassen..
    Außerhalb der Interrupt-Routine testen, ob das zuletzt empfangene Byte CR ist.
    Auch alle übrigen Byte-Dröseleinen, Löschen des selbstgestrickten Empfangsbuffers etc., stets außerhalb der Interrupt-Routine.
    Und beim Zerdröseln und Auswerten der empfangenen Daten die Interrupts ausschalten, sonst funkt noch was dazwischen, was ganz merkwürdige Phänomene verursacht.


    Deine Stringvariable "New_Command" ist mit 100 Bytes doch reichlich lang. Bascom ist krötenlahm, wenn es Strings zusammendröselt.
    Frei aus dem Gedächtnis ist es so, dass Bascom immer den kompletten String umkopiert, wenn auch nur ein einziges Zeichen hinzugefügt werden muss. Man nagle mich auf letztere Aussage nicht fest, aber sowas in der Art könnte hier "unter der Haube" passieren.
    Darum also lieber mit 'nem Bytearray arbeiten, immer schön Zeichen für Zeichen.

  • Und beim Zerdröseln und Auswerten der empfangenen Daten die Interrupts ausschalten, sonst funkt noch was dazwischen, was ganz merkwürdige Phänomene verursacht.

    Das würde ich dann aber nicht machen, da Du damit ja auch die SW-PWM "ausschaltest"... ;) - und auch Daten verlierst, falls während der Auswertung schon wieder neue rein kommen.


    lieber das empfangene Array in ein zweites umkopieren, und das dann auswerten, das Umkopieren sollte recht schnell gehen, und dann hat man genug Zeit, die empfangenen Daten auszuwerten, ohne dass sie währenddessen von neuen überschrieben werden.


    "BCM" heisst "Binary Code Modulation"

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

  • "... aber hüte Dich: Furcht, Zorn, Software-PWM - die dunkle Seite der Macht sind sie! Begibst du dich auf diesen Pfad einmal, für immer wird beherrscht davon dein Schicksal."


    ;)



    Davon abgesehen, was ich von Weich-PWM halte, ist das Umkopieren des Arrays gar nicht nötig. Würde auch nur den Speicherbedarf im RAM verdoppeln und Zeit fressen.
    Die Interrupt-Routine, die das serielle Byte abholen soll, soll das im Prinzip ja schon machen: Sie kopiert genau dieses eine Byte in das Array, das dann außerhalb beliebig beackert werden könnte (wenn es denn überhaupt notwendig wäre, was es aber gar nicht ist).
    Wegen der Linearität kann da auch gar nichts dazwischen funken. Im Gegenteil: Trifft ein neues Byte ein, landet es direkt im Ziel-Array, das dann direkt in die PWM einfließt. Ist doch optimal. Mehr gibt es ja gar nicht zu beackern.


    Was flipp86 da treibt ist jedenfalls extrem zeitaufwändig. Das Splitten eines 100 Byte Strings in Bascom dauert vermutlich eine halbe Ewigkeit. Bis das durch ist, sind mit hoher Wahrscheinlichkeit neue Bytes eingetrudelt, die den noch nicht voll abgearbeiteten String teilweise überschreiben.
    Das würde komplett entfallen, wenn er die Bytes einzeln abholt und direkt in das Array schubst.


    Darüber hinaus würzt flipp86 das Ganze auch noch mit dem lahmen Print-Befehl, der nach dem (überflüssigen) Splitten, aber noch vor dem Aktualisieren von Spwm1 bis Spwm9, 'nen ellenlangen String ausgibt.
    In der Zeit kann auch schon wieder seriell was neues eintrudeln, dabei sind die PWM-Werte Spwm1 bis spwm9 noch gar nicht mit den letzten Daten aktualisiert.



    Nochwas: Zur Effizienz des Input-Befehls lese man:
    http://rowalt.de/mc/avr/avrboard/06/avrb06.htm