PWM Signal in µC einlesen

  • Hallo


    Ich habe mir vor kurzem ein RC Modellflugzeug gekauft (Skyartec Funjet). Da dieser Flieger über kein Seitenruder
    verfügt habe ich mir gedacht man könnte den Kanal zum schalten von Leds benutzten.
    Die Leds wären dann als Strobe und Beacon lights an den Flügelspitzen bzw. Rumpfoberseite (nein Unterseite
    nicht nun doch) und würden mit unterschiedlichen Frequenzen blinken. Zum Anschalten könnte man den "Knüppel" für das
    Seitenruder nach links oder rechts bewegen und zum Ausschalten in die entgegen gesetzte Richtung. Der
    "Knüppel" für das Ruder ist allerdings federbelastet und springt nach dem loslassen wieder zurück in neutralposition.


    Könnte mir jemand von euch einen Programmcode für Bascom coden (?). Als µC habe ich an den ATtiny13
    aufgrund seiner größe gedacht. Die Schaltung sollte möglichs ohne externen Quarz auskommen.
    Den Code auf den µC flashen schaffe ich noch alleine aber fürs Programmieren fehlen mir die grauen Zellen :wacko: ^^


    Gruß


    edit = rot


    Danke! Problem erledigt! Schaltung funktioniert!


    Software: PWM Signal in µC einlesen


    Schaltung und Layout: PWM Signal in µC einlesen




  • Das wäre so die einfachste Möglichkeit das Signal auszuwerten.
    Oder soll das Blinken der Leds auch vom µC übernommen werden, denn mit dem Code wird der Ausgang nur ein- und ausgeschaltet.
    Die Werte die Pulsein liefert hängen leider auch der Taktfrequenz ab, deswegen kann ich nicht garantieren, dass es mit diesen Werten funktioniert.
    Zur Not müsste man dort einfach die Werte noch verändern.

  • Zitat

    Oder soll das Blinken der Leds auch vom µC übernommen werden, denn mit dem Code wird der Ausgang nur ein- und ausgeschaltet.

    Wenn der Grundcode erstmal steht bekomme ich das hin (einfach mit waitms).

    Die Werte die Pulsein liefert hängen leider auch der Taktfrequenz ab, deswegen kann ich nicht garantieren, dass es mit diesen Werten funktioniert.
    Zur Not müsste man dort einfach die Werte noch verändern.

    Danke für den Code =) mal gucken ob es mit den Werten funktioniert.
    Als ich den Code in Bascom eingefügt habe um zu kompilieren versuchte kam folgende Fehlercodes:


    Dim Signal As Word = Out of SRAM space, in file G:\ ...


    Pulsein Signal , Pinb , 0 , 1 = Assignment error [SIGNAL: 0 __WTMPC: 36] , in file G:\


    und LOOP expected , in File :


    ich habe mir nochmal die version von mcselec.com heruntergeladen. allerdings mit den selben fehlern
    meine version ist


    Compiler version :1.11.9.8
    Compiler build :1.11.9.8.001
    IDE version :1.11.9.8
    Serial number Serial DEMO


    Es wird wahrscheinlich nur ein kleiner Fehler sein der das ausmacht.


    gruß

  • Dim Signal As Word = Out of SRAM space, in file G:\ ...


    Pulsein Signal , Pinb , 0 , 1 = Assignment error [SIGNAL: 0 __WTMPC: 36] , in file G:\


    und LOOP expected , in File :

    Der Tiny13 hat nur 64 Byte SRAM.
    Schau mal unter Options->Compiler->Chip. Dort sind Werte für HW Stack, Soft Stack und Framesize eingetragen. Die sind zusammen wohl schon größer als 64. Die Summe muss kleiner 63 sein, damit du deine Word Variable noch hinzufügen kannst.
    Alternativ kannst du im Code auch
    $TINY
    angeben, dann werden die Stacks nicht benutzt.
    Der Rest sind bestimmt Folgefehler.


    BEye

  • Ach okey..
    hmm dann schmeiß ich den Code eben auf einen tiny2313 - so große Platzprobleme habe ich dann doch nicht :D .
    Empfiehlt es sich ein Quarz zu benutzen?
    Ich passe den Code bis morgen an (wäre cool wenn ihr dann nochmal rübergucken könntest ;) )


    gruß


    edit: ist der UCSK Pin der "für mich" alte SCK Pin? also der für ISP (MOSI,MISO,REST,SCK)




    edit2: So doch noch heute :D


  • Zitat

    edit: ist der UCSK Pin der "für mich" alte SCK Pin? also der für ISP (MOSI,MISO,REST,SCK)

    Jap PB7 ist SCK..


    Grüße Jakob


    EDIT: Ja, das sieht doch gut aus, nur wird das Programm erst nach einem kompletten Durchlauf aufhören, aber das dürfte ja eigentlich nicht soo schlimm sein oder ?

  • hmm dann schmeiß ich den Code eben auf einen tiny2313 - so große Platzprobleme habe ich dann doch nicht :D .

    Nur *falls* es doch mal Platzprobleme gibt: Tiny25/45/85 ist auch nicht größer als Tiny13, hat aber 128 bzw. 256 bzw. 512 Byte RAM... ;)


    EDIT: Und das ist ja nun doch anders als ursprünglich geplant..? - also jetzt eine Seite Strobe, andere Strobe+Beacon, wird gestartet und läuft dann 60 mal durch..?


    Du könntest das ja auch so machen: bei Knüppel rechts machst Du Strobe - das läuft dann immer in ner Schleife durch - wenn dort zwischendurch der Knüppel wieder in der Mitte war und dann wieder rechts, dann springst Du weiter in ne Schleife "Strobe und Beacon", wenn Knüppel links kommt, dann wieder auf "aus"


    und in der Strobe-und-Beacon-Schleife abfragen, wenn Knüppel links, dann zurück in die erste Schleife...


    dann kannst Du das frei schalten: Knüppel einmal rechts = Strobe, noch mal rechts = Strobe + Beacon, Knüppel nach links = wieder nur Strobe, noch mal links = wieder komplett aus...


    Nochmal EDIT: natürlich könnte man das auch einfach durchschalten: bei jedem Knüppeldruck nach rechts das "Programm" eins weiter, also Aus - Strobe - Strobe+Beacon - wieder aus - dann könnte man mit Knüppel nach links noch andere Sachen (z.B. Landescheinwerfer) *unabhängig davon* steuern, Pins sind ja noch frei am Tiny... ;)


    Und nochmal EDIT: wegen dem Quarz, wenn da genug Unterschied in der Pulslänge ist (also nicht gerade Mittelstellung = 1 µs, Rechtsanschlag = 1,1 µs oder so, dann sollte das auch ohne Quarz gut gehen... der interne RC-Oszi ohne Teiler ist aber doch 8 MHz und nicht 9,6...?!?

    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!

    3 Mal editiert, zuletzt von Pesi ()

  • Hi


    Danke Pesi für deine Anmerkungen :) . Ich find die Ideen auch alle super aber um ehrlich zu sein war ich schon froh das ich den Code hinbekommen habe...


    Zu den Oszi kann ich nix sagen (wegen keiner Ahnung und Fresse halten und so ;) ) ich habe das nur vom Code von samotronta05 übernomen. Außerdem ist mir gerade noch aufgefallen das X = 0 aus Zeile 13 in die Do-loop schleife gehört - also Zeile 23.


    Pesi: Würdest du mir (bzw. allen Mitlesern) den Code soweit verändern das man:
    - Knüppel "Null" Stellung: Nichts
    - Rechts: Strobe an
    - Null: Nichts
    - Rechts: Strobe + Beacon an
    - Null: Nichts
    - Rechts: Strobe + Beacon aus


    und unabhängig davon noch nach links einen anderen Pin schalten (zb. )
    - Knüppel Null: Nichts
    - Links: An
    - Null: Nichts
    - Links: Aus


    Quasi genau so wie du in deinem Edit meintest. Ich habe das nur nochmal wiederholt.

    Zitat

    Nochmal EDIT: natürlich könnte man das auch einfach durchschalten: bei jedem Knüppeldruck nach rechts das "Programm" eins weiter, also Aus - Strobe - Strobe+Beacon - wieder aus - dann könnte man mit Knüppel nach links noch andere Sachen (z.B. Landescheinwerfer) *unabhängig davon* steuern, Pins sind ja noch frei am Tiny... ;)

    Mit der Software hätte wären dann ja alle Möglichkeiten ausgereitzt :D .
    Schafft du dir den Code einfach so aus den Handgelenken zu schütteln? Ich schaffe das nähmlich nicht mit den Interrupts usw. Aber als Belohnung könnte ich dir exklusiv ein (das erste) Crashvideo präsentieren (youtube :rolleyes: )
    Der nächst Crash kommt garantiert (gleich mal weiter den Rumpf kleben 8| )


    gruß

  • Sorry, habe vorhin noch Besuch bekommen, und jetzt gehe ich dann in's Bett - morgen bin ich den ganzen Tag unterwegs, aber am Sonntag mach' ich dann mal die SW, versprochen!

    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!

  • Brauchst du nicht zu machen. Ich teste gerade noch, aber bis jetzt geht alles bis auf mein Senderakku :pinch:
    Edit so alles Fertig:

    Zitat


    der interne RC-Oszi ohne Teiler ist aber doch 8 MHz und nicht 9,6...?!?


    Ja ursprünglich war aber vom Attiny13 die Rede und da sagt das Datenblatt auf Seite 25 4,8Mhz oder 9,6Mhz, beim Attiny2313 sind das aber natürlich 8Mhz.


    Getestet hab ich das ganze ebenfalls mit einem RC-Oszi mit 8Mhz, allerdings auf einem 644.
    Siehe hier:Klick
    Der Strobe kommt leider durch die Kamera extrem schlecht rüber....sieht in echt hundert mal besser aus, fast wie das orginal.


    Ich hoffe der Code ist so verständlich und übersichtlich.
    Fragen?, Fragen!


    Edit2:
    Da die ganzen Kommentare verrutscht sind einfach hier herunterladen dann passt die Formatierung auch: Rechtsklick speichern unter



    So jetzt will ich Schrott sehn :D
    Greetz
    Samotronta05, der sich jetzt wieder mit Delphi und der verdammten d2xx.dll rumschlagen darf...

  • Ich hoffe der Code ist so verständlich und übersichtlich.
    Fragen?, Fragen!

    Ja alles Super verständlich und gut kommentiert. ABER: Da ich in Berufsschule damals das mit den Interrupts und Timern an mir vorbeifliegen lasse habe (damn it :thumbdown: ) hab ich noch n paar Fragen.


    Code
    $crystal = 8000000
    Config Timer0 = Timer , Prescale = 1024
    On Timer0 Isr_timer0


    Durch den Prescaler werden die 8000000Hz ja durch 1024 geteilt (= 7812,5 Hz)
    Der Timer0 läuft nach 256 ja wieder über also 7812,5 Hz / 256 = 30,517578125 Hz.
    Wird durch On Timer0 Isr_timer0 der Interrupt immer ausgelöst wenn der Timer0 einmal durchgelaufen ist? Und das passiert ja 30 mal in der Sekunde also alle 33 Millisekunden.
    Wenn das alles so richtig sein sollte: Warum wird der Isr_timer0 dann immer alle 20ms ausgeführt?



    Hier verstehe ich noch nicht ganz warum das Stobe angeht wenn der Interrupt das erste Mal ausgelöst wird. Die Variable Zaehler ist ja noch 0 aber der tiefste Case fängt erst bei 1 an. Oder ist "der" dann so "schlau" das der quasi mit case else aus der Schleife springt und bei der If Modus > 0 Then weitermacht?
    Und warum wird der timer auf 100 gesetzt anstatt auf 0 ?


    Gruß


    Ich hoffe du hast alle meine Fragen verstanden


    PS: Pesi: du bekommst natürlich auch das Video exklusiv als PN :thumbup: . Morgen geh ich wieder mitn Kumpel fliegen ääh ich meine crashen :rolleyes: ;( (Mit Cam ;) )

  • Ja alles Super verständlich und gut kommentiert. ABER: Da ich in Berufsschule damals das mit den Interrupts und Timern an mir vorbeifliegen lasse habe (damn it :thumbdown: ) hab ich noch n paar Fragen.


    Code
    $crystal = 8000000
    Config Timer0 = Timer , Prescale = 1024
    On Timer0 Isr_timer0


    Durch den Prescaler werden die 8000000Hz ja durch 1024 geteilt (= 7812,5 Hz)
    Der Timer0 läuft nach 256 ja wieder über also 7812,5 Hz / 256 = 30,517578125 Hz.
    Wird durch On Timer0 Isr_timer0 der Interrupt immer ausgelöst wenn der Timer0 einmal durchgelaufen ist? Und das passiert ja 30 mal in der Sekunde also alle 33 Millisekunden.
    Wenn das alles so richtig sein sollte: Warum wird der Isr_timer0 dann immer alle 20ms ausgeführt?


    Also das mit dem Prescaler ist schon korrekt, nur der Rest stimmt nicht.
    Erstmal läuft der Timer von 100 weg also nur noch 156 Schritte, nur beim ersten mal halt die 256 Schritte, weil ich vergessen habe oben Timer0 = 100 einzufügen, macht aber auch nichts.
    Zweitens hast du die Division vertauscht. Es sind 7812,5 pro Sekunde, dass heißt man muss die 156 durch 7812,5 teilen und das sind dann 0,019968 Sekunden bzw. ca. 20ms.
    Ansonsten empfehle ich dir das hier, wenn man zu faul zum Rechnen ist: Klick

    Hier verstehe ich noch nicht ganz warum das Stobe angeht wenn der Interrupt das erste Mal ausgelöst wird. Die Variable Zaehler ist ja noch 0 aber der tiefste Case fängt erst bei 1 an. Oder ist "der" dann so "schlau" das der quasi mit case else aus der Schleife springt und bei der If Modus > 0 Then weitermacht?
    Und warum wird der timer auf 100 gesetzt anstatt auf 0 ?


    Das Strobe wird tatsächlich erst nachdem der Interrupt durch den Timer zweimal ausgelöst wurde aktiviert, beim ersten Aufruf ist Zaehler ja noch null und da er in der Case-Abfrage keinen Befehl findet den er bei 0 ausführen soll, macht er mit dem Rest weiter und Zählt dann hoch, sodass nach 20ms das Strobe aktiviert wird.
    Ansonsten würde das Strobe immer aktiviert, wenn man es ausschalten möchte, denn wenn alles aus ist, ist Zaehler = 0, um zu vermeiden, dass ein Licht an bleibt und die 20ms Verzögerung beim Einschalten merkt man eh nicht.
    Der Timer zählt von 100 weg, also 256-100=156 Schritte um auf die 20ms zu kommen, wie oben erklärt.
    Wenn sonst noch was unklar ist, gilt einfach Fragen.
    Gruß

  • 1. Wow! Bei soviel Fachwissen frage ich mich warum du nur so wenige Beiträge bisher geschrieben hast.
    Gerade weil du in Texten sehr verständlich erklären kannst.


    2. Warum ist die Division 156 / 7812,5 = 0,019968 ? Auf der Seite wo ich mich in das
    Timer-ding eingelesen hatte steht es Sinngemäß anders: 7812,5 / 156 = 50,080


    3. An welchem Pin wird der zweite Kanal geschaltet?
    Config Pinb.0 = Input 'Anschluss am Empfänger b.0
    Config Portb.0 = Output 'Schaltausgang 2
    Ist Pinb.0 und Portb.0 nicht das selbe?




    Ich habe mal einen Schaltplan fertig gemacht.
    Findet dort jemand etwas was mach besser machen kann(Größen der Widerstände,Kapazitäten)?
    Den zweiten Kanal habe ich erstmal weggelassen weil ich nicht weiß wo der angeschlossen wird



    Achja ich war heute nicht fliegen. Auch wenn der Wind relativ schwach war wollt ich nicht mein Glück testen. ;) Das Video bekommt ihr aber noch.


    gruß

  • 1. Wow! Bei soviel Fachwissen frage ich mich warum du nur so wenige Beiträge bisher geschrieben hast.
    Gerade weil du in Texten sehr verständlich erklären kannst.


    Danke, ich muss aber gestehen, dass ich mich auch erst ein Jahr mit den Avrs beschäftige.



    2. Warum ist die Division 156 / 7812,5 = 0,019968 ? Auf der Seite wo ich mich in das
    Timer-ding eingelesen hatte steht es Sinngemäß anders: 7812,5 / 156 = 50,080


    Korrekt hier muss man aber unterscheiden, ich habe ausgerechnet, dass der Timer0 alle 20 ms ausgeführt wird, in deiner Rechnung wird die Hertzzahl ausgerechnet.
    Es kommt aber das gleiche raus, denn 50,08 Hertz ergeben: 1 Sekunde / 50,08 Hertz = 0.019968 Sekunde bzw. ca. 20 ms.


    3. An welchem Pin wird der zweite Kanal geschaltet?
    Config Pinb.0 = Input 'Anschluss am Empfänger b.0
    Config Portb.0 = Output 'Schaltausgang 2
    Ist Pinb.0 und Portb.0 nicht das selbe?


    Ohh stimmt hab ich einfach übersehen, weil ich die Anschlüsse nachher noch geändert habe, da ich das ganze auf einem Atmega644 getestet habe.


    Grundsätzlich kannst du aber jeden Pin nehmen, ich würde jedoch die Pinne des Programmers, die UART und den Quarz freihalten, denn man ärgert sich, wenn man genau diese Pinne später nochmal braucht. Ansonsten einfach so belegen, dass es am besten zum Layout passt.




    Ich habe mal einen Schaltplan fertig gemacht.
    Findet dort jemand etwas was mach besser machen kann(Größen der Widerstände,Kapazitäten)?


    ISP nach RN-Standard ?
    Man könnte auch einen 6-Pin ISP-Anschluss verwenden um Platz zu sparen.
    Als Pullup am Reset würde ich 10k nehmen, da ansonsten manche Programmer den Pegel nicht sauber auf Low ziehen.
    Eventuell noch einen kleinen Elko parallel zum Abblockkondensator schalten.




    Achja ich war heute nicht fliegen. Auch wenn der Wind relativ schwach war wollt ich nicht mein Glück testen. ;) Das Video bekommt ihr aber noch.


    Hmm du bringst mich auf die Idee meinen Flieger mal wieder rauszuholen. *schon mal den Sekundenkleber suchen*
    Gruß

  • Wegen dem Timer... wieso nicht einfach so konfigurieren, dass er alle 20ms einen Interrupt auslöst? Wenn ich das richtig sehe, ist das doch die kleinste benötigste Zeitspanne.


    Folgende Werte lösen laut AVR-Timer-Calculator nach genau 20000µs mit dem 16bit Timer einen Interrupt aus:


    Code
    Prescaler  Reload
      4    	25536
      8    	45536
     16    	55536
     32    	60536
     64    	63036
    128    	64286
    258    	64911
  • ?( - *ist* doch so konfiguriert:


    Code
    Isr_timer0:   	'wird alle 20ms ausgeführt

    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!