Forum: Mikrocontroller und Digitale Elektronik Welchen Mikrocontroller für Millisekunden-Stoppuhr?


von Michael (arcturus)


Lesenswert?

Hallo!

Ich möchte für meinen Arduino Uno Rev3 zu Hobbyzwecken eine 
Millisekunden-Stoppuhr bauen. Ich möchte nicht auf die Arduino-interne 
Millisekunden-Zählung zurückgreifen, weil der interne 16 MHz-Taktgeber 
eine zu große Gangungenauigkeit hat. Auch möchte ich nicht einen 
externen Takt auf dem Arduino verarbeiten, weil manche 
Programmbibliotheken (z.B. OneWire) Interrupts und somit die Zählung 
eines Taktsignal zeitweilig abstellen können.

Meine Idee ist, ein peripheres Modul aufzubauen, das auf dem Takt eines 
Echtzeit-Moduls basiert. Z.B. dem DS3231 RTC, der unter Anderem ein 32 
kHz-Rechtecksignal bereitstellt; Ganggenauigkeit +- 5 ppm. Ein simpler 
Mikrocontroller sollte in diesem Takt einen Zähler erhöhen, und bei 
Anfrage des Arduino ausgeben. Ein 32-bit Zähler wäre genügend. Die 
Schnittstelle vom Mikrocontroller zum Arduino sollte folgende Funktionen 
unterstützen:

* Start-Signal (PinX): Zwischenspeichern des aktuellen Zählerstands in 
einen Speicher „start“ auf dem Mikrocontroller.
* Stopp-Signal (PinY): Zwischenspeichern des aktuellen Zählerstands in 
einen Speicher „stopp“ auf dem Mikrocontroller.
* Übertragung der Speicher „start“ und „stopp“ zum Arduino. Evtl. 
I2C-Protokoll? Oder was der Arduino Uno Rev3 sonst noch unterstützt.
* Zurücksetzen des Zählers auf 0. Per separatem Pin oder anderem 
Protokoll?

Ein typischer Messvorgang würde so ablaufen:
Die Stoppuhr erhöht den aktuellen Zähler laufend im eingehenden Takt. 
Der Arduino gibt das Start-Signal an die Stoppuhr. Die Stoppuhr 
speichert den aktuellen (Start-)Zählerstand. Die Zeit verrinnt. Der 
Arduino gibt das Stopp-Signal an die Stoppuhr. Die Stoppuhr speichert 
den aktuellen (Stopp-)Zählerstand. Der Arduino gibt das Kommando zur 
Übertragung der Zählerspeicher. Die Start- und Stoppzählerstände werden 
an den Arduino übertragen. Die Differenz der Zähler, die Zeitdauer, wird 
auf dem Arduino berechnet..

Optional wäre auch ein Abfragen der Zählerstände (Start-Zähler und 
aktueller Stand) nützlich, während einer laufenden Messung. Das darf 
dann aber die Bearbeitung eines Stoppsignals nicht verzögern.

Außer mit dem Arduino Uno habe ich keine Erfahrung mit Mikrocontrollern. 
Mit PC-Programmierung reichlich.

Welchen Mikrocontroller würdet Ihr empfehlen im Hinblick auf die 
folgenden Randbedingungen:
* Programmierung bevorzugt in C oder C++. Zur Not in Assembler.
* Kostenlose Entwicklungsumbgebung für Windows 10 sollte es geben.
* Programm aufspielen per Arduino Uno Rev3 möglich. (Oder 
Hardware-Schnittstelle max. 15 EUR)
* Pins für: Start, Stopp, Takt, serielle Übertragung der Zählerstände. 
Evtl. Zurücksetzen.
* Gute Verfügbarkeit in Deutschland, preiswert.

Michael

von Harry L. (mysth)


Lesenswert?

Takte deinen ATMega extern mit nem billigen TCXO statt dem onboard-Quarz 
und der Dropps ist gelutscht.

Andererseits kann ich mir nicht vorstellen, wieso ein normaler UNO für 
so eine läppische ms-Zählung zu ungenau sein soll.

Millisekunden sind für praktisch jeden halbwegs aktuellen µC absoluter 
Pillepalle.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Michael schrieb:
> Hallo!
>
> Ich möchte für meinen Arduino Uno Rev3 zu Hobbyzwecken eine
> Millisekunden-Stoppuhr bauen. Ich möchte nicht auf die Arduino-interne
> Millisekunden-Zählung zurückgreifen, weil der interne 16 MHz-Taktgeber
> eine zu große Gangungenauigkeit hat.

Wie meinen? Das ist zwar kein echter Quarz und nur ein Resonator, aber 
der hat auch um die 1% Genauigkeit.

> Meine Idee ist, ein peripheres Modul aufzubauen, das auf dem Takt eines
> Echtzeit-Moduls basiert. Z.B. dem DS3231 RTC, der unter Anderem ein 32
> kHz-Rechtecksignal bereitstellt; Ganggenauigkeit +- 5 ppm. Ein simpler
> Mikrocontroller sollte in diesem Takt einen Zähler erhöhen, und bei
> Anfrage des Arduino ausgeben. Ein 32-bit Zähler wäre genügend. Die
> Schnittstelle vom Mikrocontroller zum Arduino sollte folgende Funktionen
> unterstützen:

Alles Käse. Löte den Resonator runter und einen genauen Takt drauf, ggf. 
auch aus einem genauen Quarzozilaltor, der mit VCC/GND versorgt werden 
muss. Alternativ kann man einen 32,768 kHz Takt in TOSC1 einspeisen und 
Timer2 damit betreiben. Allerdings wird es dann etwas kniffelig, ein 
Auflösung von 1ms zu bekommen. Da muss man in Software einiges tricksen.

> Außer mit dem Arduino Uno habe ich keine Erfahrung mit Mikrocontrollern.

Man braucht hierfür aber keine ZWEI Mikrocontroller!

> Welchen Mikrocontroller würdet Ihr empfehlen im Hinblick auf die
> folgenden Randbedingungen:
> * Programmierung bevorzugt in C oder C++. Zur Not in Assembler.

Praktisch jeder Arduino. Selbst der Nano/Micro reicht.

> * Kostenlose Entwicklungsumbgebung für Windows 10 sollte es geben.

Arduino.

> * Programm aufspielen per Arduino Uno Rev3 möglich. (Oder
> Hardware-Schnittstelle max. 15 EUR)

Braucht man nicht, weil fast alle Arduinos per USB programmierbar sind.

> * Pins für: Start, Stopp, Takt, serielle Übertragung der Zählerstände.
> Evtl. Zurücksetzen.

Haben alle ausreichend.

> * Gute Verfügbarkeit in Deutschland, preiswert.

Ist bei den Meisten gegeben.

von Falk B. (falk)


Lesenswert?

Man kann auch noch mehr tricksen. Den Resonator am "echten" AVR beim 
Arduino Uno ablöten und die 16 MHz vom Quarz, welcher den Hilfs-AVR für 
die USB-Verbindung treibt (U3) auf den Haupt-AVR legen.

U3 Pin 2 (XTAl2) an ZU4 Pin 9 (XTAL1)

Der Quarz hat vermutlich +/-50ppm oder weniger Fehler.

: Bearbeitet durch User
von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

Ich würde

Michael schrieb:
> Ich möchte nicht auf die Arduino-interne Millisekunden-Zählung
> zurückgreifen, weil der interne 16 MHz-Taktgeber
> eine zu große Gangungenauigkeit hat.

Ich glaube, da hast du etwas durcheinander gebracht. Der interne 
Taktgeber ist in der Tat ungenau, hat aber 8 MHz. Arduino Boards werden 
aber immer mit einem Keramik Resonator (auch ungenau) oder Quartz 
angetrieben. Ein normaler 16 MHz Quarz ist nicht weniger genau, als ein 
32 kHz Uhrenquarz.

> Auch möchte ich nicht einen externen Takt auf dem Arduino verarbeiten,
> weil manche Programmbibliotheken (z.B. OneWire) Interrupts und somit
> die Zählung eines Taktsignal zeitweilig abstellen können.

Die Timer zählen Takte unabhängig von der Interruptfreigabe. Viele AVR 
Modelle bieten sogar die Möglichkeit, einen zweiten Quarz extra für 
diesen Zweck anzuschließen.

Siehe z.B. 
https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
Kapitel 8.5 Low Frequency Crystal Oscillator

> Meine Idee ist, ein peripheres Modul aufzubauen, das auf dem Takt eines
> Echtzeit-Moduls basiert. Z.B. dem DS3231 RTC, der unter Anderem ein 32
> kHz-Rechtecksignal bereitstellt; Ganggenauigkeit +- 5 ppm. Ein simpler
> Mikrocontroller sollte in diesem Takt einen Zähler erhöhen, und bei
> Anfrage des Arduino ausgeben.

Wenn dein Arduino eine Interruptsperre hat, wird er das 
Zwischenspeichern des aktuellen Zählerstands verzögert auslösen und 
daher ebenso die falsche Zeit erhalten. Damit gewinnst du nichts. Mache 
dir lieber Gedanke, wie du einen internen Timer dazu verwenden kannst.

> Welchen Mikrocontroller würdet Ihr empfehlen
http://stefanfrings.de/stm32/stm32l0.html

Der hat sogar eine kalibrierbare RTC mit eigenem 32 kHz Quarz, falls du 
dazu unbedingt eine RTC verwenden willst. Ich würde allerdings eher 
einen Timer mit dem 8 MHz Hauptquarz takten, denn das lässt sich 
leichter auf exakte Millisekunden runter teilen.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Michael schrieb:
> Millisekunden-Stoppuhr bauen.
> Millisekunden-Zählung
> Ganggenauigkeit +- 5 ppm.

Finde den Fehler… (Falls nicht gerade Tagelang am Stück Millisekunden 
gezählt werden sollen.)

PS. ppm steht nicht für ›parts per millisecond‹.

von Mi N. (msx)


Lesenswert?

Löte den Resonator aus und stelle die Verbingung lt. Bild her: 
http://mino-elektronik.de/bilder/Fmeter_6LED/UNO_R3_takt_1_5_1.jpg
Damit wird der ATmega328 vom lokalen 16 MHz Quarz versorgt.

