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
Dir hilft auch Timer1 nichts, solange die Zeitbasis der ungenaue RC-Oszillator ist.
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.
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
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?
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?
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?
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.
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.
EAF schrieb: > Stimmt nicht. Offensichtlich entzieht sich das deiner > Fachkenntnis/Beurteilung. Und ich entziehe dir auch deine Fachkenntnis/Beurteilung.
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.
Dann guckt euch das an, dann werdet ihr schlauer: https://forum.arduino.cc/t/probleme-mit-jitter-bei-arduino-uno-boards/206571/3
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.
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.
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).
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.