PPM Signale auswerten, bzw. 6-Kanal Empfänger ?

Zwischenfrage :

ich habe mal die Datenblätter (ATmega16 & ATtiny44) grob verglichen- die Register der Timer sind offens.
gleich - d.h. man muss das nicht wieder auf den ATtiny umstricken ? Bis auf PIN-# ggf. , richtig ?

Gruss Billy
 
Hab ich jetzt nicht konkret verglichen. Beim Tiny44 besitzt Timer0 allein schon zei OC-Units (für die beiden Richtungen), entsprechend hst Du allein a weitere Bits. Grundsätzlich hast Du ähnliche Timer (dewegen war der ja vogeschlagen), der Prgrammablauf bleibt ähnlich. Beim setzen der Registerbist schauen wir später nochmal genauer hin. Beim Timer0 konkurriert allerdings der einzige externe Interruptpin mit einem der beiden OC-Pins. Deswegen sind die Flanken nicht mehr mit dem externen Interrupt zu detektieren, sondern mit dem Pin Change Interrupt eines anderen Beines (beim Tiny24/44/84 kann jedes Bein bei einem Flankenwechsel (Pin Change) einen Interrupt auslösen. Beim Mega16 gab es das noch nicht. Allerdings triggert der Pin Change IRQ (wenn er aktiviert ist) auf jede Flanke, auf jeden Wechsel. Das muß dann in der "Measure-ISR" berücksichtigt werden.

Deine gemessenen Rohdaten zeigen einerseits eine erhebliche Abweichung zu den erwarteten Werten. Das kann einerseits am Takt des Controllers liegen, andererseits auch am Signal selbst.Wenn Du die Möglichkeit hast, versuch das ganze mal bitte mit einem 8MHz Quarz oder Quarzoszillator (und den dann korrekten Fuses).
Die Varianz der Werte untereinander hält sich in Grenzen, sollte aber auch nicht vernachlässigt werden.
Der Tiny besitzt 14 Beine. Zwei für die Stromversorgung, zwei für die PWM-Ausgänge, einer fürs Signal, einer bleibt Reset. Bleiben acht frei.
Selbst, wenn Du irgendwelche zusätzlichen Funktionen (Licht, Pfeife etc) an andere Kanäle knüpfen willst - ich würde ein Paar Beine für die Kalibration vorsehen.
Die Kalibrationswerte könnten dabei im Eeprom gelagert werden.

Grundsätzlich habe ich eine Lösung im Hinterkopf (quasi Deine, nur eben mit ganzen Zahlen), die die gemessenen Werte in Abhängigkeit der Minima/Maxima auf ein Byte streckt (genauer: der Fall Wert größer "neutral" wird gegen "max" auf 255 gestreckt, der Fall Wert kleiner "neutral" gegen "min").
Du solltest Dir auf dieser Basis die Grundlegenden Funktionen der Kanäle überlegen. Wenn wirklich nur sechs Loks gesteuert werden sollen, also jeder Kanal eine, könnte man mit drei Beinen den Kanal festlegen, auf den der einzelne IC reagieren soll. Dann kannst Du die Firmware in mehrere ICs brennen, und später beliebig den Kanal wechseln.
Wenn Du einen oder mehrere Kanäle für Spezialfunktionen verwenden willst, mußt Du das natürlich global für die Anlage festlegen.

Soo.....
lösbar ist das auf diesem Wege - stellt sich die Frage, ob man das ganze nicht auch irgendwie volldigital realisieren kann.
Derzeit Sollen ja sechs analoge Pulsweiten ausgewertet werden - man könnte statt eines solchen Signals auch ein serielles Telegramm auf die Spannung modullieren, ähnlich dem UART. Bidirektional wäre ... kniffelig, aber von einen Sender an alle Empfänger wäre machbar. Jeder Empfänger bekommt 'ne eigene Adresse, das Telegramm beginnt mit der Zieladresse. Nur das Ziel wertet das restliche Telegramm aus.
Sowas wäre mit 'nem Controller sogar einfacher auszuwerten, unter Bascom könnte man möglicherweise die RC-5-Funktionen zweckentfremden.
 
Hallo...

Hab ich jetzt nicht konkret verglichen. Beim Tiny44 besitzt Timer0 allein schon zei OC-Units (für die beiden Richtungen), entsprechend hst Du allein a weitere Bits. Grundsätzlich hast Du ähnliche Timer (dewegen war der ja vogeschlagen), der Prgrammablauf bleibt ähnlich. Beim setzen der Registerbist schauen wir später nochmal genauer hin. Beim Timer0 konkurriert allerdings der einzige externe Interruptpin mit einem der beiden OC-Pins. Deswegen sind die Flanken nicht mehr mit dem externen Interrupt zu detektieren, sondern mit dem Pin Change Interrupt eines anderen Beines (beim Tiny24/44/84 kann jedes Bein bei einem Flankenwechsel (Pin Change) einen Interrupt auslösen. Beim Mega16 gab es das noch nicht. Allerdings triggert der Pin Change IRQ (wenn er aktiviert ist) auf jede Flanke, auf jeden Wechsel. Das muß dann in der "Measure-ISR" berücksichtigt werden.

Ach Du Schreck...ich blicke jetzt schon nicht durch. Wie soll ich das je verstehen ? Und dann wieder alles anders...

Deine gemessenen Rohdaten zeigen einerseits eine erhebliche Abweichung zu den erwarteten Werten. Das kann einerseits am Takt des Controllers liegen, andererseits auch am Signal

Ich kann sagen, dass das Signal auch in der Logik-Variante sehr störanfällig ist/war. Sauber war das nie. Abweichungen in den Kanälen
gab es da schon immer - liegt wohl auch an den Schiebepotis ...in der Praxis ist dann das grösste Problem, dass das Funkfeuer der Lok-
motoren (Kollektorfeuer) auch noch den Empänger stören kann. Daher haben die Motortreiber-Schaltungen einen sehr grossen Bereich
für den Totpunkt der Schaltung, um Störimpulse abzublocken (z.B. direktes Umpolen der Schaltung, Signalausfall, etc.). entsprechend
träge reagieren die Loks,was aber auch nicht stört, denn einen Zug kann man in echt ja auch nicht innerhalb von ein paar Sekunden in
der Fahrtrichtung umschalten.
Auch in der VAriante wurde jeder Empfänger mit einem eigenen Poti (SMD-miniatur) auf die Pause,
also quasi Stillstand (Potimittelstellung des Senders) abgeglichen.

Deine gemessenen Rohdaten zeigen einerseits eine erhebliche Abweichung zu den erwarteten Werten. Das kann einerseits am Takt des Controllers liegen, andererseits auch am Signal selbst.Wenn Du die Möglichkeit hast, versuch das ganze mal bitte mit einem 8MHz Quarz oder Quarzoszillator (und den dann korrekten Fuses).

kein Problem- das Experiementierboard hat Quarze "an Board". Ich versuche das gleich...
Melde mich dann. Irgendwie nimmt das ein Ausmass an, das mir nicht mehr verständlich ist.

Wenn wirklich nur sechs Loks gesteuert werden sollen, also jeder Kanal eine, könnte man mit drei Beinen den Kanal festlegen, auf den der einzelne IC reagieren soll. Dann kannst Du die Firmware in mehrere ICs brennen, und später beliebig den Kanal wechseln.
Wenn Du einen oder mehrere Kanäle für Spezialfunktionen verwenden willst, mußt Du das natürlich global für die Anlage festlegen.

Nein- wirklich nur ein Kanal pro Lok für die Fahrtregelung ! sonst nichts. Kein Schnick-Schnack.

Anbei habe ich mal ein Programm aus beiden Teilen verhochzeitet, mit dem ich eine Lok ganz "okay" steuern kann.
Allerdings stottert der Motor in beiden Breichen bei der max. Geschwindigkeit (Wert für OCR0/2 um die 220-255)

siehe hier :



CodeBox BascomAVR
'Bascom Hardware-PWM
$regfile = "m16def.dat"
$crystal = 2000000
$baud = 2400

Dim Empf(6) As Integer
Dim Channel As Byte
Dim Wert As Word
Dim Li As Integer , Re As Integer
Dim Linkso As Byte , Rechtso As Byte

Config Int0 = Rising

Config Timer1 = Timer , Prescale = 1 , Capture Edge = Rising       ', Noise Cancel = 1

Config Pinb.3 = Output
Const Tccr0value = 2 ^ Wgm00 + 2 ^ Com01 + 2 ^ Cs01 + 2 ^ Cs00

Config Pind.7 = Output
Const Tccr2value = 2 ^ Wgm20 + 2 ^ Com21 + 2 ^ Cs22

Tccr0 = Tccr0value
Tccr2 = Tccr2value

Ocr0 = 0
Ocr2 = 0

On Timer1 Pausedetect
On Int0 Measure

Enable Interrupts
Enable Int0
Enable Timer1
Enable Timer0

Do_loop:
Do
     If Empf(6) > 559 Then
     Goto Nothing
     End If

     If Empf(6) < -559 Then
     Goto Nothing
     End If

     If Empf(6) < -5 Then
        Re = 0
        Li = Empf(6) / 11
        Li = Abs(li) * 5
        Goto Links
     End If

     If Empf(6) > 5 Then
        Li = 0
        Re = Empf(6) / 11
        Re = Re * 5
        Goto Rechts
     End If

Ocr0 = 0
Ocr2 = 0

    'Waitms 10
    'Print Rechtso ; "     " ; Linkso ; "     " ; Chr(13) ;

Loop
End

Measure:
If Channel > 0 And Channel < 7 Then
  Stop Timer1
  Wert = Timer1 - 64809
  Empf(channel) = Wert
End If
Timer1 = 62878
Incr Channel
Start Timer1
Return

Pausedetect:
Channel = 0
Return

Nothing:
Goto Do_loop

Links:
Ocr2 = 0
Linkso = Li
Ocr0 = Linkso
Goto Do_loop

Rechts:
Ocr0 = 0
Rechtso = Re
Ocr2 = Rechtso
Goto Do_loop




Gruss Billy
 
Mist...ist leider ein 16MHz Quarz,,,
Sorry. Kann ich dann doch nicht checken.
ich bin leider sehr Mathe-schwach. Wenn ich NICHT mit Fliesskomma arbeite,
wie wandle ich denn dann die Werte aus deinem Code (4000er-Schritte) um in 255er ?
Oder anders gefragt : wie streched man einen wert ohne fliesskomma ?

Gruss Billy

PS : ich habe mich gerade mal eingelesen - da kann soviel schieflaufen mit den Fuses usw.
ich möchte das eigentlich unterlassen, da wegen der Frequenz rum zu spielen.
 
Zuletzt bearbeitet:
Hallo Sorry- aber ich steige an dieser Stelle aus...das ganze verstehe ich nicht mehr, kann nur noch copy/paste arbeiten.
Das macht für mich keinen Sinn. Ich verstehe diese ganze Timer/PWM-Sache nicht. Egal was ich versuche...es klappt
einafch nicht, wenn ich das mal selber versuche. Sinn würde das für mich nur noch mit 2 16-Bit Timern machen, die
ich direkt mit der PWM Funktion und den ausgelesen Daten verarbeiten kann, aber der µC, der das kann ist zu gross.

Ich lege das ganze zu den Akten. Ich habe auch einfach keine Zeit, dass weiter "zu verstehen" zu versuchen.
Ich dachte, das wäre einfacher um zu setzen.
Danke für die Mühe.

Sorry.

Gruss Billy
 
Nein- wirklich nur ein Kanal pro Lok für die Fahrtregelung ! sonst nichts. Kein Schnick-Schnack.
Dann hast Du beim Tiny24/44/84 ja jede Menge Bein über. Zweimal Stromversorgung, Reset, zwei PWM-Ausgänge, ein Signaleingang. Bleiben acht ungenutzt. Mit drei Beinen kannst Du die konkrete Flanke festlegen (drei Bit, 2^3 Möglichkeiten). Empfehlenswert wären A0, A1, A2. In Der Schaltung dann einfach (Löt-)Jumper oder 'n Mäuseklavier gegen Gnd dran, dann kannst Du die Lok einfach von Kanal 2 auf 5 umschalten. Im Programm gibst Du dann nicht mehr Kanal"6" als Konstante vor, sondern liest PinA ein und maskierst die restlichen Pins weg (AND mit &B00000111). Statt auf "Kanal-Array(6)" zuzugreifen, greifst Du auf "Kanal-Array(PINA And b00000111)" zu. Für den High zustand werden die internen Pullups gesetzt.
Wären noch fünf Beine frei. Könnte man drei Taster dranhängen -> lege derzeitigen Messwert als "max", "min" und "null" fest.
Die letzten beiden Beine dann für Übernahme der Konfiguration ins Eeprom freihalten (ein Taster, eine LED). Da sich das Eeprom nur begrenzt of beschreiben läßt, wäre so auch leicht sicherzustellen, daß nach einem Reset nur ein mal geschrieben werden darf.
da kann soviel schieflaufen mit den Fuses usw.
Hmm... Du hast doch bereits die Frequenz des internen Oszillators geändert - das sind doch auch Fusbits. Ich habe von Bascom nie einen Programmer genutzt, das HEX-File letztlich immer über das AVR-Studio flashen lassen. Da sind die Fuses eigentlich recht übersichtlich. Ok, wenn man 'ne externe Clock oder 'n externen Quarz einstellt, und da keiner angeschlossen ist, steht der Controller. Wenn man den Resetpin disabled, kommt man mit SPI-Programming nicht mehr rein (weil das eben auch den Reset nutzt). Bei einigen Controllern könnte man sich noch mit dem debugWire aussperren.
Egal... lass es so...
wie streched man einen wert ohne fliesskomma ?
Indem Du statt single-Variablen integer oder words dividierst. Bascom dividiert dann logischerweise Ganzzahlen - ggf mußt Du dabei "intelligent" runden - ein zweiter zu beachtender Punkt ist die Genauigkeit.
Ich würde so vorgehen:
Als erstes ist der "Nullwert" zu bestimmen (oder festzulegen).
Danach ermittelst Du die Extrema ("max" und "min"). Du ziehst den Nullwert davon ab (bzw beim "min" andersrum um positive Werte zu erhalten). Die Ergebnisse sollten zwischen 0 und 4000 liegen. Bytes reichen eh nicht -> wir nutzen words (16bit).
Für eine bessere Genauigkeit beim rechnen versechzehnfachst Du die Werte - indem sie einfach viermal nach links geschoben werden (das kann der Controller wahnsinnig schnell). Da die extrema 255 entsprechen sollen, müßtest Du die Werte durch 255 teilen (Verhältnisgleichung, Dreisatz) - das geschieht aber ganzzahlig (da words). Die Nachkommastellen würden einfach abgeschnitten werden. Deswegen (Trick15) addieren wir vor dem dividieren erstmal 127 (die hälfte von 255), und dividieren anschließend durch 255. Als Ergebnis erhältst Du je einen Divisor-Wert für max und min. (Kannst Du natürlich auch selbst berechnen, und als Konstante vorgeben, aber so kann der Controller sie selbst bestimmen).
Der Nullwert und die Divisoren für max und min sind also bekannt.
Um den duty-Sollwert eines gemessenen Kanal-Rohwertes (Kanal-Array) zu bestimmen, überprüfst Du erstmal, ob der Wert gößer oder kleiner dem "Nullwert" ist (legt den zu verwendenden PWM-Kanal fest, und welcher der beiden Divisoren zu verwenden ist), berechnest die (positive bzw absolute) Differenz zum Nullwert. Das ganze durch verschieben wieder mit 16 multipliziert. Jetzt müßte durch den Divisor geteilt werden, wieder mit demselben Runden-Trick. Da der Divisor als Konstante nicht bekannt ist, muß die vorher zu addierende Hälfte erstmal berechnet werden - durch einmaliges rechtsschieben (=/2). Danach teilst Du durch den Divisor, und hast den PWM-Sollwert. Fertig.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)