Michael schrieb:
> * Gute Verfügbarkeit in Deutschland, preiswert.

Das Stück Litze gibt es hierzulande zu kaufen.

von Mi N. (msx)


Lesenswert?

Alternativ habe ich auch noch eine Stoppuhr auf ATmega48/88/328 Basis:
http://mino-elektronik.de/fmeter/fm_software.htm#bsp6
Die Zeitbasis kann man ja auf 1 kHz reduzieren und wenn es tatsächlich 
auf 5 ppm genau sein müßte, kann man einen TCXO verwenden. 10 MHz oder 
20 MHz habe ich in der Schublade. Irgendeine Platine dazu müßte ich auch 
noch haben.

von Rainer W. (rawi)


Lesenswert?

Michael schrieb:
> Welchen Mikrocontroller würdet Ihr empfehlen im Hinblick auf die
> folgenden Randbedingungen:
> ...

Nimm einen ATmega328, so wie er auch auf dem einen oder anderen Arduino 
drauf ist. Der besitzt Timer/Zähler, die du für deinen Zweck nutzen 
kannst und unabhängig vom Prozessor ist. Das brauchst du nicht extern 
aufzubauen.

von Manfred P. (pruckelfred)


Lesenswert?

Sherlock schrieb:
> Michael schrieb:
>> Ich möchte nicht auf die Arduino-interne Millisekunden-Zählung
>> zurückgreifen, weil der interne 16 MHz-Taktgeber
>> eine zu große Gangungenauigkeit hat.
>
> Ich glaube, da hast du etwas durcheinander gebracht.

Wer - eher Du als Michael.

> Der interne Taktgeber ist in der Tat ungenau,

Wie ungenau?

> hat aber 8 MHz.

Welche? Die Masse meiner hat 16 MHz, nur die 3,3V-Version des ProMini 
wird mit 8 MHz getaktet.

von Uwe K. (ukhl)


Lesenswert?

> Andererseits kann ich mir nicht vorstellen, wieso ein normaler UNO für
> so eine läppische ms-Zählung zu ungenau sein soll.

Weil er keinen Quarz hat, sondern ein Keramikresonator.

von Michael B. (laberkopp)


Lesenswert?

Michael schrieb:
> Welchen Mikrocontroller würdet Ihr empfehlen

Arduino Uno.

Michael schrieb:
> weil der interne 16 MHz-Taktgeber eine zu große Gangungenauigkeit hat.

Michael schrieb:
> Ganggenauigkeit +- 5 ppm

Eng. Das schaffen 32768 Uhrenquartze gerade eben aber die liefern keine 
Millisekunde Auflösung. 10ppm gäbe es
https://de.rs-online.com/web/p/schwingquarz/1735927


> Auch möchte ich nicht einen externen Takt auf dem Arduino verarbeiten,
> weil manche Programmbibliotheken (z.B. OneWire) Interrupts und somit die
> Zählung eines Taktsignal zeitweilig abstellen können.

Niemand zwingt dich, schlecht zu programmieren.

Michael schrieb:
> Ein typischer Messvorgang würde so ablaufen:
> Die Stoppuhr erhöht den aktuellen Zähler laufend im eingehenden Takt.
> Der Arduino gibt das Start-Signal an die Stoppuhr. Die Stoppuhr
> speichert den aktuellen (Start-)Zählerstand. Die Zeit verrinnt. Der
> Arduino gibt das Stopp-Signal an die Stoppuhr. Die Stoppuhr speichert
> den aktuellen (Stopp-)Zählerstand

Das kann problemlos ein interner Hardwarezähler des Arduino machen.

Man konnte versuchen einen TXCO zu nutzen als Taktquelle für den Arduino 
aber die laufen mit 3.3V.

https://www.mouser.de/ProductDetail/Pletronics-Inc/UCE4031035LK015000-16.0M

von Michael (arcturus)


Lesenswert?

Vielen Dank für alle Antworten.

Leider hat niemand meine Frage nach dem geeigneten, simplen 
Mikrocontroller beantwortet.

Manche zweifelten den Sinn einer besseren Genauigkeit als die 
Arduino-interne
Millisekunden-Zählung an oder verwechselten Auflösung mit Genauigkeit.
Der Arduino Uno Rev3 speist, ab Werk, den Millisekunden-Zähler über 
einen 16 MHz ceramic resonator (CSTCE16M0V53-R0). Das läuft über den 
TCNT0 – Timer/Counter Register des ATmega328P und die Timer/Counter0 
overflow interrupt service routine. Dieser Taktgeber hat laut Datenblatt 
(https://www.mouser.de/datasheet/2/281/p16e-522700.pdf) eine mögliche 
Ungenauigkeit von "Initial Frequency Tolerance ±0.5%" also 5000 ppm. Es 
mag viele Anwendungen geben, für die das genau genug ist. Ich wollte 
aber für meine Hobby-Lernzwecke eben eine genauere Stoppuhr 
implementieren. Der von mir avisierte DS3231 RTC hat eine mögliche 
Ungenauigkeit von 5 ppm - tausend mal besser.

Manche haben vorgeschlagen, das Arduino-Board "aufzubohren", um einen 
genaueren Takt zu haben. Das ist im Prinzip ein konstruktiver Beitrag; 
aber das war gar nicht meine Fragestellung.

(1.) Ich will eine Lösung ohne einen Umbau des Arduino.

(2.) ist da noch die Sache mit dem Interrupt und Zählerblockiern. Selbst 
wenn der Arduino-Oszillator perfekt wäre, könnten eingebundene Libraries 
(OneWire) über eine Interruptsperre den Millisekunden-Zähler 
verfälschen. Das kann man umgehen mit meinem Lösungsansatz des externen 
Zählers.
Wenn eine Bibliotheksfunktion die Interrupts ungeschickterweise zu lange 
sperrt, geht der Millisekunden-Zähler falsch. Wer es nicht glaubt, dass 
der Zähler von den Interrupts abhängt, lasse bitte mal folgenden Code 
laufen auf einem Arduino Uno Rev3. Einmal mit auskommentiertem 
//noInterrupts() und einmal mit aktivierten noInterrupts():
1
void setup() {
2
  Serial.begin(9600);
3
  //noInterrupts();
4
}
5
6
void loop() {
7
  Serial.print(millis());
8
  Serial.println(" ms");
9
  float x;
10
  //waist some time:
11
  for (long int t = 0; t < 5000; t++) {x = sin(t);}
12
  Serial.println(x);
13
}
Michael

von Clemens S. (zoggl)


Lesenswert?

Michael schrieb:
> Ich wollte aber für meine Hobby-Lernzwecke eben eine genauere Stoppuhr
> implementieren.

Michael schrieb:
> Leider hat niemand meine Frage nach dem geeigneten, simplen
> Mikrocontroller beantwortet

Doch. Es wurden mehrere Controller, RTCs genannt.

Michael schrieb:
> (1.) Ich will eine Lösung ohne einen Umbau des Arduino.

Dann kauf eben einen mit Quarz der Due hat einen. (- soeben wurde ein 
weiterer Controller genannt.)

Du bist gerade in der "nicht ein Geisterfahrer sondern hunderte" 
Situation.

Die Lösung ist nicht mehr Controller sondern besser programmieren.

Deine gezeigte Routine hat kein Problem mit dem internen Timer. Der 
stimmt. Du fragst ihn nur unregelmäßig ab, da die serielle Ausgabe eine 
variable Zeit dauert. (Mehr oder weniger Zeichen)

Wenn du ihn mit einem Interrupt abfragst, das Ergebnis speicherst und 
dann ausgibst, ist das alles kein Problem.

Der due bietet sogar DMA. Damit kannst du den seriellen Datentransfer 
aufrecht erhalten, während dieser seriell sendet, ohne dass der 
Prozessor irgend etwas tun muss.

Stell dir das als drei Blöcke vor:
Block1 zählt genau die Zeit
Block2 (Interrupt) liest Zeitstempel aus Block1 aus und speichert diese
Block3 versendet die gespeicherten Daten über die serielle Schnittstelle

Die Blöcke laufen parallel und haben keinen zeitlichen Einfluss 
aufeinander.

Als weiteren Irrweg kannst du auch ein RTC Modul verwenden. Die haben 
teilweise einen Interrupt eingang und liefern dafür einen Zeitstempel.

Oder wir haben deine Anforderungen alle falsch verstanden und du willst 
eine Stoppuhr mit max einer Millisekunde Messzeitraum und 5ppm Auflösung 
bauen. Dann lautet deine Lösung TDC.

Zusammenfassung: komm aus deiner Sackgasse und dir wird geholfen.

: Bearbeitet durch User
von Motopick (motopick)


Lesenswert?

Michael schrieb:
> Vielen Dank für alle Antworten.
>
> Leider hat niemand meine Frage nach dem geeigneten, simplen
> Mikrocontroller beantwortet.

Was soll man auch jemandem antworten, dessen gesamte geistige
Komfortzone nur aus "Adruinos" besteht?

Eine ms-Stoppuhr koennte schon ein uralter 4 bit-Controller von
Oki stemmen, und wuerde sich dabei noch langweilen.

Wenn es leistungsmaessig sparsam zugehen soll, waere ein MSP430FG4617
(m)ein guter Kandidat. Der kann LCD(-onGlass) direkt treiben.
Leider kein billiges Vergnuegen. Von Atmel gaebe es den ATMEGA169,
und von ST diverse STM8 die das auch koennten.
Fuer das uebliche LCD waere ein kleiner PIC mit einem 4096 kHz Quarz
meine erste Wahl. Bei der Auswahl auf einen internen Oszillator achten.
Den Quarz braucht es "nur" zur genauen Messung. Nach der Messung
schaltet man wieder auf den internen 30 kHz Takt.
Weitere externe Komponenten braucht es da ueberhaupt nicht.

Was willst du eigentlich mit "OneWire" an einer Stoppuhr?
Aus ueblichen RTCs kommt auch kein 1 ms Takt?

von Maxim B. (max182)


Lesenswert?

Michael schrieb:
> Vielen Dank für alle Antworten.
>
> Leider hat niemand meine Frage nach dem geeigneten, simplen
> Mikrocontroller beantwortet.

Hallo,
meine erste Wahl wäre ATMega1284P. Und kein Arduino jeglicher Art. 16k 
SRAM, JTAG-Debug.

> Manche zweifelten den Sinn einer besseren Genauigkeit als die
> Arduino-interne
> Millisekunden-Zählung an oder verwechselten Auflösung mit Genauigkeit.
> Der Arduino Uno Rev3 speist, ab Werk, den Millisekunden-Zähler über
> einen 16 MHz ceramic resonator (CSTCE16M0V53-R0). Das läuft über den
> TCNT0 – Timer/Counter Register des ATmega328P und die Timer/Counter0
> overflow interrupt service routine. Dieser Taktgeber hat laut Datenblatt
> (https://www.mouser.de/datasheet/2/281/p16e-522700.pdf) eine mögliche
> Ungenauigkeit von "Initial Frequency Tolerance ±0.5%" also 5000 ppm.

Das ist wohl zu viel.
Wenn du wirklich genau willst, bei Mouser gibt es TG2520SMN 
16.0000M-MCGNNM0 mit nur 0,5 ppm, 16 MHz, kostet nur 0,85 € pro Stück. 
Allerdings braucht es 2,8-3,3 Volt Speisung und Ausgang ist mit "Clipped 
sine wave". Deshalb ist zusätzlich noch 3V oder 3V3 Spannungsregler (das 
wird auch auf Frequenzstabilität positiv wirken) notwendig. Und für 
Ausgang noch zusätzlich AHCT-Invertor, evtl. mit Schmitt-Trigger, so wie 
74AHCT1G14.

von Motopick (motopick)


Lesenswert?

Maxim B. schrieb:

> meine erste Wahl wäre ATMega1284P. Und kein Arduino jeglicher Art. 16k
> SRAM, JTAG-Debug.

Gibt es einen besonderen Grund fuer 128 k Flash und 16 k RAM?
Ein Glass-LCD kann er ja wohl nicht direkt treiben.
Und JTAG gibt es schon fuer Controller die einige Nummern kleiner sind.
Wenn man es fuer so etwas simples, wie einen 1 kHz-Zaehler braucht.

> Wenn du wirklich genau willst, bei Mouser gibt es TG2520SMN
> 16.0000M-MCGNNM0 mit nur 0,5 ppm, 16 MHz, kostet nur 0,85 € pro Stück.

Welchen positiven Effekt, sollte "0,5 ppm" bei einer Uhr, die gerade
mal 1 ms aufloesen kann, haben?
Messzeiten von einem Jahr?

von Frank K. (fchk)


Lesenswert?

Michael schrieb:

> Manche zweifelten den Sinn einer besseren Genauigkeit als die
> Arduino-interne Millisekunden-Zählung an
Du sollst ja auch nicht den ms-Zähler der Arduino-Umgebung nutzen, 
sondern einen Hardwarezähler eines Timers.

> (2.) ist da noch die Sache mit dem Interrupt und Zählerblockiern. Selbst
> wenn der Arduino-Oszillator perfekt wäre, könnten eingebundene Libraries
> (OneWire) über eine Interruptsperre den Millisekunden-Zähler
> verfälschen. Das kann man umgehen mit meinem Lösungsansatz des externen
> Zählers.
1wire kann man auch anders implementieren, beispielsweise über einen 
UART. Dann können die Interrupts problemlos aktiv bleiben, weil der UART 
das Timing macht.

fchk

von Mi N. (msx)


Lesenswert?

Michael schrieb:
> Leider hat niemand meine Frage nach dem geeigneten, simplen
> Mikrocontroller beantwortet.

Du kannst gerne einen weiteren Arduino verwenden oder der Einfachheit 
wegen, einen einzelnen ATmega/tiny - meinetwegen auch mit dem Bootloader 
des UNO R3.
Ein sehr günstiger TCXO wurde Dir genannt, die 3 V Versorgungsspannung 
wird mit einer Zenerdiode oder weissen LED stabilisiert und das 
Ausgangssignal ist groß genug, um damit einen ATxyz kapazitiv 
eingekoppelt zu takten.

Reicht Dir das nicht?

von Rainer W. (rawi)


Lesenswert?

Maxim B. schrieb:
> meine erste Wahl wäre ATMega1284P. Und kein Arduino jeglicher Art. 16k
> SRAM, JTAG-Debug.

16k SRAM für eine Stoppuhr?
Meinst du kBit?

: Bearbeitet durch User
von Obelix X. (obelix)


Lesenswert?

Michael schrieb:
> Leider hat niemand meine Frage nach dem geeigneten, simplen
> Mikrocontroller beantwortet.

Annähernd jeder mit Hardware Timer und vernünftiger Programmierung.

Michael schrieb:
> (1.) Ich will eine Lösung ohne einen Umbau des Arduino.

Schmeiß dich doch auf den Boden und schreie ganz laut "Ich will aber, 
ich will".

: Bearbeitet durch User
von Hugo H. (hugo_hu)


Lesenswert?

Der Freitag, der ein Sonntag war ... :-)

