Arduino DDS Signal Generator, empfehlenswert?

Das werde ich wohl auch tun, einfach kaufen, ansaften, vermessen und gegebenenfalls "hacken".

Grmpf, dann kriege ich vermutlich etwas Probleme. Aber probieren geht ueber studieren. Solange ich keine hoellische Entwicklungsumgebung installieren muss. Cypress Sachen habe ich ja auch schonmal ans Laufen bekommen, ist allerdings viele Jahre her.

Fuer mich Analogix vermutlich genau das richtige, man schiebt den Hebel auf "D" und es faehrt los :-)

Ich vermute mal dass man das ganze auch rauswerfen und vom Assembler Level aus neumachen koennte. Solange nicht eine DRM-artige Sperre im uC sitzt.

Mit einem Debugger koennte ich vermutlich genausowenig anfangen wie mit einer Gitarre :-)

Klingt gut.

--
Gruesse, Joerg 

http://www.analogconsultants.com/
Reply to
Joerg
Loading thread data ...

Wobei ich dort auch auf "krumme" Werte gehen kann wo das Phasenrauschen ein wenig besser wird.

381Hz daneben waere ueberhaupt kein Problem, solange er die eisern haelt und nicht gross in der Phase schlottert. Geringes Phasenrauschen ist erheblich wichtiger als genaue Frequenz.
--
Gruesse, Joerg 

http://www.analogconsultants.com/
Reply to
Joerg

Joerg ( snipped-for-privacy@invalid.invalid):

Die IDE ist Java, also mehr oder weniger eine höllische Umgebung ;-)

73 de Tom
--
DL7BJ * DL-QRP-AG #1186 * DARC  OV I19 * FISTS #15933 * ARRL 
http://www.dl7bj.de                https://twitter.com/dl7bj
Reply to
Thomas 'Tom' Malkus

Was, echt? ...

Das ist hier schon lange deaktiviert und zumindest in Richtung Web habe ich nicht vor das zu aendern. Jedenfalls nicht nach den Vorkommnissen die es sogar in unsere eher laendlichen Abendnachrichten schafften.

--
Gruesse, Joerg 

http://www.analogconsultants.com/
Reply to
Joerg

Joerg schrieb:

Hallo,

ich fürchte bei DDS mit wenig Bits, so etwa 16, bekommt man bei krummen Frequenzen immer erhebliches Phasenrauschen. Dagegen helfen wohl nur genügend viele Bits im Akkumulator. Aber man muß wohl auch genügend weit unter der halben Taktfrequenz liegen um wenig Phasenrauschen zu ermöglichen. Die Unsicherheit der Phase ist halt mindestens eine halbe Taktperiode und die muß genügend klein gegenüber der Signalperiode sein. Bei 200 kHz Signal und 50 MHz Takt sind es 10 ns zu 5 µs, ein Verhältnis

1 zu 500. Aber bei 201 kHz sind es 1 zu 497,512, das geht nur mit erheblich mehr Phasenrauschen als bei 200 kHz wo das Teilverhältnis ganzzahlig ohne Rest ist.

Bye

Reply to
Uwe Hercksen

Hi Uwe,

Wieso denn das eigentlich? Wenn die Sinustabelle hinreichend Stützpunkte hat, sollte da eigentlich nie ein Phasenrauschen entstehen, höchstens Oberwellenanteile im Bereich der Samplerate.

Bitte? Shannon gilt auch hier. Was wiss man mit zwei Abtastwerten pro Periode im DDS... Also, ich würde über 1/10 der Taktrate nie hinausgehen wollen.

Wie kommst Du darauf?

Marte

Reply to
Marte Schwarz

Gut, aber da waere es kein Problem auf 201.21MHz zu gehen wo das Teilerverhaeltnis 497 ist. 495 waere 202.02MHz, und so weiter. Selbst wenn ich das aus einer LUT machen muesste, ich brauche im Prinzip nur so um die 300 diskrete Frequenzen und diese muessen auch nicht aequidistant zueinander liegen. Das sollte in den nichtfluechtigen Speicher eines modernen uC reinpassen. Ausser etwas RS232 muss der ansonsten nicht viel machen.

--
Gruesse, Joerg 

http://www.analogconsultants.com/
Reply to
Joerg

Dann ist definitiv das DDS-Prinzip an sich nicht das richtige für dich bzw. dein Problem!

Mal 'ne Frage: weißt du eigentlich überhaupt, wie DDS funktioniert? Ich befürchte fast, daß du das nicht weißt. Deine bisherigen Einlassungen in diesem Thread legen diese Vermutung mittlerweile doch recht nahe.

