Forum: Mikrocontroller und Digitale Elektronik ATTiny85 Timer Probleme


von Christopher T. (ger-3118)


Lesenswert?

Hallo in die Runde,
als Fachfremder versuche ich mich gerade in der Mikrocontroller 
Programmierung, also bitte seid nachsichtig mit mir^^.

Ich benutze den ATTiny85 für eine Anwendung bei der die 
Arduino-Funktionen tone(); delay(); ,millis(); verwendet werden. 
Darüberhinaus wird ein Servo über PWM angesteuert und eine Zeit 
gemessen. Diese Zeit habe ich zu Beginn über millis() gemessen. Da diese 
Funktion anscheinen bei Zeiten von mehreren Minuten, Abweichungen von 
mehreren Sekunden erzeugt, habe ich versucht einen TimerInterrupt auf 
dem Timer 1 zu nutzen um die Zeit genauer zu messen. in einer Testsketch 
hat das auch gut funktioniert.

Wenn ich den Timer 1 nun bei dem großen Programm für die Zeitmessung 
nutze, bekomme ich die Fehlermeldung, dass der Vektor mehrfach belegt 
wurde. "
C:\Users\chris_000\AppData\Local\Arduino15\packages\ATTinyCore\hardware\ 
avr\1.1.2\cores\tiny/Tone.cpp:535:  multiple definition of 
`__vector_3'")

Ich verstehe es so, dass tone() ebenfalls auf dem Timer 1 läuft und es 
somit zu Problemen kommt.

Die anderen Arduino Funktionen laufen anscheinend auf Timer0 und nur 
tone() ist das Problem.

Gibt es eine Möglichkeit das Problem aufzulösen? Z.B. tone() ebenfalls 
auf Timer 0 zu schieben?

Wäre dankbar für jeden Hinweis.
Grüße,
Christopher

von MWS (Gast)


Lesenswert?

Dir hilft auch Timer1 nichts, solange die Zeitbasis der ungenaue 
RC-Oszillator ist.

von EAF (Gast)


Lesenswert?

MWS schrieb:
> ...

Christopher T. schrieb:
> habe ich versucht einen TimerInterrupt auf
> dem Timer 1 zu nutzen um die Zeit genauer zu messen.
Das wird nix, da stimme ich MWS vollständig zu.

Du könntest OSCCAL verändern/kalibrieren, z.B. Temperatur abhängig.
1%, besser wirds wohl nicht werden.

von Christopher T. (ger-3118)


Lesenswert?

Ok, was ich daran nur nicht verstehe, ist, dass ich bei den millis() 
etwa 3-4 Prozent daneben bin. Sowohl zu schnell als zu langsam. Bei dem 
Timer war ich deutlich genauer, auf jeden Fall unter 1 Prozent. Ich habe 
es natürlich nicht statistisch über mehrere Stück ausgewertet. Woran 
könnte es denn liegen, dass millis() so ungenau ist?
Grüße

von EAF (Gast)


Lesenswert?

Christopher T. schrieb:
> dass millis() so ungenau ist?

Mills ist nicht ungenau, hat sogar eine eingebaute Korrektur.

Was daneben geht, ist der interne Oszillator. Die Fehlpeilung ist im 
Datenblatt beschrieben.
Aber, sachte ich das nicht schon?

von MWS (Gast)


Lesenswert?

Christopher T. schrieb:
> Woran könnte es denn liegen, dass millis() so ungenau ist?

Blockierende (lange) Interruptserviceroutinen oder anderweitiges Sperren 
des Interrupts, der die Millies updated. Da geht die Uhr aber nur 
langsamer und nicht schneller. Beschreib doch kurz die Hardware, ist ein 
Quarz angeschlossen?

von Christopher T. (ger-3118)


Lesenswert?

Die Hardware besteht einzig aus dem Attiny 85 ohne Quarz.
Grüße

von EAF (Gast)


Lesenswert?

Christopher T. schrieb:
> Die Hardware besteht einzig aus dem Attiny 85 ohne Quarz.
Und, mit wieviel MHz betreibst du ihn?
1MHz ?
8?
16?
Oder gar 16,5?

von BlaBla (Gast)


Lesenswert?

Christopher T. schrieb:
> Ok, was ich daran nur nicht verstehe, ist, dass ich bei den millis()
> etwa 3-4 Prozent daneben bin. Sowohl zu schnell als zu langsam. Bei dem
> Timer war ich deutlich genauer, auf jeden Fall unter 1 Prozent. Ich habe
> es natürlich nicht statistisch über mehrere Stück ausgewertet. Woran
> könnte es denn liegen, dass millis() so ungenau ist?

Das Problem ist die Arduino-Software. Die hat viele interrupt-gesteuerte 
Hintergrundprozesse. Da hilft nur ohne Arduino-SW programmieren.

von EAF (Gast)


Lesenswert?

BlaBla schrieb:
> Das Problem ist die Arduino-Software. Die hat viele interrupt-gesteuerte
> Hintergrundprozesse. Da hilft nur ohne Arduino-SW programmieren.

Stimmt nicht. Offensichtlich entzieht sich das deiner 
Fachkenntnis/Beurteilung.

Punkt 1:
Einzig die Timer ISR wird üblicherweise etabliert.
Selbst das ist beim Tiny85 nicht unbedingt der Fall(auswählbar)

Punkt 2:
Es gibt keinen Tiny85 im originalen Arduino Umfeld. Das sind alles 
fremde, hinzugeladene Plattformdefinitonen. Hier ist leider geheim, 
welche verwendet wird.

von BlaBla (Gast)


Lesenswert?

EAF schrieb:
> Stimmt nicht. Offensichtlich entzieht sich das deiner
> Fachkenntnis/Beurteilung.

Und ich entziehe dir auch deine Fachkenntnis/Beurteilung.

von Peter D. (peda)


Lesenswert?

BlaBla schrieb:
> Das Problem ist die Arduino-Software. Die hat viele interrupt-gesteuerte
> Hintergrundprozesse. Da hilft nur ohne Arduino-SW programmieren.

Wasn Quatsch, millis() benutzt einen Timer und ist damit von 
Programmlaufzeiten unabhängig. Man muß schon elend lange die Interrupts 
sperren, damit ein kompletter Überlauf verloren geht.

millis() zählt aber keine glatten 1.000ms, sondern irgendwas krummes. Es 
kann daher beim Auslesen zu Rundungsfehlern kommen. Genaueres sollte im 
Manual stehen.

von BlaBla (Gast)


Lesenswert?

Dann guckt euch das an, dann werdet ihr schlauer:

https://forum.arduino.cc/t/probleme-mit-jitter-bei-arduino-uno-boards/206571/3

von Peter D. (peda)


Lesenswert?

Christopher T. schrieb:
> Gibt es eine Möglichkeit das Problem aufzulösen? Z.B. tone() ebenfalls
> auf Timer 0 zu schieben?

Prinzipiell ja, wird aber tricky. Die Anzahl an Compareregistern ist 
begrenzt und Tonausgabe in SW benötigt recht häufige Interrupts.

Nimm den ATmega328PB, der hat 5 Timer.

von EAF (Gast)


Lesenswert?

BlaBla schrieb:
> Und ich entziehe dir auch deine Fachkenntnis/Beurteilung.
Wie willst du das denn tun?

Tipp:
Versuche doch mal, dich etwas dichter an die Realität zu koppeln.

von Peter D. (peda)


Lesenswert?

Man kann auch den ADC in free running als zusätzlichen Timerinterrupt 
benutzen. Mit ADC-Teiler 128 hat man alle 1664 CPU-Takte einen Interrupt 
(=4,8ms bei 8MHz).

von Christopher T. (ger-3118)


Lesenswert?

Ich betreibe ihn bei 8Mhz internal.



EAF schrieb:
> Christopher T. schrieb:
>> Die Hardware besteht einzig aus dem Attiny 85 ohne Quarz.
> Und, mit wieviel MHz betreibst du ihn?
> 1MHz ?
> 8?
> 16?
> Oder gar 16,5?

von Christopher T. (ger-3118)


Lesenswert?

Hast du zufällig ein paar Codeschnipsel auf denen ich aufbauen kann?
Danke für die Tipps.

Peter D. schrieb:
> Man kann auch den ADC in free running als zusätzlichen Timerinterrupt
> benutzen. Mit ADC-Teiler 128 hat man alle 1664 CPU-Takte einen Interrupt
> (=4,8ms bei 8MHz).

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.