ADC-Wert-Konvertierung

Ich erhalte den vollen ADC-Wert von 0 to 16348. Ich versuche, es in 4-20 mA und dann in 0-25 bar Druck umzuwandeln, da ich letztendlich Druck messe.

Ich verwende die y = mx+cGleichung, scheitere aber kläglich. Kann mir bitte jemand eine Anleitung geben, damit ich etwas lernen kann.

Ich versuche so etwas wie

4 = m*0 +c
c = 4.

20 = m*16348 +4.

m = 0.0009789.

Mein Controller unterstützt keine Fließkommazahlen ... daher bereitet er mir Probleme. Kann mir jemand weiterhelfen>?

Sind Sie sicher, dass 4 mA einer 0-Zählung und 20 mA einer 16383-Zählung entsprechen?
Versuchen Sie, es als y = x * mn / md + c zu schreiben. Dann ist mn = 16 und md = 16348. Stellen Sie sicher, dass Sie die Multiplikation vor der Division durchführen.

Antworten (3)

Da Ihr Mikrocontroller kein Gleitkomma unterstützt, müssen Sie die Zahlen vergrößern und dann wieder nach unten dividieren. Dazu müssen Sie lange (32-Bit) Arithmetik verwenden.

Für den ADC sind 4 mA = 0 und 20 mA = 16384. Daher wird die Differenz 16 mA auch durch 16384 dargestellt.

Wenn wir den vollen Wert des Balkendiagramms, 25, nehmen und durch 16384 dividieren, erhalten wir: 0,001526. Aber wir können diesen Wert nicht direkt verwenden, da es sich um einen Gleitkommawert handelt. Also nehmen wir stattdessen eine Million und machen dasselbe. 1000000 / 16384 = 61,03 Jetzt haben wir eine Zahl, die nahe genug an einer Ganzzahl liegt, mit der wir arbeiten können.

Wenn wir den Messwert vom ADC nehmen, mit 61 multiplizieren und durch 40000 dividieren (was 1000000 / 25 ist), dann haben wir eine Zahl im Bereich von 0 bis 25. Um dies auszuprobieren, wenn wir einen Wert nehmen, der der Hälfte des Bereichs entspricht (16384/2), dann erhalten wir für 8192 * 61 / 40000 12,49 oder die Hälfte von 25 (aber aufgrund seiner ganzzahligen Division wird er auf 12 abgerundet)

Wenn Sie für eine andere Anwendung einen ganzzahligen Wert in skalierten Hundertern (dh multipliziert mit 100) wünschen, könnten Sie durch 400 statt durch 40000 dividieren und 1249 erhalten (entspricht 12,49).

Der Code sieht also ungefähr so ​​​​aus (ich habe Casting verwendet, um sicherzustellen, dass alle erforderlichen Berechnungen so lange durchgeführt werden)

#define CONSTANT1 = (1000000L / 16384L)       // 61    
#define CONSTANT2 = (1000000L / 25L)          // 40000

unsigned short ADC_value;
unsigned short bar_value;

ADC_value = get_ADC();
bar_value = (unsigned char)(((unsigned long)ADC_Value * CONSTANT1) / CONSTANT2);

Es ist nicht sehr klar, was Sie tun, also gehen wir Schritt für Schritt vor.

Der Sensor gibt also einen Strom aus, wobei 0-25 Bar 4-20mA entsprechen.

ICH S e N S = 16 M A P 25 B A R + 4 M A

Jetzt hat der ADC selbst einen Eingangsbereich, zB 0-5V und wandelt ihn in eine ganze Zahl um. Ich weiß nicht, wie Sie 16348 erhalten, der nächste übereinstimmende Wert wäre 16383, was binär 111111'11111111 ist. (Das ist der Maximalwert eines 14-Bit-ADC)

Sie benötigen also einen Widerstand wie R = 250 Ohm, der an Ihren Sensorausgang (an Masse) angeschlossen ist und den Strom in 1-5 V umwandelt

Nun, die Formel lautet

v A D C = 4 v P 25 B A R + 1 v

und dies wird auf den ADC-Bereich abgebildet

N A D C = 16383 16 20 P 25 B A R + 16383 4 20
und seine Rückseite
P = ( N A D C 16383 4 20 ) 20 25 B A R 16383 16

oder nach dem aufräumen:

P = 125 N A D C 409575 262128 B A R

Dies ist das Beste, was Sie bekommen können, die Auflösung beträgt jedoch nur 1 Bar, da p eine ganze Zahl ist. Und wie in den Kommentaren gesagt, ist es wichtig, die Teilung als allerletzten Schritt durchzuführen.

Die Auflösung ist schlecht, obwohl der Dynamikbereich 16383/20 * 16 = 13106 beträgt (das ist die Anzahl der Schritte, auf die der ADC Ihren Eingangsbereich abbildet). Für eine bessere Auflösung können Sie sich für Millibar entscheiden:

