Arduino Audio-Ausgang: 10 Schritte (mit Bildern)

Arduino Audio-Ausgang: 10 Schritte (mit Bildern)

Inhaltsverzeichnis:

Anonim

Generieren Sie Sound oder geben Sie analoge Spannungen mit einem Arduino aus. Dieses Instructable zeigt Ihnen, wie Sie einen wirklich einfachen Digital-Analog-Wandler einrichten, damit Sie mit wenigen digitalen Pins auf einem Arduino analoge Wellen aller Formen und Größen erzeugen können. (Dieser Artikel ist ein Begleiter zu einem anderen Instructable, das ich über das Senden von Audio in ein Arduino geschrieben habe. Das finden Sie hier.)

Einige Ideen, die mir einfallen:

Probenbasiertes Instrument- Speichern Sie Samples auf dem Arduino oder auf einer SD-Karte und lösen Sie die Wiedergabe mit Knöpfen oder anderen Steuerelementen aus. Schauen Sie sich meinen Arduino-Drum-Sampler an, um eine Vorstellung davon zu bekommen, wie Sie anfangen sollen.

digitaler synthesizer- Säge-, Sinus-, Dreieck-, Puls- oder beliebige Wellenformen erstellen - Schauen Sie sich meinen Wellenformgenerator an, um loszulegen

MIDI zur Steuerung des Spannungsmoduls / MIDI-Synthesizers- Empfangen Sie MIDI-Meldungen und wandeln Sie sie in eine Spannung um, damit Sie einen analogen Synthesizer mit MIDI steuern oder die MIDI-Daten zur Ausgabe von Audiodaten einer bestimmten Frequenz verwenden können

Analogausgang- Möglicherweise müssen Sie irgendwann analoge Spannungen von Ihrem Arduino erzeugen, um möglicherweise mit einem analogen Gerät zu kommunizieren

Effektbox / digitale Signalverarbeitung- In Kombination mit einem Mikrofon / Audioeingang können Sie alle Arten von digitalen Signalmanipulationen durchführen und das verarbeitete Audio an die Lautsprecher senden. Ein Beispiel finden Sie in meinem Feld für Vokaleffekte.

Audiowiedergabegerät- Machen Sie Ihren eigenen iPod. Mit dem Hinzufügen eines SD-Shields können Sie Ihren eigenen Arduino-MP3-Player erstellen (lesen Sie in der Wave-Shield-Dokumentation nach, wie Sie mit dem Code beginnen können). Die hier bereitgestellten Schaltkreise und Codes sind mit SD-Abschirmungen kompatibel, die über SPI kommunizieren.

Nutzen Sie die Informationen hier, um ein großartiges Projekt für den DIY Audio Contest zusammenzustellen! Wir verschenken einen HDTV, einige DSLR-Kameras und jede Menge andere großartige Dinge! Der Wettbewerb endet am 26. November.

TeileListe:

(x9) 1/4 Watt 20kOhm Widerstände Digikey 0KQBK-ND

(x7) 1/4 Watt 10kOhm Widerstände Digiikey CF14JT10K0CT-ND

(x2) TS922IN Digikey 497-3049-5-ND Ich mag diese, weil sie von der 5-V-Versorgung des Arduino abgeschaltet werden können (ein 924 funktioniert auch, aber sie scheinen im Moment nicht auf Digikey verfügbar zu sein)

(x1) 10 kOhm Potentiometer linear Digikey 987-1308-ND

(x1) 0,01 uF Kondensator Digikey 445-5252-ND

(x1) 220 uF Kondensator Digikey P5183-ND

(x1) 0,1 uF Kondensator Digikey 445-5303-ND

(x1) 1/4 Watt 3 kOhm Widerstand Digikey CF14JT3K00CT-ND

(x1) 1/4 Watt 10 Ohm Widerstand Digikey CF14JT10R0CT-ND

(x1) Arduino Uno Amazon

Zusätzliche Materialien:

