2 Kanal Digitalpotentiometer (AD8402)

  • Liebe Forenmitglieder,

    ich moechte zwei Motorsteuerungen (Ansteuerung von Servo und Motor) eines RC-Bootes mit dem Raspberry Pi ansteuern. Hierfür muss an den jeweiligen Eingang der Motorsteuerung ein Spannungssignal zwischen 0,25V und 0,35 V gegeben werden. Zur Erzeugung dieses Spannungssignals möchte ich einen 2-Kanal Digitalpotentiometer verwenden.

    Mein Ansatz:

    Ich habe mir das Buch "Raspberry Pi Das umfassende Handbuch" von Kofler Kühnast und Scherbeck (5. Auflage) gekauft und darin ist auf S. 427 die Ansteuerung eines Digitalpotentiometers MCP4132 beschrieben.

    Da ich aber zwei Widerstände gleichzeitig und verschieden verändern muss, reicht mir dieses Bauteil nicht aus. Ich erkläre kurz die Ansteuerung, wie sie in dem Buch beschrieben ist:

    (Links Raspberry Pi GPIO, Rechts MCP4132)

    Anschluss:

    Pin1 (3,3 V) an VDD

    Pin26 (CE1) an CS

    Pin23 (SCLK) an SDK

    Pin19 (MOSI) an SDI

    Pin21 (MISO) an SDO

    Pin6 (GND) an VSS

    Eine Ansteuerung dieses Potis ist ebenfalls ausführlich beschrieben:

    Code
     #!/usr/bin/python3
    import spidev
    import time
    import RPi.GPIO as GPIO
    spi = spidev.SpiDev()
    spi.open(0,1) 
    spi.max_speed_hz = 5000
    spi.xfer([0x00, 0x80])

    In dem Beispielcode wird durch "spi.open(0,1)" CE1 angesteuert. Durch folgenden Befehl wird dadurch die Taktfrequenz des "Serial-Clock-Signals" auf 5kHz festgelegt.

    Code
    spi.max_speed_hz = 5000


    Der Befehl

    Code
    spi.xfer([0x00, 0x80])

    sendet zwei Byte an den Poti, der erste Byte setzt den Befehl Write Data, der zweite setzt den Befehl Maximalwert des Widerstandes.

    Ein sehr simpler Code.

    Nun möchte ich das gleiche für meinen Digitalpoti erreichen.

    Das Datenblatt befindet sich im Anhang, ein Bild von der Pinbelegung ebenfalls.

    Entsprechend der Pinbelegung wuerde ich wie folgt vorgehen:

    (Links Raspberry Pi, Rechts AD8402)

    Pin1 (3,3 V) an VDD (Pin 11)

    Pin26 (CE1) an CS (Pin7)

    Pin23 (SCLK) an CLK (Pin9)?

    Pin19 (MOSI) an SDI (Pin8)

    Pin21 (MISO) an ?

    Pin6 (GND) an DGND (Pin5)?, AGND (Pin1) ?

    Das Abgreifen und Anlegen der Spannung gelingt zwischen A1, B1, W1. Ich wuerde A1 und A2 an Pin1(3,3V) anlegen. und B1 und B2 an GND an W1 und W2 wuerde ich die Spannung abgreifen.

    Wisst ihr, ob die bisherigen Pinbelegungen richtig vorgenommen wurden und wie der Rest der Pins belegt werden muss? (RS, CS, SHDN...)

    RS setzt den Widerstandswert auf den mittleren Wert. Was der SHDN-Pin macht ist mir nicht so ganz klar geworden. Ich zitiere mal aus dem Datenblatt:

    Kann mir jemand erklaeren, was damit gemeint ist? Brauche ich diese Pin-Belegungen fuer eine simple Ansteuerung?

    Ich habe mich noch nie mit solch einem Datenblatt beschaeftigt. Koennt ihr daraus ablesen, wie ich dann tatsaechlich das oben genannte Programm erweitern muss und ich wie Daten zu dem DigitalPoti senden muss, um an beiden Pins W1 und W2 die Spannung individuell abgreifen kann?

    Ich hoffe, einer von euch kennt sich mit solchen Dingen aus, ich bin dort leider noch ein Anfaenger und wuerde mich freuen, wenn mir jemand sagen kann, wie ich die Daten zum Poti senden muss und wo das in dem Datenblatt ersichtlich ist.

    Vielen Dank und viele Gruesse,

    Salzforscher

  • Hierfür muss an den jeweiligen Eingang der Motorsteuerung ein Spannungssignal zwischen 0,25V und 0,35 V gegeben werden. Zur Erzeugung dieses Spannungssignals möchte ich einen 2-Kanal Digitalpotentiometer verwenden.

    ...

    Ich wuerde A1 und A2 an Pin1(3,3V) anlegen. und B1 und B2 an GND an W1 und W2 wuerde ich die Spannung abgreifen.

    Kann man machen. Wenn man aber (sicher) nur in diesem Bereich regeln will, sollte man das gleich so einstellen. Also jeweils einen Widerstand vor A1 / A2 gegen 3V3 und jeweils einen vor B1 / B2 gegen GND. Richtig ausgelegt, kannst Du nun die ganze Auflösung (255 Schritte) für diesen Spannungsbereich nutzen. Außerdem kannst Du nicht "versehentlich" viel zu weit aus dem Sollbereich raus regeln... Für die Berechnung müsste man wissen, welches Poti Du genau nimmst (1K/10K/50K/100K?). Anmerkung: Wichtig ist (generell), dass Deine Motorsteuerung am Eingang eine hohe Impetanz aufweist...

    Da ich aber zwei Widerstände gleichzeitig und verschieden verändern muss, reicht mir dieses Bauteil nicht aus.

    Naja, hier müsste man "gleichzeitig" genauer definieren: Die zwei Potis werden (soweit ich das gelesen habe) auch über einzelne Adressen angesteuert - Du musst also auch zwei Befehle schicken. Ob die beiden Potis nun in einem Gehäuse sind oder nicht, hat diesbezüglich keinen Einfluss... Der Verdrahtungsaufwand sinkt halt... Zwei einzelne Potis wären also durchaus eine technisch gleichwertige Option bzw. sogar besser: Es können ja beide Potis auf das gleiche Datensignal reagieren, wenn Du den gleichen Einstellwert willst (Selektion über jeweils einen CS).

    Ich bezweifle allerdings, dass der Zeitunterschied, wenn du beide Potis einzeln einstellst überhaupt relevant ist...

    Ja, MOSI (MasterOutSlaveIn) an SDI (SerialDataInput) passt.

    MISO (MasterInSlaveOut) wird nicht verwendet, da der AD8402 keinen SDO hat, bekommst Du keine "Antwort"

    Ja, DGND, AGND und GND sind zu verbinden (Zitat unter Table 8: 1All AGND pins must be connected to DGND.)

    Wisst ihr, ob die bisherigen Pinbelegungen richtig vorgenommen wurden und wie der Rest der Pins belegt werden muss? (RS, CS, SHDN...)

    Zitate Table 8:

    RS: "Active Low Reset to Midscale. Sets RDAC registers to 80H." => Also auf HIGH, solange Du nicht das Poti in die Mitte stellen möchtest

    CS: "Chip Select Input, Active Low. When CS returns high, data in the serial input register is decoded, based on the address bits, and loaded into the target DAC register." => Low: Daten Schicken. Wechsel auf HIGH => Daten werden an DAC übertragen. Aber das hat der AD8400 auch - und Du auch bereits verkabelt.

    SHDN: Terminal A Open Circuit. Shutdown controls Variable Resistor 1 and Variable Resistor 2. => Auf High legen (Überstrichen bedeutet invertiert - also HIGH - ShutDown LOW). Wenn Du auf Low legst, dann wird Anschluss A1/A2 unterbrochen - in diesem Fall würde obiger Spannungteiler gegen GND gehen...

    Der Rest Deiner nachfolgenden Fragen bezieht sich auf obige Pins - und die habe ich (hoffentlich verständlich) erklärt.

    Bezüglich Software kann ich nicht so allgemein weiter helfen, da ich diesen Typen auch noch nicht selbst angesteuert habe. Du musst das Ding halt laut Datenblatt ansteuern und/oder bereits von bestehenden Projekten übernehmen. Bei konkreten Fragen kann ich ev. weiter helfen...

    ...wenn Software nicht so hard-ware ;) ...

    Freue mich über jeden like :thumbup:

  • Hallo VeryPrivat,

    vielen Dank fuer deine freundliche und ausfuehrliche Antwort. Das Anschliessen der Pins hat soweit geklappt. ich denke dort liegt kein Fehler vor. und es ist ein 10 KOhm Poti. :)

    Den Programmcode habe ich entsprechend meiner Einleitung uebernommen, lediglich moechte ich den Befehl mit spi.xfer([...]) entsprechend aendern.

    Ich habe gehofft etwas wie eine Uebersicht der Kommandobits in dem Datenblatt zu finden. Leider habe ich in dem Dokument diese Informationen nicht finden koennen. Aber Derartiges muesste dort doch eigentlich zu finden sein oder ist sowas unueblich?

    Wie dem auch sei, habe ich nochmal geschaut, ob es (weitere) Tutorials/Informationen gibt. Einige Informationen sind sicherlich hier zu finden:

    https://www.analog.com/en/education/e…aqs/ad8402.html

    Ein Tutorial zur Ansteuerung einer Diode mit einem Arduino und dem Ad8402 findet sich hier:

    https://learnarduinoonline.blogspot.com/2019/12/spi-po…nd-arduino.html

    Leider werde ich daraus nicht ganz schlau. Wird dem Poti hier mit j ein Integer-Wert zugeschrieben?

    Ob mich diese Informationen bisher aber weiter bringen weiss ich nicht. Schade, dass sowas immer wie das Suchen der Nadel im Heuhaufen umschrieben werden kann und die Informationen nicht einfach zu finden sind. Im schlimmsten Fall werde ich es wie im Buch beschrieben mit zwei MCP4132 durchfuehren und CE0 sowie CE1 zur Ansteuerung verwenden. (Vielen Dank fuer den Tipp...)

    Faellt dir noch etwas ein?

    Vielen Dank und viele Gruesse,

    Jens Keller

  • Das was Du erwartest - eine Übersicht der notwendigen Kommandos - wirst Du so in keinem (richtigen) Datenblatt finden. Das ist die "Aufgabe" von Anleitungen, Application Notes oder Tutorials. Im Datenblatt steht alles was Du (wirklich) brauchst: Timing Diagramm und Aufbau des Protokolls. Und wenn Du das befolgst, dann klappt das auch auf jedem System. Da das Protokoll sehr einfach ist, dürfte es theoretisch auch funktionieren, wenn Du die Daten mit Tasten rein triggerst (ich gehe weiter unten nochmals darauf ein).

    Die Details des Timing Diagramms (auf Seite 10, Figure 4) würde ich mal mal außen vor lassen und mich vorerst auf den richtigen Ablauf (Figure 3, 4) kümmern.

    1) Also zuerst mal !CS (! bedeutet negiert) auf LOW.

    2) Jetzt, das jeweilige Adress- bzw. Datenbit an SDI anlegen.

    3) CLK auf HIGH und wieder auf LOW (geringe Mindestwartezeit für tCH = 10ns siehe Table 4)

    4) nächstes Datenbit anlegen. Jetzt wiederholt sich 1-3 (außer !CS, der bleibt low)

    5) Wenn alle Daten übertragen wurden wieder !CS auf HIGH. Danach stellt sich der Ausgangswert ein.

    Die restlichen Pins haben wir ja schon oben definiert.

    In Figur 3 siehst Du auch den den Inhalt der Daten erklärt. Zuerst die beiden Adressbits (A1/A0), danach der Einstellwert (D7 bis D0).

    In Table 13 auf Seite 22 ist übrigens noch erklärt, was das jeweilige Adressbit bedeutet.

    Für solche einfachen seriellen Protokolle verwende ich normalerweise nicht mal die dafür vorgesehene Hardware sondern schreibe das einfach in einer Schleife mit entsprechenden Waits raus. Das ist genau der Vorteil des SPI Protokolls: Clk gibt an, wann die Daten übernommen werden sollen. Daher ist das Timing ziemlich unkritisch und Du kannst das notfalls auch per Tasten rein schieben... Wie Du in der Tabelle der Timing Angaben siehst (Table 4), gibt es nur Mindestzeiten (CLK to SDO Propagation Delay ist in unserem Fall irrelevant). Du kannst also die Wartezeiten so lange machen, dass Du "zusehen" kannst - das könnte beim Verständnis und der Fehlersuche hilfreich sein.

    Übrigens, das braucht Zeit. Aber in solchen Situationen suche ich nicht lange nach fertigen Lösungen, sondern setze es lieber selbst um wie es im Datenblatt beschrieben ist. Auch andere machen Fehler und dann ist die Fehlersuche viel aufwändiger, als wenn Du es gleich selbst gemacht hättest...

    Ich fange immer klein an: Ein einfacher Versuchsaufbau und mal probieren bis mal was klappt, danach so lange "aufblasen" bis es so ist wie ich es brauche. Mir scheint, Du gehst einen anderen Weg: Vorher alles 100% definieren, überlegen und die fertige Hardware aufbauen. Bei mir klappt das nie ohne Zwischenschritte und ich habe schon oft beobachtet, dass sich diese Versuche im Sand verlaufen...

    ...wenn Software nicht so hard-ware ;) ...

    Freue mich über jeden like :thumbup:

  • Hallo VeryPrivat,

    vielen Dank malwieder fuer deine ausfuehrliche Hilfe.

    Ich werde mal ein kleines Programm schreiben, dass diese Schritte nacheinander durchfuehrt und schauen ob sich etwas tut. Sobald ich erste Schritte durchfuehre, werde ich sie hier natuerlich beschreiben. Malschauen, was passiert :)

    In diesem Sinne wuensche ich einen schoenen Restsonntag...

    Salzforscher

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!