P = 1000 ( 125 N A D C 409575 ) 262128 M ich l l ich B A R

Führen Sie auch hier zuerst die Multiplikation durch. Und: Der größte Wert des Zählers ist 1.638.300.000, was 31 Bit belegt. Sie müssen also sicherstellen, dass Ihr Mikrocontroller diese Berechnung mit 32-Bit-Ganzzahlwerten durchführt.

Einige Ideen:

  • Wenn Sie diese großen Zahlen nicht mögen, können Sie statt 16383 auch 16384 verwenden. Dies ist nur eine kleine Abweichung, erlaubt aber möglicherweise mehr Streichungen im Bruch. Wenn Sie niemals 25 Bar messen werden, versuchen Sie es mit einem Widerstand, der bereits bei 24 Bar die maximale Spannung liefert. Dieser Wert ermöglicht auch mehr Stornierungen.

  • Einige Mikrocontroller, z. B. von Microchip, ermöglichen die Angabe von Min/Max-Referenzspannungen, z. B. können Sie zwei Spannungen verbinden, die die obere und untere Grenze des ADC definieren. Bei 1 V und 5 V werden die 1-5 V vom Widerstand auf die vollen 14 Bit des ADC abgebildet, sodass Sie die vollen 16384 Schritte erhalten, nicht nur 80 % davon.

  • Der letzte Punkt kann auch durch einen Operationsverstärker erreicht werden.

BEARBEITEN:

Da die Werte maximal 31 Bit benötigen, sollten Sie einen vorzeichenbehafteten 32-Bit-Ganzzahlwert verwenden (dh 1 Bit für das Vorzeichen und 31 für die Zahl). Wenn kein Sensor angeschlossen ist / der ADC weniger als 1 V erhält, erhalten Sie einen negativen Wert für den Druck, der als ungültig bezeichnet werden kann.

Wenn Sie vorzeichenlose 32-Bit-Ganzzahlen verwenden, erhalten Sie in diesem Fall etwas Müll und können nicht zwischen gültigem und ungültigem Wert unterscheiden.

Ich vermute, dass Sie tatsächlich einen Wert von 0 bis 16383 (3FFFh) erhalten, wie es für einen 14-Bit-ADC üblich ist. Es scheint ziemlich seltsam, dass Ihr ADC für 4 mA den Wert Null angeben würde, aber das sagen Sie uns, also nehme ich an, dass Sie eine spezielle Schaltung haben, die dies für Sie erledigt.

Die Umwandlung in Milliampere als mittleren Schritt ist Unsinn, das ist eine Darstellung, die von Menschen verwendet wird und von Ihrer Software nicht benötigt wird, es sei denn, Sie möchten den Strom auf einem Display oder so anzeigen. Es scheint, dass Sie diesen mittleren Schritt nicht benötigen, er verursacht lediglich Rundungsfehler.

Dasselbe gilt für Gleitkommazahlen: In den meisten Fällen sollten Sie keine Gleitkommazahlen verwenden, da die Wahrscheinlichkeit groß ist, dass sie schrecklich langsam sind. Sie sind immer langsamer als ganze Zahlen, aber besonders dann, wenn keine FPU an Bord ist.

Was Sie also tun sollten, ist: Hören Sie beim Programmieren auf, so zu denken, wie Sie es beim Rechnen tun. Gleitkommazahlen sind für die Fälle reserviert, in denen Sie Genauigkeit und fortgeschrittenere Mathematik benötigen, wie z. B. Trigonometrie. Ihr Programm wird in 95% der Fälle mit rohen Ganzzahlen einwandfrei funktionieren.

Für das vorliegende Problem haben Sie einen ganzzahligen Wert von 0 bis 16383, den Sie in 0-25 bar umwandeln möchten. Mit gibt y = mx + cIhnen 25 = m*16838 + 0, m = 25/16838. Wenn Sie also einen beliebigen ADC mit multiplizieren, 25/16383erhalten Sie den Balkenwert, dh adc_read * 25 / 16383.

Wir müssen auch mit 1000 multiplizieren, um eine höhere Auflösung zu erhalten, Millibar statt Bar. Anscheinend ist der größte Wert, den wir in diesem Fall jemals finden können, 16383 (max ADC read) multipliziert mit 25*1000= 159 * 10 ^ 6. Dies passt nicht in eine 16-Bit-Ganzzahl, also müssen wir 32-Bit-Arithmetik verwenden.

uint32_t adc_read = ADC_DATA_REGISTER;
uint8_t millibar = (uint8_t)(adc_read * 25ul * 1000ul / 16383ul);

Und das ist es. Angenommen, 0 entspricht tatsächlich 4mA.