Schnittstelle AD7811 ADC mit Arduino über SPI

TL;DR: Ich bekomme nicht die korrekten Werte vom AD7811 ADC zurück. Ich gebe dem ADC einen Eingang von meinem Benchtop-Netzteil (Tenma 72-2540) in den analogen Eingang 1 und erhalte verschiedene (und immer völlig falsche) Ergebnisse zurück (obwohl es eine gewisse Konsistenz gibt, lesen Sie weiter!). Ich habe zusätzliche Fragen zu dem Teil, der besser für einen separaten Beitrag geeignet wäre.

Genaueres zum Problem

Ich wollte den AD7811 ADC schnell mit meinem Arduino Mega 2560 testen, da ich vorhabe, den AD7811 für ein Hobbyprojekt zu verwenden, und er unterscheidet sich geringfügig von dem einzigen SPI-ADC, den ich zuvor verwendet habe (keine dedizierte „Slave-Auswahl“ an sich der AD7811, hat eine Kombination aus Conversion Start, Receive Frame Start und Transmit Frame Start). Durch die Verknüpfung von CONVST, RFS und TFS scheint es ähnlich zu funktionieren, wie Slave Select normalerweise für SPI-Geräte funktioniert. Ich werde das Mega nicht in meinem letzten Projekt verwenden, es war nur schneller, es zum Laufen zu bringen.

Schaltung Hier ist ein Diagramm meiner Schaltung, es implementiert das „Typische Verbindungsdiagramm“ auf Seite 10 des Datenblatts. (Ich habe auch einen Screenshot davon unter meiner Schaltung eingefügt)

Schema von Arduino verbunden mit AD7811

Typisches Anschlussdiagramm aus dem Datenblatt

Fotos von Verbindungen

Hier sind einige Aufnahmen, die zeigen, wie ich alles angeschlossen habe.

Ansicht von oben nach unten auf das Steckbrett

Nahaufnahme von ADC-Verbindungen

Makroansicht

Code

    #include <SPI.h>

const int convst = 42;  // CONVST pin on AD7811 connected to Pin 42 on Arduino
uint16_t return_val = 0;

// value to transfer to the control register (see page 7 of the datasheet)
uint16_t control = 0B1011000011; 

void setup() {
  // start the SPI library:
  SPI.begin();
  SPI.beginTransaction(SPISettings(2000, MSBFIRST, SPI_MODE0));
  pinMode(convst, OUTPUT);
  digitalWrite(convst, HIGH);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(convst, LOW); // Initiate the conversion process. Since TFS is also brought low, MOSI data is latched into the ADC (page 16)
  SPI.transfer(control>>2); // Transfer first 8 MSB of control settings (page 7 datasheet) i.e. 0B10110000 
  SPI.transfer(control<<6); // Transfer last 2 bits of control settings i.e. 0B11000000

  delayMicroseconds(3);      // Conversion process takes at most 2.3us 
  digitalWrite(convst, HIGH);// Bring CONVST, RFS and TFS high. First sentence of page 16 indicates that this would cause the result to be put on the SPI bus
  delayMicroseconds(1);
  return_val = SPI.transfer16(0); //read the 10 bit result
  return_val = return_val >> 6;   //SPI.transfer16 stores our result as a 16 bit number, but ADC only has 10bit resolution. Rightshift by 6 to correct this error. 

  Serial.println("Return");
  Serial.println(return_val); //print the value that we got back
  delay(1000);
}

Zurückgegebene Werte

Wie ich im TL;DR sagte, sind die Werte, die ich zurückbekomme, immer „falsch“ (vielleicht ist „nicht das, was ich erwartet hatte“ besser), aber es sind nicht unbedingt immer die gleichen Werte. Wenn ich beispielsweise 1 VDC in Eingang 1 des ADC einspeise, erhalte ich die Werte 617, 616, 105 und 104 als meine Rückgabewerte, die ich an die serielle Ausgabe drucke (dies ist, nachdem ich um 6 nach rechts bitverschoben habe). Es gibt kein wirklich erkennbares Muster, aber es ist immer einer dieser 4 Werte. Für 1 VDC-Eingang und mit Vref bei 5 VDC würde ich etwa 204 oder 205 als Rückgabewert erwarten (1/5 * 1024). Wenn ich auf 2VDC Eingang wechsle, bekomme ich 722, 721, 210, 209.

Scope-Erfassungen

  1. Nachweis, dass das Steuerregister beschrieben wird (MOSI-Leitung)

Die Steuerungseinstellungen scheinen den Arduino auf der MOSI-Leitung zu verlassen. Es gibt einen „Glitch“ (Terminologie?), der auftritt, wenn 0 von SPI.transfer16() übertragen wird: siehe die Aufnahme unten, es gibt eine kurze Spitze von ~300 ns Dauer um die fallende Flanke des 8. Taktzyklus. Ich bin mir nicht sicher, warum dies auftritt, ich sage dem Arduino, dass er eine 0 für diese Transaktion schreiben soll. Blau ist SLCK, Rot ist MOSI (Pin 51 Arduino)

