Eigenbau ADC am Raspberry Pi
von Benutzer:Fpgakuechle (Volker Urban)
2015-01-24: 1. Stadium: "Materialsammlung", Grobgliederung
Als "Versuchsaufbau" zum Artikel Hardwarenahe Programmierung am Raspberry Pi diente ein "diskret" aufgebauter Analog Digital Umsetzer. Verwendet werden eine Handvoll Widerstände 1k, 2k und ein Komperator (OPV) Typ Texas Instrument TLC393C. Die Idee ist dieser Application Note: [1] entnohmen. Da keine Sample&Hold Stufe vorgeschaltet ist, eignet sich dieser Aufbau nur für langsame ändernde Größen wie der Widerstand eines Temperaturfühlers.
Im Versuchsaufbau wurde die Messgröße durch ein Poti zwischen Betriebsspannung und Masse nachgestellt.
Prinzip/Aufbau
Komperator mit der zu messenden Spannung an dem einen und dem Ausgang eines Digital-Analog-wandlers an dem anderen Eingang. Der DAC ist als Widerstandsnetzwerk R 2R aufgebaut. Der RasPi steuert über 8 Ausgänge den DAC und liest das Ergebnis des Spannungsvergleich an einem Eingang.
Open Drain Stufe Komperatorausgang
Der Ausgang des Komperators ist im hochohmigen Zustand wenn die referenzspannung (DAC) höher ist als die zu messende Spannung. Die Schaltung ist also um einen PullUp-Widerstand gegen die betriebsspannung zu ergänzen um ein im RasPi auswertbares Signal zu erhalten. Dieser wurde erst extern ergänzt. Erste Messungen ergaben allerdings eine Spannung von ca. 2.4V statt 3V3. Das weist darauf hin das im RasPi ein standardmäßig der PullDown gegen Masse aktiv ist. Deshalb wurde für dieses Pin der PullUp aktiviert worauf sich der gewünschte Pegel von 3.3V einstellt. Somit ist der externe Widerstand verzichtbar. Siehe [2]:
const int C_PIN_COMPRES = 1;
/* .. code snip .. */
pinMode(C_PIN_COMPRES,INPUT);
/* variant 1 -> all internals Pull off -> external PullUp resistor needed */
pullUpDnControl(C_PIN_COMPRES,PUD_OFF);
/* variant 2 -> internal PullUp to 3.3V activated -> none external resistor needed */
pullUpDnControl(C_PIN_COMPRES,PUD_UP);
Pinzuordnung
Die Nummer der Pins nach der wiredPi Bibliothek wird in einem Feld aus 8 Integer abgelegt. Der Index entspricht dabei der binären Wertigkeit am DAC - auf Index 7 liegt das Pin 13. Ist nur dieses aktiv ('1') und die anderen Null wird der DAC mit dem wert 128 (also 2 hoch 7) angesteuert, als stellt sich also ein Wert um die halbe Maximalspannung ein.
/* pin numebering of pins driving the R2R DAC network */
/* 0 1 2 3 4 5 6 7 */
const int C_PIN_2POW[8] = { 8, 9, 7, 0, 2, 3,12,13};
const int C_PIN_COMPRES = 1;
Kalibrierung
Jeweils ein Bit am DAC wird aktiviert und die eingestellte Spannung mit einem Multimeter ermittelt. Dieser Wert wird als 32 bit integer gespeichert, wobei 1 einer abgelesenen Spannung von 100µV entspricht. Ebenso wird die Offsetspannung ermittelt, die Spannung die anliegt wenn kein bit am DAC aktiviert ist.
/*values in 100 microvolt aka a teenth of a milivolt*/
const int C_CALIB_OFFSET = -8 ;
/* 0 1 2 3 4 5 6 7 */
const int C_CALIB_2POW[8] = {131,262,531,1055,2090,4170,8300,16540};
Steuerprogramm
/* compare and adjust intervall */
for (i=7;i>=0;i--) {
digitalWrite(C_PIN_2POW[i],HIGH);
delayMicroseconds(300);
/*if reference (DAC) voltage < unknown voltage*/
if (digitalRead(C_PIN_COMPRES) == HIGH)
/* increase lower intervall boundary */
digitalWrite(C_PIN_2POW[i],LOW);
/* decrease reference value */
else intervall_low_bound += intervall_halfwidth;
intervall_halfwidth /= 2;
}
Optimierung
Höhere Samplerate
Die Samplerate das AD-Wandlers wird bei der sukzessiven Approximation wird bestimmt durch:
- die Zeit die es braucht bis sich am Ausgang des Widerstandnetzwerkes (DAC) die Referenzspannung sicher eingestellt hat - settling time
- die Zeit bis die Ausgangs des Komperators durchgeschaltet hat
- die Zeit bis im Rasperry das signal des Komperators sicher erkennt wurde
Im verwendeten Aufbau wird der Messzeitpunkt durch die Wartezeit zwischen setzen eines einzelnen eines bits des DAC und if-Abfrage des Vergleichsergebnisses eingestellt.
- bitspezifische Wartezeit für Verstreichen der settling time
- kapazitätsarmer Aufbau
Genauigkeit
- Tabelle von 256 Referenzwerten statt nur 8 referenzwerte für die bits