Also: Wenn du kein Phasenrauschen brauchen kannst (jedenfalls nicht mehr, als der Muttertakt schon selber hat), müssen es ganzzahlige Teiler sein. Und das ist genau das, was bei DDS meist nicht der Fall ist, denn die Idee von DDS ist es ja gerade, zugunsten möglichst vieler aus einem Muttertakt erzeugbarer Frequenzen ein gewisses Maß an Phasenrauschen für die meisten der erzeugbaren Frequenzen in Kauf zu nehmen.

Reply to
Heiko Nocon

Er will dich nur nervös machen :-) Die IDE ist genau das Richtige für dich: Hat ein Editor-Fenster und hauptsächlich zwei Knöpfe, nebst Datei öffnen und Speichern: Compilieren und Upload. Kein Schnickschnack mit Projektverwaltung, Settings (außer dem virtuellen COM-Port) o.ä., wie man es von "großen" IDEs her kenn. Läuft prima unter Windows, Mac und Linux. Und Java ist für Desktop-Anwendungen genauso sicher, wie wenn du eine IDE wie WinAVR installierst, also will heissen, Java hat kompletten Zugriff auf den Rechner als Desktopanwendung. Als Applet im Browser normalerweise nicht, da ist es dann eine gute Idee, das für den Browser auszustellen, falls es da mal wieder eine der Sicherheitslücken gibt, aber die Arduino IDE ist eine Desktop-Anwendung.

--
Frank Buss, http://www.frank-buss.de 
electronics and more: http://www.youtube.com/user/frankbuss
Reply to
Frank Buss

Letzten Sommer habe ich ein kleines Projekt mit dem Arduino imlementiert. Das Programmiersystem ist ganz nett, solange man die Beispiele und Libs "as is" verwenden kann. Ich benötigte aber alle 3 Timer sowie spezielle Pins und hatte einige Mühe, herauszufinden, welche Module ich mit meiner Konfiguration beeinträchtige. Auch die Zuordnung der Chip-Pins zu den Boardpins war etwas verwirrend.

Ich hab es hinbekommen, aber ein weiteres, ähnliches Projekt würde ich mit anderen Atmeltools starten. Dann plant man die Chipkonfiguration straight forward. Die Hardware war für meine Zwecke OK.

--
Gruß, Raimund
Reply to
Raimund Nisius

Am 04.02.2013 18:22, schrieb Uwe Hercksen:

Nein, man bekommt nicht die Frequenz die man will, sondern irgend etwas in der Nähe. Man bekommt aber kein Phasenrauschen.

Es gibt auch keine "unsicherheit" in der Phase. Das ist ein ganz normales abgetastetes System und wenn man zurück in die analoge Ebene will gehört der interpolierende Tiefpass mit dazu.

Ein DDS ist ein Frequenzteiler und die Phasenmodulation des Taktes wird im gleichen Verhältnis runtergeteilt. Auch in der Praxis, wenn man nicht gerade einen genial guten Oszillator von Pascall oder so hat, den schon jede Pufferstufe verschlechtert.

Was bei DDS stören kann, sind zyklisch auftretende Phasenfehler wenn man eine Frequenz einstellt, die knapp neben einer glatten Subharmonischen der Clock liegt. Das äußert sich in unerwünschten Trägerchen (spurious), aber nicht in Phasenrauschen.

Gruß, Gerhard

Reply to
Gerhard Hoffmann

Am 04.02.2013 19:13, schrieb Heiko Nocon:

In Anbetracht des nachfolgenden Mülls legst du dich ganz schön weit raus.

Gerhard

Reply to
Gerhard Hoffmann

Das weiss ich schon. Auch wenn mein erster selbst gebauter Oszillator im Leben noch eine Roehre hatte, ganz so alt bin ich nun doch nicht :-)

Deshalb schrieb ich ja, ganzzahlige Verhaeltnisse sind in diesem Fall kein Problem. Das senkt schonmal Nebentraeger oder "Birdies". Es ging mir nur darum ob irgendwas in diesem Arduino Generator im argen liegt was nicht per Hack behebbar ist. Das koennte z.B. sein weil sie dort einen ziemlich schlabbrigen Schaltregler draufhaben.

--
Gruesse, Joerg 

http://www.analogconsultants.com/
Reply to
Joerg

Sehr gut. Was SW angeht bin ich mehr die Bunti-Bildi-Klicki Welt gewoehnt, so wie das bei SCADA Programmen ist. Man holt sich ein Manometer aus der Library, setzt es auf den Bildschirm, fuellt dessen Eingabemaske aus, und schon hat man eine huebsche Druckanzeige aus dem Pumpengehaeuse.

Dann ist es ja in Orndung. Im Browser muss das ausgeschaltet bleiben, da traue ich dem Kram nicht.

--
Gruesse, Joerg 

http://www.analogconsultants.com/
Reply to
Joerg

Du weißt offensichtlich auch nicht, wie DDS funktioniert.