von Clemens L. (c_l)


Lesenswert?

Michael schrieb:
> Ein 32-bit Zähler wäre genügend. Die Schnittstelle vom Mikrocontroller
> sollte folgende Funktionen unterstützen:
>
> * Start-Signal
> * Stopp-Signal
> * Übertragung der Speicher „start“ und „stopp“
> * Zurücksetzen des Zählers auf 0

Der SN74LV8154 hat nur einen Zwischenspeicher, aber soweit ich sehe, 
kannst du einfach bei 0 starten. Sechs Eingänge und acht Ausgänge; wenn 
dein Arduino nicht genügend freie GPIOs hat, kannst du die Zahl mit 
einem Decoder (74xx138) und/oder einem Shift-Register (74xx165) 
verringern.

von Teo D. (teoderix)


Lesenswert?

Obelix X. schrieb:
> Michael schrieb:
>> Leider hat niemand meine Frage nach dem geeigneten, simplen
>> Mikrocontroller beantwortet.
>
> Annähernd jeder mit Hardware Timer und vernünftiger Programmierung.

Interrupts sollte er noch können...  PIC10Fxxx ;D

von Peter D. (peda)


Lesenswert?

Michael schrieb:
> Wer es nicht glaubt, dass
> der Zähler von den Interrupts abhängt

Das hat doch hier nie auch nur ein einziger bezweifelt, daß unbedarfte 
Programmierung Seiteneffekte haben kann und wird. Unsinnig häufige 
serielle Ausgaben sind der Todesstoß für jeden Programmablauf.

Die Arduino-Libs sind darauf optimiert, daß ein Anfänger damit schnell 
zurecht kommt. Sie sind jedoch nicht auf möglichst geringe Seiteneffekte 
und CPU-Last optimiert.

Für 1-wire gibt es z.B. Interrupt basierte Lösungen für den AVR, die 
keine riesen CPU-Zeit vergeuden.
Wie schon vorgeschlagen wurde, gibt es Quarzoszillatoren entsprechender 
Genauigkeit. Der µC-Typ und die Firmware haben bei sinnvoller 
Strukturierung keinerlei Einfluß auf die Genauigkeit.

von Bauform B. (bauformb)


Lesenswert?

Als unabhängiger neutraler Beobachter versuche ich mal, möglichst wenig 
in Frage zu stellen. Natürlich kann man alles anders machen.

Michael schrieb:
> für meinen Arduino Uno Rev3
> manche Programmbibliotheken (z.B. OneWire)
> ein peripheres Modul
Dieser Arduino ist also nicht verhandelbar und da läuft schon irgendwas, 
was kaum geändert werden kann. Also ist so ein Modul vernünftig.

> Z.B. dem DS3231 RTC
Maxim B. schrieb:
> TG2520SMN16.0000M-MCGNNM0 mit nur 0,5 ppm, 16 MHz, kostet nur
> 0,85 € pro Stück.
Eindeutig diesen. Weil viel billiger und trotzdem genauer.

> Ein 32-bit Zähler wäre genügend
> * Start-Signal (PinX)
> * Stopp-Signal (PinY)
> * Übertragung der Speicher zum Arduino. Evtl. I2C-Protokoll?
Vorzugsweise UART; ist einfacher zu programmieren.

> * Zurücksetzen des Zählers auf 0. Per separatem Pin oder anderem
> Protokoll?
Protokoll, weil man sowieso ein Mini-Protokoll für die Übertragung der 
Speicher und die optionale Abfrage braucht.

> Die Differenz der Zähler, die Zeitdauer, wird auf dem Arduino berechnet
Das geht nach ca. 7 Wochen Dauerbetrieb schief (32-Bit Overflow).

> Optional wäre auch ein Abfragen der Zählerstände (Start-Zähler und
> aktueller Stand) nützlich, während einer laufenden Messung.
Kein Problem für den uC auf dem Modul.

> Außer mit dem Arduino Uno habe ich keine Erfahrung mit Mikrocontrollern.
> Mit PC-Programmierung reichlich.
> Welchen Mikrocontroller würdet Ihr empfehlen im Hinblick auf die
> folgenden Randbedingungen:
> * Programmierung bevorzugt in C oder C++. Zur Not in Assembler.
> * Kostenlose Entwicklungsumbgebung für Windows 10 sollte es geben.
> * Programm aufspielen per Arduino Uno Rev3 möglich.
> * Pins für: Start, Stopp, Takt, serielle Übertragung der Zählerstände.
> * Gute Verfügbarkeit in Deutschland, preiswert.

STM32C011J4M6 oder J6M6. Bei Reichelt 1.35€, bei Digikey 0.69€. Die 
32-Bit CPU ist keinen Verschwendung, weil man für die 32-Bit Zähler 
nicht aufpassen muss.
 - SO-8 Gehäuse; das geht von der Pinanzahl plus-minus-Null auf
 - wird zu 100% in C programmiert; GCC gibt es direkt bei ARM
 - kann die Millisekunden problemlos per Interrupt zählen
 - braucht ansonsten keine Interrupts
 - muss nicht geflasht werden, braucht kein Programmiergerät. Das 