(1x) USB-Kabel Amazon

(1x) Steckbrett (dieses kommt mit Überbrückungsdrähten) Amazon

(1x) Überbrückungskabel Amazon

Zubehör:

Schritt 1: Digital-Analog-Wandler

DAC steht für "Digital-Analog-Wandler". Da der Arduino keine Analogausgangsfunktionen hat, müssen wir einen DAC verwenden, um digitale Daten (Zahlen / Zoll / Byte) in eine analoge Wellenform (oszillierende Spannung) umzuwandeln. Eine einfache, leicht zu programmierende und kostengünstige Möglichkeit, dies zu tun, ist die Verwendung einer sogenannten R2R-Widerstandsleiter. Im Wesentlichen werden eingehende digitale Bits (0 V und 5 V von Arduino) gewichtet und zu einer Spannung zwischen 0 und 5 Volt summiert (siehe Schema in Abb. 2 auf der Wikipedia-Widerstandsleiterseite). Sie können sich eine Widerstandsleiter als mehrstufigen Spannungsteiler vorstellen.

Die Widerstandsleiter, die ich in diesem Tutorial demonstrieren werde, ist ein 8-Bit-DAC. Dies bedeutet, dass sie 256 (2 ^ 8) verschiedene Spannungspegel zwischen 0 und 5 V erzeugen kann. Ich habe jeden der digitalen Pins 0-7 mit jedem der 8 Anschlüsse in meinem 8-Bit-DAC verbunden (siehe Abb. 1 und 3).

Ich mag es, diese Widerstandsleiter-DACs zu verwenden, weil ich immer die Materialien in der Nähe habe, sie sind billig und ich denke, sie machen Spaß, aber sie liefern nicht die beste Audioqualität. Sie können einen Chip kaufen, der genau so funktioniert wie ein R2R-DAC (und mit dem gesamten Code in dieser Anleitung kompatibel ist), der jedoch interne, stark abgestimmte Widerstände für eine bessere Audioqualität hat. Ich mag diesen, da er abläuft eine einzige 5V-Versorgung (Sie können sogar Stereo-Audio damit machen), aber es gibt noch viel mehr, suchen Sie nach "Paralleleingang, 8 Bit, DAC IC".

Alternativ gibt es Chips, die serielle Daten aufnehmen, um eine Digital-Analog-Wandlung durchzuführen. Diese Chips haben im Allgemeinen eine höhere Wiedergabetreue (definitiv bessere Qualität als der Widerstandsleiter-DAC) und verwenden nur zwei oder drei der Ausgangspins des Arduino (im Gegensatz zu 8). Die Nachteile sind, dass sie etwas schwieriger zu programmieren sind, teurer sind und nicht mit dem Code in diesem Instructable funktionieren, obwohl ich sicher bin, dass es einige andere verfügbare Tutorials gibt. Nach einer kurzen Suche nach digikey sahen diese gut aus. Versuchen Sie für Arduino, etwas zu finden, das an einer einzigen 5-V-Versorgung liegt.

Noch eine Anmerkung - es scheint eine Art Missverständnis zu geben, das bei 8-Bit-Audio auftritt -, dass es immer wie die Soundeffekte eines Mario-Spiels klingen muss - aber 8-Bit-Audio mit diesem wirklich einfachen DAC kann tatsächlich die Sounds der Stimmen und Instrumente von Menschen replizieren Nun gut, ich bin immer wieder erstaunt über die Klangqualität, die von einer Reihe von Widerständen ausgehen kann.

Schritt 2: DAC einrichten und testen

Ich habe meinen DAC auf einem Steckbrett aufgebaut (Abb. 1-3). Das Schema ist in Abb. 8 dargestellt. Nachfolgend sind einige Beispiele aufgeführt, die die in den Abb. 4-7 gezeigten Wellenformen erzeugen. In den folgenden Codeteilen sende ich einen Wert zwischen 0 und 255 an "PORTD", wenn ich Daten an den DAC senden möchte. Dies sieht folgendermaßen aus:

PORTD = 125; // Daten an DAC senden

Dies wird als direkte Adressierung des Ports bezeichnet. Auf dem Arduino befinden sich die digitalen Pins 0-7 alle auf Port d des Atmel328-Chips. Mit dem Befehl PORTD können wir die Pins 0-7 anweisen, in einer Zeile auf HIGH oder LOW zu gehen (anstatt achtmal digitalWrite () verwenden zu müssen). Dies ist nicht nur einfacher zu codieren, es ist für das Arduino auch viel schneller zu verarbeiten, und es bewirkt, dass sich alle Pins gleichzeitig ändern, anstatt nacheinander (mit digitalWrite () können Sie immer nur mit einem Pin gleichzeitig sprechen). Da Port d acht Pins hat (digitale Pins 0-7), können wir ihm einen von 2 ^ 8 = 256 möglichen Werten (0-255) senden, um die Pins zu steuern. Wenn wir zum Beispiel die folgende Zeile geschrieben haben:

PORTD = 0;

es würde die Pins 0-7 auf LOW setzen. Wenn der DAC an den Pins 0-7 eingerichtet ist, werden 0 V ausgegeben. wenn wir folgendes gesendet haben:

PORTD = 255;

es würde die Pins 0-7 auf HIGH setzen. Dadurch gibt der DAC 5 V aus. Wir können auch Kombinationen von LOW- und HIGH-Zuständen senden, um eine Spannung zwischen 0 und 5 V vom DAC auszugeben. Zum Beispiel:

PORTD = 125;

125 = 01111101 im Binärformat. Dies setzt Pin 7 auf LOW (das MSB ist 0), Pins 6-2 auf HIGH (die nächsten fünf Bits sind 1), Pin 1 auf LOW (das nächste Bit ist 0) und Pin 0 auf HIGH (das LSB ist 1). Wie das geht, können Sie hier nachlesen. Um die Spannung zu berechnen, die dieser vom DAC ausgibt, verwenden wir die folgende Gleichung:

Spannungsausgang von DAC = (an PORTD gesendeter Wert) / 255 * 5V

so für PORTD = 125:

Spannungsausgang von DAC = (125/255) * 5 V = 2,45 V

Der folgende Code sendet mehrere Spannungen zwischen 0 und 5 V aus und hält jeweils kurz an, um die oben beschriebenen Konzepte zu demonstrieren. In der main loop () Funktion habe ich geschrieben:

PORTD = 0; // send (0/255) * 5 = 0 V out DAC

delay (1); // warte 1ms

PORTD = 127; // send (127/255) * 5 = 2,5 V out DAC

delay (2); // warte 2ms

PORTD = 51; // send (51/255) * 5 = 1 V out DAC

delay (1); // warte 1ms

PORTD = 255; // send (255/255) * 5 = 5 V out DAC

delay (3); // warte 3ms

Die Ausgabe ist auf einem Oszilloskop in 4 dargestellt. Die horizontale Mittellinie über dem Oszilloskop repräsentiert 0 V und jede horizontale Linie repräsentiert eine Spannungszunahme / -abnahme von 2 V. Die Bildnotizen in Abb. 4 zeigen die Ausgabe der obigen Codezeilen. Klicken Sie auf das Bild, um die Bildnotizen anzuzeigen.

Der folgende Code gibt eine Rampe von 0 auf 5 V aus. In der loop () - Funktion wird die Variable "a" von 0 auf 255 erhöht. Bei jeder Erhöhung wird der Wert von "a" an PORTD gesendet. Dieser Wert wird für 50us gehalten, bevor ein neuer Wert von "a" gesendet wird. Sobald "a" 255 erreicht, wird es auf 0 zurückgesetzt. Die Zeit für jeden Zyklus dieser Rampe (auch als Periode bezeichnet) dauert:

Periode = (Dauer jedes Schritts) * (Anzahl der Schritte)

