Raspberry Pi Pico: MCP4725 programmieren
Der Raspberry Pi Pico ist ein Mikrocontroller mit vielen digitalen Ein- und Ausgängen. Allerdings besitzt er keinen analogen Ausgang, weshalb man zum Erzeugen von analogen Signalen einen externen Digital-Analog-Wandler (DAC) benötigt. Im einfachsten und günstigsten Fall kann das ein MCP4725-Modul sein.
Der Raspberry Pi Pico liefert die digitale Logik und erzeugt Werte für das Signal (z. B. Sinus, Dreieck, Rechteck usw.).
Der MCP4725 wandelt diese digitalen Werte in eine analoge Spannung um. Das heißt, der MCP4725 ist in dem Sinne nicht programmierbar, sondern er hat nur einen Ausgang, der eine Spannung von 0 Volt bis VCC annehmen kann, die ihm übermittelt wird. Das heißt, der zu steuernde Mikrocontroller muss laufend Daten liefern, wenn aus dem Ausgang eine Signalform ausgegeben werden soll.
Aufbau und Bauteile

| Raspberry Pi Pico | MCP4725-Modul | |
|---|---|---|
| 3V3 | Pin 36 | 3V3 |
| GND | Pin 33 | GND |
| GPIO0 I2C SDA | Pin 1 | I2C SDA |
| GPIO1 I2C SCL | Pin 2 | I2C SCL |
I2C-Kommunikation
Die Kommunikation zwischen dem Raspberry Pi Pico und dem MCP4725 erfolgt über den I2C-Bus. Bei dieser Kommunikation wird neben der Bus-Adresse des MCP4725 auch ein Kommando und die Daten übertragen.
- WRITE COMMAND FOR FAST MODE: Dient dazu, schnell einen neuen Digitalwert in das DAC-Register zu schreiben, ohne in das interne EEPROM zu schreiben. Die Ausgangsspannung wird dabei ohne Verzögerung geändert.
- WRITE COMMAND FOR DAC INPUT REGISTER: Dient dazu, einen neuen Digitalwert in das DAC-Register zu schreiben, ohne in das interne EEPROM zu schreiben. Zusätzliche können Konfigurationsbits übertragen werden (z. B. Power-Down aktivieren).
- WRITE COMMAND FOR DAC INPUT REGISTER AND EEPROM: Dieses Kommando schreibt den neuen DAC-Wert sowohl ins DAC Input Register als auch ins EEPROM des Bausteins. Nach einem Neustart oder Power-Up lädt der MCP4725 automatisch diesen gespeicherten Wert wieder ins DAC-Register und setzt damit die Ausgangsspannung.
Programmcode: WRITE COMMAND FOR FAST MODE
Der folgende Programmcode sendet über den I2C-Bus einen digitalen Wert (12 Bit = 4.096 Stufen) an den MCP4725. Die Ausgangsspannung wird dabei ohne Verzögerung auf 3,0 Volt geändert.
# Bibliotheken laden import machine # Konfiguration: Gleichspannung voltage = 1.0 # Ausgangsspannung in Volt VCC_DAC = 3.3 # VCC in Volt # I2C-Initialisierung DAC = machine.I2C(0, scl=machine.Pin(1), sda=machine.Pin(0), freq=400000) # Minimal- und Maximal-Werte setzen voltage = max(0, min(VCC_DAC, voltage)) # Spannung in Dezimalzahl umrechnen (12 Bit: 0 - 4095) value = int((voltage / VCC_DAC) * 4095) # 12-Bit-Wert in zwei Bytes zerlegen (FAST MODE) high_byte = (value >> 8) & 0x0F low_byte = value & 0xFF # I2C: Daten an den DAC senden (Fast Mode) DAC.writeto(0x60, bytes([high_byte, low_byte]))
Programmcode: WRITE COMMAND FOR DAC INPUT REGISTER
Der folgende Programmcode sendet über den I2C-Bus einen digitalen Wert (12 Bit = 4.096 Stufen) an den MCP4725. Die Ausgangsspannung wird dabei ohne Verzögerung auf 3,0 Volt geändert. Zusätzlich könnten noch Konfigurationsbits übertragen werden (siehe Datenblatt MCP4725).
# Bibliotheken laden import machine # Konfiguration: Gleichspannung voltage = 1.0 # Ausgangsspannung in Volt VCC_DAC = 3.3 # VCC in Volt # I2C-Initialisierung DAC = machine.I2C(0, scl=machine.Pin(1), sda=machine.Pin(0), freq=400000) # Minimal- und Maximal-Werte setzen voltage = max(0, min(VCC_DAC, voltage)) # Spannung in Dezimalzahl umrechnen (12 Bit: 0 - 4095) value = int((voltage / VCC_DAC) * 4095) # 12-Bit-Wert in zwei Bytes zerlegen high_byte = (value >> 4) & 0xFF low_byte = (value & 0x0F) << 4 # Write Command command = 0x40 # I2C: Daten an den DAC senden DAC.writeto(0x60, bytes([command, high_byte, low_byte]))
Programmcode: WRITE COMMAND FOR DAC INPUT REGISTER AND EEPROM
Standardmäßig nimmt die Ausgangsspannung einen Wert von der Hälfte von VCC an. Bei VCC = 3,3 Volt sind das etwa 1,65 Volt.
Es kann jedoch Anwendungen geben, bei denen das nicht sinnvoll ist. Wenn man beispielsweise nach dem Einschalten 0 Volt erwartet, weil sonst Dinge in Gang gesetzt werden, die man nicht möchte.
Der folgende Programmcode sendet über den I2C-Bus einen digitalen Wert (12 Bit = 4.096 Stufen) an den MCP4725. Der DAC stellt die Ausgangsspannung ein und schreibt den Wert in sein EEPROM. Dieser Wert wird dann zukünftig bei der Inbetriebnahme automatisch eingestellt.
# Bibliotheken laden import machine # Konfiguration: Gleichspannung voltage = 0.0 # Ausgangsspannung in Volt VCC_DAC = 3.3 # VCC in Volt # I2C-Initialisierung DAC = machine.I2C(0, scl=machine.Pin(1), sda=machine.Pin(0), freq=400000) # Minimal- und Maximal-Werte setzen voltage = max(0, min(VCC_DAC, voltage)) # Spannung in Dezimalzahl umrechnen (12 Bit: 0 - 4095) value = int((voltage / VCC_DAC) * 4095) # 12-Bit-Wert in zwei Bytes zerlegen high_byte = (value >> 4) & 0xFF low_byte = (value & 0x0F) << 4 # Write Command command = 0x60 # I2C: Daten an den DAC senden DAC.writeto(0x60, bytes([command, high_byte, low_byte]))
Erläuterungen zu den Programmcodes
Begrenzung des minimalen und des maximalen Werts (Spannung)
voltage = max(0, min(VCC_DAC, voltage))
Hier wird sichergestellt, dass die Spannung, die angegeben wird (voltage), innerhalb von 0 bis DAC_VCC (3.3) liegt. Ist der Wert kleiner als 0, dann wird 0 verwendet. Liegt er darüber, dann wird DAC_VCC verwendet.
Umrechnung der Spannung in einen ganzzahligen Wert
value = int((voltage / 3.3) * 4095)
Der MCP4725 erwartet ganzzahlige Werte zwischen 0 und 4095 (12 Bit Länge). Diese Berechnung wandelt die analoge Spannung „voltage“ in eine Ganzzahl um.
12-Bit-Ganzzahl in zwei Byte mit jeweils 8 Bit umwandeln
Für die Kommunikation über den I2C müssen die Daten mit einer Länge von 12 Bit in zwei Byte mit einer Länge von 8 Bit aufgeteilt werden.
Für den Fast Mode ohne Write Command:
high_byte = (value >> 8) & 0x0F low_byte = value & 0xFF
- high_byte: Hier werden die ersten 8 Bit nach rechts verschoben und die vorderen 4 Bit (8 - 11) maskiert. Diese Variable enthält somit die vorderen 4 Bit des 12-Bit-Werts.
- low_byte: Hier werden die hinteren 8 Bit (0 – 7) maskiert. Diese Variable enthält somit die hinteren 8 Bit des 12-Bit-Werts.
Für die Kommunikation mit Write Command:
high_byte = (value >> 4) & 0xFF low_byte = (value & 0x0F) << 4
- high_byte: Hier werden die Bits um 4 Bit nach rechts verschoben, wodurch die hinteren 4 Bit abgeschnitten werden. Diese Variable enthält also die vorderen 8 Bit (4 - 11) des 12-Bit-Werts.
- low_byte: Hier werden die hinteren 4 Bit maskiert und anschließend um 4 Bit nach links verschoben. Diese Variable enthält also die hinteren 4 Bit (0 - 3) des 12-Bit-Werts.
Daten an den DAC senden
Gesendet werden die Daten über den I2C-Bus an den DAC. „DAC“ ist im Programmcode das I2C-Objekt, an das mit „writeto()“ die Daten gesendet werden. Da mit dem I2C-Bus mehrere Geräten verbunden sein können, wird mit „0x60“ der MCP4725 adressiert. Danach folgen die Daten.
Im Fast Mode wird kein Write Command für den MCP4725 benötigt:
DAC.writeto(0x60, bytes([high_byte, low_byte]))
Für das Write Command ist der Aufbau der Daten anders:
DAC.writeto(0x60, bytes([command, high_byte, low_byte]))
Raspberry Pi Pico als Signalgenerator mit dem MCP4725
Aus einem Raspberry Pi Pico und einem MCP4725 lässt sich ein digital steuerbarer Signalgenerator bauen. Natürlich kein richtig professioneller, sondern vergleichsweise einfach mit einer geringen Genauigkeit und kleinen Spannung.
Die Frage ist, was technisch machbar, praktisch sinnvoll ist und wo die Grenzen liegen.
Übersicht: I2C
- Raspberry Pi Pico: Grundlagen zum I2C
- Raspberry Pi Pico: I2C verbinden und programmieren
- Raspberry Pi Pico: Troubleshooting I2C - Fehler, Probleme und Lösungen
Weitere verwandte Themen:
- Raspberry Pi Pico als Signalgenerator
- Raspberry Pi Pico als CD4093
- Messen mit dem Raspberry Pi Pico
- Raspberry Pi Pico: Elektronik lernen
- Raspberry Pi Pico: Elektronische Schaltungen programmieren
Frag Elektronik-Kompendium.de
Hardware-nahes Programmieren mit dem Raspberry Pi Pico und MicroPython
Das Elektronik-Set Pico Edition ist ein Bauteile-Sortiment mit Anleitung zum Experimentieren und Programmieren mit MicroPython.
- LED: Einschalten, ausschalten, blinken und Helligkeit steuern
- Taster: Entprellen und Zustände anzeigen
- LED mit Taster einschalten und ausschalten
- Ampel- und Lauflicht-Steuerung
- Elektronischer Würfel
- Eigene Steuerungen programmieren
Online-Workshop: Programmieren mit dem Raspberry Pi Pico
Gemeinsam mit anderen und unter Anleitung experimentieren? Wir bieten unterschiedliche Online-Workshops zum Raspberry Pi Pico und MicroPython an. Einführung in die Programmierung, Sensoren programmieren und kalibrieren, sowie Internet of Things und Smart Home über WLAN und MQTT.
Besuchen Sie unser fast monatlich stattfindendes Online-Meeting PicoTalk und lernen Sie uns kennen. Die Teilnahme ist kostenfrei.






