Forum: Mikrocontroller und Digitale Elektronik Ein Code, mehrere Controller.


von Armin A. (10110010)


Lesenswert?

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

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Armin A. schrieb:
> Hier eine Tabelle mit den genauen Werten:

 Und die Werte sind was ?

 Wo kommen die Kommas her ?

von Jim M. (turboj)


Lesenswert?

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.

von Armin A. (10110010)


Lesenswert?

@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.

von Einer K. (Gast)


Lesenswert?

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.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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 ?

von M. K. (sylaina)


Lesenswert?

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.

von M. K. (sylaina)


Lesenswert?

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.
von Thomas E. (picalic)


Lesenswert?

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
von Noch einer (Gast)


Lesenswert?

> 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.

von Thomas E. (picalic)


Lesenswert?

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.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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
von Armin A. (10110010)


Lesenswert?

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.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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.

von Cyblord -. (cyblord)


Lesenswert?

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
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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...

von Cyblord -. (cyblord)


Lesenswert?

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.

von Armin A. (10110010)


Lesenswert?

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?

von Cyblord -. (cyblord)


Lesenswert?

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.

von Einer K. (Gast)


Lesenswert?

Armin A. schrieb:
> Nutzt der Timer einen
> anderen Quarz, der genauer ist oder den selben?
Wieviel Quarze hast du in deiner Schaltung?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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 ?

von S. K. (hauspapa)


Lesenswert?

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

von Cyblord -. (cyblord)


Lesenswert?

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.

von Armin A. (10110010)


Lesenswert?

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
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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
von Armin A. (10110010)


Lesenswert?

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
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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
von Armin A. (10110010)


Lesenswert?

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
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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
von S. K. (hauspapa)


Lesenswert?

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

von Armin A. (10110010)


Lesenswert?

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?

von Thomas E. (picalic)


Lesenswert?

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?

von Armin A. (10110010)


Lesenswert?

OK, kommen wir mal zu Kalibrieren.

Wie kalibriere ich den Internen und muss ich das für jeden Tiny separat 
durchführen?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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.

von Thomas E. (thomase)


Lesenswert?

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.

von Stefan K. (stefan64)


Lesenswert?

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

von Armin A. (10110010)


Lesenswert?

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.

von Dietrich L. (dietrichl)


Lesenswert?

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...

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Armin A. (10110010)


Lesenswert?

Für einen Externen Quarz ist es zur Zeit zu Spät.
Werde das mal für eine spätere Version in Betracht ziehen.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

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
Noch kein Account? Hier anmelden.