Programm kann über die vorhandene UART-Verbindung vom Arduino ins RAM 
geladen werden. Oder per USB-UART Adapter vom PC aus.

von Mi N. (msx)


Lesenswert?

Michael schrieb:
> Außer mit dem Arduino Uno habe ich keine Erfahrung mit Mikrocontrollern.

Bauform B. schrieb:
> SO-8 Gehäuse; das geht von der Pinanzahl plus-minus-Null auf

Das meinst Du jetzt ernst?

Der TO ist der Meinung, ein externes Taktsignal könne von einem UNO R3 
nicht schnell genug behandelt werden. Wie will er denn sicherstellen, 
daß die Abfrage des peripheren Zählers im ms-Raster funktioniert? Die 
zeitgerechte Triggerung von 'start' und 'stopp'-Signalen kann ja auch 
durch interne Blockaden behindert werden.

Vielleicht ist es doch einfacher, auf ein RP2040 Pico-Board umzusteigen, 
das fix und fertig günstiger ist als jede Zusatzschaltung. 
Erfahrungsgemäß haben diese günstigen Boards einen recht genau laufenden 
Quarz mit <= 5 ppm ohne extra Abgleich. Über den Temperaturbereich wurde 
zwar nichts gesagt, aber die Drift des Oszillators ist bei 
'menschengerechten' Umgebungstemperaturen nicht sehr groß.

: Bearbeitet durch User
von Bauform B. (bauformb)


Lesenswert?

Mi N. schrieb:
> Wie will er denn sicherstellen,
> daß die Abfrage des peripheren Zählers im ms-Raster funktioniert?

Die Abfrage ist nicht zeitkritisch, die passiert ja erst, wenn alles 
erledigt ist.

> Die zeitgerechte Triggerung von 'start' und 'stopp'-Signalen kann
> ja auch durch interne Blockaden behindert werden.