Periode = 50us * 256 = 12800us = 0,0128s

Die Frequenz ist also:

Rampenfrequenz = 1 / 0,0128s = 78Hz

Die Ausgabe des DAC auf einem Oszilloskop ist in Abb. 5 zu sehen.

Der folgende Code gibt eine um 2,5 V zentrierte Sinuswelle aus, die bis zu maximal 5 V und mindestens 0 V oszilliert. In der loop () -Funktion wird die Variable "t" von 0 auf 100 erhöht. Bei jeder Erhöhung wird der folgende Ausdruck verwendet:

127 + 127 * sin (2 * 3,14 * t / 100)

wird an PORTD gesendet. Dieser Wert wird für 50us gehalten, bevor "t" erneut erhöht und ein neuer Wert an PORTD gesendet wird. Sobald "t" 100 erreicht, wird es auf 0 zurückgesetzt. Die Periode dieser Sinuswelle sollte sein:

Periode = (Dauer jedes Schritts) * (Anzahl der Schritte)

Periode = 50us * 100 = 5000us = 0,005s

so sollte die Frequenz sein:

Rampenfrequenz = 1 / 0,005s = 200Hz

Dies ist jedoch nicht der Fall. Die Ausgabe des DAC ist in Abb. 6 dargestellt. Wie in den Bildnotizen angegeben, hat er keine Frequenz von 200 Hz, sondern eine Frequenz von 45 Hz. Dies liegt daran, dass die Zeile:

PORTD = 127 + 127 · sin (2 · 3,14 · t / 100);

Die Berechnung dauert sehr lange. Im Allgemeinen benötigt das Arduino für die Multiplikation / Division mit Dezimalzahlen und die Funktion sin () viel Zeit.

Eine Lösung besteht darin, die Sinuswerte vorab zu berechnen und im Speicher des Arduino zu speichern. Wenn die Arduino-Skizze ausgeführt wird, muss Arduino diese Werte nur aus dem Speicher abrufen (eine sehr einfache und schnelle Aufgabe für Arduino). Ich habe ein einfaches Python-Skript (siehe unten) ausgeführt, um 100 Werte von 127 + 127 * sin (2 * 3.14 * t / 100) zu generieren:

Mathe importieren

für x im Bereich (0, 100):

print str (int (127 + 127 * math.sin (2 * math.pi * x * 0.01)),) + str (","), Ich habe diese Werte in einem Array namens "Sinus" in der Arduino-Skizze unten gespeichert. Dann habe ich in meiner Schleife für jeden Wert von "t" ein Sinuselement an PORTD gesendet:

PORTD = Sinus t;

Der Ausgang dieses DAC für diese Skizze ist in Abb. 7 dargestellt. Sie können sehen, dass er erwartungsgemäß eine Sinuswelle von 200 Hz ausgibt.

Schritt 3: DAC-Puffer

Jetzt, da wir ein gutes Signal von Arduino haben, müssen wir es schützen. Der R2R-DAC reagiert sehr empfindlich auf Belastungen. Wenn Sie also versuchen, die Lautsprecher direkt vom DAC anzusteuern, wird das Signal stark verzerrt. Bevor Sie etwas mit dem Signal anfangen können, müssen Sie eine Art Pufferschaltung einrichten. Ich habe einen der Operationsverstärker im Dual-Operationsverstärker-Paket TS922 als Spannungsfolger eingerichtet, um meinen DAC vom Rest meiner Schaltung zu puffern (siehe Schema in Abb. 6, versorgen Sie den Operationsverstärker unbedingt mit 5 V und Masse).

Sobald dies eingerichtet war, verdrahtete ich eine LED und einen 220-Ohm-Widerstand in Reihe zwischen dem Ausgang des Operationsverstärkers und Masse. Die Skizze unten gibt eine langsame Rampe aus dem DAC aus, sodass Sie tatsächlich sehen können, wie die LED heller wird, wenn die Spannung ansteigt. Die Periode der Rampe ist:

Periode = (Dauer jedes Schritts) * (Anzahl der Schritte)

Periode = 5 ms * 256 = 1280 ms = 1,28 s

Die LED benötigt also 1,28 Sekunden, um von Aus auf volle Helligkeit hochzufahren.

Schritt 4: Tiefpassfilter

Der Zweck eines Tiefpassfilters besteht darin, den Ausgang des DAC zu glätten, um das Rauschen zu reduzieren. Durch Verwendung eines Tiefpassfilters für das Signal können Sie die "Stufen" in Ihrer Wellenform glätten, während die Gesamtform der Wellenform erhalten bleibt (siehe Abb. 4). Ich habe einen einfachen RC-Durchflussfilter verwendet, um dies zu erreichen: einen Widerstand und einen Kondensator in Reihe zur Erde. Verbinden Sie den Widerstand mit dem ankommenden Signal und den Kondensator mit Masse. Das von der Verbindungsstelle zwischen diesen beiden Komponenten kommende Signal wird tiefpassgefiltert. Ich habe dieses gefilterte Signal in eine andere Pufferschaltung gesendet (ich habe einen Operationsverstärker in einer Spannungsfolgerkonfiguration verdrahtet), um das gefilterte Signal vor Lasten weiter unten in der Schaltung zu schützen. Weitere Informationen finden Sie im Schema in Abb. 5.

Sie können die Werte des Kondensators und des Widerstands, die Sie für ein Tiefpassfilter benötigen, nach folgender Gleichung berechnen:

Grenzfrequenz = 1 / (2 * pi * R * C)

Nyquists Theroum besagt, dass für ein Signal mit einer Abtastrate von x Hz die höchste Frequenz, die erzeugt werden kann, x / 2 Hz ist. Sie sollten die Grenzfrequenz auf x / 2Hz einstellen (oder je nach Belieben etwas niedriger). Wenn Sie also eine Abtastrate von 40 kHz (Standard für die meisten Audiodaten) haben, können Sie maximal 20 kHz (die Obergrenze des hörbaren Spektrums) wiedergeben, und die Grenzfrequenz Ihres Tiefpassfilters sollte bei etwa 20 kHz liegen.

Für eine Grenzfrequenz von 20.000 Hz und 1 kOhm Widerstand:

20000 = 1 / (2 * 3,14 * 1000 * C)

C = ~ 8 nF

Da 8nF-Kondensatoren schwer zu bekommen sind, habe ich auf 0,01uF aufgerundet. Dies ergibt eine Grenzfrequenz von ungefähr 16 kHz. Sie können mit verschiedenen Werten herumspielen und sehen, was Ihnen am besten gefällt. Ich mag eine stärkere Filterung, da sie mehr unerwünschtes Rauschen entfernt.

Schritt 5: Signalamplitude

Als nächstes habe ich ein Potentiometer hinzugefügt, um die Amplitude meines Signals zu steuern. Dazu verdrahtete ich den Ausgang des 2. Spannungsfolgers mit einer Seite eines 10k-Potentiometers. Die andere Seite des Topfes habe ich mit Masse verbunden. Das aus der Mitte des Topfes kommende Signal hat eine einstellbare Amplitude (zwischen 0 und 2,5 V), je nachdem, wo der Topf gedreht wird. Weitere Informationen finden Sie im Schaltplan (Abb. 7). Sie können den Ausgang des Signals vor dem Pot und nach dem Pot (auf halben Weg gedreht) in Abb. 6 sehen.

Schritt 6: Verstärker