Nein, genau das ist DDS eben nicht, bzw. nur in bestimmten Sonderfällen.

Das wäre dann eine sauschlecht implementierte DDS. Wahrscheinlich von jemandem gebaut, der ebenfalls nicht verstanden hat, wie DDS funktioniert...

...

Im Prinzip gibt es drei(*) wesentliche Kriterien für ein DDS, von denen gewöhnlich zwei durch die Implementierung festgelegt sind und einer durch den Nutzer. Das sind:

1) Fo: Die auszugebende Frequenz (Nutzer)

2) N: Anzahl der Samples für eine Periode der auszugebenden Frequenz (Implementierung)

3) Fmax: Die maximale Frequenz, mit der über die Samples der Waveform iteriert werden kann (Implementierung)

(*) Eigentlich gibt es noch eine vierte, nämlich den Digitalisierungfehler der Samples der Waveform, aber den drücken wir hier mal in den Skat, weil er für die Funktionsweise von DDS an sich irrelevant ist.

...

Mit diesen drei Größen kann man nun jedenfalls sehr leicht zwei Bedingungen formulieren, mit deren Hilfe sich die Ergebnisse einer DDS in drei grundverschiedene Klassen einteilen lassen.

1) Fmax/(Fo*N) ergibt eine ganze Zahl > 0

Wenn diese Bedingung zutrifft UND NUR DANN, sind Frequenz und Phase von Fo "korrekt" (so korrekt wie Fmax halt) und die DDS mutiert praktisch zum einfachen Frequenzteiler.

Da Fmax normalerweise der limitierende Faktor der Gesamtkonstruktion ist und sehr direkt die Gerätekosten bestimmt und außerdem N außer bei zu produzierenden Rechtecksignalen (N=2) i.d.R. recht hoch ist, ist diese Situation bei praktischen DDS-Anwendungen eher selten anzutreffen. Eigentlich fast nie.

2) Fmax/(Fo*N) ist eine rationale Zahl > 0

Wenn nur diese Bedingung zutrifft, ist nur noch die Frequenz korrekt, nicht aber die Phase. Der aus dem nichtganzzahligen Verhältnis ZWINGEND resultierende Fehler wird in der Form von Phasenrauschen ausgegeben. Genauer sieht man das übrigens, wenn man sich die "Frequenz" anschaut, mit der tatsächlich über die Samples iteriert wird. Das ist dann nämlich kein periodischer Vorgang mehr. Nunja, genau genommen ist er es zumindest bei sinnvollen Implementierungen doch. Die Basisfrequenz dieses Signals entspricht aber dann dem _KGV_ von Fmax und Fo.

3) Keins der beiden Kriterien trifft zu, also ein irrationales Verhältnis.

Dann haben wir den worst case. Frequenz- und Phasenfehler. Oder bei miesen Implementierungen halt merkliche Phasensprünge.

Wobei: die ganz miesen Implementierungen liefern auch bei 2) u.U. schon Phasensprünge. Wenn nämlich das KGV zu groß wird für die Genauigkeit der von Vollidioten gern sinnloserweise benutzten (Gleit-)kommazahlen. Als wenn es effiziente Integer-Fehlerverteilungsalgorithmen wie etwa Bresenham nicht schon seit vielen Jahrzehnten fix und fertig zum Abschreiben gäbe...

Reply to
Heiko Nocon

Thomas 'Tom' Malkus schrieb:

Meine ist völlig abgenudelt. ;o)

Schon mal sowas gesehen (hoffentlich übersteht die Formatierung das Senden)? Ich definiere Objekte gleich mit den Portpins zusammen und das Programm enthält fast nur Sachen wie if(!Pwr.U_12V()) Pwr.U_12V(1); Eine Gesamt-Portmap habe ich zwar aufgestellt, durch die Objekte kann ich da aber nicht mehr durcheinander kommen, sobald die einmal zugeordnet sind.

#ifndef T_POWERSTATE_H #define T_POWERSTATE_H

#include "type_def.h"