Der Einwand ist allerdings mehr als berechtigt :(

von Georg M. (g_m)


Lesenswert?

AVR Datasheet:
"Two 16-bit Timer/Counter Type B (TCBn) can be combined to work as a 
true 32-bit input capture."

Damit kann man sehr lange Millisekunden zählen.

von Rene K. (xdraconix)


Lesenswert?

Er redet ja immer nur von Arduino Uno Rev 3 - es ist ein Atmega328P - 
der hat 3 Timer. Die werden auch beim stoppen der jeglicher ISR durch 
seine "One-Wire Bibliothek" nicht gestoppt - die Timer laufen weiter. Er 
kann ein Überlauf verpassen, ja - aber dann vergleicht man halt die 
Timercounter...

1ms bei 5ppm - da lacht dich der 328er aus. Ernsthaft... Schau über 
deinen "Arduino" Tellerand hinaus - such dir das DB und leg los.

von Sebastian W. (wangnick)


Lesenswert?

Hallo Michael,

Michael schrieb:
> Dieser Taktgeber hat laut Datenblatt
> (https://www.mouser.de/datasheet/2/281/p16e-522700.pdf) eine mögliche
> Ungenauigkeit von "Initial Frequency Tolerance ±0.5%" also 5000 ppm. Es
> mag viele Anwendungen geben, für die das genau genug ist. Ich wollte
> aber für meine Hobby-Lernzwecke eben eine genauere Stoppuhr
> implementieren. Der von mir avisierte DS3231 RTC hat eine mögliche
> Ungenauigkeit von 5 ppm - tausend mal besser.

Ok.

Michael schrieb:
> Manche haben vorgeschlagen, das Arduino-Board "aufzubohren", um einen
> genaueren Takt zu haben. Das ist im Prinzip ein konstruktiver Beitrag;
> aber das war gar nicht meine Fragestellung.
> (1.) Ich will eine Lösung ohne einen Umbau des Arduino.

Ok.

Michael schrieb:
> (2.) ist da noch die Sache mit dem Interrupt und Zählerblockiern. Selbst
> wenn der Arduino-Oszillator perfekt wäre, könnten eingebundene Libraries
> (OneWire) über eine Interruptsperre den Millisekunden-Zähler
> verfälschen. Das kann man umgehen mit meinem Lösungsansatz des externen
> Zählers.
> Wenn eine Bibliotheksfunktion die Interrupts ungeschickterweise zu lange
> sperrt, geht der Millisekunden-Zähler falsch. Wer es nicht glaubt, dass
> der Zähler von den Interrupts abhängt, lasse bitte mal folgenden Code
> laufen auf einem Arduino Uno Rev3. Einmal mit auskommentiertem
> //noInterrupts() und einmal mit aktivierten noInterrupts():

Das stimmt auch. Der Grund dafür ist aber nicht, dass der Timer nicht 
weiterlaufen würde! Der Grund dafür ist, dass die Arduino-IDE den Timer 
so programmiert, dass er Mikrosekunden zählt, um damit 
delayMicroseconds() umsetzen zu können. Und da auf dem Atmega328P dieser 
Timer ein 16-Bit-Zähler ist, läuft er nach 65ms über und erzeugt einen 
Interrupt. Und wenn die Interrupts gesperrt sind, dann werden diese 
Überläufe nicht gezählt, und dadurch geht millis() falsch. Schau dir den 
entsprechenden Quellcode gerne einmal unter C:\Program Files 
(x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring.c an.

Eine möglich Lösung für deine Stoppuhr wäre also, anstelle eines zweiten 
Atmega328P eine genaue externe 1kHz-Taktquelle an deinen Arduino Uno an 
Pin D5 anzuschließen, und diesen Pin als "T1" zu konfigurieren, so dass 
er Timer 1 hochzählt. Der würde dann nur alle 65 Sekunden überlaufen und 
einen Interrupt auslösen, und dann hättest du weitere 65 Sekunden um 
darauf zu reagieren bevor der nächste Interrupt den vorherigen 
"überschreibt". Und dein Stoppuhr-Signal würdest du an Pin D8 
anschließen. Diesen Pin kann man als "ICP1" konfigurieren. Dann merkt 
sich bei einem Signal auf diesem Pin der Atmega328P des Arduino den 
aktuellen Stand des Timers 1 in einem Register (auch wenn Interrupts 
gesperrt sein sollten!) und fordert einen Interrupt an. Und wenn dieser 
Interrupt behandelt wird, kannst du den Wert des Registers auslesen und 
bekommst die genaue Millisekunde, zu der das Signal aufgetreten ist, 
selbst wenn deine Interruptroutine erst etwas verzögert aufgerufen 
werden sollte.

So eine Lösung halte ich für einfacher machbar als diejenige mit zwei 
Mikrocontrollern, vor allem wenn du noch dabei bist, dich in die 
Hardware einzuarbeiten.

LG, Sebastian

: Bearbeitet durch User
von Teo D. (teoderix)


Lesenswert?

Sebastian W. schrieb:
> Und wenn die Interrupts gesperrt sind, dann werden diese Überläufe nicht
> gezählt, und dadurch gehtmillis()
>  falsch.

Na und, das zugehörige Flag wird aber weiterhin gesetzt! ...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Michael schrieb:
> Meine Idee ist, ein peripheres Modul aufzubauen
Das ist wirklich mal eine schräge Idee (wenn offenbar auch eine recht 
zeitgemäße).

Zusammenfassend gilt: du brauchst keinen zusätzlichen Mikrocontroller 
suchen, der auf dem Arduino verbaute µC kann das locker und luftig. Denn 
bei den üblichen 16MHz Taktfrequenz kann der dank RISC-Architektur pro 
Millisekunde etwa 16'000 Maschinenbefehle ausführen. Es kann bestenfalls 
sein, dass er durch schlechte Software oder blockierende Bibliotheken an 
der zeitgerechten Ausführung gehindert wird. Dann sollte man sich aber 
eher die schlecht programmierte Software vorknüpfen, als ein 
Coprozessorsystem zu etablieren.

> keine Erfahrung mit Mikrocontrollern.
Wie gesagt: das Datenblatt deines µC enthält den Weg zur Lösung der 
Aufgabe.

Dass man für eine ultra genau gehende Uhr eine entsprechend ultra genaue 
Taktquelle braucht, steht dann auf einem anderen Blatt.

Mi N. schrieb:
> daß die Abfrage des peripheren Zählers im ms-Raster funktioniert? Die
> zeitgerechte Triggerung von 'start' und 'stopp'-Signalen kann ja auch
> durch interne Blockaden behindert werden.
Da haben wir die Casus Knacksus.

: Bearbeitet durch Moderator
von Clemens S. (zoggl)


Lesenswert?

Sebastian W. schrieb:
> C:\Program Files
> (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring.c

ohne Worte

Sebastian W. schrieb:
> Eine möglich Lösung für deine Stoppuhr wäre also, anstelle eines zweiten
> Atmega328P eine genaue externe 1kHz-Taktquelle an deinen Arduino Uno an
> Pin D5 anzuschließen, und diesen Pin als "T1" zu konfigurieren, so dass
> er Timer 1 hochzählt.

und damit der zählende Atmega nicht überläuft kann man einen dritten 
Atmega an den ersten hängen und den Pin überlauf Interrupt dorthin 
geben, dann kann dieser damit gezählt werden. Damit hast du einen echten 
64 bit Zähler. Diesen Wert kann dann er erste Atmega per SPI auslesen, 
und über die serielle Schnittstelle den korrekten Wert der Stoppuhr 
ausgeben, wenn der Trigger Pin TC1B auslöst.

von Rene K. (xdraconix)


Lesenswert?

Clemens S. schrieb:
> und damit der zählende Atmega nicht überläuft kann man einen dritten
> Atmega an den ersten hängen und den Pin überlauf Interrupt dorthin
> geben, dann kann dieser damit gezählt werden. Damit hast du einen echten
> 64 bit Zähler. Diesen Wert kann dann er erste Atmega per SPI auslesen,
> und über die serielle Schnittstelle den korrekten Wert der Stoppuhr
> ausgeben, wenn der Trigger Pin TC1B auslöst.

Ja.. also ich wäre da für einen vierten Atmega. Der Überwacht ob 
zwischen Atmega 1 und 3 aktuell keine SPI Tätigkeit stattfindet. Nicht 
das genau in den acht Takten der Wert überläuft und nicht gezählt wird - 
nur zur Sicherheit... versteht sich. ;-)

von Norbert (der_norbert)


Lesenswert?

Clemens S. schrieb:
> und damit der zählende Atmega nicht überläuft kann man einen dritten
> Atmega an den ersten hängen und den Pin überlauf Interrupt dorthin
> geben

Wer hat nicht schon von einem High-Performance Arduino cluster geträumt.
Wenn man die dann auch noch noch mehrdimensional vernetzt…
… das gibt 'ne Stoppuhr wie sie die Welt noch nicht gesehen hat.

von Sebastian W. (wangnick)


Lesenswert?

Sebastian W. schrieb:
> Eine möglich Lösung für deine Stoppuhr wäre also, anstelle eines zweiten
> Atmega328P eine genaue externe 1kHz-Taktquelle an deinen Arduino Uno an
> Pin D5 anzuschließen, und diesen Pin als "T1" zu konfigurieren, so dass
> er Timer 1 hochzählt.

Du kannst natürlich dazu auch das SQW-Signal einen DS3231 verwenden. Bei 
32768Hz liefert es alle ~30uS einen Zählimpuls, und so genau ließe sich 
dann auch die Millisekunde bestimmen. Damit würde Timer 1 zwar schon 
alle 2 Sekunden überlaufen. Ich kenne aber keine Arduino-Bibliothek, die 
die Interrupts derart lange sperren würde.

LG, Sebastian

von Peter D. (peda)


Lesenswert?

Ich hatte zuerst mit 80C51 angefangen, konkret AT89C2051. Der hat nur 2 
16Bit-Timer. Ein Timer ging für die UART als Baudratengenerator drauf, 
blieb also nur noch einer übrig. Den konnte man teilen und hatte somit 2 
* 8Bit Timer/Counter. Damit war es dann kein Problem, einen 
Frequenzmesser zu bauen. Der Zeitbasisteiler liefert somit alle 256 
CPU-Zyklen einen Interrupt zum Zählen der höherwertigen Bytes. Der 
andere 8Bit Timer zählt das Eingangssignal. Der C51 Compiler hat sehr 
kompakten Code erzeugt, so daß kein Interrupt verloren ging. Durch das 
float Format war die Auflösung auf 6 Digits begrenzt. Das Ergebnis wurde 
gemultiplext angezeigt und auch über die UART gesendet.
Später habe ich dann das Zahlenformat mit Assembler aufgebohrt. Die 
Rechnung f_in = f_cpu * count_in / count_cpu ist ja nicht zeitkritisch.

Es ist also kein Problem, mit nur 2 8Bit-Timer/Counter beliebig genau zu 
messen. Die Zählweite ist nur durch den verfügbaren SRAM limitiert.

von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

Manfred P. schrieb:
>> Der interne Taktgeber ist in der Tat ungenau,
>> hat aber 8 MHz.

> Wie ungenau?
> Welche? Die Masse meiner hat 16 MHz

Normalerweise meinen Leute hier im Forum den internen R/C Oszillator. 
Dieser hat bei den klassischen AVR 8 MHz +/-10%, soweit ich mich 
erinnere.

Im gleichen Beitrag wie ich darauf hin der (interne) Quarz-Oszillator
> nicht weniger genau, als ein 32 kHz Uhrenquarz
ist.

: Bearbeitet durch User
Beitrag #7830553 wurde vom Autor gelöscht.
von Mi N. (msx)


Lesenswert?

Norbert schrieb:
> … das gibt 'ne Stoppuhr wie sie die Welt noch nicht gesehen hat.

Diese wird auch schon dazu gehören, denn unter 200 s darf man keine 
Zeiten messen. Andernfalls werden die 'geforderten' 5 ppm überschritten 
;-)

von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

Michael schrieb:
> Leider hat niemand meine Frage nach dem geeigneten, simplen
> Mikrocontroller beantwortet.

Doch, habe ich:

Sherlock 🕵🏽‍♂️ schrieb:
>> Welchen Mikrocontroller würdet Ihr empfehlen
> http://stefanfrings.de/stm32/stm32l0.html

Vermutlich ist dieser dir nicht simpel genug. Schade, denn der hat sogar 
einen seriellen Bootloader (einige Modelle der Serie auch USB) ab Werk 
dabei und kann mit der Arduino IDE programmiert werden.

> Ich will eine Lösung ohne einen Umbau des Arduino (Uno)

Dann nimm doch einen ATmega328 mit Quarz. Simpler wird es nicht. Statt 
Quarz kannst du auch einen hoch präzisen Oszillator als Taktquelle 
verwenden.

> Selbst wenn der Arduino-Oszillator perfekt wäre, könnten
> eingebundene Libraries (OneWire) über eine Interruptsperre den
> Millisekunden-Zähler verfälschen.

Sehe ich nicht so. Die Timer/Counter zählen von ganz alleine ohne 
Software. Du nimmst z.B. einen 8,192 MHz Quarz (oder Taktgeber), stellst 
den Prescaler des 16 Bit Timer/Counter auf 1024 und lässt ihn frei 
laufend die Takte zählen. Das TCNT Register zählt dann acht Takte pro 
Millisekunde.

Mit der "Input Capture" Funktion kannst du den aktuellen Zählerstand bei 
einem Signal von einem Pin in ein ICR Register kopieren. Auch das 
passiert ohne Software. Danach hast du alle Zeit der Welt, dieses 
Register per Software auszulesen.

Beim Auslesen teilst du den Wert aus dem Register durch 8, so kommst du 
auf glatte Millisekunden.

> Wenn eine Bibliotheksfunktion die Interrupts ungeschickterweise
> zu lange sperrt, geht der Millisekunden-Zähler falsch.
> Wer es nicht glaubt

Niemand zwingt dich, die millis() Funktion zu benutzen.

von Michael (arcturus)


Lesenswert?

Hallo!

Von den etlichen Beiträgen kann ich aus Zeitgründen nur auf manche 
eingehen.

Zum Verständnis der Verfälschung der eingebauten Arduino-internen 
Zeitzählung durch Interruptsperren möchte ich das Problem nochmals 
zahlenmäßig darlegen:
Der Oszillator-Takt (16 MHz) wird in den 8-bit Timer/Counter Register 
TCNT0 eingespeist in einem Prescaler-Teilverhältnis von 64:1. Wenn 
dieses Register überläuft, also nach 64 * 256 Oszillator-Zyklen, wird 
per Interrupt die Service Routine TIMER0_OVF_vect aufgerufen. In dieser 
werden die internen Zählervariablen für die millis() und micros() 
entsprechend aufgestockt. Wenn per noInterrupts() der Aufruf von 
TIMER0_OVF_vect blockiert wird für weniger als 64 * 256 Zyklen, ist das 
unproblematisch. Das entsprechende Interruptflag wird gesetzt und nach 
Ablauf der Interruptsperre wird TIMER0_OVF_vect aufgerufen. Dauert die 
Sperre länger als 2 x 64 x 256 Zyklen, werden zwei oder mehr 
TIMER0_OVF_vect-Aufrufe ausgelassen, aber nur einer nachgeholt. Dann 
wird die Zeitzählung falsch. Am Interruptflag lässt sich nicht ablesen, 
wie viele Interrupts ausgelassen wurden.

Sebastian W. schrieb:
> Eine möglich Lösung für deine Stoppuhr wäre also, anstelle eines zweiten
> Atmega328P eine genaue externe 1kHz-Taktquelle an deinen Arduino Uno an
> Pin D5 anzuschließen, und diesen Pin als "T1" zu konfigurieren, so dass
> er Timer 1 hochzählt.
Sherlock 🕵🏽‍♂️ schrieb:
> Du nimmst z.B. einen 8,192 MHz Quarz (oder Taktgeber), stellst
> den Prescaler des 16 Bit Timer/Counter auf 1024 und lässt ihn frei
> laufend die Takte zählen. Das TCNT Register zählt dann acht Takte pro
> Millisekunde.

Von Sebastian W. (wangnick) und später von Sherlock (rubbel-die-katz) 
wurde ein Ansatz vorgeschlagen, den ich mal ausprobieren werde, wenn ich 
einen externen Taktgeber gekauft habe.
Der Vorschlag ist den 16-bit Timer/Counter TCNT1 des Arduino zu 
verwenden und in mit einem akkuraten externen Takt zu versehen. Bei dem 
von mir avisierten Taktgeber DS3231 RTC mit 32 kHz würde ein Überlauf 
erst nach 2 Sekunden stattfinden. D.h. wenn eine Interruptsperre nicht 
länger als 2 Sekunden geht - und ansonsten wäre etwas sehr faul im 
System - würden keine Zählerverluste auftreten.

Was man wissen muss, ist dass der TCNT1 für die PWM-Funktion der Pins 9 
und 10 und in der Servo-Library verwendet wird. Solange man die nicht 
braucht, geht der Ansatz wohl. Sonst nicht.

Von den vorgeschlagenen Mikrocontrollern waren manche ‚überqualifiziert‘ 
für die einfache Zählaufgabe.

Clemens L. schrieb:
> Der SN74LV8154 hat nur einen Zwischenspeicher, aber soweit ich sehe,
> kannst du einfach bei 0 starten. Sechs Eingänge und acht Ausgänge; wenn
> dein Arduino nicht genügend freie GPIOs hat, kannst du die Zahl mit
> einem Decoder (74xx138) und/oder einem Shift-Register (74xx165)
> verringern.
Clemens L. (c_l) hat einen sehr simplen Chip genannt, den SN74LV8154 
Zweifach-Binärzähler, 16 Bit. Fast genau was ich wollte, wenn er direkt 
seriell mit dem Arduino kommunizieren könnte.

Bauform B. schrieb:
> STM32C011J4M6 oder J6M6. Bei Reichelt 1.35€, bei Digikey 0.69€. Die
> 32-Bit CPU ist keinen Verschwendung, weil man für die 32-Bit Zähler
> nicht aufpassen muss. ...
Bauform B. (bauformb) hat den Mikrocontroller STM32C011J4M6 
vorgeschlagen. Der scheint die von mir gestellten Anforderungen zu 
erfüllen (siehe meine ursprüngliche Anfrage). Ich muss das Datenblatt 
noch genauer studieren. Bemerkenswert, dass es den in der 
Familienpackung schon für 0,287 € pro Stück gibt. Einzeln 1,52 €.

Peter D. schrieb:
> Ich hatte zuerst mit 80C51 angefangen, konkret AT89C2051. ...
Peter D. (peda) schlägt den AT89C2051 vor. Sieht interessant aus. Da 
werde ich mal prüfen, wie ich ein Programm aufspielen würde. Ich will 
eigentlich keine Programmier-Hardware kaufen.

Michael

: Bearbeitet durch User
von Rene K. (xdraconix)


Lesenswert?

Diskussion sinnlos - er hat sich auf die "Zwei-Chip Version" so 
eingeschossen das er den Wald vor Bäumen nicht sieht - und das Ziel 
liegt wirklich, wirklich so nah vor ihm. Ich bin raus....

Versuch:

Michael schrieb:
> IMER0_OVF_vect-Aufrufe ausgelassen, aber nur einer nachgeholt. Dann
> wird die Zeitzählung falsch. Am Interruptflag lässt sich nicht ablesen,
> wie viele Interrupts ausgelassen wurden.

NEIN! Du zählst nicht die Anzahl der Interrupte sondern die Counter - 
und wenn du das Ding ne Sekunde laufen läst und der CPU dabei zu 105% 
ausgelastet ist - du zählst den Counter!!!!! Dein einzigster Gegner ist 
der BOF. Wenn der Timer auf 1ms läuft dann kannst du den 65 Sekunden 
laufen lassen ohne ihn zurück zu setzen.

Manchmal fragt man sich echt - mit dem 328p fliegen Drohnen GPS gestüzt, 
da laufen zeitkritisch 3D Drucker mit Marlin und Klipper und hier wird 
wegen nem simpelsten Timer nen zweiter MC genommen - unbegreiflich.

: Bearbeitet durch User
von Rainer W. (rawi)


Lesenswert?

Michael schrieb:
> Wenn eine Bibliotheksfunktion die Interrupts ungeschickterweise zu lange
> sperrt, ...

Daran wäre der Programmierer Schuld, der das Ding in die Welt gesetzt 
hat und derjenige, der diese Bibliotheksfunktion in seinem Code nutzt. 
Natürlich kann einem immer der Himmel auf den Kopf fallen ...

von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

Michael schrieb:
> Bei dem
> von mir avisierten Taktgeber DS3231 RTC mit 32 kHz würde ein Überlauf
> erst nach 2 Sekunden stattfinden.

Der liefert aber nicht 32 kHz, sonder 32,768 kHz.

Aus dem Datenblatt:
> the 32kHz pin is enabled and outputs a 32.768kHz square-wave signal

Mit welcher Zauberei willst du daraus exakte Millisekunden ableiten?

: Bearbeitet durch User
von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

Rainer W. schrieb:
> Daran wäre der Programmierer Schuld, der das Ding in die Welt gesetzt
> hat und derjenige, der diese Bibliotheksfunktion in seinem Code nutzt.

Dass die Bibliotheken im Arduino Umfeld teilweise richtig schlecht sind 
ist ja nichts Neues. Der Fokus liegt da auf "einfach" oder zumindest 
"scheinbar einfach".

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Sherlock 🕵🏽‍♂️ schrieb:

> Michael schrieb:
>> Bei dem
>> von mir avisierten Taktgeber DS3231 RTC mit 32 kHz würde ein Überlauf
>> erst nach 2 Sekunden stattfinden.
>
> Der liefert aber nicht 32 kHz, sonder 32,768 kHz.
>
> Aus dem Datenblatt:
>> the 32kHz pin is enabled and outputs a 32.768kHz square-wave signal
>
> Mit welcher Zauberei willst du daraus exakte Millisekunden ableiten?

Nun, wirklich exakt geht natürlich nicht. Aber hinreichend exakt geht 
wahrscheinlich schon. Der Fehler durch den unvermeidlichen Jitter wegen 
der nicht ganzzahlig teilbaren Frequenzen addiert sich halt zum 
Grundfehler der Taktquelle.

Muß man halt einfach ausrechnen, ob man damit noch im zulässigen Bereich 
ist.

Wobei mir in dem ganzen Thread nicht wirklich klar geworden ist, wie 
genau es am Ende wirklich sein muss und schon garnicht, warum es so 
genau sein muss...

von Maxim B. (max182)


Lesenswert?

Motopick schrieb:

> Gibt es einen besonderen Grund fuer 128 k Flash und 16 k RAM?
Ja. Grund ist so: es ist billiger, gleich mehrere IC zu kaufen. Auch es 
ist leichter, immer möglichst mit gleichen zu tun zu haben. Deshalb 
nehme ich fast immer ATMega1284P, es sei denn ich brauche mehr Pins oder 
USARTs usw.
> Ein Glass-LCD kann er ja wohl nicht direkt treiben.
Das ist ja schlechteste von allen Anzeigen, die ich überhaupt kenne. 
Deshalb ist Manko nicht zu groß.  Lieber LED-Anzeige, oder auch 
ILI9341-Bildschirm mit Hintergrundbeleuchtung.

Motopick schrieb:
> Welchen positiven Effekt, sollte "0,5 ppm" bei einer Uhr, die gerade
> mal 1 ms aufloesen kann, haben?

16 MHz kostet z.Z. weniger als 1 €, billiger als manche mit 50 ppm. Und 
schlechter wird es mit 0,5 ppm bestimmt nicht arbeiten.

: Bearbeitet durch User
von Mi N. (msx)


Lesenswert?

Michael schrieb:
> Was man wissen muss, ist dass der TCNT1 für die PWM-Funktion der Pins 9
> und 10 und in der Servo-Library verwendet wird. Solange man die nicht
> braucht, geht der Ansatz wohl. Sonst nicht.

Was man wissen muß, der Arduino braucht die ganze Zeit eine 
Versorgungsspannung. Solange man diese nicht woanders braucht, geht der 
Ansatz wohl. Sonst nicht.


Michael schrieb:
> Bei dem
> von mir avisierten Taktgeber DS3231 RTC mit 32 kHz würde ein Überlauf
> erst nach 2 Sekunden stattfinden. D.h. wenn eine Interruptsperre nicht
> länger als 2 Sekunden geht

Ach so. Es muß Millisekunden genau sein und aber 2 s Verzögerung stören 
bei der Stoppuhr nicht.

Nimm den DS3231 und sei glücklich!

Sherlock 🕵🏽‍♂️ schrieb:
> Der liefert aber nicht 32 kHz, sonder 32,768 kHz.
>
> Aus dem Datenblatt:
>> the 32kHz pin is enabled and outputs a 32.768kHz square-wave signal
>
> Mit welcher Zauberei willst du daraus exakte Millisekunden ableiten?

Ganz einfach: Man muß oft durch 32 teilen und ab und zu durch 33 - jede 
Millisekunde :-)

von Sebastian S. (amateur)


Lesenswert?

Der Typ Mikrokontroller, den Du letztendlich auswählst, ist egal.
Die haben alle programmierbare Teiler.
An dieser Stelle geht es um die Peripherie und sonst Garnichts.

Wichtig ist nur der Taktgeber. Üblicherweise ein Quarz. Hier variieren 
die Genauigkeiten und natürlich die Preise - und zwar stark.

Low- und Least-Cost-Lösungen haben eine entsprechende Genauigkeit und 
gehen zwischendurch auch mal etwas spazieren (Grundgenauigkeit und vor 
allem Temperaturdrift).
Ein richtig guter, am besten ein geheizter Quarz, kann aber schon mal 
der Geldbörse eine Schlankheitskur verpassen.

Aber wie gesagt: Solange Du den Mikroprozessor selbst innerhalb seiner 
Spezifikationen betreibst ist der Name völlig unwichtig.

von Peter D. (peda)


Lesenswert?

Michael schrieb:
> Peter D. (peda) schlägt den AT89C2051 vor.

Vorschlagen würde ich ihn nicht mehr. Ich wollte nur darlegen, daß man 
schon mit sehr wenigen Ressourcen Zeiten und Frequenzen genau messen 
konnte.

Es gibt als Upgrade den AT89LP4052 oder AT89LP51RD2 und der Wickenhäuser 
und SDCC sollen wohl auch recht guten Code erzeugen.

von Rene K. (xdraconix)


Lesenswert?

Was redet ihr immer von Interrupts?! Ihr braucht keine Interrupts bei 
einem Zeitzähler. Lasst den Timer laufen und vergleicht das Counter 
Register...

8Bit mit Frequenz an PD5 (Timer 1 input) sollte einem die interne 
Frequenz nicht reichen.

1
    #include <avr/io.h>
2
 
3
    int main(void)
4
    {
5
        DDRD &= ~(1 << DDD5);     // PD5 säubern
6
        PORTD |= (1 << PORTD5);   // PD5 PullUp ein, Eingang
7
        TCCR1B |= (1 << CS12) | (1 << CS11) | (1 << CS10);
8
        // Timer 1 starten, Rising Edge
9
    
10
        while (1)
11
        {
12
            //TCNT1 Register vergleichen(da steht die ZEIT!)
13
        }
14
    }

Das ist es, mehr braucht es nicht....

von Bauform B. (bauformb)


Lesenswert?

Ob S. schrieb:
>> Der liefert aber nicht 32 kHz, sonder 32,768 kHz.
>> Mit welcher Zauberei willst du daraus exakte Millisekunden ableiten?
> Nun, wirklich exakt geht natürlich nicht. Aber hinreichend exakt geht
> wahrscheinlich schon.

Außerdem: selbst wenn du einen perfekten 1kHz Takt hast und Input 
Capture benutzt, kann der Zählerstand bis 999.9µs falsch sein. Man 
könnte sogar behaupten, der 32768Hz Takt ist ca. 32-fach genauer.

von Axel S. (a-za-z0-9)


Lesenswert?

Mi N. schrieb:

>> Aus dem Datenblatt:
>>> the 32kHz pin is enabled and outputs a 32.768kHz square-wave signal
>>
>> Mit welcher Zauberei willst du daraus exakte Millisekunden ableiten?
>
> Ganz einfach: Man muß oft durch 32 teilen und ab und zu durch 33 - jede
> Millisekunde :-)