Wenn wir von Verstärkern sprechen, denken wir oft an Schaltungen, die die Amplitude eines Signals erhöhen. In diesem Fall geht es darum, den Strom des Signals so zu erhöhen, dass eine Last (wie ein Lautsprecher) angesteuert werden kann. In dieser Phase der Schaltung habe ich beide Operationsverstärker auf einem TS922-Gehäuse als parallele Spannungsfolger eingerichtet. Dies bedeutet, dass ich den Ausgang des Amplituden-Potis an den nicht invertierenden Eingang beider Operationsverstärker gesendet habe. Dann habe ich beide Operationsverstärker als Spannungsfolger verdrahtet und ihre Ausgänge miteinander verbunden. Da jeder Operationsverstärker 80 mA Strom liefern kann, können sie zusammen 160 mA Strom liefern.

Schritt 7: DC-Offset

Bevor Sie ein Signal an die Lautsprecher senden, müssen Sie sicherstellen, dass es um 0 V schwingt (typisch für Audiosignale). Bisher schwankt der Arduino-DAC-Ausgang, mit dem wir es zu tun haben, um 2,5 V. Um dies zu beheben, können wir einen großen Kondensator verwenden. Wie im Schaltplan angegeben, habe ich einen 220-uF-Kondensator verwendet, um mein Signal mit Gleichstrom zu versetzen, sodass es um 0 V schwingt. Die Ausgabe des DC-Offset-Signals (blau) und des Nicht-Offset-Signals (gelb) für zwei verschiedene Amplituden ist in den Abbildungen 2 und 3 dargestellt.

Schritt 8: Ausgabe

Schließlich verdrahtete ich eine 1/4 "Mono-Buchse mit zwei Drähten. Ich verband die Erdungsleitung mit der Erdung des Arduino und die Signalleitung mit der negativen Leitung des 220uF-Kondensators. Der Erdungsstift ist normalerweise der größere Stift an der Buchse. Prüfen Sie, ob der Gewindeabschnitt der Buchse durchgehend ist, um sicherzustellen, dass Sie den Erdungsstift richtig positioniert haben (siehe Abb. 5).Der Signalstift ist durchgehend mit der Klammer, die aus der Buchse herausragt (Abb. 5) Für mehr Information.

Schritt 9: 40kHz Abtastrate

Für diejenigen unter Ihnen, die Audio mit einer Abtastrate von 40 kHz produzieren möchten, finden Sie hier einen Code, der Timer-Interrupts verwendet, um dies zu ermöglichen. Mit Arduino-Timer-Interrupts können Sie in Ihrer main loop () -Funktion eine Pause einlegen und zu einer speziellen Funktion springen, die als "Interrupt-Routine" bezeichnet wird. Sobald diese Routine abgeschlossen ist, kehren Sie zu der Stelle zurück, an der Sie in der Schleife aufgehört haben (). Sie richten die Häufigkeit dieser Interrupts im setup () - Teil Ihres Codes ein und legen sie fest. Hier erfahren Sie alles über das Einrichten von Interrupts. Wenn Sie jedoch nur an 40-kHz-Interrupts interessiert sind, können Sie einfach Teile des folgenden Codes kopieren.

Um den Interrupt einzurichten, müssen Sie die folgenden Zeilen in Ihre setup () - Funktion kopieren:

cli (); // Interrupts deaktivieren

// setze timer0 interrupt auf 40kHz

TCCR0A = 0; // setze das gesamte TCCR0A-Register auf 0

TCCR0B = 0; // dasselbe für TCCR0B

TCNT0 = 0; // Zählerwert auf 0 initialisieren

// Vergleichsregister für 40-kHz-Inkremente setzen

OCR0A = 49; // = (16 * 10 ^ 6) / (40000 * 8) - 1 (muss <256 sein)

// CTC-Modus einschalten

TCCR0A | = (1 << WGM01);

// CS11 Bit für 8 Prescaler setzen

TCCR0B | = (1 << CS11);

// Timer-Vergleichsinterrupt aktivieren

TIMSK0 | = (1 << OCIE0A);

sei (); // Interrupts aktivieren

Der Inhalt der Interruptroutine ist in der folgenden Funktion gekapselt:

ISR (TIMER0_COMPA_vect) {// 40kHz Interruptroutine

}

