mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ADC sehr ungenau


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Benjamin G. (benjamin95)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe Probleme mit dem ADC vom STM32L476 µC. Ich habe eine PCP 
entworfen und will die Spannung an einem Pin mithilfe des ADCs messen. 
Dazu verwende ich den ADC1 mit 12bit Auflösung in DMA mode. Lege ich den 
Pin auf Ground, liefert mir der ADC einen Wert von 500 (von max. 4095). 
Lege ich 3.3V an, was auch die Spannung am VREF+ Pin entspricht, bekomme 
ich 3578 (also auch nicht das Maximum). Es scheint als würde ein sehr 
großer Offsetfehler von 500 und eine sehr starke nichtlinearität 
vorhanden sein. Wisst ihr wo der Fehler liegen kann. Schaltplan und Code 
im folgendem bzw. angehängt. (ANALOG_IN2 ist der eingangspin zum ADC, 
SENSOR_CONTROL2 ist zur zu und abschalten der Spannungsversorgung an 
einem angeschlossenem Sensor)

Mit dem Multimeter hab ich den Pin natürlich gemessen und die Spannungen 
passen!

PS: Sonst funktioniert alles einwandfrei (GPIO, UART, ...).

Code zur configuration des ADCS (mithilfe von CubeMX erstellt)

static void MX_ADC1_Init(void)
{

  ADC_MultiModeTypeDef multimode;
  ADC_ChannelConfTypeDef sConfig;

    /**Common config
    */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV12;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.NbrOfConversion = 2;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.NbrOfDiscConversion = 1;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = ENABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    _Error_Handler(_FILE_, _LINE_);
  }

    /**Configure the ADC multi-mode
    */
  multimode.Mode = ADC_MODE_INDEPENDENT;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  {
    _Error_Handler(_FILE_, _LINE_);
  }

    /**Configure Regular Channel
    */
  sConfig.Channel = ADC_CHANNEL_15;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_1;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    _Error_Handler(_FILE_, _LINE_);
  }

    /**Configure Regular Channel
    */
  sConfig.Channel = ADC_CHANNEL_16;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  sConfig.OffsetNumber = ADC_OFFSET_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    _Error_Handler(_FILE_, _LINE_);
  }

}


Vielen Dank für eure Hilfe :)

: Bearbeitet durch User
Autor: Roland E. (roland0815)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diode verpolt eingebaut?