Das klappt aber dann nur im Mittel bzw. bei langen Zeiten. Bei einer 
kurzen Zeit - sagen wir 10ms - ist der Fehler dann schon eheblich 
gegenüber der angeblichen Genauigkeit von 5ppm.

Wenn man wie der TO 1,000000ms Auflösung bei gleichzeitig hoher 
Genauigkeit will, bringt einen die DS3231 nicht weiter. Dann muß es 
schon ein Taktgeber sein, dessen Frequenz ganzzahlig durch 1000 teilbar 
ist.

Aber der ganze Thread ist natürlich hochgradiger Schwachsinn. Schon der 
ATMega328 hat 3 (drei!) Hardwaretimer. Selbst wenn man sich dann darauf 
versteift, das Arduino-Framework zu verwenden und das dann einen (!) 
Timer mißhandelt, hat man immer noch zwei weitere. Wie ein Vorredner 
schon bemerkte: das "Problem" braucht nicht mehr µC, sondern weniger 
dämliche Programmierung.

'nuff said, EOD

von Mi N. (msx)


Lesenswert?

Axel S. schrieb:
> Das klappt aber dann nur im Mittel bzw. bei langen Zeiten. Bei einer
> kurzen Zeit - sagen wir 10ms - ist der Fehler dann schon eheblich
> gegenüber der angeblichen Genauigkeit von 5ppm.