Sie wollen die Interruptroutine so kurz wie möglich halten, nur das Nötigste. Sie können alle Ihre anderen Aufgaben (Überprüfen der Tasten, Einschalten der LEDs usw.) in der Schleife () ausführen. Denken Sie auch daran, dass das Einrichten von Interrupts andere Arduino-Funktionen wie analogWrite und Delay beeinträchtigen kann.

Im folgenden Code verwende ich die Interrupt-Funktion, um einen neuen Sinuswert mit einer Rate von 40 kHz an PORTD zu senden und die Variable "t" zu erhöhen. Die Abbildungen 1 und 2 zeigen die (ungefilterte) Ausgabe des Codes auf einem Oszilloskop. Wir können die erwartete Häufigkeit wie folgt berechnen:

Frequenz = (Abtastfrequenz) / (Schritte pro Zyklus)

Frequenz = 40.000 / 100 = 400 Hz

Bei einer Abtastfrequenz von 40 kHz erwarten wir eine Dauer jedes Schritts von:

Dauer jedes Abtastschritts = 1 / (Abtastfrequenz)

Dauer jedes Probenschritts = 1 / 40.000 = 25us

Schritt 10: Zusätzliche Tipps

Dieser DAC verwendet eine ganze Menge der verfügbaren digitalen Pins des Arduino, einschließlich einiger, die normalerweise für die serielle Kommunikation und PWM verwendet werden. Hier einige Tipps, die Ihnen helfen, mit Pin-Konflikten umzugehen.

Wenn Sie eine serielle Kommunikation durchführen möchten: Software Serial ist eine Arduino-Bibliothek, mit der Sie jeden der Arduino-Pins in serielle Pins umwandeln können. Wenn Sie ein Arduino-Projekt ausführen, das serielle Kommunikation erfordert, vermeiden Sie normalerweise die Verwendung der digitalen Pins 0 und 1, da diese frei sein müssen, um serielle Daten zu senden. Ich verwende sie gerne für den 8-Bit-DAC, da die Pins 0-7 alle Teil von PORTD auf dem Atmel328-Chip des Arduino sind. Auf diese Weise kann ich alle in einer einzigen Codezeile ansprechen. PORTB hat nur 6 Pins (digitale Pins 8-13) und PORTC hat nur 6 Pins (analoge Pins 0-5). Sie können also keinen 8-Bit-DAC nur mit diesen Ports erstellen.

Wenn Sie die PWM-Pins verwenden müssen oder andere Pins als DAC verwenden müssen: Wenn Sie die PWM-Pins verwenden müssen, können Sie die Pins 3, 5 und 6 mit Bit-Manipulationen freigeben und durch die Pins 8, 12 und 13 ersetzen. Angenommen, Sie möchten die Nummer 36 an PORTD senden. Sie können die folgenden Zeilen verwenden:

// definiere Variablen:

boolean bit3state;

boolean bit5state;

boolean bit6state;

// in deiner Hauptschleife ():

bit3state = (36 & B00001000) >> 3; // erhalte das dritte Bit von 36

bit5state = (36 & B00100000) >> 5; // erhalte das fünfte Bit von 36

bit6state = (36 & B01000000) >> 6; // Erhalte das sechste Bit von 36

// Sende Daten an den Port ohne die Pins 3, 5 und 6 zu stören

PORTD | = (36 & B10010111); // High-Pins mit der Nummer 36 setzen, wobei Nullen die Bits 3, 5 und 6 ersetzen

PORTD & = (36 | B01101000); // Setzen Sie die niedrigen Pins auf niedrig, indem Sie die Zahl 36 durch diejenigen ersetzen, die die Bits 3, 5 und 6 ersetzen

// Daten an Portb senden, ohne die Pins 9, 10 und 11 zu stören

PORTB | = 0 | (bit3state) | (bit5state << 4) | (bit6state << 5); // setze hohe Pins