Autor: A. S. (achs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
relevant (und unkritisch) sind nur die 100R und die Diode.

Benjamin G. schrieb:
> Mit dem Multimeter hab ich den Pin natürlich gemessen und die Spannungen
> passen!

Wo zwischen genau? Der Teil fehlt vollkommen.

: Bearbeitet durch User
Autor: Possetitjel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Benjamin G. schrieb:

> eine PCP entworfen

VUA

Autor: Harlekin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sind Vref-, Vref+, VSSA und VDDA beschalten?
Spannung zwischen den Pins Vref- und Vref+ sowie VSSA und VDDA prüfen.

Autor: Harlekin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den Code habe ich jetzt nicht studiert. Wie verhalten sich mehrere 
Messwerte nacheinander?

Autor: Harlekin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo im Code wird Vref gewählt?

/The internal voltage reference buffer supports two voltages:
• 2.048 V
• 2.5 V
An external voltage reference can be provided through the VREF+ pin when 
the internal voltage reference buffer is off.
The VREF+ pin is double-bonded with VDDA on some packages. In these 
packages the internal voltage reference buffer is not available./

Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe an der Sensorversorgung keinerlei Siebmittel, sondern eher was, 
was die Versorgung schlechter (hochohmiger) macht, nämlich einen MOSFet. 
Es wäre also evtl. sinnvoll, die Versorgung abzublocken.

Autor: M.Edy (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Benjamin G. schrieb:
> Ich habe eine PCP entworfen ...

Alles klar
https://www.urbandictionary.com/define.php?term=PCP

Autor: Andreas S. (igel1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne Code und Schaltplan genau gesichtet zu haben, hier nur ein Hinweis:

Es gibt eine Menge "Application Notes" von ST zum Thema ADC-Genauigkeit.
Ich habe mir z.B. folgende abgespeichert (Filenamen sind von mir frei 
gewählt - Du erkennt an den Namen aber, wonach Du suchen musst):

AN4073.Improve_ADC_accuracy_STM32F2xx_STM32F4xx.pdf
AN3116.STM32s ADC modes.pdf
AN2834.ADC_accuracy_in_STM32Fx_and_STM32L1_series.pdf
AN1636.Understanding_and_Minimising_ADC_Conversion_Errors.pdf

Viele Grüße

Igel1

Autor: ADC Freund (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
klingt so, als würdest du das Signal auf den falschen Kanal legen und 
lediglich das Übersprechen messen. Wenn der eigentliche Messkanal 
floatend ist, misst der so in etwa das was der falsche Kanal am Eingang 
liegen hat.

Beitrag #5399381 wurde vom Autor gelöscht.
Autor: Benjamin G. (benjamin95)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK also:

Diode ist richtig drinnen

Die Spannung habe ich jetzt noch einmal direkt am Pin gemessen. Wenn ich 
den Sensor auf GND hänge, liegen am Pin 0,077 V an. Wenn ich ihn auf VCC 
(3,23 V hänge) liegen 3,1 V an. Also nicht wirklich ideal! Aber das 
erklärt noch immer nicht die große Ungenauigkeit.  Vref-, Vref+, VSSA 
und VDDA sind laut dem Datenblatt des µCs beschalten. Also Vref- auf 
GND, Vref+ auf VCC. VSSA auf GND und VDDA über eine Induktivität von VCC 
entkoppelt verbunden.

VREF+ wird doch automatisch als Referenzspannung für den ADC verwendet. 
Also im user Manual habe ich nichts gefunden.

Auch wenn ich die Versorgung des Sensors weglasse, bekomme ich ungenaue 
Werte.

Die Pins sind richtig verbunden, also ich messe mit dem ADC nicht das 
Übersprechen.

Mehrere Messwerte hintereinander ergeben immer das gleiche Ergebnis.

PS: PCB.... nicht PCP ^^

Autor: A. S. (achs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Benjamin G. schrieb:
> Die Spannung habe ich jetzt noch einmal direkt am Pin gemessen.

was ist mit "Pin" gemeint? Ich hoffe, der AD-Eingangs-Pin am 
µController? Dann bleibt der zweite Teil der Frage weiterhin offen:

Achim S. schrieb:
> Wo zwischen genau? Der Teil fehlt vollkommen.

Messe mal wirklich (bei 0V) genau zwischen dem AD-Eingangs-Pin und dem 
GND-Ref-Pin.

Gegen VCC entsprechend gegen den HIGH-REF-Pin.

Autor: Benjamin G. (benjamin95)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja natürlich der Analog eingangspin des ADCs!

Also die Spannung zwischen deim Eingangspin und dem VREF- beträgt 0,05V. 
Ich bekomme jedoch einen Digitalwert von 543 (bei 12 bit Auflösung). 
Wenn ich den Sensor auf GND schalte.

Wenn ich den Eingang auf VCC schalte, hab ich eine Spannung von -0,163 V 
zwischen dem Pin und VREF+ (also VREF+ ist um 0,163V höher als der 
Eingangspin des ADCs) Der Digitalwert beträgt dabei 3634.

Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat das S&H-Glied des ADCs denn genug Zeit, um sich auf die 
Eingangsspannung aufzuladen? So ein ADC multiplext in der Regel ja 
mehrere Eingänge auf ein S&H-Glied und wenn man zu schnell zwischen den 
Eingängen umschaltet hängt die Spannung, die am Ende rauskommt, auch 
irgendwie davon ab, was an den anderen Eingängen anliegt.

Autor: Harlekin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Harlekin schrieb:
> An external voltage reference can be provided through the VREF+ pin when
> the internal voltage reference buffer is off.

http://www.st.com/resource/en/reference_manual/dm00083560.pdf
Seite 680f Kapitel 21 Voltage reference buffer (VREFBUF)

Register VREFBUF_CSR: Der Default-Wert ist extern, somit müsste es 
eigentlich passen.

Benjamin G. schrieb:
> 0,05V. Ich bekomme jedoch einen Digitalwert von 543
(4.8)
> 3.067V 3634
(301)

Ich habe das Datenblatt noch nicht verstanden: könnte wegen der 
Kalibriermöglichkeit ein Faktor 10 enthalten sein?

Autor: Harlekin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Kalibrieren ist in folgendem Kapitel beschrieben:
18.4.8 Calibration (ADCAL, ADCALDIF, ADCx_CALFACT) auf Seite 515

Autor: Benjamin G. (benjamin95)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Update.

Eine Kalibrierung habe ich laut reference Manual durchgeführt. Ich habe 
jetzt eine identische zweite Platine angefertigt. Bei der funktioniert 
der ADC mit dem exakt gleichem Programm perfekt. Ich habe aber die 
komplett gleiche Schaltung aufgebaut und mehrmals kontrolliert.

Mir ist jedoch aufgefallen, dass bei der Platine bei welcher der ADC 
nicht funktioniert zwischen dem µC ADC Eingangs PIN und dem Pin des 
Steckers welcher mit dem Eingangs PIN des ADCs über einen 100 Ohm 
Widerstand (R40) und einer Diode (D2) gegen Ground verbunden ist(siehe 
Schaltplan oben), eine Spannung von 0,051 V herrscht, wenn der 
Eingangspin mit Ground verbunden ist. Dies ist bei der anderen Platine 
nicht der Fall.

Meine Idee war nun, dass ein Strom aus dem Eingangspin des ADCs 
rausfließt und einen Spannungsabfall am Widerstand verursacht. Dieser 
Gedanke hat sich durch Messen auch Bestätigt! Es fließt ein Strom von 
0,6 mA über den 100 Ohm Widerstand nach Ground. Dies erklärt schon 
einmal die Spannungsdifferenz. Mir ist aber nicht bewusst, warum dort 
ein Strom fließt?  Der Pin ist eindeutig richtig konfiguriert (bei der 
andern Platine funktioniert das Programm ja). Kann es sein, dass der µC 
kaputt ist? (beim Einlöten etwas beschädigt, oder so)

PS: Bei der anderen Platine fließt dort kein Strom!

Eure Meinungen dazu würden mich interessieren!

LG Benjamin

Autor: Sven B. (scummos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klingt nach ESD-Schaden. Controller wegwerfen und neuen einbauen. 
Passiert.

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehe ich auch so. Der Eingang ist wohl defekt.

Autor: Benjamin G. (benjamin95)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja klingt logisch!

Hab den µC ausgetauscht und es funktioniert!

Danke euch :)

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.