Bei 10 ms ist der Fehler (Jitter) 0,3%, was eigentlich nicht schlecht 
und besser als die ms Auflösung des 1 kHz Taktes ist.
Wie geschrieben können <= 5 ppm erst ab 200 s erreicht werden.

> Aber der ganze Thread ist natürlich hochgradiger Schwachsinn.

Da stimmen WIR Dir alle zu. Offensichtlich hat der TO nur Erfahrung, 
LIBs auf einem PC zusammenzuklicken. Hier die Arduino IDE zu verwenden 
und sich auf das zu versteifen, was man alles nicht machen darf, ist eh 
der verkehrte Weg.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Axel S. schrieb:
> Wenn man wie der TO 1,000000ms Auflösung bei gleichzeitig hoher
> Genauigkeit will
Dann ist immer noch die Frage, ob man diese ultraexakte 1,000000ms 
tatsächlich überhaupt braucht.

Denn die Abtastung mit exakt 1,000000ms ergibt bezogen auf das 
Start-Stop-Signal hat ja bereits einen Jitter von +-500,000µs (im Grunde 
sogar fast +-1ms, denn es könnte ja sein, dass die beiden Signale zum 
jeweils ungünstigsten Zeitpunkt abgetastet werden). Insofern ist diese 
exakte 1,000000ms sowieso nur Augenwischerei.

Wenn dann so ein Jitter tolerabel ist, dann muss letztendlich einfach 
nur die reale Abtastzeit kleiner oder gleich 1ms sein.

Und wenn der Jitter nicht tolerabel ist, dann reicht eben auch eine 
Abtastung mit ultragenauen 1,000000 ms nicht aus. Dann muss das 
Start-Stop-Signal deutlich schneller abgetastet werden und/oder die Uhr 
deutlich höher auflösen.

: Bearbeitet durch Moderator
von Falk B. (falk)


Lesenswert?

Lothar M. schrieb:
> Und wenn der Jitter nicht tolerabel ist, dann reicht eben auch eine
> Abtastung mit ultragenauen 1,000000 ms nicht aus. Dann muss das
> Start-Stop-Signal deutlich schneller abgetastet werden und/oder die Uhr
> deutlich höher auflösen.

Was mit der Input Capture Funktion spielend möglich ist, so man sie denn 
beherrscht. Damit kann man die Eingangssignale mit dem vollen 
Timer/Oszillatortakt auflösen, beim vielgepriesenen Arduino Uno 16 MHz 
bzw. 62,5ns. Ob das den Ansprüchen des OP genügt? ;-)

von Sebastian W. (wangnick)


Lesenswert?

Michael schrieb:
> Zum Verständnis der Verfälschung der eingebauten Arduino-internen
> Zeitzählung durch Interruptsperren möchte ich das Problem nochmals
> zahlenmäßig darlegen:
> Der Oszillator-Takt (16 MHz) wird in den 8-bit Timer/Counter Register
> TCNT0 eingespeist in einem Prescaler-Teilverhältnis von 64:1. Wenn
> dieses Register überläuft, also nach 64 * 256 Oszillator-Zyklen, wird
> per Interrupt die Service Routine TIMER0_OVF_vect aufgerufen. In dieser
> werden die internen Zählervariablen für die millis() und micros()
> entsprechend aufgestockt. Wenn per noInterrupts() der Aufruf von
> TIMER0_OVF_vect blockiert wird für weniger als 64 * 256 Zyklen, ist das
> unproblematisch. Das entsprechende Interruptflag wird gesetzt und nach
> Ablauf der Interruptsperre wird TIMER0_OVF_vect aufgerufen. Dauert die
> Sperre länger als 2 x 64 x 256 Zyklen, werden zwei oder mehr
> TIMER0_OVF_vect-Aufrufe ausgelassen, aber nur einer nachgeholt. Dann
> wird die Zeitzählung falsch. Am Interruptflag lässt sich nicht ablesen,
> wie viele Interrupts ausgelassen wurden.

Du hast völlig recht. Genau so wird es in wiring.c gemacht. Und meine 
Erinnerung an einen 16-bit-Timer 0 auf dem Atmega328P war falsch.

Michael schrieb:
> Von Sebastian W. (wangnick) und später von Sherlock (rubbel-die-katz)
> wurde ein Ansatz vorgeschlagen, den ich mal ausprobieren werde, wenn ich
> einen externen Taktgeber gekauft habe.

Ok. Viel Spaß und Erfolg!

> Was man wissen muss, ist dass der TCNT1 für die PWM-Funktion der Pins 9
> und 10 und in der Servo-Library verwendet wird. Solange man die nicht
> braucht, geht der Ansatz wohl. Sonst nicht.

Stimmt.

Die PWM-Funktion der Pins 9 und 10 ergibt sich übrigens aus dem 
Atmega328P-Datenblatt durch die alternative Funktion OC1A des 
Hardwarepins PB1 und OC1B von PB2. Wenn man andenkt, die 
Hardwareresourcen eines Mikrocontrollers so wie hier Timer 1, die 
Alternativfunktion T1 von PD5, und die Alternativfunktion ICP1 von PB0 
zu verwenden, dann fallen deren anderen Funktionen natürlich auch weg. 
Und wenn man so etwas ausprogrammiert, dann muss man dieses Datenblatt 
eh genau studieren.

LG, Sebastian

von Jens M. (schuchkleisser)


Lesenswert?

Maxim B. schrieb:
> Wenn du wirklich genau willst, bei Mouser gibt es TG2520SMN
> 16.0000M-MCGNNM0 mit nur 0,5 ppm, 16 MHz, kostet nur 0,85 € pro Stück.
> Allerdings braucht es 2,8-3,3 Volt Speisung und Ausgang ist mit "Clipped
> sine wave". Deshalb ist zusätzlich noch 3V oder 3V3 Spannungsregler (das
> wird auch auf Frequenzstabilität positiv wirken) notwendig. Und für
> Ausgang noch zusätzlich AHCT-Invertor, evtl. mit Schmitt-Trigger, so wie
> 74AHCT1G14.

Der TCXO ist schick, aber:
der Ausgang ist lt. Dabla "0,8Vpp min", d.h. es könnte mit einem AHCT 
gehen, könnte aber auch nicht. Oder les ich das falsch?

Mein Ansatz wäre: lass den Inverter weg und kopple das Signal mit einem 
Kondensator (k.A, 2-stellige pF?) auf den Eingang des auf "Quarz" 
eingestellten µCs, zusätzlich evtl. mit einem Spannungsteiler von 
vielleicht 2x 100k oder so den Eingang in die Mitte der 
Versorgungsspannung ziehen.
Der µC sieht so einen normalen Quarz und der interne Kram kann seinen 
normalen Job machen.

Oder: einen TCXO nehmen, der Rechteck/CMOS ausgibt und den dann mit 
einem Pegelwandler 74LVC1T45 auf 5V umsetzen.

von Mi N. (msx)


Lesenswert?

Jens M. schrieb:
> Mein Ansatz wäre: lass den Inverter weg und kopple das Signal mit einem
> Kondensator (k.A, 2-stellige pF?) auf den Eingang des auf "Quarz"
> eingestellten µCs, zusätzlich evtl. mit einem Spannungsteiler von
> vielleicht 2x 100k oder so den Eingang in die Mitte der
> Versorgungsspannung ziehen.

Falls hier noch irgendjemand lesen sollte:
1 nF nach XTALin (o.ä.) und bloß keinen zusätzlichen Spannungsteiler 
verwenden!
Typische Oszillatorschaltungen in µCs verwenden einen internen Inverter 
mit hochohmigem Widerstand für die Gegenkopplung. Da stellt sich der 
richtige Pegel für optimale Empfindlichkeit von alleine ein.

von Norbert (der_norbert)


Lesenswert?

Vorschläge kommen hier, da bin ich zutiefst erschüttert!

Für eine Millisekunden Stoppuhr kann man doch — wenn man die ernsthaft 
betreiben möchte — alles unterhalb einer Caesium-Fontäne vergessen.

von Peter D. (peda)


Lesenswert?

Der Mensch hat etwa 200..300ms Reaktionszeit auf visuelle Reize. Zwar 
kompensieren sich die Zeiten bei Start und Stop weitgehend, aber eben 
nicht perfekt. Daher ist eine Schrittweite von 10ms vollkommen 
ausreichend, wie sie auch die käuflichen Stoppuhren haben. Eine 
Auflösung von 1ms täuscht mehr vor, als real möglich ist.
Erst z.B. bei Betätigung durch Lichtschranken läßt sich eine höhere 
Genauigkeit erzielen.

