RGB über Infrarot steuern (Bascom)

  • Hallo,
    habe meine RGB Beleuchtung nun schon länger fertig und wollte nun mal die "Software" richtig machen.
    Dabei habe ich ein großes Problem und zwar:



    Ich habe hier mal ein vereinfachten Teil meines Codes genommen ( Ausschnit aus einem Sub-Programm, welches durch die Farben fadet.)
    Das Problem ist die Fernbedineung. Taste 0 z.B. soll das Subprogramm beenden. Das Funktioniert auch, aber nur wenn ich die Taste 0 gedrückt halte.
    Das Programm ruft den RC5 Code nur an einer Stelle ab, eig. sollte es dies aber permanent tun.
    Habe gelsen, das das mit "Interrupts" geht, finde aber irgendwie kein Beispiel, wo ich das Erkennen kann, wie das geht.
    Kann mir da evtl. jemand helfen?

  • Ein uneleganter Weg wäre, den Getrc5(address , Command) in einen Timer-Interrupt zu packen, der alle soundsoviel Millisekunden aufgerufen wird.
    Da sehe ich alledings das Problem voraus, dass dennoch mitunter ein Signal verschluckt wird. Die Aufrufe laufen ja nicht synchron mit dem "zufälligen" Eintreffen eines Empfangssignals. Um das zu beurteilen müsste man schon genauer wissen, was der Getrc5(address , Command) im Detail tut.


    Dieser Befehl ist allerdings auch recht verschrien. Er ist zwar schön einfach in der Anwendung, gilt aber als ewige Problemquelle.


    Man kann den natürlich von Hand nachprogrammieren, wenn man denn wirklich mit RC5 zu tun hat. Bei Mikrocontroller.net habe ich da mal ein Sammlung fertiger Routinen gesehen, auch für andere Protokolle als RC5.


    Der normalerweise klarste Weg ist der, den IR-Empfänger mit einem interruptfähigen Pin zu verbinden und einen Pin-Change-Interrupt zu setzen.
    Dann braucht man nämlich keinen Timer-Interrupt, der alle x Millisekunden aufgerufen wird, um nachzuschauen. Sondern dann wird mit Empfang eines Signals der Interrupt aufgerufen. Und wirklich nur dann.


    Kannst ja mal probieren, ob das so auf die lasche Tour funktioniert, den Getrc5(address , Command) in 'ne Interrupt-Routine zu packen.
    Setze dort zunächst mal testweise einen Befehlt, der eine bestimmte Farbe einstellt und für 'ne Sekunde hält. Ganz ohne den Getrc5, einfach nur um zu sehen ob die Routine auch wirklich aufgerufen wird, wenn der Pin durch den IR-Empfänger getriggert wird. Das ist nämlich schon mal die halbe Miete.
    Dann diesen Teil wieder entfernen und dafür den richtigen Getrc5 einsetzen.


    Kann aber sein, dass das ganz so lau nicht funzt, denn beim Empfang eines Kommandos wird der Interrupt-Pin ja mehrmals getriggert. Folglich würde die Interrupt-Routine mehrfach angesprungen werden, was sich mit "Get..." irgendwie beißt.
    Müsstest wohl von der Interrupt-Rouine in eine andere Routine springen und dort, noch vor Getrc5 weitere Interrupts ausschalten.


    Für den RC5-Code habe ich da nichts fertiges anzubieten. Ich habe aber mal 'ne Routine für ein anderes IR-Protokol zu Fuß progrmmiert.

  • Hi,


    ich wollte dir auch schon antworten, aber bin gerade total im Klausurstress. Dein Problem ist das klassische wenn man sich mit RC5 am µC befasst und RGB Leds steuern will :D.
    Hatte ich auch damals und hab viel rumprobiert (damals noch blutiger Anfänger in der µC-Programmierung)


    Was mich ans Ziel gebracht hatte, war genau der von Irrlicht beschriebene Weg zu Fuß. Den hat ich nicht selbst entwicklet, sonder bin im Roboternetzforum auf einen super Beitrag gestoßen.


    Ich kann dir immoment mangels Zeit nicht mehr helfen als dir den Beitrag zu verlinken. Sieht erstmal kompliziert aus, funktioniert aber 100%tig. (Auch ohne das man die Auswertung zu Fuß verstanden hat ;) )


    Lies dir das mal durch und schau ob du es hinbekommst. Wenn nicht, in 1 1/2 Wochen kann ich dir mehr helfen.


    So hier noch der Link .


    Viele Grüße
    Philipp

  • Hallo und danke euch beiden für die Antwort. War leider durch den Urlaub etwas verzögert und habe mich nun mal an die Sache gemacht und eine Testschaltung aufgebaut.
    Zu dem Code habe ich eine Frage und zwar


    Code
    Config Timer0 = Timer , Prescale = 8
      On Timer0 Timer_irq
      Const Timervorgabe = 78                                   'Timeraufruf alle 178µs (10 Samples = 1 Bit = 1,778ms)
      Enable Timer0                                             'Hier werden die Timer aktiviert
      Enable Interrupts


    Dieser Wert ist ja abhängig von der Taktfrequenz meines Prozessors, allerdings, wie berechne ich nun diesen?
    Mein Versuch war nun, (AT Mega 8 mit 3686411 Hz).
    f(1,778ms) => 562 Hz.


    Mit einer Tabelle (siehe hier: http://www.roboternetz.de/community/threads/18099-Codebeispiel-für-Lesen-von-RC5-Code-mit-Interrupt-Routine/page2?p=176154&viewfull=1#post176154 ) habe ich dann daraus einen Prescaler von 64 und einen Wert von 154 errechnet.
    Leider klappt das damit nichts, das Programm reagiert nicht auf Eingaben.


    Kann mir jemand "Entschlüsseln" wie ich das genau Berechne?


    Viele Grüße
    Dirk


    [/code]

  • Hi,


    Du hast das auch nicht richtig berechnet. Timeraufruf alle 178µs! Warum nimmst Du da die 1,778ms?


    Also, 178µs, dann soll der Timerinterrupt ausgelöst werden. Du wirst schnell feststellen das Du dies mit einem normalen Timerüberlauf kaum hinbekommen wirst. Deshalb die "Const Timervorgabe". Du musst dabei den Timer mit einem Wert vorladen damit der am Ende nur noch für 178µs zählt und dann überläuft.


    Ich gebe Dir mal ein Beispiel wie ich es bei meinem Mini-Dimmer anwende, Du kannst es dann selbst auf Deine Frequenz umrechnen:


    µC Takt = 4MHz
    Prescaler für Timer0 = 8 -> somit zählt der Timer0 alle 2µs eins weiter
    Timervorgabe = 180


    Der Timer0 löst den Interrupt aus wenn er von 255 zu 0 überläuft. Wenn wir den nun nicht mit einem Wert vorladen würden, dann wären es von Timerinterrupt zu Timerinterrupt 512µs. Also zu lange. Daher laden wir den Timer mit einem Wert (Timervorgabe) vor. Das lässt sich nun leicht berechnen. Pro Timerüberlauf sind es 256 Zählschritte. Wir brauchen davon aber nur 178µs / 2µs = 89 Zählschritte. Also 256 - 89 = 167.


    Warum habe ich nun 180 genommen? Hehe, probiers aus. Die berechnete Timervorgabe ist reine Theorie. Wenn nun die Praxis hinzu kommt, Takttoleranz des µC usw.. Dann wirst Du feststellen das es besser ist wenn der Timerinterrupt ein bissel öfter als eigentlich nötig aufgerufen wird. Wenn der Timerinterrupt seltener aufgerufen wird als er eigentlich sollte, dann funktioniert der Empfang nicht ;)


    Gruß, Benny.

  • Dann Probiere ich mal mein Glück (In Mathe bin ich ja ein totaler Versager, naja fürs Abi hats grad gereicht ;) )


    uC Takt: 3686411 Hz
    Prescaler bleibt bei 8
    => Timer 0 braucht also ~ 0.00217ms => 2,2µs
    Damit würde der Timer 567,6µs brauchen.
    178µs/2,2µs = 82,02 ~ 82 Zählschritte.
    256-82 = 174


    Ist die Rechnung so richtig?
    Denke dann hab ich das verstanden, sollte also auch funktionieren wenn ich 180 oder 190 einsetzte?
    Dann probiere ich das heute Abend mal aus, bin leider noch unterwegs.



    Edit: Leider funktioniert es trotzdem nicht.
    Hardware läuft aber, da der normale getrc5 Befehl funktioniert.
    Dankeschön
    Gruß
    Dirk