enum e_powerstate { // Für Ausgaben der Klasse powerstate: psStart= 0, // Gerät ist gerade gestartet psEin= 1, // Gerät ist eingeschaltet psNachlauf= 2, // Gerät ist im Nachlauf psUSB= 3, // Gerät ist aus };

//============================================================================ class t_powerstate { // Es gibt drei Möglichkeiten der Spannungsversorgung, die über die Portpins // p_Netz (Netzspannung) und p_U_12V (interne Spannung) ermittelt werden können: // 1. p_Netz= 1 und p_U_12_V= 1 => Gerät ist eingeschaltet // 2. p_Netz= 0 und p_U_12_V= 1 => Gerät wird über Nachlaufrelais versorgt und ist im Nachlauf // 3. p_Netz= 0 und p_U_12_V= 0 => Gerät wird über USB versorgt und ist ausgeschaltet // Der aktuelle Status wird über den Zeiger pVar ausgegeben, indem die Bits b_Netz und // b_U_Intern aktualisiert werden public: t_powerstate(uint8& Fehler);

inline e_powerstate State() const { return m_State; }

void Init(); // Portpins einrichten

bool8 Check(); // Netzstatus überprüfen, true bei Änderung

void U_12V(bool8 An); // Interne 12V-Spannung der Peripherie Ein/Aus bool8 U_12V() const; // Zustand der internen Spannung abfragen

void Ausschalten(); // Nachlaufrelais abfallen lassen

private: const uint8 p_Netz; // Portpin Optokoppler Netz const uint8 p_U_12V; // Portpin Abfrage 12 V-Versorgung const uint8 p_U_Intern; // Interne Spannung für Module schalten: H= Aus, L= Ein

uint8& mr_Fehler; // Globale Referenz für Fehlermeldungen e_powerstate m_State; // Globale Referenz für Ausgabe des Powerstate uint8 m_Last_Net; // Merker für letzten Zustand des Netzports uint32 m_Next_Time; // Zeitpunkt für nächste Prüfung, damit nicht jeder Durchlauf 10ms hängt };

#endif

//============================================================================ t_powerstate::t_powerstate(uint8& Error): p_Netz(4), p_U_12V(17), p_U_Intern(3), mr_Fehler(Error), m_State(psStart), m_Last_Net(0), m_Next_Time(0) {} //---------------------------------------------------------------------------- void t_powerstate::Init() { // Zugeordnete Portpins einrichten digitalWrite(p_Netz, HIGH); // Messung der Netzspannung einrichten pinMode(p_Netz, INPUT_PULLUP); // Netzeingang mit Pullup lesen digitalWrite(p_U_12V, LOW); // Messung der internen Spannung einrichten pinMode(p_U_12V, INPUT); // Interne Spannung ohne Pullup lesen // TODO: Mit neuem Shield Pullup verwenden digitalWrite(p_U_Intern, HIGH); // Internen Bus ausschalten pinMode(p_U_Intern, OUTPUT); // Interne Spannung über Ausgang schalten

m_Last_Net= digitalRead(p_Netz); // Anfangswerte lesen } //---------------------------------------------------------------------------- ....

Reply to
Edzard Egberts

Edzard Egberts (ed snipped-for-privacy@tantec.de):

Ich finde, das ist sehr viel Aufwand für die Abfrage von 3 Ports und das Schalten von einem Port.

Das mit den Ports mache ich ganz simpel, gusseisern, in einer Datei:

#define PULS1_EIN PORTD |= (1

Reply to
Thomas 'Tom' Malkus

Thomas 'Tom' Malkus schrieb:

Ja, das stimmt. Zuerst habe ich auch ein paar hundert Zeilen "Direktcode" herausgehauen (wie Du ihn gewohnt bist) und als dann alles lief, den Code "klassifiziert". Dabei sind dann die ganzen Fehler und Inkonsistenzen aufgefallen, die ich in dem Wust vorher nicht gesehen habe. Außerdem habe ich noch ein ähnliches Projekt am Start und kann die meisten Objekte wieder verwenden.

Das ist der Sinn des Aufwands, alles so klein zerlegen und so gut "dokumentieren", dass danach alles stimmt. Ich bin das von wesentlich größeren Projekten so gewohnt (habe etwa 15 Jahre Vollzeit C++ programmiert) und habe es genau deshalb 'mal in den Raum gestellt, weil so ein Stil hier wohl eher unbekannt ist, bzw. ich zeigen wollte, worüber ich überhaupt rede.

Nein, sind 22k, passt rein und funktioniert, mehr interessiert mich nicht, da keine Performanceprobleme bestehen. Außerdem habe ich bisher

8051er programmiert und keine AVR.
Reply to
Edzard Egberts

Edzard Egberts (ed snipped-for-privacy@tantec.de):

Unbekannt ist mir das nicht, ObjectPascal und C++ verwende ich auf den großen Systemen. Aber dieser Aufwand ist bei Mikrocontrollern, wenn es nicht gerade größere Embedded Devices sind, IMHO etwas viel. Ich verwende viele Dinge auch einfach wieder, weil sie einfach ausgegliedert sind. Aber das kann ja jeder so machen wie er will ;-)

Aber doch hoffentlich nicht nur für diese 3 Ports?

73 de Tom
--
DL7BJ * DL-QRP-AG #1186 * DARC  OV I19 * FISTS #15933 * ARRL 
http://www.dl7bj.de                https://twitter.com/dl7bj
Reply to
Thomas 'Tom' Malkus

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.