von Bauform B. (bauformb)


Lesenswert?

Norbert schrieb:
> Für eine Millisekunden Stoppuhr kann man doch — wenn man die ernsthaft
> betreiben möchte — alles unterhalb einer Caesium-Fontäne vergessen.

Die sind doch schon wieder veraltet, bis dieses Projekt fertig wird. Man 
sollte gleich auf die übernächste Generation setzen ;)

https://nachrichten.idw-online.de/2024/09/04/die-erste-atomkern-uhr-der-welt

von Norbert (der_norbert)


Lesenswert?

Bauform B. schrieb:
> Die sind doch schon wieder veraltet, bis dieses Projekt fertig wird. Man
> sollte gleich auf die übernächste Generation setzen ;)

Der Gedanke ist ja gut, aber gibt's dafür denn auch eine Arduino Lib?
Sonst sehe ich die nächste große Enttäuschung auf dieses Forum 
zusteuern.

von Jens M. (schuchkleisser)


Lesenswert?

Mi N. schrieb:
> 1 nF nach XTALin (o.ä.) und bloß keinen zusätzlichen Spannungsteiler
> verwenden!

OK, danke für den Tipp.
Ist das dann eigentlich eine "Geht meistens"-Bastelkiste oder wäre das 
tatsächlich im Rahmen der Datenblätter "legal"?
Ich hab auf Anhieb nicht gefunden, wie hoch der 
Quarz-Wechselspannungsanteil sein muss, z.B. beim ATmega328P.

Bauform B. schrieb:
> Die sind doch schon wieder veraltet, bis dieses Projekt fertig wird. Man
> sollte gleich auf die übernächste Generation setzen ;)

Hatte letztens eine Werbung für Chip Scale Atomic Clock, ein auflötbares 
Modul mit einem TCXO, der von einer Atomreferenz gezogen wird.
Gepflegte 2600 Mäuse für 10MHz auf etwa 30x30x10mm, mit
1
short-term stability (Allan Deviation) of 3.0 × 10–10 at τ = 1 sec, typical long-term aging of <9 × 10–10/month, and maximum frequency change of ±3 × 10–10 over the operating temperature range of –40°C to +80°C.

von Mi N. (msx)


Lesenswert?

Jens M. schrieb:
> Ist das dann eigentlich eine "Geht meistens"-Bastelkiste oder wäre das
> tatsächlich im Rahmen der Datenblätter "legal"?
> Ich hab auf Anhieb nicht gefunden, wie hoch der
> Quarz-Wechselspannungsanteil sein muss, z.B. beim ATmega328P.

Bei ATmega48/88/328 hatte ich das schon vor > 10 Jahren gemacht: 
Problemlos.
Gerade bei den 48/88/328P Controllern ist die Amplitude am Quarz sehr 
klein, daß man bei Betrieb mit >= 16 MHz die 'full swing'-Option 
einschalten muß.
Im Schaltplan hatte ich C12 mit .1u angegeben aber immer 1 nF bestückt: 
http://mino-elektronik.de/fmeter/fm48.png

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Bauform B. schrieb:
> Die sind doch schon wieder veraltet, bis dieses Projekt fertig wird. Man
> sollte gleich auf die übernächste Generation setzen ;)

Thorium Nuclear Clock!

von Adam P. (adamap)


Lesenswert?

Michael schrieb:
> Wenn eine Bibliotheksfunktion die Interrupts ungeschickterweise zu lange
> sperrt, geht der Millisekunden-Zähler falsch.

Dann verwende die Arduino IDE einfach nicht.
Nimm das Microchip Studio und schreib den Code selber, dann weißt du zu 
100% was dein Code anstellt.
1ms ist jetzt echt kein Hexenwerk.

von Harald K. (kirnbichler)


Lesenswert?

Hat der Threadersteller eigentlich irgendwo erwähnt, was diese 
hyperpräzise Stopuhr steuern und was mit ihr gemessen werden soll?

Drückt da ein Mensch auf einen Knopf? Ist da eine Lichtschranke, geht es 
um Pferderennen, Autorennen oder die Zeit, die Schantalle mal wieder das 
Bad blockiert?

von Axel S. (a-za-z0-9)


Lesenswert?

Adam P. schrieb:
>> Wenn eine Bibliotheksfunktion die Interrupts ungeschickterweise zu lange
>> sperrt, geht der Millisekunden-Zähler falsch.
>
> Dann verwende die Arduino IDE einfach nicht.

Es liegt nicht an der Arduino IDE. Es liegt an den Bibliotheken, die 
alle glauben sie wären die einzigen auf der Hardware. Dazu noch der 
häufige Mangel an Dokumentation, auf welche Hardware sie auf welche 
Weise zugreifen. Das führt dazu, daß man oft noch nichtmal zwei Arduino 
Fremd-Bibliotheken im gleichen Projekt verwenden kann.

von Maxim B. (max182)


Lesenswert?

Jens M. schrieb:
> Der TCXO ist schick, aber:
> der Ausgang ist lt. Dabla "0,8Vpp min", d.h. es könnte mit einem AHCT
> gehen, könnte aber auch nicht. Oder les ich das falsch?
>
Hysteresis für 74AHCT1G14 ist 0,4 V. Was kleiner ist als 0,8Vpp. Obere 
und untere threshold voltage können zwar stark schwanken, aber 
Trennkondensator und Poti lösen das Problem. Oder besser mit Poti 
ausprobieren und danach zwei feste Widerstände einlöten.

: Bearbeitet durch User
von Mi N. (msx)


Lesenswert?

Maxim B. schrieb:
> Oder besser mit Poti
> ausprobieren und danach zwei feste Widerstände einlöten.

Abgesehen davon, daß das völlig unnötig ist, ist diese Fummelei auch 
eher schlechter.
Wenn eine Verstärkung benötigt werden sollte (bei AVRs jedenfalls 
nicht), dann bitte einen Inverter wie zum Beispiel 74AUP1GU04 verwenden.

von Maxim B. (max182)


Lesenswert?

Oder noch besser: TCXO mit 2*F_CPU nehmen und mit 1/2 74AHCT74 teilen.

von Mi N. (msx)


Lesenswert?

Maxim B. schrieb:
> Oder noch besser:

Schade, daß Du das nicht begründet hast. Dann könnte man diesen 
Vorschlag schön zerlegen. Er ist nämlich großer Unfug!

von Joachim B. (jar)


Lesenswert?

solange der µC nicht in der Sonne über 60°C aufheizt könnte man den ja 
mit einer Heizung auf 50°C konstant halten und so wegdriften durch 
Temperatur verhindern.
Temperatur konstant in engen Bereichen zu halten ist einfacher als 
genaue Takte zu halten. Mit 50°C könnte man die genaue ms leichter 
einhalten und korrigieren, zumal auch einige µC eingebaute 
Temperaturmessungen für Timerkorekturen erlauben.

Es geht nicht um Temperaturen aufs °C genau zu halten nur um 20°C-60°C 
zu vermeiden.

https://de.statista.com/statistik/daten/studie/1032379/umfrage/orte-in-deutschland-mit-einer-temperatur-von-ueber-40-grad-celsius/

also nichts für das Armaturenbrett im PKW

: Bearbeitet durch User
von Maxim B. (max182)


Lesenswert?

Mi N. schrieb:
> Er ist nämlich großer Unfug!

Doch: man bekommt SICHER 50:50 Takt, weder 55:45 oder 40:60, was in 
anderen Varianten nicht auszuschließen wäre.

von Norbert (der_norbert)


Lesenswert?

Maxim B. schrieb:
> Mi N. schrieb:
>> Er ist nämlich großer Unfug!
>
> Doch: man bekommt SICHER 50:50 Takt, weder 55:45 oder 40:60, was in
> anderen Varianten nicht auszuschließen wäre.

Dann misst sich die Millisekunde gleich viel symmetrischer…

von Maxim B. (max182)


Lesenswert?

Norbert schrieb:
> Dann misst sich die Millisekunde gleich viel symmetrischer…

Deine Aussage zeigt, daß du Datasheet für Mikrocontroller noch nicht 
kennst.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Maxim B. schrieb:
> Kuck mal Datasheet.

Du meinst, dass der 328P bei 5V und 16MHz nur innerhalb eines 
Tastverhältnis-Bereiches von 40:60 bis zu 60:40 spezifiziert ist?
Welcher TCXO macht's denn schlechter?

von Harald K. (kirnbichler)


Lesenswert?

Der Drops ist übrigens gelutscht, der Threadstarter ist hier schon seit 
über 'ner Woche nicht mehr an Bord.

von Hugo H. (hugo_hu)


Lesenswert?

Harald K. schrieb:
> schon seit
> über 'ner Woche nicht mehr an Bord

Die Popcorn-Tüte ist längst leer ... ;-)

von Wastl (hartundweichware)


Lesenswert?

Harald K. schrieb:
> Der Drops ist übrigens gelutscht

Schon längst, nachdem man nicht mal erfahren darf wozu das
Ganze und die unheimlich hohe Genauigkeit dienen soll.

von Norbert (der_norbert)


Lesenswert?

Wastl schrieb:
> Schon längst, nachdem man nicht mal erfahren darf wozu das
> Ganze und die unheimlich hohe Genauigkeit dienen soll.

Als moderner Ersatz für den guten alten Abreißkalender.

von Mi N. (msx)


Lesenswert?

Harald K. schrieb:
> Der Drops ist übrigens gelutscht, der Threadstarter ist hier schon seit
> über 'ner Woche nicht mehr an Bord.

Das ist doch wie immer völlig unwichtig.

Hugo H. schrieb:
> Die Popcorn-Tüte ist längst leer ... ;-)

Dann schwingt Dich auf, hole Waffel-Eier, Gelee-Hasen oder Pfannkuchen 
mit Eierlikör, damit Du in der Fastenzeit nicht verhungern mußt.

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.