Hallo alle miteinander! Ich sitze aktuell an einem Hobby Projekt, in dem ich möglichst genaue Frequenzen benötige. Diese sollen einstellbar sein. Mein Ziel ist es gerade, vier LEDs mit meinen voreingestellten Frequenzen blinken zu lassen. Dafür habe ich mich an mein Arduino gesetzt und ein Programm geschrieben, das fürs bloße Auge zu laufen scheint und in manchen Fällen die laufende Frequenz sichtbar verfälscht. Eine genauere Untersuchung des Sachverhaltes hat mir zwei unvermeidbare Störungen offenbart. Erstens: Mit dem Arduino kann ich mit der millis() Funktion die Millisekunden zählen um darüber meine Taktfrequenzen laufen zu lassen, doch die millis() Funktion läuft asynchron mit einer Ungenauigkeit von 100ppm. Das führt in meinem Programm zu einer Verschiebung der Taktmuster, was in einem Uneinheitlichen Gesamtmuster der Frequenz endet. Das heißt, wenn ich 11Hz einstelle, liefert mir der Arduino eine Frequenz von 10.989Hz für ca 1.365 Sekunden, woraufhin ein einzelner Puls mit 10.8695Hz folgt. Das ganze wiederholt sich zyklisch. Letzten Endes habe ich somit keine stabile Frequenz, sondern ein Gemisch von 2 Frequenzen, die sich je nach eingestellter Frequenz in unterschiedlichen, aber festen Zeitintervallen wiederholen. Zweitens: Wie im Punkt Erstens zu erkennen, kann ich mit dem Arduino nicht alle Frequenzen darstellen. Wenn ich z.B. 11Hz haben möchte, liefert mir der Arduino in der Umsetzung 10.989Hz. Das liegt daran, das ich die gewünschte Frequenz mit einer float Variable nur auf 2 Nachkomma-Stellen ausrechnen kann, was mit dem Timer jedoch nicht vereinbar ist da mir die millis() Funktion nur Ganzzahlen liefert. Das heißt wiederum, dass ich letzten Endes nur ein begrenztes Repertoire an Frequenzen habe, die ich darstellen kann. Theoretisch ließe sich das Problem Nummer 1 mit einem externen DS3231 realisieren, da dieser als Echtzeituhr mit einer Abweichung von 2ppm stabile Millisekunden Werte liefert. Der zweite Punkt ist mit dem Arduino jedoch leider nicht korrigierbar. Alles in allem eignet sich der Arduino also nicht für mein Vorhaben. Darum möchte ich die Schaltung anders realisieren, wozu mir jedoch die Kenntnisse für passende ICs oder ähnlichem fehlen. Ich suche eine Komponente, mit der ich stabile Frequenzen im Bereich von 1Hz bis 100Hz darstellen kann. Als ersten Gedanken hatte ich da einen TLC555 Timer als astabile Kippstufe. Allerdings ist mir auf diese Weise nicht möglich, die Frequenzen mit einem Mikrocontroller oder einem Drehgeber zwischen 1Hz und 100Hz selber einzustellen. Dafür müsste ich ja einen einstellbaren Kondensator einbauen, der mir in der Einstellung zu ungenau arbeitet (sofern es überhaupt welche gibt. Eine Softwareseitige Einstellung wäre optimal. Programmierbare Oszillatoren finde ich bei Mouser oder ähnlichen Seiten nur für Frequenzen ab 100kHz. Der Ausgang muss mir nur ein Rechtecksignal liefern. Das ist auch schon die Stelle an der ich hängen bleibe. Womit lässt sich mein Vorhaben realisieren? Ein paar Ideen wären nett; und seid mir bitte nicht zu böse - ich bin noch Anfänger Danke :)
Gast
#7080850
Thomas G. schrieb: > Programmierbare Oszillatoren finde ich bei Mouser oder ähnlichen Seiten > nur für Frequenzen ab 100kHz. Genau so. Und dann tust du den Ausgang noch durch 100.000 teilen (Nachteiler) und fertig ist die Laube.
Gast
#7080866
Welcher Arduino? UNO, oder Nano? Dann: Thomas G. schrieb: > liefert mir der Arduino eine > Frequenz von 10.989Hz für ca 1.365 Sekunden, woraufhin ein einzelner > Puls mit 10.8695Hz folgt. Das ganze wiederholt sich zyklisch. Arduino fügt Schaltmillis ein. Ca alle 42ms Thomas G. schrieb: > Womit lässt sich > mein Vorhaben realisieren? Verwende doch besser Timer 1
Gast
#7080881
Sofern Du einen Arduino verwendest, darfst Du den zumeist bestückten keramischen Resonator nicht verwenden, da er zu ungenau ist. Beim Arduino UNO beispielsweise kann man den Takt vom ATmega16U2 verwenden. Wie man dies umlötet findest Du hier unter Punkt "automatischer Abgleich ..." http://mino-elektronik.de/fmeter/fm_software.htm#bsp7 Genaue Zeiten - auch und gerade im unteren Frequenzbereich - mit einer Auflösung von 62,5 ns @ 16 MHz Takt kann man mit einem Timer erzeugen. Beispiel findest Du hier: http://mino-elektronik.de/Generator/takte_impulse.htm Sieh es Dir einfach an. Es sind C-Programme, die man auch auf einem AVR8-Arduino laufen lassen kann. Sofern die absoluten Zeiten im ppm-Bereich liegen müssen, kommst Du um einen stabileren Taktgeber nicht herum. Stichwort: TCXO. Relative Zeiten kann man dadurch stabil halten, daß alle Oszillatoren vom gleichen Taktgeber betrieben werden und daher nicht gegeneinander driften können.
Gast
#7080897
Klingt nach einem Fall für 4 Zustandsautomaten. Dort ist ein Beispiel mit Erklärungen für 3 blinkende Leuchtdioden: http://stefanfrings.de/multithreading_arduino/index.html Das kannst du selbstverständlich auf 4 erweitern. Wenn das auf Basis von millis() machst, kannst du die Blink-Intervalle natürlich auch nur im Raster von 1ms einstellen. Klar könnte man auch 0,1ms oder gar 0,01ms Intervalle benutzen, was aber nichts daran ändert, dass man damit nicht jede beliebige Frequenz exakt erzeugen kann. Für 37 Hz brauchst du z.B. 0,027027027ms pro Intervall wären, die Zahl hat zu viele Nachkommastellen. Das kriegst du mit keinem digitalen Timer hin. Und wenn doch, dann scheitert er an anderen Wunsch-Frequenzen. Überdenke nochmal deine Anforderungen. Vermutlich verlangst du da mehr als nötig. Mit cleveren Algorithmen kannst du zumindest näherungsweise an deine Wunsch-Werte heran kommen. Du musst nur dafür sorgen, dass die Abweichung sich nicht immer weiter auf-summiert. Denke an den 29. Februar. Der wird ab und zu eingefügt, um die Abweichung unseres Kalenders auszugleichen. Spontan fällt mir den Bresenham Algorithmus ein, mit dem man schräge Linien auf den Bildschirm zeichnet, die nicht exakt ins Pixelraster passen. Das gleiche Prinzip müsste man auch deine Zeiten anwenden können. Schau dir das mal an: https://de.wikipedia.org/wiki/Bresenham-Algorithmus
Gast
#7080904
Stefan ⛄ F. schrieb: > Für 37 Hz brauchst du z.B. 0,027027027ms pro Intervall wären, die Zahl > hat zu viele Nachkommastellen. Die Nachkommastellen kommen von Deinem Taschenrechner. Hier ist sinnvolles Runden hilfreich.
Gast
#7080906
m.n. schrieb: > Für 37 Hz brauchst du z.B. 0,027027027ms pro Intervall Hoppla, es sind Sekunden, nicht ms. Die Zahl ist sogar periodisch, hat unendlich viele Nachkommastellen! > Die Nachkommastellen kommen von Deinem Taschenrechner. > Hier ist sinnvolles Runden hilfreich. Würde ich auch tun, aber der TO will es exakt. Deswegen schrieb ich: > Überdenke nochmal deine Anforderungen. > Vermutlich verlangst du da mehr als nötig.
Gast
#7080916
Mit einem anstaendigen Controller der ein paar Timer hat, erledigt sich solch ein "Problem" quasi von selbst. Ansonsten tut es auch ein wenig richtige Signalverarbeitung um solche Signale zu erzeugen. Aber wer nur den Buddelkasten spielt, kennt nichts anderes. Stattdessen muessen externe Timer bemueht werden. Da kann man doch nur lachen.
Gast
#7080921
Stefan ⛄ F. schrieb: > Würde ich auch tun, aber der TO will es exakt. Exakt gibt es in der Physik nicht. Hinreichend genau ist angesagt. NoArno schrieb: > Da kann man doch nur lachen. Ja, lach einen Anfänger nur aus. Dummer Mensch!
Gast
#7080922
NoArno schrieb: > Mit einem anstaendigen Controller der ein paar Timer hat, > erledigt sich solch ein "Problem" quasi von selbst. Leider ziemlich unkonkret, wie soll das dem TO helfen? Und wie machst du damit exakt 37 Hz?
EAF schrieb: > Welcher Arduino? > UNO, oder Nano? Ich verwende einen Arduino Klon, den Elegoo UNO R3, mit einem ATMEGA328P > Thomas G. schrieb: >> Womit lässt sich >> mein Vorhaben realisieren? > Verwende doch besser Timer 1 Eine gute Idee die ich gerne testen würde, bei der ich leider nicht durchblicke wie ich den Timer 1 einstellen soll. Da verstehe ich nicht welchen prescaler ich auswählen soll oder was für TOP Werte zu verwenden sind.
m.n. schrieb: > Sofern die absoluten Zeiten im ppm-Bereich liegen müssen, kommst Du um > einen stabileren Taktgeber nicht herum. Stichwort: TCXO. > Relative Zeiten kann man dadurch stabil halten, daß alle Oszillatoren > vom gleichen Taktgeber betrieben werden und daher nicht gegeneinander > driften können. Wie genau arbeitet ein TCXO? Angenommen ich verwende einen, der mit einem Frequenzteiler auf meinen ausgewählten 1Hz bis 100Hz Bereich runterskaliert. Liefert der mir beispielsweise einen stabilen 3Hz Wert? Normale Oszillatoren bekommen sowas doch auch hin oder nicht?
Bitte definiere "Exakt" in maximale prozentuale Abweichung. Genauigkeit: +/- X % (bitte X ausfüllen) Ein Frequenzbereich von 1Hz bis 100Hz stellt keine Herausforderung dar. Der Resonator vom Arduino Uno hat eine maximale Abweichung von +/- 0,5 %. So schlecht ist das nun auch wieder nicht. Wenn man 50Hz einstellt, kommen etwas zwischen 49,75Hz und 50,25Hz raus (im schlimmsten Fall). Genau genug? Synchronität ist beim Timer kein Problem. Auf jeden Fall den Timer nehmen! Wenn das zu ungenau ist, muss ein Quarz her. Sonst fällt mir nur noch eine Atomuhr ein. Und: Programm hochladen, das hilft.
Stefan ⛄ F. schrieb: > Klar könnte man auch 0,1ms oder gar 0,01ms Intervalle benutzen, was aber > nichts daran ändert, dass man damit nicht jede beliebige Frequenz exakt > erzeugen kann. Wie funktioniert das beim Arduino? So würde ich näher an meine Wunsch-Frequenz kommen können. > Für 37 Hz brauchst du z.B. 0,027027027ms pro Intervall wären, die Zahl > hat zu viele Nachkommastellen. Das kriegst du mit keinem digitalen Timer > hin. Und wenn doch, dann scheitert er an anderen Wunsch-Frequenzen. Leider. Genau so sieht es auch bei 3Hz aus - wie machen das die Oszillatoren im Labor? Sind da mit RC-Schwingkreisen alle Frequenzen nahtlos darstellbar? > Überdenke nochmal deine Anforderungen. Vermutlich verlangst du da mehr > als nötig. Das könnte sein. Andererseits versuche ich möglichst genau zu arbeiten. Wenns digital an Grenzen stößt müsste es doch analog umsetzbar sein oder?
Gast
#7081008
> Ich sitze aktuell an einem Hobby Projekt, in dem ich möglichst > genaue Frequenzen benötige. Nicht schwafeln, sondern konkrete Angaben: wie genau. > Diese sollen einstellbar sein. Mein Ziel ist es gerade, vier > LEDs mit meinen voreingestellten Frequenzen blinken zu lassen. Ich denke, das Problem ist eher die Erzeugung der Frequenzen mit delay(). Das ist nämlich sehr ungenau, eher im Promille-Bereich. TXCO ist der komplett falsche Weg, dort geht es um ppm, also um Faktor 1000 genauer. Genauso programmierbare Oszillatoren. Natürlich kann man das so machen, ist aber für dein "Hobbyprojekt" eher totaler Overkill, so wie ich das sehe. Ich denke, dass die absolute Frequenz gar nicht so wichtig ist, sondern dass die 4 LEDs "synchron" bleiben. Und das geht am besten von einer Zeitbasis weg. Z.B. wie schon angedeutet mit dem Timer1. Du errechnest on the fly, wann das nächste Event ist, lässt dann einen Interrupt generieren und schaltest den entsprechenden Ausgang. Dann überlegen, wann das nächste Event sein soll. Fertig. Oder wenn es ein klein wenig jittern darf, ganz ohne Interrupt, einfach den Zähler periodisch abfragen und bei overflow einen Software-Zähler hochzählen. Oder den Overflow-Interrupt die Überläufe zählen lassen für kleine Frequenzen. Analog ist noch viel ungenauer (Temperaturabhängigkeit etc.) Die Zeitbasis bei den Arduinos hängt vom Hersteller ab, manche verwenden Resonatoren, andere Quarze.
Ein bißchen Gehirnakrobatik vorweg kann eigentlich nicht schaden. Will man 100Hz mit 10ppm Genauigkeit einstellen können, braucht man 100ns Auflösung, also 10MHz Zähltakt. Für 10Hz Ausgangssignal muß der Zähler dann bis 1 Million zählen, also braucht es mindestens einen 20-bit-Zähler. Will man das mit einem 8-bit AVR erreichen, muß man ziemlich tief in die Trickkiste greifen, nach einer Anfängerlösung sieht das für mich nicht aus. Mehrere Timer braucht man im Übrigen nicht, 4 OutputCompare-Kanäle reichen. Auch die Ungenauigkeit des Oszillators kann man mit einer Kalibrierkurve kompensieren, Temperaturmessung ist ja an Bord. Man muß aber dann mit passend genauem Frequenzzähler kalibrieren :-) Eine BluePill wäre hier wohl die bessere Wahl. Gruß Klaus (der soundsovielte)
Uwe K. schrieb: > Bitte definiere "Exakt" in maximale prozentuale Abweichung. > > Genauigkeit: +/- X % (bitte X ausfüllen) Idealerweise eine Genauigkeit von +/- 0%. Mir ist bewusst, das dies nicht möglich ist. Die Abweichung von 10.989Hz auf 10.8695Hz liegt bei knapp 1.09%. Was sind denn realistische Grenzen, +/- 0.2%? Sie sollte kleinstmöglich sein.
Gast
#7081020
Thomas G. schrieb: > Eine gute Idee die ich gerne testen würde, bei der ich leider nicht > durchblicke wie ich den Timer 1 einstellen soll. Da verstehe ich nicht > welchen prescaler ich auswählen soll oder was für TOP Werte zu verwenden > sind. Das kann man doch berechnen... Oder? Soweit mir bekannt, sind die Regeln im Datenblatt aufgeführt.
zyxwv schrieb: > Nicht schwafeln, sondern konkrete Angaben: wie genau. Ich möchte Frequenzen bis 30Hz mit 2 Nachkommastellen wählen können. >> Diese sollen einstellbar sein. Mein Ziel ist es gerade, vier >> LEDs mit meinen voreingestellten Frequenzen blinken zu lassen. > > Ich denke, das Problem ist eher die Erzeugung der Frequenzen mit > delay(). In meinem Programm arbeite ich nicht mit der delay() Funktion. Hier wird die BlinkWithoutDelay-Mechanik genutzt, in der ich, wie du schon sagtest, on the fly die Intervalle ausrechne.. Bzw die Abschnitte dazwischen. Im Monitor fällt mir allerdings auf, das die Intervalle nicht eingehalten werden, sondern frequenzabhängig nach gewissen Zeiten, das Intervall jeweils um 1ms überschreiten. Bei eingestellten 11Hz (was real etwa 10.989Hz sind), passiert das alle 1,3 Sekunden. Damit sieht mein Ausgangssignal nicht so aus, wie es aussehen sollte. > Genauso programmierbare Oszillatoren. > Natürlich kann man das so machen, ist aber für dein "Hobbyprojekt" eher > totaler Overkill, so wie ich das sehe. Overkill gibts hier für mich nicht. Wenn alles rund läuft, würde ich am Ende alles gerne auf einer PCB zusammenbringen und mich freuen. PCB gerber Files erstellen muss ich im Prozess nur auch noch lernen. > Ich denke, dass die absolute Frequenz gar nicht so wichtig ist, sondern > dass die 4 LEDs "synchron" bleiben. Und das geht am besten von *einer* > Zeitbasis weg. Z.B. wie schon angedeutet mit dem Timer1. > Du errechnest on the fly, wann das nächste Event ist, lässt dann einen > Interrupt generieren und schaltest den entsprechenden Ausgang. Dann > überlegen, wann das nächste Event sein soll. Fertig. Genau hier liegt ja das Problem..? > Die Zeitbasis bei den Arduinos hängt vom Hersteller ab, manche verwenden > Resonatoren, andere Quarze. Beim ELEGOO UNO R3 ist ein metallisches Gehäuse mit einer 16000 Aufschrift. Auf der Rückseite zähle ich nur 2 Pins, deshalb gehe ich laut anderer Internetseiten mal davon aus, dass es sich hierbei um einen Quarz handelt.
Gast
#7081067
Thomas G. schrieb: > die millis() Funktion läuft asynchron mit einer Ungenauigkeit von 100ppm Nimm doch micros(). LG, Sebastian
Thomas G. schrieb: > Uwe K. schrieb: >> Genauigkeit: +/- X % (bitte X ausfüllen) > > Idealerweise eine Genauigkeit von +/- 0%. Mir ist bewusst, das dies > nicht möglich ist. Natürlich nicht. Alles hat Toleranzen. Auch die Atomuhr hat Abweichungen. Wichtig ist es genau zu Wünschen. Nennt man spezifizieren. Du möchtest Frequenzen bis 30Hz. Und wo fangen wir an? Genau wünschen! Ich spekuliere mal auf 1Hz bis 30Hz mit 2 Nachkommastellen genau für den Sollwert. Kriegt man mit einer Toleranz von +/- 0,001 % hin. Genau genug? An eine Kalibrierung kommt man wohl nicht vorbei. Versuche es mit einem Teiler von 8 und CTC mit dem Timer1 (16-Bit Timer). CTC mehrfach durchlaufen und anpassen. Bei einem Teiler von 256 schafft man es direkt mit einem CTC. Dann aber mit +/- 0,025 % maximaler Abweichung. Damit würde ich anfangen. Hilfreich ist en Frequenzmesser mit 10facher Genauigkeit, um das Ergebnis zu prüfen. P.S.: Hobby: mit maximalem Aufwand, den geringsten nutzen erzeugen. Aber VIEL Spaß gehabt 😉. So viel zum Thema „Overkill“.
Gast
#7081093
Thomas G. schrieb: > Wie funktioniert das beim Arduino? So würde ich näher an meine > Wunsch-Frequenz kommen können. Der Timer0 wird schon vom Arduno Framework belegt. Aber du kannst einen anderen Timer verwenden, der z.B. alle 0,1 ms einen Interrupt auslöst und dann in der ISR einen Counter hochzählen. Aber da auch das wie gesagt nur eine halbe Lösung wäre, die auf keinen Fall die von dir geforderten exakten Frequenzen erzeugen könnte, erspare ich mir hier, dafür ein konkretes Beispiel zu schreiben. Wenn du es wirklich ernst meinst, wirst du selbst etwas finden. Mit ISR und der korrekten Nutzung von Variablen in diesem Kontext wirst du dich ohnehin beschäftigen müssen, sobald du über den Arduino Standard hinaus gehst. Thomas G. schrieb: > Andererseits versuche ich möglichst genau zu arbeiten. Typischer Anfängerfehler. Man hat kaum Erfahrung, weniger Ahnung, will es aber so gut wie möglich machen, auf jeden Fall besser als die Profis. Jetzt fehlt nur noch, dass es insgesamt nicht mehr 20 Euro kosten darf. Dabei kann ich dir nicht helfen.
Gast
#7081107
Thomas G. schrieb: > deshalb gehe ich > laut anderer Internetseiten mal davon aus, dass es sich hierbei um einen > Quarz handelt. Ich behaupte, dass ein in Hochsprache (C++) programmierter µC der falsche Ansatz ist, eine stabile Frequenz ohne Jitter erzeugen zu wollen.
Uwe K. schrieb: > Ich spekuliere mal auf 1Hz bis 30Hz mit 2 Nachkommastellen genau für den > Sollwert. Genau. > Kriegt man mit einer Toleranz von +/- 0,001 % hin. Genau genug? An eine > Kalibrierung kommt man wohl nicht vorbei. Das sollte genau genug sein. > Versuche es mit einem Teiler von 8 und CTC mit dem Timer1 (16-Bit > Timer). CTC mehrfach durchlaufen und anpassen. > > Bei einem Teiler von 256 schafft man es direkt mit einem CTC. Dann aber > mit +/- 0,025 % maximaler Abweichung. Damit würde ich anfangen. Wenn ich es geschafft habe das umzusetzen, werde ich davon berichten. > P.S.: Hobby: mit maximalem Aufwand, den geringsten nutzen erzeugen. Aber > VIEL Spaß gehabt 😉. So viel zum Thema „Overkill“. Haha, Ups
Gast
#7081163
Ganz klassisch macht man das mit einer PLL und einen programmierbaren Teiler. Damit kann man exakte 1 Hz Schritte ohne jeden prinzipbedingten Fehler erzeugen, solange die Referenzfrequenz auch exakt ist.
Gast
#7081178
Juri schrieb: > Thomas G. schrieb: >> Programmierbare Oszillatoren finde ich bei Mouser oder ähnlichen Seiten >> nur für Frequenzen ab 100kHz. > > Genau so. Und dann tust du den Ausgang noch durch 100.000 teilen > (Nachteiler) und fertig ist die Laube. Bisher habe ich nur von irgendwelchen, halbseidenen Tricksereinen gelesen, die aller mehr oder weniger direkt in die Hose gehen. Hol dir bei Mouser den programmierbaren Oszillator und schalte einen Nachteiler nach. Machst du diesen Nachteiler programmierbar, hast du ein sehr universelles Gerät. Ist sehr hohe Genaugkeit gefragt? Speise/synchronisiere deinen Oszillator aus einem TCXO oder OCXO. Aber ich wiederhole mich...
Gast
#7081235
Wenn ich ein genaues Timing brauche, dann nehme ich ein FPGA. Da kann ich im Mikrosekundenbereich (und kleiner) arbeiten. Die Timerbreite in Bits ist skalierbar. Es können mehrere Dutzend Timer laufen, die sich gegenseitig nicht stören. Und wenn eine CPU zufällig im Interrupt ist, funktioniert das Timing es immer noch. Aber es muss ja immer ein Bastelarduino sein. Ich bastel mit denen auch, aber wenn ich verschärfte Anforderungen habe, muss ich andere Werzeuge benutzen.
Gast
#7081242
PittyJ schrieb: > Wenn ich ein genaues Timing brauche, dann nehme ich ein FPGA. Beim Blinken einer LED kommt es selten auf genaues Timing (im Sinne von Jitter) an. Hier geht es wohl eher darum, dass die Phasenlage sich nicht verschiebt. Vielleicht reicht schon eine einfache Software-DDS, die mit dem T0-Overflow getaktet wird und für jeden Output-Kanal einen eigenen Phasenakkumulator besitzt - hängt von den Anforderungen an die Frequenzen/Phasenlage ab.
Thomas G. schrieb: > EAF schrieb: >> Welcher Arduino? >> UNO, oder Nano? > > Ich verwende einen Arduino Klon, den Elegoo UNO R3, mit einem ATMEGA328P > >> Thomas G. schrieb: >>> Womit lässt sich >>> mein Vorhaben realisieren? >> Verwende doch besser Timer 1 > > Eine gute Idee die ich gerne testen würde, bei der ich leider nicht > durchblicke wie ich den Timer 1 einstellen soll. Da verstehe ich nicht > welchen prescaler ich auswählen soll oder was für TOP Werte zu verwenden > sind. Hallo, du schaust ins Manual, Kapitel Timer 1, bspw. CTC Modus, schaust dir die Formel an und stellst sie nach TOP um. N ist der Prescaler und ins OCR1A Register käme der TOP Wert rein. Dann rechnest du hin und her mit welchen Prescaler du einen ganzzahligen TOP Wert für 1Hz bekommst. Ist TOP keine Ganzzahl hätte man schon eine Abweichung von Haus aus drin. Das sollte sich mit 16Bit Zählbereich geradeso ausgehen, grob überschlagen.
Gast
#7081295
>Ich sitze aktuell an einem Hobby Projekt, in dem ich möglichst genaue >Frequenzen benötige. > Dafür habe ich mich an mein Arduino gesetzt und ein Programm >geschrieben, das fürs bloße Auge zu laufen scheint und in manchen Fällen >die laufende Frequenz sichtbar verfälscht. Wenn du mit bloßem Auge eine Ungenauigkeit siehst, dann liegt es mit Sicherheit nicht an der Zeitbasis des Arduino sondern an einem Fehler in deinem Programm. "Möglichst" genau geht es, wenn eine Atomuhr nimmst. Oder du musst erst einmal "möglichst genau definieren". Die nächst einfachere du ein GPS-Signal zur Synchronisation der Zeitbasis nimmst. In absteigender Reihenfolge kannst du entweder - ein Rubidiumnormal - einen Ofen kontrollierten Oszillator - oder einen Temperaturkompensierten Oszillator kaufen Desweiteren gibt es nicht "den Arduino", sondern Haufenweise völlig unterschiedliche Hardware, auf der das Arduino Framework läuft. Die Arduinos "Uno" und "Nano" haben einen Resonator, der für Frequenzmessungen mit mehr als 4 Stellen zu ungenau ist. Nimmst du aber einen PiPico mit Arduino-Framework, hat der einen sehr stabilen Quartz und die Systemfrequenz kann auf 150MHz hochgestellt werden, sodass auch noch kleine Zeitquantisierungen möglich sind.
Gast
#7081299
chris_ schrieb: > Wenn du mit bloßem Auge eine Ungenauigkeit siehst, dann liegt es mit > Sicherheit nicht an der Zeitbasis des Arduino sondern an einem Fehler in > deinem Programm. sehe ich auch so. @TO: Wenn deine 4 LEDs in sync bleiben sollen dann mach einen Takt und leite davon die Takte der 4 LEDs ab. Das bleibt syncron auch wenn sich mal deine millis um eine 1ms verschieben würden.
Gast
#7081369
Thomas G. schrieb: > Wie genau arbeitet ein TCXO? Das ist ein temperaturkompensierter Quarzoszillator, der über einen weiten Temperaturbereich eine auf ca. 1 ppm (je nach Typ) stabile Frequenz liefert. Wie sich jetzt gezeigt hat, hat Deine Schaltung einen Quarzoszillator, wo man von einer Grundgenauigkeit von <= 50 ppm ausgehen kann. Daraus folgt, daß er für Deine auf vier Stellen genaue Takterzeugung ohne weiteren Abgleich ausreichend ist. Da Du einen ATmega328 verwendest, könntest Du die oben verlinkten AVR-Programmbeispiele damit laufen lassen. Pro erzeugte Frequenz braucht man einen OCRx-Ausgang, wovon der 328 insgesamt sechs Stück hat. Daß jeweils zwei an einem gemeinsamen Timer hängen, stört nicht. Insgesamt kann man damit also sechs unterschiedliche Blinkfrequenzen erzeugen - sehr genau und jitterfrei. Man kann zwar die Arduino-IDE verwenden, sollte aber tunlichst setup() und loop() vermeiden, damit man alle Timer selbst benutzen kann. Du brauchst also keinerlei andere oder zusätzliche Hardware, aber ein wenig Arbeit, um zu verstehen, wie die Timer mit ihren OXRx-Ausgängen arbeiten. Bleibt noch die Frage, wie Du die unterschiedlichen Frequenzen einstellen willst. Per Poti wäre zu ungenau. Per Tastatur oder per ser. Schnittstelle?
Thomas G. schrieb: > in dem ich möglichst genaue > Frequenzen benötige. Das ist Wischiwaschi, damit kann keiner was anfangen. Thomas G. schrieb: > Mein Ziel ist es > gerade, vier LEDs mit meinen voreingestellten Frequenzen blinken zu > lassen. Hä? Für Blink-LEDs braucht es überhaupt keine Genauigkeit. Kein Mensch kann Fehler im ms-Bereich erkennen. Erzähl mal konkret, was das überhaupt werden soll. Thomas G. schrieb: > Als ersten Gedanken hatte ich da einen TLC555 Timer als astabile > Kippstufe. Guter Witz. Ein RC-Oszillator ist um Längen ungenauer, als ein MC mit Quarz.
Gast
#7081384
Peter D. schrieb: > Das ist Wischiwaschi, damit kann keiner was anfangen. Der TO hatte mittlerweile beschrieben, wie genau er es haben möchte. Man muß es nur lesen und verstehen wollen. Peter D. schrieb: > Für Blink-LEDs braucht es überhaupt keine Genauigkeit. Kein Mensch kann > Fehler im ms-Bereich erkennen. Der TO möchte es so haben, weil er etwas lernen will. Daß instabile Blinkschaltungen relativ schnell sichtbar in der Phasenlage auseinanderlaufen, ist kein Geheimnis. Das ist selbst dem TO als Programmieranfänger aufgefallen. Daß Du das nicht brauchst, ist nicht relevant.
m.n. schrieb: > Daß instabile > Blinkschaltungen relativ schnell sichtbar in der Phasenlage > auseinanderlaufen, ist kein Geheimnis. Wenn sie von einem gemeinsamen Basistakt erzeugt werden, aber schon. Das Problem ist das Einstellen in kleinen Schritten. Damit kann sich eine sehr lange Priodendauer ergeben, bis alle 4 Zähler wieder den Startwert erreicht haben. Mit 4 hohen Primzahlen als Teiler dauert das eben. Das hat aber nicht das geringste mit der Genauigkeit der Taktbasis zu tun.
Gast
#7081417
Peter D. schrieb: > Wenn sie von einem gemeinsamen Basistakt erzeugt werden, aber schon. Lies doch mal, was hier bereits geschrieben wurde. Deine nutzlose Nörgelei bringt dem TO nichts.
m.n. schrieb: > Lies doch mal, was hier bereits geschrieben wurde. Auseinander laufen können nur 4 unabhänge RC-Oszillatoren. Sobald man einen gemeinsamen Basistakt hat, sind alle Abläufe streng deterministisch. m.n. schrieb: > Deine nutzlose Nörgelei bringt dem TO nichts. Nörgeln (Helfen) kann man erst, wenn es einen Quelltext gibt. Ich habe auch nicht genörgelt, sondern nur gefragt, was da ganze überhaupt soll.
Gast
#7081445
m.n. schrieb: > Stefan ⛄ F. schrieb: >> Würde ich auch tun, aber der TO will es exakt. > > Exakt gibt es in der Physik nicht. Hinreichend genau ist angesagt. Naja, Stefan ist weder Physiker noch Mathematiker. Also nicht übelnehmen. So, zur Sache: Wenn man irgendwelche möglichst präzisen Signale erzeugen will, die auch noch frei wählbar im Betrieb sein sollen, dann greift man der Einfachheit zuliebe zu einem kleinen DDS-Schaltkreis. Wenn man hingegen ohne zusätzliche Schaltung auskommen will, dann wären da µC-interne Timer die Wahl, aber das setzt zusätzliche Überlegungen voraus. Und da kommt zumindest das Rechnen mit echten Brüchen ins Spiel, womit auch Teilungsverhältnisse darstellbar sind, die bei Dezimaldarstellung zu nicht enden wollenden Nachkommastellen führen. Sowas geht vom Prinzip her auch mit einem Arduino, aber man muß sich schon etwas mehr mit Rechnen und dem Verwenden von Timern befassen als nur millis() aufzurufen. W.S.
W.S. schrieb: > ohne zusätzliche Schaltung auskommen will, dann wären da µC-interne > Timer die Wahl, aber das setzt zusätzliche Überlegungen voraus. Und da > kommt zumindest das Rechnen mit echten Brüchen ins Spiel, Nö. Das sind einfache Zähler und Modulooperationen. DDS in Software. Beitrag "Re: auf einfache Weise von 11MHz auf 300kHz teilen/generieren" Ok, ist Assembler und damit nicht so ganz das Gelbe vom Ei für Arduinos, aber man erkennt das Prinzip. Beitrag "Re: SPWM auf Atmega8, bitte um Feedback hinsichtlich Optimierung" Das ist "Arduino", sprich C++ in einfachster Form. Man muss nur die Tabelle weglassen und schon hat man seine nahezu X-beliebigen Frequenzen.
Gast
#7081486
Peter D. schrieb: > Auseinander laufen können nur 4 unabhänge RC-Oszillatoren. Sobald man > einen gemeinsamen Basistakt hat, sind alle Abläufe streng > deterministisch. Genau. Schon deshalb kann ich das Problem des TO nicht nachvollziehen. Und wenn er unabhängige Oszillatoren hat, auch welche vom Typ TCXO, dann werden die irgendwann merklich auseinandergelaufen sein.
HildeK schrieb: > Genau. > Schon deshalb kann ich das Problem des TO nicht nachvollziehen. Ich schon. Man kann mit schlechter Software, basierend auf fehlenden Kenntnissen, JEDEN Murks machen, der scheinbar funktioniert, im Detail dann aber versagt.
Gast
#7081495
Ich halte es für erwähnenswert, dass die loop Schleife keine while
Schleife ist, wie man sich das als Anfänger vorstellt. Die Loop muss man
sich so vorstellen:
while(1){
loop(); <--- hier wird dein Code ausgeführt
ArduinoKram(); <-- kostet Zeit
}
Auch digitalWrite() etc. benötigt unterschiedlich lange, was auch zu
einer verschiebung führt.
Teste deinen code mal mit
- micros() anstatt millis()
- in einer while(1) Schleife anstatt in der loop()
- evtl. direkten Port Zugriff anstatt digitalWrite()
Die bessere Variante ist jedoch einen Timer zu verwenden und dann über
direkten Port Zugriff die GPIOs schalten.
Thomas G. schrieb: > Idealerweise eine Genauigkeit von +/- 0%. Eine Genauigkeit von 0% ist leicht zu erreichen. Denn dann ist selbst das ungenaueste Signal noch genau genug. Du forderst eine "Ungenauigkeit" oder eine "Abweichung" von 0%. Aber alle, die so etwas verlangen, ingorieren die Realität. Denn die einzig relevante Frage ist nicht, was du willst, sondern was die Anwendung braucht. Und diese Rahmenbedingungen vernüftig zu klären und darauf basierend eine kostenmäßig taugliche Lösung für diese Anwendung zu finden, das ist die Aufgabe eines Technikers. Alles andere sind irgendwelche nutzlosen Gedankenspiele, die man durch Einsatz beliebiger Geldmengen leicht lösen kann. Peter D. schrieb: > Ich habe auch nicht genörgelt, sondern nur gefragt, was da ganze > überhaupt soll. Auf die Antwort bin ich auch gespannt.
Gast
#7081536
Thomas G. schrieb: >> Kriegt man mit einer Toleranz von +/- 0,001 % hin. Genau genug? An eine >> Kalibrierung kommt man wohl nicht vorbei. > > Das sollte genau genug sein. Ganz doof gefragt: verfügst du überhaupt über die Messtechnik, um dein Ergebnis zu verifizieren? Ansonsten ist selbst mit dem Uno noch eine Menge Luft nach oben, wie schon andere geschrieben haben.
Gast
#7081538
> was da ganze > überhaupt soll. Das ist doch nun einfach. Ein Caesium kontrollierter Arduinowurstblinker. Braucht doch fast jeder (nicht). Wenn es wenigstens ein Stroboskop waere... > eine "Abweichung" von 0%. ist, wie ich schon schrieb, mit einer PLL bezogen auf die Referenzfrequenz leicht zu erreichen. Das sollte sich vielleicht auch einmal in "FPGA-Kreisen" herumsprechen. Das es auch ausserhalb eines FPGA eine oder mehrere PLLs geben kann. Und nicht nur diese haesslichen DCMs.
Gast
#7081563
Falk B. schrieb: > Nö. Das sind einfache Zähler und Modulooperationen. DDS in Software. Ach nö. Ein Zählerausgang liefert hi oder lo und damit nur das Vorzeichen, während ein DDS ein analoges Signal liefert und damit schlußendlich eine Stützstelle, die nach einem Tiefpaß den richtigen Signalverlauf (soweit technisch möglich) liefert. Du solltest dringend mal nachlesen, wie ein DDS funktioniert. Und wenn man exakte Frequenzverhältnisse mit Timern haben will, dann kommt man nicht umhin, sich um Rechendinge zu kümmern wie gemeinsame Teiler von Integers usw. - sonst addieren sich die restlichen Phasenfehler und die Signale an den Ausgängen laufen langsam auseinander. Wenn einen das nicht schert, dann ist das Benutzen von Timern ohne weitere Berechnungen möglich. Sonst eben nicht. W.S.
Gast
#7081564
Lothar M. schrieb: >> Ich habe auch nicht genörgelt, sondern nur gefragt, was da ganze >> überhaupt soll. > Auf die Antwort bin ich auch gespannt. Das muß der TO überhaupt nicht beantworten. Er ist Anfänger und kann tun und lassen, was er will. Er möchte Programmieren lernen und hat sich ein Ziel gesetzt. Das ist allemal besser, als irgendwelche, fertigen Entprellroutinen herunterzuladen und instinktlos einzusetzen. Klassikradio schrieb: > Ein Caesium kontrollierter Arduinowurstblinker. > Braucht doch fast jeder (nicht). Noch so ein namenloser Stinkstiefel, bei beim Wiederkäuen seines Frühstücks Schluckauf bekommen hat.
Gast
#7081567
Klassikradio schrieb: >> eine "Abweichung" von 0%. > ist, wie ich schon schrieb, mit einer PLL bezogen auf die > Referenzfrequenz leicht zu erreichen. Naja, nicht 0%, sondern eher daß die restliche Frequenzabweichung im Phasenfehler untergeht. Aber 'leicht' ist was anderes. Es gibt durch den notwendigen Teiler immer ein Raster. W.S.
Gast
#7081587
Peter D. schrieb: > Auseinander laufen können nur 4 unabhänge RC-Oszillatoren. Sobald man > einen gemeinsamen Basistakt hat, sind alle Abläufe streng > deterministisch. Wieder mal eine sprachliche Ungenauigkeit. Meinst du langsame Änderungen in der Frequenz oder in der Phase? Und es sind nicht nur RC-Oszillatoren betroffen, sondern im Prinzip alle. Bloß das Ausmaß ist unterschiedlich. So. Ich geb dir mal ein Beispiel zum Prinzip: ein Ausgang soll ein Signal mit 10 Hz ausgeben und ein anderer eines mit 50 Hz. Rein theoretisch sollten beide Signale gegeneinander nicht phasenmäßig auseinanderlaufen. Aber wenn bei einem die exakte Frequenz 10.0001 Hz ist und bei dem anderen die exakte Frequenz 49.9999 Hz, weil sich das eben aus den Integer-Teilerwerten ergibt, dann laufen die Signale langsam in der Phase auseinander - obwohl sie aus dem selben Takt generiert werden. W.S.
Gast
#7081609
> Er ist Anfänger und kann tun und lassen, was er will. Dann soll er es auch lassen hier zu fragen. Mein Fruehstueck habe ich uebrigens schon gut verdaut. > daß die restliche Frequenzabweichung im > Phasenfehler untergeht Ist die PLL gelockt, gibt es keinen Frequenzfehler. Nur einen fixen Versatz in der Phase. Hat das Schleifenfilter einen I-Anteil, wird disee Phasenabweichung auf ein Minimum geregelt.
Um hier ein paar aufgekommene Fragen zu beantworten: Bei meinen aufblinkenden LEDs handelt es sich um ein Stroboskop. Alle LEDs greifen auf den selben Timer zu, haben unterschiedliche Startpunkte im Intervall, in dem sie sozusagen synchronisieren. Nach einem Intervalldurchlauf haben die LEDs nämlich gleiche Schaltzeiten, im 4er Modus haben sie 2 unterschiedliche Schaltzeiten. Zur Verbildlichung, nach Intervall 1 schaltet die LED 1 ein und LED 3 aus, im zweiten Intervall schaltet 3 ein und 1 aus. mit 2 Intervallen komme ich so auf eine Vierteilung der Frequenz. In meinem Programm blitzen die LEDs nur auf, weil ich sie nicht bis zu den Flanken eingeschaltet haben möchte. Warum benutze ich dafür Arduino? Weil ich ein Arduino Board habe und dachte, dass es sich damit ganz gut umsetzen lässt. Erst nach längerer Beschäftigung und Umsetzung wurde mir die Ungenauigkeit bewusst. Da ich für mein Projekt tatsächlich stabile Frequenzen benötige, sehe ich in den kleinen Abweichungen zu viel Fehler. Ich möchte meine Idee mit allen Mitteln umsetzen, weshalb ich aufgrund meiner Problematik andere Lösungen in Betracht ziehe, die genauer aber eventuell um einiges schwieriger sind. Zu irgendwas muss mein B. Eng. ja gut sein, harte Elektrotechnik mit Schaltungsentwürfen und Bauteile-Auswahl habe ich so leider nie gelernt. Entfernen werde ich mich vom Arduino warscheinlich nicht, da ich damit immernoch einen Bildschirm, Taster und Drehgeber programmieren kann um mir mein Objekt so zusammen zu schustern. Mit der if (currentMillis - previousMillis >= interval) { // save the last time you blinked the LED previousMillis = currentMillis; Option driftet mein Intervall immer in gewissen abständen 1ms weg. Mit if (currentMillis - previousMillis >= interval) { // save the last time you blinked the LED previousMillis = previousMillis + interval; halte ich zwar ein festes Intervallraster ein das per se nicht driftet, aber meinen Fehler verdoppelt. So kommt nämlich immernoch der Versatz von 1ms in den gleichen Abständen zusammen, UND zusätzlich wird in der gleichen Phase 1ms hinten abgezogen. Damit verliere ich also 2ms. An die micros() Funktion habe ich auch schon gedacht, so sollte ja eigentlich eine höhere Nachkommastelle darstellbar sein. Ein Blick in den Monitor hat jedoch gezeigt, dass die micros() Funktion das Intervall in den gleichen Abständen um 42 Mikrosekunden übersteigt. Heißt, auch hier ist ein Drift vorhanden. Ich würde gerne den Ansatz mit dem Timer1 ausprobieren, mit dem die Auflösung verändert wird und eine ms-genaue Einstellung möglich sein sollte. Die Register zu verändern stellt für mich leider immernoch eine kleine Herausforderung dar. Messinstrumente zur Verifizierung stehen mir leider nicht zur Verfügung. Zur Analyse steht mir nur der Monitor der Arduino IDE zur Verfügung.
Thomas G. schrieb: > Warum benutze ich dafür Arduino? Weil ich ein Arduino Board habe und > dachte, dass es sich damit ganz gut umsetzen lässt. Erst nach längerer > Beschäftigung und Umsetzung wurde mir die Ungenauigkeit bewusst. ;-) Die "Ungenauigkeit" liegt zu 99% in deinen Fähigkeiten. > Da ich für mein Projekt tatsächlich stabile Frequenzen benötige, sehe WIE Stabil? Atomuhrgenau wird es sicher NICHT sein! Selbst der eher gurkige Oszillator der kleinen Arduinos mit ca. 0,1% Fehler wird es VERMUTLICH tun. Ein Quarz, den man auch sehr einfach nachrüsten kann hat nur 0,01% (100ppm) und weniger Frequenzfehler. > ich in den kleinen Abweichungen zu viel Fehler. Wie "siehst" du sie denn? Mit dem alles sehenden Auge von Mordor? > Ich möchte meine Idee mit allen Mitteln umsetzen, weshalb ich aufgrund Wieviele Milliarden kannst du investieren? ;-) > Entfernen werde ich mich vom Arduino warscheinlich nicht, da ich damit > immernoch einen Bildschirm, Taster und Drehgeber programmieren kann um > mir mein Objekt so zusammen zu schustern. Das kommt der Sache schon näher. > Mit der > if (currentMillis - previousMillis >= interval) { > // save the last time you blinked the LED > previousMillis = currentMillis; > > Option driftet mein Intervall immer in gewissen abständen 1ms weg. Das ist auch nicht die optimale Lösung, wenn man im Bereich von 1ms oder gar darunter arbeiten will. > An die micros() Funktion habe ich auch schon gedacht, so sollte ja > eigentlich eine höhere Nachkommastelle darstellbar sein. Ein Blick in > den Monitor hat jedoch gezeigt, Welcher Monitor? > Ich würde gerne den Ansatz mit dem Timer1 ausprobieren, mit dem die > Auflösung verändert wird und eine ms-genaue Einstellung möglich sein > sollte. Den kann man auf einen CPU-Takt genau einstellen. > Die Register zu verändern stellt für mich leider immernoch eine > kleine Herausforderung dar. Na dann mal los, so viele sind es nicht. Beitrag "Re: 20 LEDs unterschiedlich blinken lassen" Beitrag "Re: Arduino Micro SPWM" > Messinstrumente zur Verifizierung stehen mir leider nicht zur Verfügung. AHA! Und wie hast du dann deine behaupteten Abweichungen und Drift gemessen? > Zur Analyse steht mir nur der Monitor der Arduino IDE zur Verfügung. OMG! Und du glaubst, daß du damit in DEM Zeitbereich was gescheit messen kannst? Dream on. Du braucht ein einfaches Oszilloskop, zur Not auch ein billiger Logikanalysator, aber der ist nervig, wenn man periodische Signale anschauen will.
Falk B. schrieb: > Die "Ungenauigkeit" liegt zu 99% in deinen Fähigkeiten. Plausibel. >> ich in den kleinen Abweichungen zu viel Fehler. > > Wie "siehst" du sie denn? Mit dem alles sehenden Auge von Mordor? Bei 16Hz sehe ich mit dem bloßen Auge, dass die LEDs nicht in Phase bleiben. Wenn ich 2 LEDs beobachte, sehe ich wie sich eine LED an die Phase der anderen annähert und dann "überholt". Kann man sich wie einen Phaser vorstellen, falls dir das was sagt. Nur das es hier kein Ton ist, sondern blinkende LEDs. >> Ich möchte meine Idee mit allen Mitteln umsetzen, weshalb ich aufgrund > > Wieviele Milliarden kannst du investieren? ;-) Ich dachte da eher an wenns digital nicht klappt, dann irgendwie analog. >> Mit der >> if (currentMillis - previousMillis >= interval) { >> // save the last time you blinked the LED >> previousMillis = currentMillis; >> >> Option driftet mein Intervall immer in gewissen abständen 1ms weg. > > Das ist auch nicht die optimale Lösung, wenn man im Bereich von 1ms oder > gar darunter arbeiten will. Bisher ist mir neben dem Tipp mit dem Timer1 keine weitere Option bekannt. >> An die micros() Funktion habe ich auch schon gedacht, so sollte ja >> eigentlich eine höhere Nachkommastelle darstellbar sein. Ein Blick in >> den Monitor hat jedoch gezeigt, > > Welcher Monitor? In der IDE unter Werkzeuge > Serieller Monitor, lassen sich Werte mit printf auf der Konsole anzeigen. > AHA! Und wie hast du dann deine behaupteten Abweichungen und Drift > gemessen? Da sieht man im seriellen Monitor die zeitlichen Abstände, wenn man sie anzeigen lässt. Die einzigen Frequenzen die stabil laufen sind 1Hz und Vielfache von 5Hz. > OMG! Und du glaubst, daß du damit in DEM Zeitbereich was gescheit messen > kannst? Dream on. Sweet dreams are made of this
Stefan ⛄ F. schrieb: > Würde ich auch tun, aber der TO will es exakt. Deswegen schrieb ich: Das hat er zumindest nicht geschrieben: Thomas G. schrieb: > Ich suche eine Komponente, mit der ich stabile Frequenzen im Bereich von > 1Hz bis 100Hz darstellen kann. Und das geht auf jeden Fall.
Thomas G. schrieb: > Bei 16Hz sehe ich mit dem bloßen Auge, dass die LEDs nicht in Phase > bleiben. Wie sollen die denn blinken? Zeig doch mal eine Skizze mit einem Diagramm.
W.S. schrieb: > Aber wenn bei einem die exakte Frequenz 10.0001 Hz > ist und bei dem anderen die exakte Frequenz 49.9999 Hz, weil sich das > eben aus den Integer-Teilerwerten ergibt, dann laufen die Signale > langsam in der Phase auseinander So macht man das ja auch nicht. Man rechnet die Brüche nicht aus, sondern rechnet einfach direkt mit den gebrochenen Zahlen. Dazu braucht es nichtmal eine langsame float-Lib, sondern es reicht ein einfacher Integer-Akku. Z.B. wir haben 100Hz Basistakt und wollen daraus 7Hz erzeugen, d.h. wir müßten durch 14,285714285714285714285714285714 teilen. Statt dessen wird 7 (=Ausgangsfrequenz) in den Akku addiert und bei >=100 (=Eingangsfrequenz) 100 abgezogen und ein Puls generiert. Wollen wir als 2. Frequenz 3Hz, nehmen wir einen 2. Akku und machen es dort genau so. Wir haben zwar einen Jitter, der aber addiert sich nicht. Nach 2100 Takten (=kgV) ist alles wieder auf Anfang. Nimmt man als Basistakt den 16MHz Quarz des MC, dann beträgt der Jitter max 62,5ns. Das sieht niemand.
Thomas G. schrieb: > Bei 16Hz sehe ich mit dem bloßen Auge, dass die LEDs nicht in Phase > bleiben. Wenn ich 2 LEDs beobachte, sehe ich wie sich eine LED an die > Phase der anderen annähert und dann "überholt". Kann man sich wie einen > Phaser vorstellen, falls dir das was sagt. Nur das es hier kein Ton ist, > sondern blinkende LEDs. >>> Ich möchte meine Idee mit allen Mitteln umsetzen, weshalb ich aufgrund >> >> Wieviele Milliarden kannst du investieren? ;-) > > Ich dachte da eher an wenns digital nicht klappt, dann irgendwie analog. Quark. Nahezu alle Lösungen sind heute digital und ihren analogen Brüdern überlegen. Ausnahmen bestätigen die Regel. > Bisher ist mir neben dem Tipp mit dem Timer1 keine weitere Option > bekannt. Man muss es einfach richtig (tm) machen, dann geht das auch mit millis(). Zeig mal deinen Quelltext als Anhang. > In der IDE unter Werkzeuge > Serieller Monitor, lassen sich Werte mit > printf auf der Konsole anzeigen. Ja, und dein printf() dauert mehrere Millisekunden und versaut dir an den kritischen Stellen das Timing. Volle Punktzahl. > Da sieht man im seriellen Monitor die zeitlichen Abstände, wenn man sie > anzeigen lässt. Die einzigen Frequenzen die stabil laufen sind 1Hz und > Vielfache von 5Hz. Dann ist deine Software Murks, was auf grund deiner Kenntnisse nicht verwunderlich ist. Siehe oben.
Klassikradio schrieb: >> eine "Abweichung" von 0%. > ist, wie ich schon schrieb, mit einer PLL bezogen auf die > Referenzfrequenz leicht zu erreichen. Ja, "auf eine Referenzfrequenz". Und woher kommt die? Hat die auch eine "Genauigkeit" von 0,0%? > Das sollte sich vielleicht auch einmal in "FPGA-Kreisen" herumsprechen. Hach, flach. > Das es auch ausserhalb eines FPGA eine oder mehrere PLLs geben kann. Ich glaube eben ganz einfach nicht, das die Aufgabe eine solche Lösung braucht, sondern eben bestenfalls der Thomas mangels besseren Wissens es so will. W.S. schrieb: > Du solltest dringend mal nachlesen, wie ein DDS funktioniert. Man kann mit DDS auch ein Rechtecksignal erzeugen. Das braucht dann im einfachsten Fall nicht mal eine großartige Tabelle für die Wellenform, sondern man gibt einfach das MSB des Akkus aus... m.n. schrieb: > Das muß der TO überhaupt nicht beantworten. Er ist Anfänger und kann tun > und lassen, was er will. Klar muss er nicht. Trotzdem bin ich gespannt. Und weil er eine Lösung sucht, darf er ruhig daran mitwirken. > Er möchte Programmieren lernen und hat sich ein Ziel gesetzt. Das ist > allemal besser, als irgendwelche, fertigen Entprellroutinen > herunterzuladen und instinktlos einzusetzen. Lernen heißt aber auch, nicht jeden Fehler selber zu machen, sondern auch mal auf andere zu hören. Oder wie war das bei dir in der Schule? Machen wir es mal so: du hilfst ihm und zeigst ihm den Weg, dass er seinen Wunsch erfüllen kann. Thomas G. schrieb: > woraufhin ein einzelner Puls mit 10.8695Hz folgt. Einzelne Pulse haben im Grunde keine Frequenz, denn "Frequenz" heißt "Häufigkeit" und 1x ist nicht häufig.
Gast
#7081691
> von W.S. (Gast) 30.05.2022 12:46 > Du solltest dringend mal nachlesen, wie ein DDS funktioniert. Das weiß der Falk /sehr genau./ Hier ein präziser Einkanal-Frequenzgenerator z.B. für einen UNO oder Nano (so genau der 16bit-Timer halt geht): Ursprünglich verwendete ich die timerOne-Library, die ist aber ungenau, da sie nur in Mikrosekunden rechnet, und das nicht einmal genau, da sie als Quarzfrequenz nur Mehrfache von 2 MHz "zulässt".
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
MisterX schrieb: > Hier ein präziser Einkanal-Frequenzgenerator z.B. für einen UNO oder > Nano (so genau der 16bit-Timer halt geht): Naja, ob DAS ein mustergültiges Beispiel ist, wage ich zu bezweifeln.
Gast
#7081738
> Ja, "auf eine Referenzfrequenz". Und woher kommt die? Hat die auch eine "Genauigkeit" von 0,0%? Fuer ein mehrkanaliges Stroboskop kann die genaue Einhaltung der Verhaeltnisse wichtiger sein, als ein absolut genauer Wert. Wenn man sich z.B. Zahnraduebersetzungen ansehen will. Zweifelhaft bleibt mir da nur, warum es gerade ganzzahlige Vielfache von 1 sein muessen. > Hach, flach. Selber flach. Der einzige eingermassen brauchbaren Vorschlag ist vom Peter. Beitrag "Re: Arduino Timerprobleme - suche programmierbaren Oszillator" Und natuerlich geht es nicht vernuenftig mit millis() und Konsorten. Weil eben die Frequenz reziprok zur Zeit ist.
Gast
#7081744
Lothar M. schrieb: > Lernen heißt aber auch, nicht jeden Fehler selber zu machen, sondern > auch mal auf andere zu hören. Meinst Du die, die ihm sagen wollen, daß er doof und unfähig sei? > Machen wir es mal so: du hilfst ihm und zeigst ihm den Weg, dass er > seinen Wunsch erfüllen kann. Oh, das hatte ich bereits getan. Oben sind Beispiele mit einem 8 Bit Timer (ATtiny25) und einem 16 Bit Timer (ATmega328) verlinkt. Letzteres nutzt beide Kanäle vom Timer1 und hat sogar eine .ino Endung. Ich könnte ihm daraus auch ein fertiges Programm zusammenkopieren, was dann aber keinen Lerneffekt hätte. Falls der TO die erzeugten Frequenzen mit einem Arduino (328) messen möchte, hätte ich auch einen Link: http://mino-elektronik.de/fmeter/fm_software.htm#bsp7 Alternativ natürlich auch mit STM32 oder RP2040 Pico-Board ;-)
Thomas G. schrieb: > Ich möchte Frequenzen bis 30Hz mit 2 Nachkommastellen wählen können. Also 0,00 bis 30,00Hz oder auch 0 bis 3000 CentiHz. Wenn du jetzt unsgined-Integer-Zähler mit 32 Bit aufsetzt, der jede alle 100µs inkrementiert wird, dann hast du bei 30Hz einen Jitter von 3%. Wenn da reicht, dann musst du einen Interrupt erzeugen, der alle 100µs kommt und darin für jede LED einen 32-Bit-Zähler hochzählen. Und zwar addierst du dann pro Schritt einen Increment-Wert von 2^32 / (3000 x WunschfrequenzInCentiHz) auf. Nach einer Formelumstellung ergibt das Inc = cHz x 1431656. Wenn du also 20,00 Hz willst, dann musst du einfach in der 100µs-Interruptroutine einen Wert von 2000 x 1431656 = 2863312000 aufaddieren. Wenn du nur 19,99 Hz willst, dann musst du etwas weniger, nämlich 1999 x 1431656 = 2861880344 aufaddieren. Und von jedem dieser 32-Bit-Zähler nimmst du das LSB und gibts es auf die jeweilige LED aus. Damit kannst du deine Wunschfrequenz bis auf 7 Nachkommastellen genau erzeugen. So genau und stabil muss erst mal der verwendete Quarz sein. Wenn du keinen 100µs Interrupt hinbekommst, dann musst du "nur" den Faktor 1431656 so ändern, dass der berechnete Increment-Wert wieder zur gewünschten Frequenz führt.
Etwas weniger Prosa, dafür mehr Quelltext. AVR - Die genaue Sekunde / RTC
Gast
#7081863
Lothar M. schrieb: > dann hast du bei 30Hz einen Jitter von 3%. Na das ist heftig! Für eine Stroboskope-Anwendung wohl ein wenig zu viel. Auch sind 50% Tastverhältnis wohl nicht so zündend. Das müßte auch noch einstellbar sein. Mit der Arduino-Hardware bekommt man eine jitterfreie Auflösung von 62,5 ns. Warum soll man darauf verzichten?
Gast
#7081887
Klassikradio schrieb: > Der einzige eingermassen brauchbaren Vorschlag ist vom Peter. > Beitrag "Re: Arduino Timerprobleme - suche programmierbaren Oszillator" Unsinn. Nicht der Vorschlag von Peter, sondern deine schwachsinnige Behauptung, dass es der einzige einigermaßen brauchbare Vorschlag wäre. Denn hier im Thread, als vierte Antwort, wurde das Prinzip bereits erstmals erwähnt (wenn auch nur am Rande): Beitrag "Re: Arduino Timerprobleme - suche programmierbaren Oszillator" Ein weiteres Mal hier (sogar mit Link auf einen länglichen Thread zum prinzipiell gleichen Thema, incl. fertiger Lösung für einen Kanal): Beitrag "Re: Arduino Timerprobleme - suche programmierbaren Oszillator"
m.n. schrieb: > Lothar M. schrieb: >> dann hast du bei 30Hz einen Jitter von 3%. > > Na das ist heftig! > Für eine Stroboskope-Anwendung wohl ein wenig zu viel. Das glaube ich nicht, schon gar nicht bei der Anwendung des OP. Der hat mal sich KEINE Super-Duper Anforderungen an den Jitter. Also nicht real, bestenfalls gefühlt. > Mit der Arduino-Hardware bekommt man eine jitterfreie Auflösung von 62,5 > ns. Warum soll man darauf verzichten? Weils hier nicht nötig ist? Das Problem des OP liegt auf einer deutlich höheren Ebene. OSI Layer 8.
Gast
#7081968
Thomas G. schrieb: > it der > if (currentMillis - previousMillis >= interval) { > // save the last time you blinked the LED > previousMillis = currentMillis; > > Option driftet mein Intervall immer in gewissen abständen 1ms weg. > > Mit > if (currentMillis - previousMillis >= interval) { > // save the last time you blinked the LED > previousMillis = previousMillis + interval; Deckenleuchte schrieb: > Ich halte es für erwähnenswert Noch immer halte ich das für erwähnenswert!
Gast
#7081970
Lothar M. schrieb: > Ja, "auf eine Referenzfrequenz". Und woher kommt die? Hat die auch eine > "Genauigkeit" von 0,0%? Versuchen wir doch mal einen ernsthaften Überschlag: Wenn der Thomas irgend etwas per Stroboskop anschauen will, dann vermutlichst deshalb, weil es für's bloße Auge zu schnell, aber für stroboskopisches Betrachten (das Auge als Sampler...) noch nicht zu schnell ist. Also ich tippe mal auf so etwa 500..2000 rpm. Das Stroboskop muß abstimmbar sein, weil man es für ein so einigermaßen stehendes Bild an die Bewegunng des Prüflings anpassen muß. Nehmen wir also mal irgendwas in der Mitte, also z.B. 1000 rpm. Wenn da das Stroboskop um 1% frequenzmäßig daneben liegt, dann dreht sich das virtuelle Bild mit 10 rpm, also 1x in 6 Sekunden. Naja, ein stehendes Bild ist was anderes, aber 1 Umdrehung in 6 Sekunden kann man als Bastler noch aushalten. Ich denke mal, Abweichungen von 1% sind die obere Grenze des Zumutbaren. Und ob sich das Bild nun in 5 Minuten einmal um sich selbst dreht, sollte egal sein, also wäre die untere Grenze so etwa im Bereich von 0.02 %. Genauer braucht's nicht zu sein. Bei so etwa 1000 rpm liegt die Periode bei etwa 60 ms und ne Abweichung von 1% davon liegt bei 600 µs was damit die obere Grenze ist für die Ungenauigkeit. Und besser als 12µs braucht man nicht zu sein. So, da haben wir erstmal ne grobe Abschätzung. Nochwas zum Verfahren: Wenn besagte LED's so eine Art Folgeblitz sein sollen, dann reicht es aus, wenn man sie mit einem gewissen zeitlichen Abstand von der ersten LED einschaltet. Vier separate Timer braucht es da überhaupt nicht. Insofern sind alle Überlegungen zum Davonlaufen von Phase usw. überflüssig. W.S.
Gast
#7081992
W.S. schrieb: > Nochwas zum Verfahren: Wenn besagte LED's so eine Art Folgeblitz sein > sollen, dann reicht es aus, wenn man sie mit einem gewissen zeitlichen > Abstand von der ersten LED einschaltet. Vier separate Timer braucht es > da überhaupt nicht. Insofern sind alle Überlegungen zum Davonlaufen von > Phase usw. überflüssig. So isses. Wie sich die Einlassungen des TO insgesamt so lesen, soll da wohl eigentlich ein Motor betrachtet werden und zwar ein Vierzylinder. Wenn das so ist, sollte man sein Augenmerk eher darauf richten, die Messung mit dem Messobjekt zu synchronisieren, statt sie freilaufend zu realisieren. Dann gibt's erstmal kein "Fortlaufen" des Bilds. Der Rest sind dann keine vier Frequenzen, sondern eine in vier einstellbaren Phasenlagen.
Gast
#7081998
Thomas G. schrieb: > Ich suche eine Komponente, mit der ich stabile Frequenzen im Bereich von > 1Hz bis 100Hz darstellen kann. Thomas G. schrieb: > Ich möchte Frequenzen bis 30Hz mit 2 Nachkommastellen wählen können. Die Periodendauer der Signale sollten ganzzahlige Vielfache des Basistaktes sein. Sonst wird es schwierig.
Thomas G. schrieb: > Bei meinen aufblinkenden LEDs handelt es sich um ein Stroboskop. Alle > LEDs greifen auf den selben Timer zu, haben unterschiedliche Startpunkte > im Intervall, in dem sie sozusagen synchronisieren. Nach einem > Intervalldurchlauf haben die LEDs nämlich gleiche Schaltzeiten, im 4er > Modus haben sie 2 unterschiedliche Schaltzeiten. Zur Verbildlichung, > nach Intervall 1 schaltet die LED 1 ein und LED 3 aus, im zweiten > Intervall schaltet 3 ein und 1 aus. mit 2 Intervallen komme ich so auf > eine Vierteilung der Frequenz. Textuelle Beschreibungen von Timingabläufen sind immer schlecht. Zeichne das doch mal auf. Und zeichne auch mal diese unterschiedlichen "Modi" da mit ein...
c-hater schrieb: > So isses. Wie sich die Einlassungen des TO insgesamt so lesen, soll da > wohl eigentlich ein Motor betrachtet werden und zwar ein Vierzylinder. Man könnte das Spekulieren auch einfach mal sein lassen und den TO um eine gescheite Auskunft bitten. Wenn die nicht kommt, geht's halt nicht weiter.
Gast
#7082037
m.n. schrieb: > Man kann zwar die Arduino-IDE verwenden, sollte aber tunlichst setup() > und loop() vermeiden, damit man alle Timer selbst benutzen kann. Wieso soll man für vier LEDs mehr als zwei Timer benötigen?
Gast
#7082057
Wolfgang schrieb: > Wieso soll man für vier LEDs mehr als zwei Timer benötigen? Das frage ich mich auch. Ich denke, es ist alles gesagt. Man muß es nur lesen.
m.n. schrieb: > Ich denke, es ist alles gesagt. Man muß es nur lesen. Das sehe ich ganz anders. Mir fallen noch drölfzig Dinge ein, die noch nicht gesagt wurden. Nur ein Beispiel: Soll es wirklich so sein, daß ein Vierzylindermotor beobachtet werden soll, sind zwei Hallsensoren an des Kurbelwelle die einfachste Lösung, um das Timergeraffel zu umgehen. Also allgemein: soll ein externes Gerät einsynchronisiert werden, ist ein Positionssensor an diesem Gerät eine einfache Lösung. Oder: Statt ArduinoIDE AtmelStudio verwenden, da hat weniger Probleme mit den Seiteneffekten von Libraryroutinen. Da der TO aber die unwichtigsten Kleinigkeiten > Frequenz von 10.989Hz für ca 1.365 Sekunden, woraufhin ein einzelner Puls > mit 10.8695Hz folgt. Das ganze wiederholt sich zyklisch. mit akribischer Genauigkeit darstellt, die wichtigen Aussagen aber nur in homöopathischen Dosen rausrückt, können wir alle unserer Liblingsbeschäftigung Spekulation mit Begeisterung nachkommen. Vielleicht will er ja nur seine LEDstreifen-Treppenbeleuchtung so programmieren, daß eventuell eintreffende Außerirdische ein geheimes Willkommenssignal damit gesendet bekommen. Nach meiner Vermutung (Spekulation!) ist schon die Eingangsfestlegung (Frequenz je nach Wetterlage bis 30Hz oder 100Hz auf 2 Nachkommastellen einstellbar) dem zu bearbeitenden Problem total unangemessen, aber der TO "will" es so und verfollgt diesen Weg mit Begeisterung. Unzählige Menschen haben schon versucht, aus Blei Gold zu machen oder endlich das perpetuum mobile zu erfinden, warum denn nicht? Besser als mit dem Porsche Rennen in der Stadt zu veranstalten und Fußgänger umzunieten. Gruß Klaus (der soundsovielte)
Gast
#7082587
Hier das gewünschte Programm mit 4 Kanal-DDS: 4 Outputs auf PB5 .. PB2, auf PB1 zum Test die DDS-Frequenz 31250 Hz Hänge mal einen Lautsprecher an PB5 (D13)... chromatische Tonleiter 220 - 440 Hz D12 - D10 ändern anfangs (nach jedem Durchlauf der Tonleiter) ihre Frequenz um -1,5, +1,5 und 2,0 Hz, just for fun, damit sich was ändert Man müsste noch eine serielle Kommunikation dazuprogrammieren, um die Frequenzen on the fly einstellen zu können.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
MisterX schrieb: > while(1){ > cli();if(t3.ub[3]&128)PORTB|=32;else PORTB&=~32;sei(); > cli();if(t2.ub[3]&128)PORTB|=16;else PORTB&=~16;sei();cnt++; > cli();if(t1.ub[3]&128)PORTB|= 8;else PORTB&=~ 8;sei(); > cli();if(t0.ub[3]&128)PORTB|= 4;else PORTB&=~ 4;sei(); Eine Sequenz sei(); cli(); ist wirkungslos, da nach dem SEI noch einen Befehl lang alle Interrupts gesperrt sind, ein CLI aber sofort greift. Dieses Verhalten ist z.B. wichtig für den Sleep-Mode, damit garantiert ein Interrupt nicht schon vor dem Sleep-Befehl erfolgt.
Gast
#7082609
Peter D. schrieb: > Eine Sequenz sei(); cli(); ist wirkungslos, da nach dem SEI noch einen > Befehl lang alle Interrupts gesperrt sind, ein CLI aber sofort greift. "Again what learned" hätt' da Loddar g'sacht, gell ....
Gast
#7082619
Einfach das Programm kopieren (Strg+C) und in die Arduino-IDE pasten
(Strg+V).
Braucht kein Framework, also setup() und loop() sind überflüssig.
Strg+U und los geht's
CPU-Auslastung ist messbar mit
DDRB = 32+16+8+4+2+1;PORTB = 0xFE;
und
ISR(TIMER1_OVF_vect){
PINB=1;t0.ul+=t0add;t1.ul+=t1add;t2.ul+=t2add;t3.ul+=t3add;PINB=1;}
ergibt bei mir 1,1V am Anschluss 8, d.h. nur 22% Auslastung.
Man könnte mit der IRQ-Frequenz noch höher gehen.
Ich habe den Teiler testweise mit 256 (31250 Hz @ 16MHz) gemacht, d.h.
man könnte auch einen 8-bit-Timer (Timer2) verwenden.
Die Frequenzauflösung ist jenseits von Gut und Böse: 7,27368 µHz
Der Frequenzbereich ebenfalls, 1kHz ist kein Problem, jittert aber schon
merklich.
Wichtig ist, dass die 4 Kanäle phasenstarr miteinander verbunden sind.
Nebenbei, es ist schon interessant, welche Anwendung (4-Zylinder-Motor)
hier ohne jeglichen Hintergrund vermutet wird.
Der Threadopener könnte ja mal etwas zur Anwendung sagen, vielleicht ist
es ja auch ganz was anderes.
Gast
#7082630
> Eine Sequenz sei(); cli(); ist wirkungslos,
Stimmt, daher habe ich den cnt++ dazwischen reingesetzt, nachdem ich
mich am Anfang des Programmierens (als die cnt-Geschichte noch nicht
dastand) wunderte, dass plötzlich gar nichts mehr ging.
Also kann man die CPU-Last und den Jitter noch um ein paar Promille
reduzieren:1 | |
2 | |
3 | |
4 | |
5 | |
oder
1 | |
2 | |
3 | |
4 | |
5 | |
Hallo, sollte das nicht 16000000UL lauten?
1 | |
Gast
#7082848
Veit D. schrieb: > sollte das nicht 16000000UL lauten? Wer Quelltext-Kommentare lesen und verstehen kann ist klar im Vorteil. // F_CPU is the frequency of MY arduino uno, change this number for YOUR board
Gast
#7082926
Das liegt an der ... timerone-Lib (timerone.h). Die glaubt nämlich, wenn ich eine Quarzfrequenz geringfügig kleiner als 16MHz eingebe, der Quarz hätte 14MHz und berechnet dann alle Faktoren falsch. Schuld ist diese Zeile: const unsigned long cycles = (F_CPU / 2000000) * microseconds; Fällt natürlich nicht auf, da so gut wie immer 16MHz verwendet wird. Ich will aber wirklich die vorhandene Oszillator-Frequenz eingeben können, damit auch die richtige Frequenzen an den 4 Ausgängen herauskommen. Daher hatte ich zuerst die Lib lokal geändert, hat auch funktioniert. const unsigned long cycles = round(F_CPU / 2000000.0 * microseconds); Dann kam mir aber die Idee, dass ich das Dilemma umgehen kann, wenn ich die Frequenz in Float (xx.0) angebe, die Lib gezwungen ist, alle Folgeberechnungen in Float und damit richtig (ohne Abschneiden der Nachkommastellen) zu berechnen. Diese Berechnungen finden nicht auf dem UNO, sondern zur Compilezeit im PC statt, da es sich um Konstanten handelt. Daher verwenden die späteren Versionen die Lib gar nicht mehr, auch weil über den Umweg, die Ticks über ganzzahlige Mikrosekunden zu berechen, Genauigkeit verloren geht. Hat schon jemand das Programm getestet? Insgesamt bin ich schon froh, soetwas in C programmieren zu können, auf der anderen Seite habe ich das Assembler-Listing angesehen und bin erschrocken, wie ineffektiv (teilweise!) der Compiler das übersetzt. Da kann ich jeden Asm-Fan (und c-hater ;-) verstehen. In der ISR werden 10 Register (+Statusregister) auf dem Stack gesichert und dann wieder zurückgeholt, nur weil der Compiler zu doof ist, alle 4 Bytes der 32-bit-Variablen mit einem Register zu addieren. Oh oh. So könnte man die ISR statt in 8µs leicht in unter 7µs erledigen. Bei 32µs Zykluszeit eine Einsparung von 14%, die man besser in eine höhere Abtastrate stecken könnte. Bei den heutigen Preisen von 32bit-Hardware sollte man sich eigentlich nicht mehr mit dem umständlichen 8bit-Kram abgeben. Aber er liegt überall herum...
Die Spekulationen sind sehr interessant, aber einen Motor möchte ich hier nicht betreiben. Es bleibt ein normales Stroboskop, das die Frequenzen genauestens einhalten soll. Was den Timer1 angeht, scheint es mir so als müsste ich ihn initialisieren und dann bereits vorgefertigt einstellen. Mit den Registern die Parameter auswählen, dann die Zeiten ausrechnen und quasi im Bottom to Top loop laufen lassen. Kann ich den Timer mit dem Programm im Nachhinein die Top-Werte ausrechnen lassen? Bisher habe ich gedacht ich kann einfach den Timer, der für das hochzählen in den millis() zuständig ist von einer 8 bit, auf eine 16 bit Auflösung ändern. Das es sich als so kompliziert herausstellt hätte ich auch nicht erwartet. Vorhin habe ich noch kurz die Specs vom Arduino mit dem raspberry pi Pico verglichen - der ist dem Uno ja haushoch überlegen. An sich müsste der Arduino mit seinen 16MHz doch trotzdem meinen Anforderungen gerecht werden oder bin ich da zu grün hinter den Ohren?
Gast
#7083008
Thomas G. schrieb: > Die Spekulationen sind sehr interessant, aber einen Motor möchte ich > hier nicht betreiben. Es bleibt ein normales Stroboskop, das die > Frequenzen genauestens einhalten soll. Kommt mir sehr komisch vor. Mir fällt nämlich keine Anwendung für ein solches Stroboskop ein. > Vorhin habe ich noch kurz die Specs vom Arduino mit dem > raspberry pi Pico verglichen - der ist dem Uno ja haushoch überlegen. Ach echt? 16MHz vs. 125Mhz, 2kB RAM vs. 264kB RAM, 1x 8Bit-Core vs. 2x 32Bit-Core (+8 PIO-Statemachines & DMA-Fähigkeit). Also wen da eine gewisse Überlegenheit überrascht... Tss... > An > sich müsste der Arduino mit seinen 16MHz doch trotzdem meinen > Anforderungen gerecht werden oder bin ich da zu grün hinter den Ohren? Ja und ja. Genau das ist das Problem: die Hardware des UNO könnte noch relativ problemlos leisten, was du willst. Du musst nur das Arduino-Geraffel weglassen und anfangen, Datenblätter zu lesen und richtig zu programmieren.
Gast
#7083015
MisterX schrieb:
1 | |
2 | |
3 | |
4 | |
> > ... auf der anderen Seite habe ich das Assembler-Listing angesehen > und bin erschrocken, wie ineffektiv (teilweise!) der Compiler das > übersetzt Mach's halt so:
1 | |
2 | |
3 | |
4 | |
Der dafür erzeugte Assemblercode:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
Gast
#7083023
MisterX schrieb:> if(t3.ub[3]&128)PORTB|=32;else PORTB&=~32; > if(t2.ub[3]&128)PORTB|=16;else PORTB&=~16; > if(t1.ub[3]&128)PORTB|= 8;else PORTB&=~ 8; > if(t0.ub[3]&128)PORTB|= 4;else PORTB&=~ 4; Die Abfragenn können nie wahr werden, weil die "interessanten" Bits ausmaksiert werden.
Thomas G. schrieb: > Die Spekulationen sind sehr interessant, aber einen Motor möchte ich > hier nicht betreiben. Es bleibt ein normales Stroboskop, das die > Frequenzen genauestens einhalten soll. Genauer als deine Taktquelle wird es nicht. Ein 08/15 Quarz hat vielleicht 30ppm Fehler. Reicht das? Die verschiedenen, per Software und DDS erzeugten Frequenzen haben ZUEINANDER 0 Fehler, wenn man es richtig macht. > Was den Timer1 angeht, scheint es mir so als müsste ich ihn > initialisieren und dann bereits vorgefertigt einstellen. > Mit den Registern die Parameter auswählen, dann die Zeiten ausrechnen > und quasi im Bottom to Top loop laufen lassen. So in etwa, auch wenn eine mehrkanalige DDS anders funktioniert. > Kann ich den Timer mit dem Programm im Nachhinein die Top-Werte > ausrechnen lassen? Bisher habe ich gedacht ich kann einfach den Timer, > der für das hochzählen in den millis() zuständig ist von einer 8 bit, > auf eine 16 bit Auflösung ändern. Nö. > Das es sich als so kompliziert herausstellt hätte ich auch nicht > erwartet. Was hast du denn erwartet? Daß dir gebratene Tauben in den Mund fliegen? > Vorhin habe ich noch kurz die Specs vom Arduino mit dem > raspberry pi Pico verglichen - der ist dem Uno ja haushoch überlegen. Ja und? "Everything is easy with the right tool. But a fool with a tool is still a fool." > An > sich müsste der Arduino mit seinen 16MHz doch trotzdem meinen > Anforderungen gerecht werden Sicher. > oder bin ich da zu grün hinter den Ohren? Das bist du.
Gast
#7083046
>> An >> sich müsste der Arduino mit seinen 16MHz doch trotzdem meinen >> Anforderungen gerecht werden oder bin ich da zu grün hinter den Ohren? c-hater schrieb: >Ja und ja. Genau das ist das Problem: die Hardware des UNO könnte noch >relativ problemlos leisten, was du willst. Du musst nur das >Arduino-Geraffel weglassen und anfangen, Datenblätter zu lesen und >richtig zu programmieren. Nö, muss er nicht. Das hängt alles von der Fähgikeiten ab, mit C umgehen zu können. Ich vermute, dir fehlt da ein wenig die notwendige Erfahrung.
Gast
#7083070
Gerd schrieb: > Nö, muss er nicht. Das hängt alles von der Fähgikeiten ab, mit C umgehen > zu können. Na das ist ja mal spannend. Was kann C, was es möglich machen könnte, die Hardware für eine gegebene Anwendung optimal zu nutzen, ohne sie im Detail zu kennen? Also, ich kenne diesen C-Dreck seit nunmehr 40 Jahren, aber eine derartige Fähigkeit ist mir in der gesamten Zeit NIEMALS aufgefallen. Was mir allerdings nur zu oft aufgefallen ist: Wenn man C benutzt, hat man bei der optimalen Nutzung einer gegebenen Hardware immer wieder mit Restriktionen zu kämpfen, die es ohne C schlicht nicht gäbe.
Gast
#7083082
c-hater schrieb: > diesen C-Dreck Die alte Leier, wir können es nicht mehr hören. Wenn jemand diese Aufgabe nicht lösen kann, dann liegt es ganz sicher nicht an C. Wenn du das nur in Assembler hin bekommst, dann hast du ein ernsthaftes Problem. Der einzige, der gegen C kämpft bist du. Alle anderen arbeiten damit, oder mit etwas anderem. Diese Spinnerei von dir wird von Monat zu Monat schlimmer.
Gast
#7083105
Stefan ⛄ F. schrieb: > Wenn jemand diese Aufgabe nicht lösen kann, dann liegt es ganz sicher > nicht an C. Im konkreten Fall nicht, da gebe ich dir vollkommen Recht. Allerdings: ICH habe auch zu keinem Zeitpunkt behauptet, das hier C das Problem wäre... Wenn du auch nur LESEN könntest, wäre dir das klar. Aber: kannst du offensichtlich nicht. Nichtmal das...
Gast
#7083107
c-hater schrieb: > ICH habe auch zu keinem Zeitpunkt behauptet, das hier C > das Problem wäre... Du hättest Politiker werden sollen.
Gast
#7083113
> von foobar (Gast) 31.05.2022 18:33
VIELEN Dank, dass Du Dich da reingefuxt hast!
Hab es gleich implementiert. Funktioniert!
20 Bytes kürzer und schneller. Man muss nur die richtigen Tricks kennen.
Wie erzeugst Du das ASM-Listing?
ich mache es mit
"c:\Program Files (x86)\Arduino\hardware\tools\avr\avr\bin\objdump.exe"
-d -S genaueFreq.ino.elf >genFre.lst
schaut aber nicht so schön aus wie Deines
Damit das elf-File erhalten bleibt, muss man in
C:\Users\xxx\AppData\Local\Arduino15\preferences.txt
einen Eintrag ähnlich save-temps ?? oder keep-temps ?? machen, müßte ich
nachschauen.
So lernt jeder vom anderen. Geben und nehmen. Nur so funktioniert es.
Deshalb habe ich diesen Code entwickelt und veröffentlicht.
Gast
#7083127
> von STK500-Besitzer (Gast) 31.05.2022 18:42 > Die Abfragenn können nie wahr werden, weil die "interessanten" > Bits ausmaksiert werden. ?!? Es gibt pro Zeile ein interessantes Bit, und das ist bit7 (MSB) des höchstwertigen Bytes byte3 des jeweiligen Phasenakkumulators t_. (ich hätte ihn anderes benennen sollen, pa_ oder a_). Und das wird nicht ausmaskiert, sondern ausgewertet.
Ich war dann mal wieder so frei, das mal schnell zu demonstrieren. Siehe Anhang. Einmal mit 10, 20, 30, 40Hz, dann mit 10Hz und 0, 90, 180 und 270 Grad Phasenverschiebung. Viel Spaß.
Gast
#7083181
> Wie erzeugst Du das ASM-Listing?
Einfach mit gcc -S:1 | |
Kannst auch noch ein -fverbose-asm dazupacken.
MisterX schrieb: > So lernt jeder vom anderen. Geben und nehmen. Nur so funktioniert es. > Deshalb habe ich diesen Code entwickelt und veröffentlicht. Naja, aber dein Code ist arg chaotisch und schwer lesbar, kein gutes Lehrbeispiel.
Gast
#7083499
MisterX schrieb: > So lernt jeder vom anderen. Geben und nehmen. Nur so funktioniert es. > Deshalb habe ich diesen Code entwickelt und veröffentlicht. Schön, daß Du es gemacht hast. Es ist aber auch eine "selektive" Lösung, da das Tastverhältnis nicht auf kurzen Blitz einstellbar ist. Das ist für ein Stroboskop unabdingbar. Es wird auch dadurch nicht besser, daß einige Anwender durch Umdefinition der Anforderungen eine nachlässige Lösung als ausreichend anbieten. Thomas G. schrieb: > Vorhin habe ich noch kurz die Specs vom Arduino mit dem > raspberry pi Pico verglichen - der ist dem Uno ja haushoch überlegen. Als Anfänger solltest Du die Finger von dem Pico lassen, wenn Du schon Probleme mit einem AVR8 hast.
Gast
#7083508
MisterX schrieb: > Es gibt pro Zeile ein interessantes Bit, und das ist bit7 (MSB) des > höchstwertigen Bytes byte3 des jeweiligen Phasenakkumulators t_. > (ich hätte ihn anderes benennen sollen, pa_ oder a_). > Und das wird nicht ausmaskiert, sondern ausgewertet. Mein Fehler. Aber: Leerzeichen, Tabulatoren und Absätze erhöhen die Lesbarkeit. Ansonsten könnte man in diesem Fall auch statt einer if-Abfrage "?:" verwenden.
Falk B. schrieb: > Die verschiedenen, per Software und DDS erzeugten Frequenzen haben > ZUEINANDER 0 Fehler, wenn man es richtig macht. Das hatte ich auch so heraus gelesen. Es ging nie um eine hohe absolute Genauigkeit, sondern nur darum, daß sich die Fehler nicht akkumulieren und die Signale auseinander laufen. Man könnte der AVR also auch gut mit seinem internen 8MHz RC-Oszillator laufen lassen und der OP wäre glücklich. Ich sehe auch nirgends die Anforderung, daß ein Parameterwechsel besonders oft oder schnell erfolgen muß. Man kann also neue Frequenzen bequem über die langsame UART hinschicken, parsen und die neuen Parameter berechnen lassen. Ist das erfolgt, switcht man die Ausgabe einfach auf den neuen Parametersatz um.
Gast
#7083530
m.n. schrieb: > Als Anfänger solltest Du die Finger von dem Pico lassen, wenn Du schon > Probleme mit einem AVR8 hast. Da stimme ich zu… … außer wenn er (als ausgewiesener Anfänger) ein microPython drauf schiebt. (Tastendruck, UF2 drag'n'drop, fertig) Dann hätte er (ein wenig Python Grundwissen vorausgesetzt) das Programm schon lange fertig, ohne Interrupts, Assembler, usw. Denn ein ganzer Sack voller PWM-Slices (8) stehen zur Verfügung, müssen nur einmal initialisiert werden, dann läuft das Ding ganz ohne CPU Interaktion. Rein in Hardware. Der CPU-Kern muss nichts tun. (Der andere auch nicht.) Gut, ein Nachteil wäre das er nun nicht nur vier sondern acht unabhängige Kanäle hätte. Ein weiterer Nachteil, das Board ist mit sub-4€ preiswerter als so ziemlich alle Arduino Boards. Decisions, decisions…
Gast
#7083552
Norbert schrieb: > Denn ein ganzer Sack voller PWM-Slices (8) stehen zur Verfügung, müssen > nur einmal initialisiert werden, dann läuft das Ding ganz ohne CPU > Interaktion. Rein in Hardware. Das sagt sich immer so leicht und jedesmal, wenn ich den konkreten Code dazu sehen will, wird gekniffen ;-) Da die PWM-Kanäle doch recht bescheidene Funktion bieten, wäre meine Lösung die Verwendung der PIOs, wenn man hohe Auflösung und lange Zeiten braucht. Aber, um eine SM ein Signal erzeugen zu lassen, muß man sich zunächst damit auskennen und die passenden x-/y-Register wohl per DMA nachladen. Das wäre eine kurze, saubere Lösung und - wie gesagt - ein Selbstläufer, aber nichts für einen Anfänger. Solange hier aber Zittersignale mit 50% Tastverhältnis als DIE Lösung gehandelt werden, muß man nicht einmal Code für die AVR-Timer andenken.
Gast
#7083567
m.n. schrieb: > Norbert schrieb: >> Denn ein ganzer Sack voller PWM-Slices (8) stehen zur Verfügung, müssen >> nur einmal initialisiert werden, dann läuft das Ding ganz ohne CPU >> Interaktion. Rein in Hardware. > > Das sagt sich immer so leicht und jedesmal, wenn ich den konkreten Code > dazu sehen will, wird gekniffen ;-) > Da die PWM-Kanäle doch recht bescheidene Funktion bieten, wäre meine > Lösung die Verwendung der PIOs, wenn man hohe Auflösung und lange Zeiten > braucht. Aber, um eine SM ein Signal erzeugen zu lassen, muß man sich > zunächst damit auskennen und die passenden x-/y-Register wohl per DMA > nachladen. > Das wäre eine kurze, saubere Lösung und - wie gesagt - ein Selbstläufer, > aber nichts für einen Anfänger. > > Solange hier aber Zittersignale mit 50% Tastverhältnis als DIE Lösung > gehandelt werden, muß man nicht einmal Code für die AVR-Timer andenken. Nö, das sagt sich nicht leicht, das iss so.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
Das ist jetzt völlig ohne Jitter, aber manche Frequenzen sind nicht präzise zu erreichen. Im genannten Frequenzbereich 1…30Hz liegen wir teilweise mehrere 10µHz daneben. Wenn man nun den divfrac hinzunimmt, dann gibt es 16-fach feinere Auflösung, aber dafür extrem geringen Jitter im ns Bereich. Gern geschehen. ;-)
Gast
#7083570
Ups, Zeile 24 muss natürlich ccvalue schreiben!
Gast
#7083580
Stefan ⛄ F. schrieb: > Der einzige, der gegen C kämpft bist du. Alle anderen arbeiten damit, > oder mit etwas anderem. Diese Spinnerei von dir wird von Monat zu Monat > schlimmer. Also, polemisiere du mal nicht gar so sehr. Dabei kommt schlußendlich nur eines heraus: daß du außer C nix anderes kannst und deshalb gegen alle Leute wetterst, die auch andere Programmiersprachen können. Mal zur Sachlage: sogenannte 'höhere' Programiersprachen sind dazu da, daß man sich damit auf Dinge konzentrieren kann, die keinen Bezug zur verwendeten Hardware haben. Zum Beispiel wie man eine Fouriertransformation macht oder wie man eine Datenbank auswertet. Dabei bleiben selbstverständlich viele Möglichkeiten ungenutzt, die die verwendete Hardware bietet. Eben deshalb gibt es an vielen Stellen bessere Lösungen für bestimmte Details, als so etwas in einer 'höheren' Programmiersprache formulieren zu wollen. Ich geb dir mal ein simples Beispiel anhand eines Details bei der FFT: versuche mal, einen 8 bittigen Index zu spiegeln, also Bit 7 mit Bit 0 tauschen, dann Bit 6 mit Bit 1 und so weiter, bis alle Bits getauscht sind. Und das in C. Sowas in Assembler ist vergleichsweise elegant und braucht nur wenige Maschinenbefehle. Siehste. Und nochwas: Man kann C auch nutzen und zugleich sich darüber klar sein, daß diese Programmiersprache eben nicht das Weltbeste ist, sondern allenfalls das einzige, wofür man einen passablen Compiler kriegt. Man braucht also kein C-Fan zu sein. W.S.
Gast
#7083584
m.n. schrieb: > … wäre meine > Lösung die Verwendung der PIOs, wenn man hohe Auflösung und lange Zeiten > braucht. Aber, um eine SM ein Signal erzeugen zu lassen, muß man sich > zunächst damit auskennen und die passenden x-/y-Register wohl per DMA > nachladen. Geht auch super, aber DMA ist nicht nötig. Nur FIFO. Sinngemäß:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Aber ich gebe dir Recht, PIO Programmierung ist nichts für Beginner. Neues Problem erkannt: acht Mal PWM und acht Mal PIO. Alle völlig unabhängig. Jetzt müssen wir schon 16 Pins ackern lassen wo doch nur vier gefragt waren. ;-)
Norbert schrieb: > m.n. schrieb: >> Norbert schrieb: >>> Denn ein ganzer Sack voller PWM-Slices (8) stehen zur Verfügung, müssen >>> nur einmal initialisiert werden, dann läuft das Ding ganz ohne CPU >>> Interaktion. Rein in Hardware. >> >> Das sagt sich immer so leicht und jedesmal, wenn ich den konkreten Code >> dazu sehen will, wird gekniffen ;-) > > Nö, das sagt sich nicht leicht, das iss so: Schick! LG, Sebastian
Gast
#7083625
Sebastian W. schrieb: > Schick! Danke! Geht natürlich auch noch schöner:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
Und man kann's beliebig erweitern, beste Einstellungen für gegebene Frequenz berechnen, Abweichung berechnen, usw.
Gast
#7083637
Kürzere Einschaltdauern sind leicht möglich:
1 | |
2 | |
3 | |
4 | |
Mit anderen Masken wären sogar Blinkmuster einstellbar. Die cli() und sei() sind gar nicht nötig, weil es nur 8-bit-Zugriffe sind, keine breiteren, die beim 8-Bitter eine Atomisierung erfordern würden. Während der ISR sind Interrupts ja gesperrt (falls man sie nicht explizit freigibt). Dass ich diese Abfragen in der main mache und nicht im IRQ wie Falk? Gute Frage! Ich dachte zuerst, dass die ISR möglichst kurz sein sollte. Ist aber nicht nötig, da sonst ja nichts Zeitkritisches zu tun ist. Ein kleiner Vorteil könnte Dithering sein, wenn die Ausgänge aynchron gesetzt werden. Danke an alle Beitragenden! Wieder viel gelernt.
Gast
#7083689
Norbert schrieb: > Jetzt müssen wir schon 16 Pins ackern lassen wo doch nur vier gefragt > waren. ;-) Nur bin ich mit Deinem Vorschlag noch nicht ganz zufrieden ;-) Gut, bei den PWM-Timern kann man zumindest schon mal das Tastverhältnis einstellen (PWM->CHx_CC anpassen). Der Bereich von >= 60000 erfüllt auch die Vorgaben des TO für max. 4-stellige Auflösung. Dein PIO-Programm löst die Frequenz deutlich besser auf, erzeugt aber wiederum nur 50% Tastverhältnis. Um das zu beheben, müssen x- und y-Register separat für Pulse-Pause-Zeiten verwendet werden. Da es so kein freies temp-Register gibt, müssen beide Werte zyklisch per DMA nachgeladen werden. Dies läuft dann natürlich sehr elegant, die Auflösung der Impulse kann selbst bei schlapper 100 MHz Taktfrequenz auf 10 ns genau erzeugt werden und es wäre eine universelle Lösung auch für höhere Auflösungen und Frequenzen! Damit wäre ich dann zufrieden ;-)
Gast
#7083722
m.n. schrieb: > Gut, bei den PWM-Timern kann man zumindest schon mal das Tastverhältnis > einstellen (PWM->CHx_CC anpassen). Der Bereich von >= 60000 erfüllt auch > die Vorgaben des TO für max. 4-stellige Auflösung. Auf den ersten Blick… Jedes PWM-Slice kann separat getaktet werden. Damit stehen DIV 1…255 FRAC 0…15 und TOP 0…65535 zur Verfügung. 8Bit + 4Bit + 16Bit == 28Bit Auflösung 2^28 ~= 268 Millionen mögliche Einstellungen Allein der Bereich um 1Hz…30Hz schmeißt mir hundert-tausende von Kombinationen die mit beeindruckender Präzision passen. Nur mal ein Beispiel: 16MHz ÷ 256 ÷ 2083 ergibt 30,004800768Hz 16MHz ÷ 256 ÷ 2083 ergibt 29,990403071Hz 16MHz ÷ 255 ÷ 2091 ergibt 30,007220487Hz 16MHz ÷ 255 ÷ 2092 ergibt 29,992876692Hz Lass das mal für alle möglichen Teilerkombination durchrechnen (geht auf dem pico pi ohne das er kotzen muss) Das ergibt dann schon mal eine ordentliche Hausnummer. Da nimmt man einfach die Werte mit der geringsten Abweichung (µHz). Ohne Jitter! Wenn wir dann noch FRAC dazu nehmen wird's 16 mal interessanter. Oh ja, wenn ich dann noch acht Frequenzen von der PIO generieren lasse und damit die PWMs takte… Also zB. anstatt 16MHz nur 15.999998MHz… Aber man kann's mit der Genauigkeit auch übertreiben, ab hier wird's lächerlich.
Gast
#7083726
Norbert schrieb: > Aber man kann's mit der Genauigkeit auch übertreiben, ab hier wird's > lächerlich. Das nehme ich hiermit zurück. Ist nämlich bestens geeignet um eventuelle Quarz-Abweichungen direkt mit einzumassieren. ;-)
Gast
#7083737
Norbert schrieb: > 2^28 ~= 268 Millionen mögliche Einstellungen > 16MHz ÷ 256 ÷ 2083 ergibt 30,004800768Hz > 16MHz ÷ 256 ÷ 2083 ergibt 29,990403071Hz Und welche davon ist richtig? ;-)
Gast
#7083754
Noch etwas: Norbert schrieb: > Ohne Jitter! Fraktionaler Teiler ohne Jitter? Wenn das so wäre, würde ich mir eine Rolle davon unters Kopfkissen legen.
Gast
#7083758
m.n. schrieb: > Norbert schrieb: >> 2^28 ~= 268 Millionen mögliche Einstellungen > >> 16MHz ÷ 256 ÷ 2083 ergibt 30,004800768Hz >> 16MHz ÷ 256 ÷ 2083 ergibt 29,990403071Hz > > Und welche davon ist richtig? > ;-) Ja, Tippfeuler. die erste 2082 ist natürlich eine 2082. Das sieht man doch! ;-) PS. zwischen 1Hz…30Hz gibt es 231117804 mögliche Kombinationen. Ich rechne gerad' mal alle durch, wer mag bekommt ein log. Sollte nicht so groß werden, har,har.
Gast
#7083762
Norbert schrieb: > Ja, Tippfeuler. die erste 2082 ist natürlich eine 2082. > Das sieht man doch! ;-) Oder nicht doch die 2. 2083 eine 2084?
Gast
#7083774
m.n. schrieb: > Oder nicht doch die 2. 2083 eine 2084? Irgendwann ist der Wurm drin, mach am Besten selbst… ;-) Datei wird ein paar GB groß!
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
Gast
#7083790
W.S. schrieb: > Dabei kommt schlussendlich nur eines heraus: > dass du außer C nix anderes kannst Niedlich, nur leider völlig falsch. > Und nochwas: Man kann C auch nutzen und zugleich sich darüber klar sein, > dass diese Programmiersprache eben nicht das Weltbeste ist, sondern > allenfalls das einzige, wofür man einen passablen Compiler kriegt. Man > braucht also kein C-Fan zu sein. Da stimme ich dir voll zu. Deswegen nervt mich das Gehabe vom c-hater so.
Norbert schrieb: > Irgendwann ist der Wurm drin, mach am Besten selbst… ;-) > Datei wird ein paar GB groß! Und was soll der Unsinn? Die Auflösung einer DDS kann man einfach ausrechnen, da braucht man keine GB großen Dateien. Auflösung = Fein / (Akkumulatormaximum+1)
Gast
#7083849
Falk B. schrieb: > Und was soll der Unsinn? Die Auflösung einer DDS kann man einfach > ausrechnen, da braucht man keine GB großen Dateien. > Auflösung = Fein / (Akkumulatormaximum+1) Du meine Güte. Jo! Haben wir alle verstanden. Ist auch nicht wirklich schwer. Ich entgegne da: Infinity So weit bis du davon entfernt zu verstehen um was es uns eigentlich ging. Und das ist noch überaus großzügig geschätzt. Aber schön das du etwas gesagt hast.
Gast
#7083953
Stefan ⛄ F. schrieb: > Niedlich, nur leider völlig falsch. Nana, sowas kann jeder behaupten. Das klingt für mich wie ein kindliches "DOCH". Nun ja, damit sind wir schon fast vom ursprünglichen Arduino-Problem abgekommen. Aber auch hier zeigt sich eben genau DAS, was du mit deiner Antwort unbeabsichtigt zeigst. Wenn man bislang nur fertige Arduino-Funktionen wie z.B. millis() kennengelernt hat und noch keine Gedanken über eigene Vorgehensweisen/Algorithmen gedacht hat, dann verheddert man sich eben in diesen vorgefertigten Dingen und kommt nicht zum eigentlichen Ziel. Dasselbe gilt auch für "bloß keine mir unverständlichen (magischen) Zahlen, ich benutze nur Identifier, die mir jemand anderes vorgekaut hat" - um mal ein relativ junges Thema nochmal zu nennen. W.S.
Gast
#7084081
m.n. schrieb: > Dein PIO-Programm löst die Frequenz deutlich besser auf, erzeugt aber > wiederum nur 50% Tastverhältnis. Um das zu beheben, müssen x- und > y-Register separat für Pulse-Pause-Zeiten verwendet werden. Da es so > kein freies temp-Register gibt, müssen beide Werte zyklisch per DMA > nachgeladen werden. Hat mir keine Ruhe gelassen. ;-) Ich glaube das geht trotzdem völlig ohne DMA. Zwei Statemachines agieren auf dem selben Pin. Statemachine0 bekommt die volle Periodenlänge in den FIFO gestopft Statemachine1 bekommt die Zeit für den On-Teil in den FIFO gestopft
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
SM0 ist sozusagen der Master setzt den Pin am Anfang auf High löscht das PIO-IRQ Flag für SM1 zählt herunter und hechtet zum Anfang. SM1 hängt im Lauerzustand wartet auf PIO-IRQ Freigabe läuft dann geringfügig versetzt (paar Nanosekunden) los, (xxx) zählt herunter schaltet nach On-Periode den Pin auf Low, und hechtet zum Anfang. (xxx) Alles noch'n bisschen mit [delay] abgleichen/synchronisieren und fertig. Bei schlappen 200MHz erreichen wir präzise 5ns Auflösung.
Gast
#7084197
Norbert schrieb: > Ich glaube das geht trotzdem völlig ohne DMA. > Zwei Statemachines agieren auf dem selben Pin. Das kann ja jeder, aber bei vier Kanälen wären beide PIOs voll verwurschtelt. Das gefällt mir nicht! Lieber nur eine PIO und ein Programm, mit dem alle vier SMs gleichzeitig laufen. Norbert schrieb: > Bei schlappen 200MHz erreichen wir präzise 5ns Auflösung. Und diese Auflösung gibt es eben ohne Jitter. Mir ist eine konstante Kurzzeitstabilität lieber, als eine vermeintlich auf >= acht Stellen genaue Frequenz. Der lokale 12 MHz Quarzoszillator taugt auch abgeglichen sowieso nur für max. 6-stell. Genauigkeit. W.S. schrieb: > Nun ja, damit sind wir schon fast vom ursprünglichen Arduino-Problem > abgekommen. Das war doch aber auch schon ausgereizt: 2 x Timer mit je 2 x OCRx-Ausgängen liefert beste Ergebnisse.
Gast
#7084214
von Norbert (Gast) 01.06.2022 09:44 >m.n. schrieb: >> Als Anfänger solltest Du die Finger von dem Pico lassen, wenn Du schon >> Probleme mit einem AVR8 hast. >Da stimme ich zu… Ich aber nicht. Mit dem Arduino-Framework ist das so ziemlich egal, welche Komplexität eines Prozessors darunter liegt.
W.S. schrieb: > Ich geb dir mal ein simples > Beispiel anhand eines Details bei der FFT: versuche mal, einen 8 > bittigen Index zu spiegeln, also Bit 7 mit Bit 0 tauschen, dann Bit 6 > mit Bit 1 und so weiter, bis alle Bits getauscht sind. Und das in C. > Sowas in Assembler ist vergleichsweise elegant und braucht nur wenige > Maschinenbefehle. Siehste.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
Gut genug?
Veit D. schrieb: > Gut genug? Was ist daran gut? Es funktioniert, mehr nicht. Aber es ist halt nicht sonderlich schnell. Also entweder über ne 256er Tabelle oder per Inline Assembler die Bits tauschen, macht 8 Bit Load/Store Befehle und 16 Takte auf dem AVR.
Hallo, okay, Flash hat man meistens genug zur Verfügung. Assembler ist nicht mein Fachgebiet. ;-) Ich würde dann eher zur Tabelle greifen. Habe nur gelesen das es in Assembler ein Shift mit Carry Bit gibt was dafür genutzt wird.
Gast
#7084682
Gerd schrieb: >>Da stimme ich zu… > > Ich aber nicht. Mit dem Arduino-Framework ist das so ziemlich egal, > welche Komplexität eines Prozessors darunter liegt. Darum setzen sich Autofahrer in einen A320 ('A' für Arduino) und fliegen einfach los ;-) Du kannst Dir gerne etwas zusammenklicken, was PIO und DMA benutzt. Ohne deren Funktion verstanden zu haben, wird aber nichts Brauchbares dabei herauskommen - insbesondere wenn es zeitkritisch ist. Und wenn man die Funktion verstanden hat, ist Arduino da eher im Weg. .
Gast
#7085576
>Gerd schrieb: >>>Da stimme ich zu… >> >> Ich aber nicht. Mit dem Arduino-Framework ist das so ziemlich egal, >> welche Komplexität eines Prozessors darunter liegt. >Darum setzen sich Autofahrer in einen A320 ('A' für Arduino) und fliegen >einfach los ;-) >Du kannst Dir gerne etwas zusammenklicken, was PIO und DMA benutzt. >Ohne deren Funktion verstanden zu haben, wird aber nichts Brauchbares >dabei herauskommen - insbesondere wenn es zeitkritisch ist. Ja, wird hier aber nicht gebraucht, weil das Problem auch ohne PIO und DMA mit der Geschwindigkeit des PiPico zu lösen ist. Es ist ähnlich wie sich ins Knie schießen: Kann man machen, muss man aber nicht.
Gast
#7085760
> W.S. schrieb: > versuche mal, einen 8 bittigen Index zu spiegeln, > also Bit 7 mit Bit 0 tauschen, dann Bit 6 > mit Bit 1 und so weiter, bis alle Bits getauscht sind. > Veit D. schrieb: > … C-code … > Gut genug?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
$ picorun pico_pio_bitreverse.py 10000000110000000000011100001111 11110000111000000000001100000001 32bit in 24ns Gut genug? ;-)
Norbert schrieb: > $ picorun pico_pio_bitreverse.py > 10000000110000000000011100001111 > 11110000111000000000001100000001 > > 32bit in 24ns > Gut genug? ;-) Schön. Wenn das jetzt noch bitte jemand in Assembler für AVR zeigt wäre schön. :-)
Gast
#7085944
Veit D. schrieb: > Wenn das jetzt noch bitte jemand in Assembler für > AVR zeigt wäre schön. Dem AVR fehlen die dazu nötigen Befehle - zumindest wenn es elegant werden soll. Ich brauchte das mal in einer Anwendung mit 8 Bits, dafür habe ich eine Übersetzungstabelle (array im RAM) genommen.
Stefan ⛄ F. schrieb: > Dem AVR fehlen die dazu nötigen Befehle - zumindest wenn es elegant > werden soll. Was ist an normalem Assembler unelegant? Weil es nicht mit einem Super-Duper-DSP Befehl geht? > Ich brauchte das mal in einer Anwendung mit 8 Bits, dafür > habe ich eine Übersetzungstabelle (array im RAM) genommen. Im Flash wäre es sinnvoller gewesen, der "Nachteil" des 1 extra Taktes für den Lesezugriff (lpm) wohl zu verschmerzen.
Gast
#7085959
Falk B. schrieb: > Was ist an normalem Assembler unelegant? Probiere es aus, dann siehst du es. Der Lookup mittels Tabelle ist im Schnitt mehr als 8x so schnell, wie eine Berechnung. Falk B. schrieb: > Im Flash wäre es sinnvoller gewesen, der "Nachteil" des 1 extra Taktes > für den Lesezugriff (lpm) wohl zu verschmerzen. In meinem Fall nicht, denn da kam es sehr auf Performance an. War schon scheiße genug, dass der Hersteller der Platine den Ethernet Controller "Spiegelverkehrt" angebunden hat. Sämtliche Kommunikation musste durch diesen Konverter laufen.
Gast
#7085964
Stefan ⛄ F. schrieb: > Leider ziemlich unkonkret, wie soll das dem TO helfen? Und wie machst du > damit exakt 37 Hz? Naja man könnte sich mit einem Controller beschäftigen, auf die mitgelieferten Bibliotheken weitestgehend verzichten und sich was Eigenes schreiben. Das macht Anfangs natürlich mehr Arbeit, es gibt Tiefschläge etc., aber man lernt auch so einiges und ist in Zukunft eben nicht mehr auf fertige Bibliotheken angewiesen. Und man sollte auch mal seine Anforderungen überdenken. Um ne LED blinken zu lassen braucht es ganz bestimmt keinen Quarzoszillator.
Hallo, > Dem AVR fehlen die dazu nötigen Befehle Das wusste ich nicht. Vielleicht noch ein interessanter Link für alle. Bei Bedarf. :-) https://stackoverflow.com/questions/61179846/reversing-bits-in-a-byte-with-avr Kennt ihr bestimmt schon.
Veit D. schrieb: > Norbert schrieb: >> $ picorun pico_pio_bitreverse.py >> 10000000110000000000011100001111 >> 11110000111000000000001100000001 >> >> 32bit in 24ns >> Gut genug? ;-) > > Schön. Wenn das jetzt noch bitte jemand in Assembler für AVR zeigt wäre > schön. :-) Siehe Anhang, nix besonderes.
Stefan ⛄ F. schrieb: > Falk B. schrieb: >> Was ist an normalem Assembler unelegant? > > Probiere es aus, dann siehst du es. Der Lookup mittels Tabelle ist im > Schnitt mehr als 8x so schnell, wie eine Berechnung. Das wage ich zu bezweifeln. Weder in C noch ASM. Außer man vergurkt es total. Aber das geht immer. >> Im Flash wäre es sinnvoller gewesen, der "Nachteil" des 1 extra Taktes >> für den Lesezugriff (lpm) wohl zu verschmerzen. > > In meinem Fall nicht, denn da kam es sehr auf Performance an. Kann sein, muss nicht. Denn die Leistung ist die Summer aller Bearbeitungsschritte, nicht nur der eine.
Gast
#7085993
Falk B. schrieb: > Siehe Anhang, nix besonderes. Das Gute daran ist, man braucht keine Stoppuhr um die Ausführungszeit zu bestimmen. Ein Abreißkalender reicht völlig aus. ;-)
Falk B. schrieb: > Veit D. schrieb: >> Schön. Wenn das jetzt noch bitte jemand in Assembler für AVR zeigt wäre >> schön. :-) > > Siehe Anhang, nix besonderes. Danke.
Gast
#7086125
Und hier noch ein Beitrag der Musikwissentschaften zum Thema Arduino IDE und Assembler.
Gast
#7086312
Gerd schrieb: > Und hier noch ein Beitrag der Musikwissentschaften zum Thema Arduino IDE > und Assembler. Nochmal schnell auf den Kalender geschaut: 1. April ist heute nicht, aber immerhin Freitag.
Gast
#7086571
Gerd schrieb: > Und hier noch ein Beitrag der Musikwissentschaften zum Thema > Arduino IDE und Assembler. Leider alles Makulatur: Dem TO war der ganze Tinnef zu viel und hat sich folglich vor einer Woche verpisst. Viel Spaß noch beim euphorischen Fäzes-Konfundieren - ihr schafft das schon!
Jester schrieb: > Leider alles Makulatur: Dem TO war der ganze Tinnef zu viel und hat sich > folglich vor einer Woche verpisst. Nein ich bin noch da. Die Beiträge und entstandene Diskussionen sind unterhaltsam und interessant, helfen mir bei meinem Problem nur leider nicht so sehr. Die letzten Tage hatte ich generell wenig Zeit, mich damit zu befassen. Gestern sind noch mein kleines Display und der Drehregler angekommen die ich bestellt habe. Zwar könnte ich jetzt anfangen ein Auswahl-Menü zu schreiben, stecke aber nach wie vor mit dem Zeitzähler-Problem fest.
Brauchst Du einen einstallbaren Taktgeber mit einem 50:50 Verhältnis? Oder soll pro Takt ein kurzer Impuls ausgegeben werden ?
Gast
#7087020
Thomas G. schrieb: > stecke aber nach wie vor mit dem Zeitzähler-Problem fest. Seltsam. Ich hatte den Eindruck das dein Problem sowohl für einen AVR in C/C++ als auch für einen RP2040 in Python gelöst worden wäre. Beide Male mit einer Präzision welche weit über deinen Wünschen liegt.
Gast
#7087055
Norbert schrieb: > Thomas G. schrieb: >> stecke aber nach wie vor mit dem Zeitzähler-Problem fest. > Seltsam. Ich hatte den Eindruck das dein Problem sowohl für einen AVR in > C/C++ als auch für einen RP2040 in Python gelöst worden wäre. > Beide Male mit einer Präzision welche weit über deinen Wünschen liegt. Genau. Das ist so'n typischer Blindflansch, der nur eins akzeptiert: genau die perfekte Lösung seines Problems und die muss dann auch noch so gestaltet sein, dass er sie versteht... Blöd nur, dass er absolut keine Ahnung von irgendwas hat. Das macht es einigermaßen schwierig, seine Anforderungen zu erfüllen... Wahrscheinlicher ist allerdings sowieso: Ist nur ein Traffic-Troll... D.h.: es geht überhaupt nicht um ein Problem oder eine Lösung dafür, sondern allein darum, Traffic im Forum zu erzeugen. Der Troll mag's, der Forenbetreiber mag's auch. Genau das ist das Problem. Wäre die Interessenlage des Betreibers anders, würden derzeit mindestens 95% der neuen Threads direkt gecancelt werden können. Allerdings würde das Forum dann ganz_offensichtlich genauso tot aussehen, wie es effektiv sowieso ist. Garnicht gut für die Werbeeinnahmen des Betreibers...
Thomas G. schrieb: > Nein ich bin noch da. Die Beiträge und entstandene Diskussionen sind > unterhaltsam und interessant, helfen mir bei meinem Problem nur leider > nicht so sehr. Wirklich? Oder sind nur die sinnvollen Beiträge im Rauschen des Wahnsinns untergegangen? Beitrag "Re: Arduino Timerprobleme - suche programmierbaren Oszillator"
Falk B. schrieb: > Wirklich? Oder sind nur die sinnvollen Beiträge im Rauschen des > Wahnsinns untergegangen? > > Beitrag "Re: Arduino Timerprobleme - suche programmierbaren Oszillator" Ups, ja sind sie. Danke dir :) Den Code muss ich jetzt erstmal studieren und verstehen. c-hater schrieb: > Blöd nur, dass er absolut keine Ahnung von irgendwas hat. Das macht es > einigermaßen schwierig, seine Anforderungen zu erfüllen... Sorry :) Uwe K. schrieb: > Brauchst Du einen einstallbaren Taktgeber mit einem 50:50 Verhältnis? > > Oder soll pro Takt ein kurzer Impuls ausgegeben werden ? Pro Takt soll ein kurzer Impuls ausgegeben werden. Das habe ich in meinem Code mit einem doppelten Takt realisiert, für jeden Profi hier warscheinlich viel zu umständlich
> Pro Takt soll ein kurzer Impuls ausgegeben werden.
Wieviel ist ein "kurz" in ms?
Beim Takt gehe ich von der einstellbaren Frequenz zwischen 1,00 Hz und
30.00 Hz aus. Ist 4,00 Hz bis 30,00 Hz auch OK?
Und es ist auch nur ein PIN der geschaltet wird?
Gast
#7087541
Uwe K. schrieb: > Wieviel ist ein "kurz" in ms? Das ist doch völlig wurscht! Mit einem AVR-Timer kann man separate Pulszeiten für '1' und '0' Pegel generieren und nach Bedarf einstellen. http://mino-elektronik.de/Generator/takte_impulse.htm#bsp2 Hier wird beispielsweise mit einem ATtiny4313 ein Signal mit 0,01 Hz - 50 kHz erzeugt, dessen Pulsweite im Bereich von 5 µs - 10 s mit Auflösung 50 ns per RS232 einstellbar ist. ISR(TIMER1_COMPB_vect) erledigt die Pulserzeugung.
c-hater schrieb: > Wahrscheinlicher ist allerdings sowieso: Ist nur ein Traffic-Troll... Aus meiner Sicht ist es wahrscheinlicher, dass er zu den Leuten gehört, die lieber erstmal anfangen, etwas zu machen und wenn es dann auf Anhieb nicht so klappt, Schwierigkeiten mit dem Nachdenken haben. Für einen Troll hat er m.E. schon zu viel selber gemacht. Das einen "Blindflansch" zu nennen, ist zwar nicht ganz falsch, aber menschliche Blindflansche können sich durchaus weiterentwickeln, und dazu ist das Forum auch da. Für mich sieht es eher so aus, daß sein gewählter Lösungsweg völlig überflüssig komplex ist, weil er aber gerne "macht" (Stubenfliegenmethode!) und nicht so gerne nachdenkt, kein Interesse an einer einfachen Lösung hat. Und wir haben unseren Spaß daran, entweder erratene Wege aufzuzeigen oder lästerhafte Kommentare zu schreiben. So haben wir alle was davon. Nur Lothar wendet sich mit Grausen ab, weil seine Anmerkung: "Denn die einzig relevante Frage ist nicht, was du willst, sondern was die Anwendung braucht" genüßlich von allen ignoriert wird. Gruß Klaus (der soundsovielte)
Gast
#7087596
Klaus S. schrieb: > Nur Lothar wendet sich mit Grausen ab, weil seine Anmerkung: "Denn die > einzig relevante Frage ist nicht, was du willst, sondern was die > Anwendung braucht" genüßlich von allen ignoriert wird. So isses / full ack. Denn viele Technik-Freaks laufen hier mit Scheuklappen durch die Gegend. Lieber schreiben sie hier einen hochkarätigen Lösungsvorschlag anstatt zu fragen und zu überlegen was eigent- lich erreicht werden soll. Diese Scheuklappen verhindern dass sie die wahren Bedürfnisse und Fähigkeiten eines TO zwischen den Zeilen erkennen.
m.n. schrieb: > Uwe K. schrieb: >> Wieviel ist ein "kurz" in ms? > Das ist doch völlig wurscht! Wollte die Zeit im Beispiel einstellen. Vieleicht ist das eine Möglichkeit. Ich habe es mit einem alternierenden CTC-Wert gemacht. Das geht auf +/- 0,003 Hz genau, wenn man es kalibriert. > ... anstatt zu fragen und zu überlegen was eigentlich erreicht werden soll. Man muss ihn wirklich alles aus der Nase ziehen...
Gast
#7087770
weiter weg schrieb: > Denn viele Technik-Freaks laufen hier mit Scheuklappen durch > die Gegend. Lieber schreiben sie hier einen hochkarätigen > Lösungsvorschlag anstatt zu fragen und zu überlegen was eigent- > lich erreicht werden soll. Na ja, Scheuklappen? Weiß nicht. Manchmal - gerade wenn's regnet - hat man einfach Spaß daran sich um ein Problem zu ›kümmern‹, es ›durchzudenken‹ und auf die bestmögliche Art und Weise zu lösen. Und ja, ich gehöre - wie vermutlich viele - auch zu denen. Sehe es mehr als eine Fingerübung an. Hab's gerade mal mit 5ns Auflösung gemacht. Für Kanäle 0…7. In unter neunzig Zeilen. Mit der Schlange.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
Gast
#7087782
weiter weg schrieb: > Lieber schreiben sie hier einen hochkarätigen > Lösungsvorschlag .... Ich hätte den Satz noch ergänzen sollen durch: .... der an den Bedürfnissen und Kenntnissen des TO voll vorbeigeht .... Nur um seine eigenen Fähigkeiten brillieren zu lassen.
Gast
#7087796
weiter weg schrieb: > weiter weg schrieb: >> Lieber schreiben sie hier einen hochkarätigen >> Lösungsvorschlag .... > > Ich hätte den Satz noch ergänzen sollen durch: > > .... der an den Bedürfnissen und Kenntnissen des TO > voll vorbeigeht .... > > Nur um seine eigenen Fähigkeiten brillieren zu lassen. Ärgerst du dich weil so Leute wie du keinerlei substantiellen Beitrag leisten können? Oder muss man deine Kommentare eher als ›Finger-Tourette‹ ansehen?
Gast
#7087863
Norbert schrieb: > Ärgerst du dich weil so Leute wie du keinerlei substantiellen Beitrag > leisten können? > Oder muss man deine Kommentare eher als ›Finger-Tourette‹ ansehen? Keines von beiden wenn du schon so dümmlich fragst.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.