PORTB & = 255 & ~ (1-Bit-3-Zustand) & ~ ((1-Bit-5-Zustand) << 4) & ~ ((1-Bit-6-Zustand) << 5) // setze niedrige Pins

Stellen Sie sicher, dass diese PORTD- und PORTB-Leitungen in Ihrem Code direkt nebeneinander liegen. Sie möchten, dass die Pins an Port d und Port b möglichst zeitgleich geschaltet werden.

Hier ist der Code aus dem vorherigen Schritt, der so bearbeitet wurde, dass keine PWM-Pins verwendet werden. Wie Sie in Abb. 1 sehen können, weist die ungefilterte Ausgabe des DAC viele Diskontinuitäten auf, die durch die Verzögerung zwischen dem Senden von Daten an Port d und Port b sowie durch die Aufteilung der Befehle zum Setzen der Pins auf High und Low verursacht werden. Die meisten dieser Diskontinuitäten können Sie mit dem Tiefpassfilter beseitigen (Abb. 2). Wenn Sie diese Technik verwenden möchten, können Sie die Grenzfrequenz Ihres Tiefpassfilters erhöhen. Wenn Sie dies wirklich gut machen möchten, können Sie Ihre 5 höchstwertigen Bits an Port d und Ihre 3 niedrigstwertigen Bits an Port b senden. Dies würde die Amplitude einiger Diskontinuitäten verringern und die Stärke des Rauschens verringern. Ich lasse Sie das selbst herausfinden.

Wenn Ihnen die digitalen Stifte ausgehen und Sie mehr benötigen: Denken Sie daran, dass Sie Ihre analogen Pins immer als digitale E / A verwenden können. Probieren Sie die folgenden Funktionen aus. Sie funktionieren genau so, wie Sie es mit einem normalen digitalen Stift tun.

digitalWrite (A0, HIGH); // Pin A0 auf High setzen

digitalWrite (A0, LOW); // Pin A0 auf low setzen

digitalRead (A0); // Liest digitale Daten von Pin A0

Verwenden Sie andernfalls einen Multiplexer. Wenn Sie mehr digitale Ausgänge benötigen, können Sie mit dem 74HC595 drei der digitalen Stifte des Arduino in acht Ausgänge umwandeln. Sie können sogar mehrere 595 in Reihe schalten, um viel mehr Ausgangspins zu erstellen. Sie könnten Ihren gesamten DAC auf einem dieser Chips einrichten, wenn Sie möchten (obwohl es ein paar Codezeilen dauern würde, um ihn zu adressieren, und Sie möglicherweise für höhere Abtastraten zu sehr verlangsamen würden). Die Arduino-Website ist ein guter Ort, um sich mit der Verwendung des 595 vertraut zu machen.

Wenn Sie mehr digitale Eingänge benötigen, können Sie mit dem 74HC165 oder CD4021B drei der digitalen Stifte des Arduino in acht Eingänge umwandeln. Auch hier ist die Arduino-Website ein guter Ort, um den Umgang mit diesen Chips zu erlernen.

Wenn Sie die Informationen in diesem Instructable mit dem Mega oder anderen Boards verwenden möchten: In diesem Instructable habe ich ausschließlich über den Arduino Uno mit Atmel328 gesprochen. Derselbe Code läuft auf jeder Karte mit einem Atmel328- oder Atmel168-Chip einwandfrei. Sie können die gleichen Ideen auch mit einem Mega verwenden. Sie sollten versuchen, Ihren DAC an einen Port mit 8 verfügbaren Pins anzuschließen. Auf diese Weise können Sie Ihren DAC mit einer Codezeile adressieren ("PORTD ="). Auf dem Uno ist der einzige Port mit 8 verfügbaren Pins Port d. Dieses Bild zeigt, dass das Mega über mehrere Ports mit 8 Pins verfügt: Port a, b, c und l sind die naheliegende Wahl. Wenn Sie keine analogen Pins verschwenden möchten, können Sie auch die Ports f oder k verwenden.