Schreiben in das Steuerregister sowie Schreiben von 0 als Teil des Lesevorgangs

Fehler im Schreibvorgang

  1. MISO-Linie

Natürlich wollte ich die Antwort des ADC überprüfen. Blau ist SCLK, Rot ist MISO (Pin 50 auf Arduino)

MISO-Linie

Mir ist aufgefallen, dass es in den letzten 7 Taktzyklen (und noch mehr) gelegentlich zu einem exponentiellen Abfall kommt. Ich bin mir nicht sicher, was ich davon halten soll, aber es sieht nicht gut aus.

MISO mit exponentiellem Abfall

  1. Chip-Auswahl

Rot ist CONVST, RFS und TFS (zusammengebunden). Sobald dieser niedrig wird, beginnt die serielle Uhr zu ticken und Daten werden übertragen (wie in den Oszilloskopaufnahmen oben gezeigt). Blau ist SLCK, Rot ist CONVST/RFS/TFS (Pin 42)

Timing der Chipauswahl

  1. Überprüfung des Analogeingangs 1

Der Eingang zum ADC scheint sauber zu sein, ich habe ihn mit einem 10-nF-Kondensator umgangen, um den Eingang zu bereinigen.

Erfassung des ADC-Eingangs

Ich bin immer noch ziemlich neu darin, meine eigenen digitalen Designs zu erstellen, zum zweiten Mal mit SPI, also würde ich mich sehr über Hinweise oder Ratschläge freuen! Wenn mir irgendwelche Informationen fehlen, die Sie brauchen, werde ich sie für Sie besorgen. Ich bin bestrebt, mich zu verbessern, wo immer ich kann, einschließlich meiner Fähigkeiten zur Fehlerbehebung!

Antworten (1)

Wenn ich beispielsweise 1 VDC in Eingang 1 des ADC einspeise, erhalte ich die Werte 617, 616, 105 und 104 als meine Rückgabewerte, die ich an die serielle Ausgabe drucke (dies ist, nachdem ich um 6 nach rechts bitverschoben habe). Es gibt kein wirklich erkennbares Muster, aber es ist immer einer dieser 4 Werte. Wenn ich auf 2VDC Eingang wechsle, bekomme ich 722, 721, 210, 209.

Beachten Sie die Unterschiede zwischen den Werten:

  • 617 - 105 = 512
  • 616 - 104 = 512
  • 722 - 210 = 512
  • 721 - 209 = 512

Es ist klar, dass Sie Probleme haben, das neunte Bit des Werts richtig zu lesen – 2 9 = 512. Manchmal erhalten Sie „1“ und manchmal „0“.

Die Variation um einen Zählwert (617 gegenüber 616 usw.) ist einfach ein normaler Quantisierungsfehler.


Mir ist aufgefallen, dass es in den letzten 7 Taktzyklen (und noch mehr) gelegentlich zu einem exponentiellen Abfall kommt. Ich bin mir nicht sicher, was ich davon halten soll, aber es sieht nicht gut aus.

Eigentlich ist das ganz normal. Während eines Lesezyklus treibt der AD7811 nur Daten für die ersten zehn Taktzyklen, dann tristatet er seinen Ausgang. Wenn das letzte Datenbit (das LSB des Messwerts) 1 ist, fällt die Signalspannung langsam ab, wenn der Treiber ausgeschaltet wird. Sie ignorieren diese letzten 6 Bits sowieso.


Insgesamt würde ich sagen, dass das Verdächtigste, was ich sehe, das Timing auf Ihrer MOSI-Linie ist. Der AD7811 erwartet, dass die Daten während der fallenden Taktflanke stabil sind, aber in Ihren Spuren scheinen sie sich zu ändern. Möglicherweise müssen Sie den Modus in Ihrem SPI-Master zwischen Schreiben und Lesen umschalten, um dies richtig zu machen.

Das ist eines der schlimmsten Dinge am SPI-„Standard“ – es gibt vier verschiedene Möglichkeiten, um zu konfigurieren, wie die Uhr relativ zu den Daten gesteuert wird (sowohl Lesen als auch Schreiben), und es ist manchmal schwierig, die erforderlichen Einstellungen aus dem Datenblatt eines Geräts abzuleiten .

Ich weiß es zu schätzen, dass Sie sich das ansehen. Abgesehen vom 9. Bit entspricht keiner dieser Werte dem, was ich erwarten würde. Ich habe den Beitrag mit dem erwarteten Wert aktualisiert, aber für 1 VDC würde ich ungefähr 204 oder 205 (1/5 * 2 ^ 10) erwarten. Unabhängig davon, haben Sie eine Ahnung, was dazu führen könnte, dass ich das 9. Bit falsch lese?
Siehe Bearbeiten oben.