Hall Leute, ich habe mittels Assembler einen Tiny13A so programmiert, dass er ein PWM-Signal interpretiert und zwei Ausgänge schaltet. Die Schaltung kann folgende Zustände haben: 1. Ch1 Aus, Ch2 Aus 2. Ch1 An, Ch2 Aus 3. Ch1 Aus, Ch2 An 4. Ch1 An, Ch2 An Dafür habe ich einen Interrupt, der auf eine Steigende Flanke reagiert und dann so lange einen Counter hochzählt, bis eine fallende Flanke kommt. Dass Signal wird von der Funke von -100 bis +100 definiert und zeigt sich so, dass -100 1ms Sendet und +100 2ms Sendet. Ich habe die Bereiche so angepasst, dass bei -50 Zustand (2.) erreicht wird, bei 0 Zustand (3.) und bei +50 Zustand (4.). Das Funktioniert auf super. Jetzt habe ich das selbe Hex-File auf 50 Weitern Tyni13A geladen. Allerdings schalten die alle an unterschiedlichen Bereichen! Hier eine Tabelle mit den genauen Werten: Ch1 An Ch2 An Ch1 & 2 An 1. -36,3 17,3 68,4 2. -37,2 19,1 72,7 3. -36,2 18,9 71,9 4. -35,9 17,3 70,7 5. -35,4 19,1 72,4 6. -44,3 10,0 61,4 7. -28,3 28,2 82,8 8. -48,5 5,1 56,3 9. -36,4 19,5 71,5 10. -22,7 32,5 87,6 11. -32,2 22,6 75,6 12. -46,6 5,1 53,9 13. -29,1 27,6 81,9 14. -41,4 10,9 63,0 15. -25,9 32,6 87,6 16. -32,1 20,4 73,3 17. -25,5 32,3 86,7 18. -37,0 16,2 69,2 19. -34,9 19,2 73,4 20. -38,1 17,0 69,7 Prototyp: -45,7 6,3 57,6 Warum ist das so? Die Fuse-Bits sind folgendermaßen an ALLEN gesetzt: L: 0x7A H: 0xFF E: LB: 0x3F
Armin A. schrieb: > Hier eine Tabelle mit den genauen Werten: Und die Werte sind was ? Wo kommen die Kommas her ?
Siehe Datenblatt -> Genauigkeit bzw. Abweichung des internen Oszillators. Der schwankt übrigens auch mit der Temperatur und Betriebsspannung. Für diese Anwendung könnte ein Quarz nötig sein. Oder - je nach Signal - man kann das normieren indem man die Zeit zwischen 2 ansteigenden Flanken misst.
@Marc Vesely: Die Werte habe ich an der Funke abgelesen, als die Schwelle erreicht wurde um den Zustand zu wechseln. @Jim Meba: Wie messe ich den die Zeit? Dann würde ich das darüber machen.
Jim M. schrieb: > Siehe Datenblatt -> Genauigkeit bzw. Abweichung des internen > Oszillators. Der schwankt übrigens auch mit der Temperatur und > Betriebsspannung. Die Betriebsspannung kann man stabilisieren. Den AVR RC Oszillator kann man kalibrieren. Einzig mit der Temperatur wirds schwierig, da der Tiny13 keinen internen Tempsensor hat. (stimmt das?) Aber hat einen WDT. (stimmt das?) Und dessen Oszillator hat einen gegenläufigen Temperaturgang. (stimmt das?) Das bedeutet Aufwand, aber eine Anpassung an die Temeratur ist so möglich.
Armin A. schrieb: > @Marc Vesely: Die Werte habe ich an der Funke abgelesen, als die > Schwelle erreicht wurde um den Zustand zu wechseln. Bin genau so schlau wie vorher - was ist Funke ? Armin A. schrieb: > Dafür habe ich einen Interrupt, der auf eine Steigende Flanke reagiert > und dann so lange einen Counter hochzählt, bis eine fallende Flanke > kommt. Wo wird hochgezählt - gleich im Interrupt ?
Grade wenns um genaue Zeitmessungen geht kommt man eigentlich um einen Quarz-Oszilator nicht drum rum, da sind die internen RC-Oszilatoren eigentlich zu schlecht dafür, auch mit Calibration.
Marc V. schrieb: > Bin genau so schlau wie vorher - was ist Funke ? Wahrscheinlich meint er ein Funkgerät, umgangssprachlich Funke ;)
Beitrag #4944200 wurde von einem Moderator gelöscht.
M. K. schrieb: > da sind die internen RC-Oszilatoren > eigentlich zu schlecht dafür, auch mit Calibration. Kann man so pauschal nicht sagen - es gibt auch Controller, die von Haus aus einen internen Oszi mit einer Abweichung (über Temp und VCC) von <2% haben, ohne Kalibrierung durch den User. Für die Umschaltschwellen einer RC-Modellbeleuchtung reicht das allemal...
:
Bearbeitet durch User
> als die Schwelle erreicht wurde ???
Wie gross ist eigentlich die Anstiegszeit der Flanken?
Die normalen digitalen Eingänge haben gar keine Schwelle. Die Signale
sollen so schnell zwischen Low und Hight springen, dass die Schwelle
keine Rolle spielt.
Sollte der Wechsel so langsam sein, dass du die Schwelle berücksichtigen
musst, kannst du keine normalen digitalen Eingänge benutzen.
Noch einer schrieb: > Wie gross ist eigentlich die Anstiegszeit der Flanken? Aus dem Kontext (Funke, Impulslänge, +/- 100) schließe ich, daß es hier um RC-Modellbau geht und es sich um Servo-Signale vom Empfänger handelt. Die Flankensteilheit ist da sicher kein Problem.
M. K. schrieb: > Wahrscheinlich meint er ein Funkgerät, umgangssprachlich Funke ;) Bin immer noch nicht schlauer - wie wird da etwas abgelesen ? Ausserdem hat der Tiny13A die Möglichkeit auf wechselnde Flanke zu reagieren - sowohl normale INT als auch PCINT können das. Ein Timer ist auch vorhanden, wenn das Ganze in Assembler läuft kann auch die Verzögerung die durch OVF entsteht, ganz leicht kompensiert werden. Max. Fehler dürfte sich damit im Bereich von +/- 10% bewegen, wenn nicht kalibriert. Mit Kalibration dürfte das besser als 2% werden. Seine Werte sind weit darüber (auch unkalibriert), da wird es eher ein Fehler im Programm oder beim ablesen sein...
:
Bearbeitet durch User
Ja, es handelt sich um eine Fenrbedienung eines RC-Modells. Dies kann mir zeigen, welchen Wert er überträgt (-100 bis +100). Ja, es passiert alles im Interrupt. Sollte eigentlich inproblematisch sein, da zwischen der Fallenden Flanke und der nächsten steigenden locker 5ms Platz sind. Die wechsel der Flangen passieren Sofort. Das Signal ist quasie 0 oder 1. gibt nichts dazwischen. Der Tiny wird nicht warm, da er in einem Quadrocopter verbaut ist und somit durch den Fahrtwind optimal gekühlt wird. Wie kalibriere ich den Oscilator? Muss ich das für jeden Tiny einzeln durchführen? Ich dachte jetzt, ich könnte dem Problem aus dem Weg gehen, indem ich die Zeit zwischen der steigenden un der fallenden messe. nur habe ich keine Ahnung wie ich das mache. Ich weis, dass es einen Interrupt gibt, der gefeuert wird, wenn ein Überlauf des Timer stattfindet. Jetzt möchte ich bei einer Steigenden Flanke den Timer resetten und bei einer fallenden schauen, wieviele ms verstrichen sind. Google liefert dafür irgendwie nichts verständliches.
Armin A. schrieb: > nur habe ich keine Ahnung wie ich das mache. Ich dachte, du hast das in Assembler gelöst ? Poste mal das, was du geschrieben hast.
Wenn er nur mal aufhören würde immer "Funke" zu sagen. Das ist ein (Fernsteuerungs-)Sender. Und eine Fernbedienung hat man für den TV. Den gängigen Weg einen Servoimpuls zu messen, hast du ja schon fast beschrieben. Man lässt ein Timer laufen (am besten mit 1µs pro Timertick, was gut mit 8MHz Systemtakt klappt). Dann einen Interrupt auf den Eingang welcher bei steigender Flanke den Timer zurücksetzt und bei fallender Flanke den Timer ausliest. Der Timerstand repräsentiert dann direkt die Impulslänge in µs. Am genausten geht das per Capture-Eingang, aber auch die "Zu Fuß" Methode per einfachem externen Interrupt und manuellem Timer setzen + lesen, bringt noch eine meist ausreichende Genauigkeit und ist für den Anfänger leichter. Die Ungenauigkeit des internen Oszillators spielt dabei auch keine große Rolle, da man sowieso einen großzügigen Impulsbereich definieren sollte, sonst trifft man den mit einem Sender sowieso nicht. Dabei hilft es auch ungemein, wenn man sich den aktuellen Messwert einfach z.B. per UART ausgeben lassen kann. Dann sieht man auch die Abweichungen schön. Beim T13 muss man natürlich den Weg über ein Soft-UART gehen, was aber kein Problem darstellt, schon gar nicht wenn er nur für Debug genutzt wird.
:
Bearbeitet durch User
Cyblord -. schrieb: > Dann einen Interrupt auf den Eingang welcher bei steigender Flanke den > Timer zurücksetzt und bei fallender Flanke den Timer ausliest. > Der Timerstand repräsentiert dann direkt die Impulslänge in µs. Aha. Nur ist nach 256µs sein Timer übergelaufen. Nichts mit auslesen der Impulslänge über 256µs. Und 256µs reichen leider nicht, da muss man schon in der OVF-Routine eine Variable hochzählen und erst zum Schluss wird der Timerstand berücksichtigt. Aber das wusstest du ja alles schon...
Marc V. schrieb: > Cyblord -. schrieb: >> Dann einen Interrupt auf den Eingang welcher bei steigender Flanke den >> Timer zurücksetzt und bei fallender Flanke den Timer ausliest. >> Der Timerstand repräsentiert dann direkt die Impulslänge in µs. > > Aha. > Nur ist nach 256µs sein Timer übergelaufen. > Nichts mit auslesen der Impulslänge über 256µs. Das bezieht sich auch auf einen 16 Bit Timer. > Aber das wusstest du ja alles schon... Ja das weiß ich alles schon, weil ich das schon zig mal auf den verschiedensten Plattformen gemacht habe. Über µC im Modellbau brauchst du mir nichts erzählen.
hm... Theoretisch könnte ich den Timer doch so eintellen, dass dieser einen Überlauf bei 100µs verursacht und ich dann ein Register hochzähle. Dann kann ich in dem Register Zehntel Millisekunden ablesen und dann den Timer für genaueres hinzuziehen. Bevor ich jetzt den Code änder, noch eine Frage. Nutzt der Timer einen anderen Quarz, der genauer ist oder den selben? Wenn er den selben nutzt, dann dürfte mein Problem mit dem Hochzählen da das selbe sein, da der Timer ja nichts anderes macht, oder?
Armin A. schrieb: > hm... Theoretisch könnte ich den Timer doch so eintellen, dass dieser > einen Überlauf bei 100µs verursacht und ich dann ein Register hochzähle. > Dann kann ich in dem Register Zehntel Millisekunden ablesen und dann den > Timer für genaueres hinzuziehen. Ja so macht man das, wenn man nur 8 Bit Timer nehmen kann oder will. Eine andere Möglichkeit ist den maximalen Bereich, also z.B 2ms auf 256 zu skalieren, per Vorteiler. Ergibt dann halt nur 8 Bit Auflösung des Impulses. Ist aber meist keine tolle Idee. > Bevor ich jetzt den Code änder, noch eine Frage. Nutzt der Timer einen > anderen Quarz, der genauer ist oder den selben? > Wenn er den selben nutzt, dann dürfte mein Problem mit dem Hochzählen da > das selbe sein, da der Timer ja nichts anderes macht, oder? Der Timer nutzt die Taktquelle welche du einstellst. Das kann der interne Takt per Vorteiler, aber auch ein externen Takt sein. Hierzu lies doch einfach mal das Datenblatt da steht das alles drin auch mit Bildern.
Armin A. schrieb: > Nutzt der Timer einen > anderen Quarz, der genauer ist oder den selben? Wieviel Quarze hast du in deiner Schaltung?
Armin A. schrieb: > Wenn er den selben nutzt, dann dürfte mein Problem mit dem Hochzählen da > das selbe sein, da der Timer ja nichts anderes macht, oder? Dein Problem liegt nicht in hochzählen, sondern in deinem Programm. Max. möglicher Fehler mit internem Oszi beträgt 10%. Dein Fehler ist viiiiieeeeeel grosser. Willst du "deinen" Code endlich posten oder nicht ?
Relativ zueinander passen die Werte auf 2,5%. Für einen Schwellwert wohl genau genug. Du hast aber ein Problem mit exemplarabhängigem Offset. Der ist bei +/- 13%. Und Dein Testexemplar ist gerade an einem Extrem. Du musst Dir wohl mal genauer ansehen wann Du den Zähler loslaufen lässt. Und ob dort irgendwelche Initialisierungen fehlen. Mehr kann man wohl nur aus dem Code selber herauslesen. viel Erfolg hauspapa
S. K. schrieb: > Relativ zueinander passen die Werte auf 2,5%. Für einen Schwellwert wohl > genau genug. > Du hast aber ein Problem mit exemplarabhängigem Offset. Der ist bei +/- > 13%. Und Dein Testexemplar ist gerade an einem Extrem. Genau das glaube ich NICHT. Das ist bei einem Anfänger NIE das Problem. Das ist schlicht ein Programmfehler und nichts anderes.
OK, hier der Code:
1 | ;----------------------------------- |
2 | ;- Interrupts - |
3 | ;----------------------------------- |
4 | rjmp RESET ; Reset Handler |
5 | rjmp PPM ; IRQ0 Handler |
6 | RETI ; PCINT0 Handler |
7 | RETI ; Timer0 Overflow Handler |
8 | RETI ; EEPROM Ready Handler |
9 | RETI ; Analog Comparator Handler |
10 | RETI ; Timer0 CompareA Handler |
11 | RETI ; Timer0 CompareB Handler |
12 | RETI ; Watchdog Interrupt Handler |
13 | RETI ; ADC Conversion Handler |
14 | |
15 | ;----------------------------------- |
16 | ;- Reset Interrupts - |
17 | ;----------------------------------- |
18 | RESET: |
19 | LDI r16, low (RAMEND) |
20 | OUT SPL, r16 ; Setzt sen StackPointer auf Anfang |
21 | LDI r16, 0b00011000 |
22 | OUT DDRB, r16 ; Setzt Pin6->Input, Pin2->Output, Pin3->Output |
23 | LDI r16, 0b00000010 |
24 | OUT PORTB, r16 ; PullUp |
25 | LDI r16, 0b01000000 |
26 | OUT GIMSK, r16 ; Aktiviert Interupt INT0 |
27 | LDI r16, 0b00000011 |
28 | OUT MCUCR, r16 ; Interupt nur bei Steigender Flanke & Sleep erlauben |
29 | SEI |
30 | ;sleep |
31 | |
32 | ;----------------------------------- |
33 | ;- Main-Loop - |
34 | ;----------------------------------- |
35 | Loop: |
36 | rjmp Loop |
37 | |
38 | ;----------------------------------- |
39 | ; Int0 Interrupt (PPM Interpreter) - |
40 | ;----------------------------------- |
41 | PPM: |
42 | PUSH R15 |
43 | IN R15,SREG ; Save SREG |
44 | |
45 | ;----------------------------------- |
46 | ;- Fallende Flanke ermitteln - |
47 | ;----------------------------------- |
48 | WaitForDown: |
49 | ADIW XL,1 ; Increment von X Pointer Register |
50 | in R19, PINB ; Lese Pins in R19 |
51 | andi R19, 0b00000010 ; Isoliere Pin6 (PB1) |
52 | CPI R19, 0x00 ; Vergleiche ob Signal anliegt |
53 | BREQ Finish ; Wenn Signal weg, dann Fertig |
54 | rjmp WaitForDown ; Wenn weiterhin Signal anliegt, weiter zählen. |
55 | |
56 | Finish: |
57 | ;----------------------------------- |
58 | ;- Auf Rechts & Links prüfen - |
59 | ;----------------------------------- |
60 | LDI R17, 0x08 |
61 | LDI R18, 0x71 |
62 | CP XL, R18 |
63 | CPC XH, R17 |
64 | BRGE RLOn |
65 | |
66 | ;----------------------------------- |
67 | ;- Auf Rechts prüfen - |
68 | ;----------------------------------- |
69 | LDI R17, 0x07 |
70 | LDI R18, 0x36 |
71 | CP XL, R18 |
72 | CPC XH, R17 |
73 | BRGE ROn |
74 | |
75 | ;----------------------------------- |
76 | ;- Auf Links prüfen - |
77 | ;----------------------------------- |
78 | LDI R17, 0x05 |
79 | LDI R18, 0xFB |
80 | CP XL, R18 |
81 | CPC XH, R17 |
82 | BRGE LOn |
83 | |
84 | ;----------------------------------- |
85 | ;- Auf Aus prüfen - |
86 | ;----------------------------------- |
87 | cbi PORTB, 0x04 ; Ausgänge Schalten (Aus) |
88 | cbi PORTB, 0x03 |
89 | rjmp Resume |
90 | |
91 | RLOn: |
92 | sbi PORTB, 0x04 ; Ausgänge Schalten (Beide) |
93 | sbi PORTB, 0x03 |
94 | rjmp Resume |
95 | |
96 | ROn: |
97 | sbi PORTB, 0x04 ; Ausgänge Schalten (Rechts) |
98 | cbi PORTB, 0x03 |
99 | rjmp Resume |
100 | |
101 | LOn: |
102 | cbi PORTB, 0x04 ; Ausgänge Schalten (Links) |
103 | sbi PORTB, 0x03 |
104 | rjmp Resume |
105 | |
106 | Resume: |
107 | CLR XH |
108 | CLR XL |
109 | |
110 | OUT SREG, R15 ; Restore SREG |
111 | POP R15 |
112 | |
113 | RETI |
1 | Edit Mod: Code bitte in [avrasm] ... [/avrasm] einfassen |
:
Bearbeitet durch Moderator
Armin A. schrieb: > OK, hier der Code: a) BRGE wird für signed genommen, normal ist BRSH für unsigned. b) Es wird nur auf 3 Zeiten geprüft: 2,161us, 1846us und 1531us. c) Alles, was kürzer als 1531us dauert, wird nicht bearbeitet, es wird Zustand 1 angenommen. Abgesehen davon, scheint es (für mich jedenfalls) OK zu sein. P.S. Wie genau werden die Zeiten bei "Funke" gemessen und angezeigt ? P.P.S. Und vergleiche Low mit Low und nicht Low mit High. XL = Low / XH = High r17 = Low / r18 = High. Auch wenn du die Werte richtig geladen hast, verkehrt ist es trotzdem, abgesehen davon, dass r17/r18 gar keinen Registerpaar darstellt.
:
Bearbeitet durch User
Marc V. schrieb: > a) BRGE wird für signed genommen, normal ist BRSH für unsigned. > b) Es wird nur auf 3 Zeiten geprüft: 2,161us, 1846us und 1531us. Dass sind die 3 Schwellen, die ich so zu sagen gesetzt habe. bezüglich der µs müsste ich nochmal genau nachsehen. Um die Schwellen zu ermitteln habe ich etwas mit dem Fernsteuerungs-Sender experimentiert, indem ich erstmal eine grenze gesetzt habe und dann überprüft habe, ob der Controler auf die Min und Max Werte reagiert. als ich den Min & Max Wert ermittelt habe, hatte ich die Range des Counters, in dem ich meine Schwellwerte verteilen musste. Dass habe ich dann gefiertelt. So bin ich dann zu den Werten () Die Zahlen sind aber keine µs, da die Abarbeitung des Codes ja auch Zeit benötigt. Somit müsste der Zeitliche Wert etwa bei 1250µs, 1500µs & 1750µs liegen. > c) Alles, was kürzer als 1531us dauert, wird nicht bearbeitet, > es wird Zustand 1 angenommen. Dass ist richtig! > > Abgesehen davon, scheint es (für mich jedenfalls) OK zu sein. > > P.S. > Wie genau werden die Zeiten bei "Funke" gemessen und angezeigt ? An der "Funke" kann ich mir nure deren Wert anzeigen lassen, der von -100,0 bis +100,0 geht und die schwankt höchstens eine Stelle nach dem Komma. > > P.P.S. > > Und vergleiche Low mit Low und nicht Low mit High. > > XL = Low / XH = High > r17 = Low / r18 = High. Ist es nicht so: R17 R18 [0000][0000] High Low Hm... ich vergleiche doch nur Low mit Low und High mit High, oder? Was davon könnte jetzt für mein Problem verantwortlich sein? Und würde ich dieses Problem mit einem Timer (Ohne externen Quarz) lösen?
:
Bearbeitet durch User
S. K. schrieb: > Relativ zueinander passen die Werte auf 2,5%. Für einen Schwellwert wohl > genau genug. Wie das ?
1 | 7. -28,3 28,2 82,8 |
2 | 8. -48,5 5,1 56,3 <********** |
3 | 9. -36,4 19,5 71,5 |
4 | 10. -22,7 32,5 87,6 |
5 | 11. -32,2 22,6 75,6 |
6 | 12. -46,6 5,1 53,9 <********* |
7 | 13. -29,1 27,6 81,9 |
Deine Prozentrechnung errinert etwas an Kreditwucherer.
Armin A. schrieb: > Die Zahlen sind aber keine µs, da die Abarbeitung des Codes ja auch Zeit > benötigt. > Somit müsste der Zeitliche Wert etwa bei 1250µs, 1500µs & 1750µs liegen. Nein, das sind schon us bei 8MHz, so:
1 | WaitForDown:
|
2 | ADIW XL,1 ; Increment von X Pointer Register ; 2 Takte |
3 | in R19, PINB ; Lese Pins in R19 ; 1 Takt |
4 | andi R19, 0b00000010 ; Isoliere Pin6 (PB1) ; 1 Takt |
5 | CPI R19, 0x00 ; Vergleiche ob Signal anliegt ; 1 Takt |
6 | BREQ Finish ; Wenn Signal weg, dann Fertig ; 1 Takt |
7 | rjmp WaitForDown ; Wenn weiterhin Signal anliegt, weiter zählen. ; 2 Takte = 8 Takte = 1us |
Da gibt es kein etwa... Armin A. schrieb: > Hm... ich vergleiche doch nur Low mit Low und High mit High, oder? Von den Werten her schon, nur von der Logik her nicht. Bei AVR ist Register r18 höher als r17, genauso ist XH(r27) höher als XL(r26). Und Registerpaare beginnen immer mit gerader Registernummer, also ist r16/r17 ein Registerpaar, genauso ist es mit r18/r19, aber nicht mit r17/r18. In deinem Code vielleicht nicht so wichtig, aber beim ADIW und besonders beim MOVW must du schon aufpassen.
Armin A. schrieb: > Was davon könnte jetzt für mein Problem verantwortlich sein? > Und würde ich dieses Problem mit einem Timer (Ohne externen Quarz) > lösen? Kaum. Du bist schon in der ISR, da gibt es keine Unterbrechungen, dein Loop ist (fast) genau so präzise wie ein Timer mit 1us Auflösung. Aber mit einem PCINT, welches bei jedem Flankenwechsel feuert, könntest du das Problem mit Flanken zumindest vergessen. Einmal auf steigende Flanke synchronisiert, kann man nach 2 Flanken eine Messung verwerfen (Zeit zwischen 2 Impulsen). In der OVF ISR wird nur ein reserviertes Register hochgezählt und dieses wird bei Impulsende als HighRegister genommen, TIM0 als LowRegister. Fertisch. Glaube aber nicht das es viel bringt, ausser wie gesagt bei der Flankenauswertung. Von der Genauigkeit her aber nicht. P.S. Hast du die Möglichkeit Werte über (TTL-USB) auszugeben ?
:
Bearbeitet durch User
Jetzt bin ich verwirrt: Ich habe den Tiny auf 9,6MHz was doch bedeutet, dass der 0,83µs Braucht. Demnach bin ich bei 1270µs 1532µs und 1793µs. Dann ist mein etwa 1250µs, 1500µs & 1750µs nicht wirklich falsch. Das mit dem High und Low könnte ich noch ändern, aber ist nur eine Lesbare Verbesserung. Ich frage mich halt, das da so für die Unterschiede verantwortlich ist. Nein, ich habe kein TTL-USB zur Hand.
:
Bearbeitet durch User
Armin A. schrieb: > Ich habe den Tiny auf 9,6MHz was doch bedeutet, dass der 0,83µs Braucht. Das wusste ich nicht, dachte es sind 8MHz. > Demnach bin ich bei 1270µs 1532µs und 1793µs. Ja, in etwa. > Ich frage mich halt, das da so für die Unterschiede verantwortlich ist. Dein "Funke" vielleicht ? > Nein, ich habe kein TTL-USB zur Hand. Ein LA ? Ein Arduino ? Ein anderes Board ? Ein Transistor, 2 Widerstände, RS232 am Comp ? Nur wenn Tiny die Werte direkt ausgibt, kannst du sicher sein.
:
Bearbeitet durch User
Marc V. schrieb: > Wie das ? Den Messrange habe ich mangels besserer Zahlen als grösster Wert (87,6) - kleinster Wert (-48,5) = 136,1 angesetzt. Korrekt währen das laut Eingangspost wohl 200. Die Distanz innerhalb eines Datensatzes (Wert - Nachbarwert derselben Zeile) liegt zwischen 48,8 und 58,5. Macht 43,8 +/-5. Ob die +/-5 nun 2% (von 200) oder 3% sind, macht den Braten nicht fett. Die Differenz zwischen min und max der Spalte "Ch1 & 2 An" beträgt immerhin 33,7. macht +/-16,75. Bezogen auf 200 Messrange: +/-8,375%. Wenn man bedenkt das das aber ja nur der halbe Messbereich ist weil 1ms Offset zu der 1ms änderbare Messzeit hinzukommt sind es dann nurnoch +/-4,2% Fehler vom Oszillatortakt. >Deine Prozentrechnung errinert etwas an Kreditwucherer. jetzt noch mehr... hauspapa
Wenn es die "Funke" währe, dann dürfte ich doch ständig andere Werte sehen, oder? Wenn ich die 20 Tinys jetzt nochmal dranhänge kommen fast die selben Ergebnisse raus. Habe 3 Durchgänge gemacht und war erstaunt, dass es so ist. Wenn ich euch soweit richtig verstehe ist der Code soweit in Ordnung und kann nicht die Ursache sein? Der Empfänger liefert 5V. Wenn jetzt die Kontakte an dem Tiny nicht sauber sind und somit ein kleiner Wiederstand entsteht, könnte das die Ursache sein?
Servus, ich kapiere nicht, was es hier noch über die Ursache zu rätseln gibt - dachte, es wäre längst klar, daß der unpräzise interne Oszillator des Tiny für die Abweichungen verantwortlich ist. Knapp 4% reale Abweichung für einen Oszillator, der unkalibriert +/- 10% haben kann, ist doch auch plausibel, oder?
OK, kommen wir mal zu Kalibrieren. Wie kalibriere ich den Internen und muss ich das für jeden Tiny separat durchführen?
Armin A. schrieb: > Wenn ich euch soweit richtig verstehe ist der Code soweit in Ordnung und > kann nicht die Ursache sein? IMHO, nein. Falls du die Dinger programmieren kannst: Nimm irgendeinen Tiny als Referenz. Die anderen werden als Test bezeichnet. Bei den Tinys wird bezüglich Porteinstellungen nichts geändert. Verbinde Referenz_PortB.3 ===> Test_PinB.1 Verbinde Referenz_GND ===> Test_GND Beide Tinys starten, Interrupts bleiben gesperrt, nach 2 Sekunden setzt der RefTiny PortB.3 auf Null und beginnt zu zählen. TestTiny macht das gleiche sobald PinB.1 auf Null geht. Loops zum zählen sollten bei RefTiny und TestTiny von der Anzahl der Takte gleich sein, nur fragt der RefTiny seinen Zähler ab und der TestTiny fragt PinB.1 ab - aneinander angleichen. Nach 100,000 oder 1,000,000 (egal) Loops setzt der RefTiny seinen PortB.3 wieder auf Null und meldet sich nicht mehr. Sobald der TestTiny Log. 1 auf PinB.1 registriert, wird der Zählerstand in sein Eeprom reingeschrieben. Danach mit Programmer verbinden und Eeprom auslesen. Und schon hast du die (relative) Abweichung zueinander. Vergleiche das mit "Funke" und dann weisst du wer wieviel abweicht. Solange sich die Temperatur nicht drastisch ändert, sollten die Messungen auch valid sein.
Armin A. schrieb: > Wie kalibriere ich den Internen Indem du mit einem externen Takt den Timer triggerst und mit Prescaler=1 die Overflows zählst. Das sind bei 9,6MHz 375 in 10ms. Sind es mehr, inkl. dem Rest in TCNT0, läuft er zu schnell, sind es weniger läuft er zu langsam. Entsprechend veränderst du das OSCCAL-Register bis du möglichst nahe dran bist. Genau wirst du es nicht hinbekommen. Aber auf 1% kommst du auf jeden Fall ran. > und muss ich das für jeden Tiny separat durchführen? Ja natürlich. Besser sogar nach jedem Reset. Aber das wird wohl eher nicht möglich sein.
Eventuell könnte sich Dein mc auch selbstständig kalibrieren, indem er die Periodendauer des Servosignals ausmisst. Vorausgesetzt, dass diese hinreichend konstant ist. Viele Grüße, Stefan
hm... das ist eine Idee. Der Empfänger sendet immer in 20ms Abständen das Signal neu. Heist, ich könnte zuerst die Zeit zwischen den beiden Steigenden Flanke ermitteln und diesen dann für das Kalibrieren verwenden. Das ist ne gute Idee. Werde ich mal probieren.
Armin A. schrieb: > Wie kalibriere ich den Internen und muss ich das für jeden Tiny separat > durchführen? Und wie wäre es mit einem externen Quarz oder Quartzoszillator? Dann sparst Du Dir die Mühen...
Armin A. schrieb: > Heist, ich könnte zuerst die Zeit zwischen den beiden Steigenden Flanke > ermitteln und diesen dann für das Kalibrieren verwenden. Wenn Du Dir diesen Wert sowieso immer "live" holen kannst, brauchst Du den Oszilator damit nicht kalibrieren. Du kannst diesen Wert direkt nutzen, um zu rechnen, d.h. ihn als Korrekturfaktor nehmen.
Für einen Externen Quarz ist es zur Zeit zu Spät. Werde das mal für eine spätere Version in Betracht ziehen.
Hi Worin besteht das Problem, daß die 20 ATtiny unterschiedlich flott sind? Bei einem Quadro-Copter könnte ich mir vorstellen, daß sich bis zu vier µC halbwegs einig sein müssen. Wenn die gegenüber liegenden Rotoren 'invertiert' verfahren werden, dann ggf. sogar nur Zwei. Habe mir das Datenblatt zum verwendeten µC nicht zur Hand genommen, bei den mir unter die Finger geratenen ATtiny45 lässt sich der Takt nach Außen raus führen - denke mir also, daß man diesen Takt dann auch irgendwie dafür nutzen kann, um Ihn in den nächsten Chip 'rein' zu bekommen - dadurch sollten dann diese beiden µC gleich schnell sein. Allerdings nur gefährliches Halbwissen, möglich, daß Das nur mit (einem) Quarz geht und dann der Quarz-µC die 'Anderen' fremd-taktet. Was mir noch auffiel: 1MHz = 1.000.000 Schwingungen/Sekunde EINE Schwingung 0,000001 Sekunden -> 1µs Somit ergibt sich ein 1µs-Takt bei 1MHz, nicht bei 8. Sollte der Ansatz gar nicht klappen, bitte Korrigieren/Belehren MfG
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.