Ich lese einen Sinus mit variabler Frequenz und einen Offset von 2,5 V und einen Vpp von 5 V ein und bewerte diesen mit LOW und high um an einen Ausgang eine Rechteck Spannung zu erzeugen.
Bis ca. 1KHz Frequenz funktioniert dies auch super, allerdings kommt es dann zu Verzerrungen beispielsweise ist das Aussignal bei 19KHz 3 mal so lang wie das an Signal bei 20KHz ist dies dann anderes Rum das high Signal ist 3 mal so lang wie das aus Signal.
Ich möchte gern eine Abtastung von 44.000 Hz erzeugen und meinen Loop halt über einen Timer steuern. Leider habe ich davon nicht so viel Geschick dies zu realisieren. Im Moment läuft der Loop() ohne Abtastung sondern einfach nur über analogRead.
Wenn du ab ca 1kHz Probleme kriegst, spricht das dafür, dass du ca. 1ms loop() durchlaufzeit hast. Ohne Code läßt sich das schwer sagen.
ein analogReag() dauert ca. 120µs. 44kHz wirst du nicht schaffen.
Wenn du aber schlicht einen Sinus in ein Rechteck wandeln willst, ist vielleicht eine reine Hardwarelösung besser.
Im free running mode, macht der ADC ständig Wandlungen. Nachdem eine Wandlung fertig ist, wird automatisch die nächste gestartet und ein Interrupt ausgelöst. Zwischen den Wandlungen kann man dann andere Dinge tun. Das heißt anders als analogRead() blockiert das nicht! Das muss man dann auch mit dem niedrigeren Prescaler kombinieren.
Und wenn man den ADC über einen Timer steuern will, ist es auch besser das per Hand zu machen, als über die Arduino Sprachmittel mit denen man sich nur Overhead einfängt. Man kann den ADC nämlich direkt über Timer Interrupts triggern. Siehe Datenblatt Seite 256f.
Ein Komparator ist aber sicherlich die bessere Lösung!
µC ist Pflicht-Programm nicht einfach weg rationalisieren.
Danke für die Tipps ich werde es ganz einfach mache und die Frequenz nicht über 1 kHz kommen lassen.
Gibt es eigentlich eine Möglichkeit den Arduino C Dialekt in normales C oder am besten gleich in Assembler um zu wandeln ?
Dir steht frei in der Arduino IDE das ganz normale AVR C zu verwenden wie es in AtmelStudio üblich ist (das meiste davon jedenfalls). Man kann auch beides problemlos kombinieren. Die Arduino Mittel für Dinge verwenden die nicht perfomant sein müssen und dann die Register des µC direkt ansprechen wenn es schnell gehen muss oder man etwas hat, dass in der Arduino IDE nicht implementiert ist.
Den Assembler Code kann man sich mit avr-objdump ansehen:
Der interne ADC des Atmega644 funktioniert auch nicht anders als der des 328. Das ist ein sukzessiver Approximation ADC, der über den Teiler vom Prozessortakt getaktet wird. Das ist bei allen Atmegas so.
Bei dem verlinkten Projekt wurde ein externen ADC verwendet und über SPI angesteuert. Der Atmega644 wurde verwendet weil er mehr I/Os hat. Das war nötig, da die zwei DACs mit parallel-Interface haben:
Ah, da hätte ich mal genauer lesen sollen. Also Blick ins Datenblatt wo die echte Grenze ist --> ADC braucht bzw 13.5 Zyklen. ADC Clock muesste bei ~600 kHz sein --> möglich allerdings nicht mit 10 Bit Auflösung.