Tips och förslag innan man börjar med Sigma-Delta ADC?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
DanielM
Inlägg: 2166
Blev medlem: 5 september 2019, 14:19:58

Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av DanielM »

Hej!

Som ni alla vet så har jag fått mitt fina kort och nu väntar jag bara på elektronikkomponenter från Mouser.
Medan tänker jag börja programmera lite C i STM32CubeIDE och jag tänkte börja med att titta närmare på något som heter Sigma Delta ADC, dvs en "bättre" ADC på 16-bit, istället för STM32's 12-bit ADC som kan
uppfattas som en standard.

Jag läser nu dokumentet Getting started with STM32F37x/38x SDADC (Sigma-Delta ADC) AN4207 och jag har valt:
  • * 2 x SD ADC
    * 3 x Differential SD ADC
Vad rekommenderar ni här, om det finns något att tillägga?
Vilken "gain" ska man ha?
Vad ska man akta sig för?
Finns det några praktiska erfarenheter ni vill dela med er om just när det kommer till Sigma Delta ADC? :)

Jag kommer kalibrera min efter 0-3.3V vilket är VCC referensen, eller 0.6-3.0 om det finns möjlighet.
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Re: Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av Micke_s »

Min input i en osorterad lista
  • Linjäriteten nära ändlägena på en ADC brukar vara sådär.
  • Val av hastighet på ADC avgör hur många användbara bitar man får ut.
  • Kontrollera att in-impedansen på ADC räcker för inte belasta mätpunkten, kanske behövs en buffert?
  • Gain brukar man välja efter vad man ska mäta. Högsta som täcker in området typ. Kan även vara olika olinjär på olika Gain.
  • Bra avstörning för AVDD och AVREF.
  • Lite analogt filter utanför brukar inte heller skada.
  • Kanske lite skydd innan I/O pinnen också.
  • Kolla upp om det finns några begräsningar på insignalen spänningsnivåer om man väljer SD/Diff och Gain nivåer.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45175
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av TomasL »

Studera och förstå datablad och app-notes, såpass mycket att man kan dem utantill.
DanielM
Inlägg: 2166
Blev medlem: 5 september 2019, 14:19:58

Re: Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av DanielM »

Micke_s skrev: 7 december 2020, 22:17:11 Min input i en osorterad lista
  • Linjäriteten nära ändlägena på en ADC brukar vara sådär.
  • Val av hastighet på ADC avgör hur många användbara bitar man får ut.
  • Kontrollera att in-impedansen på ADC räcker för inte belasta mätpunkten, kanske behövs en buffert?
  • Gain brukar man välja efter vad man ska mäta. Högsta som täcker in området typ. Kan även vara olika olinjär på olika Gain.
  • Bra avstörning för AVDD och AVREF.
  • Lite analogt filter utanför brukar inte heller skada.
  • Kanske lite skydd innan I/O pinnen också.
  • Kolla upp om det finns några begräsningar på insignalen spänningsnivåer om man väljer SD/Diff och Gain nivåer.
Jag återkommer till ditt inlägg senare.
TomasL skrev: 7 december 2020, 22:27:07 Studera och förstå datablad och app-notes, såpass mycket att man kan dem utantill.
Jag håller på med det.
Jag har koll på grunderna, men det jag inte begriper är just hur man använder det i STM32CubeIDE.

Det finns alltså tre inställningar man kan ha:

* Differentiell
* Singel
* Singel som har samma spann som differentiell, men är bara en signal

Differentiell inställning:

Denna har formel:

Kod: Markera allt

Vin = SDADCx_AINyP - SDADCx_AINyM = ReadData * Vref/(2 x gain x 32767) 
Markering_008.png
Exempel:
Jag tänker använda 3 stycken differentiella ingångar, dvs 6 totalt.
Här använder jag VDD som referens Vref. I detta fall är det 3.3v. Rätta mig om jag har fel. Jag funderar på att använda gain 0.5x här för att jag vill mäta en skillnad mellan 0 och 3.3 volt.

Kod: Markera allt

Förstärkning: A = Vref/(2 * gain * 32767) = 3.3/(2* 0.5 * 32767)
Ingångsspänningsspann: [-Vref/(2*gain), + Vref/(2*gain)]  = [-3.3/(2*0.5), +3.3/(2*0.5)] = [-3.3, + 3.3]
Värdespann för 16-bit differentiell ADC: [-32767, +32767]
Detta betyder att när det är 3.3 volt skillnad mellan differentiella ingångarna, så har jag alltså full -32767 eller +32767 beroende på om skillnaden är -3.3v eller +3.3v

Singel som har samma spann som differentiell
Jag utesluter bara singel, då den är bara mellan [0, 32767]. Jag vill använda den andra metoden som innefattar denna formula

Kod: Markera allt

Vin = SDADCx_AINyP = (ReadData + 32767) * Vref/(gain x 65535)
Exempel:

Sätter jag gain = 0.5. och applicerar +3.3 volt så kommer jag få:

Kod: Markera allt

Vin = (ReadData + 32767) * Vref/(gain x 65535) = (2^16 + 32767) * 3.3/(0.5*65535) = 3.3
Så vid 3.3 volt in på ingången så har jag antingen full -32767 eller +32767 beroende på om skillnaden är 0v eller +3.3v

Jag kan ha fel. Det kanske ska lika gärna vara gain = 1.0 också.

Det största problemet jag har nu är att förstå hur jag ska förklara detta för STM32CubeIDE.
Markering_009.png
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
AndLi
Inlägg: 17051
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Re: Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av AndLi »

Var inte dina ADC externa SPI anslutna?
Kan man generera kod för externa komponenter i Cube nuförtiden med?
DanielM
Inlägg: 2166
Blev medlem: 5 september 2019, 14:19:58

Re: Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av DanielM »

Nej. Mina ADC är helt interna :)

Beror på vilka. Du kan generera färdig kod för:
* Trådar
* SD kort
* SPI
* I2C
* Kamera
* HDMI
* USB
* CAN
* Touch
* Neurala nätverk via STM32CubeAI (Ja, det fungerar)
* osv
DanielM
Inlägg: 2166
Blev medlem: 5 september 2019, 14:19:58

Re: Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av DanielM »

Ingen som kan något om Sigma Delta ADC för STM32? Det lär väll vara samma teori och praktik oavsett CPU, eller?
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Re: Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av Micke_s »

Min erfarenhet av Sigma delta är att du kommer ha dessa problem i slutänden.
Tror nog detta gäller alla typer av ADC.

* EMC problem som måste lösas med analoga filter utanför. Eventuellt något annat runt din processor.
* Upplösningen inte räckte till för det du tänkte mäta.
* Din kalibrering sprider för mycket mellan olika enheter när du gör många enheter
* Diverse temperaturberoende problem.
* Stegsvaret är för långsamt.
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Re: Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av Micke_s »

Gör en enkel beräkning om upplösning och dina val på förstärkning fungerar på vad du ska mäta.
Sedan är det köra på riktig hårdvara för att se om det stämmer med verkligheten.

När det gäller STM32 så är det registeruppsättningarna du ska studera och ställa in.
Jag är lite osäker om det är själva egenskaperna på en ADC eller egenskaperna på själva registerna på STM32 du frågar efter.

Du kan även stöta på att Databladet:s data ljuger/förskönar/döljer egenskaper och du inte kan använda Sigma-Delta ADC:n till din tillämpning.
DanielM
Inlägg: 2166
Blev medlem: 5 september 2019, 14:19:58

Re: Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av DanielM »

Nu har jag börjat fått det fungera med SD-ADC.
Jag lade till en interupt på varje SD-ADC. Så när det händer något, så nyper den ett värde.

Då ska denna funktion köras. Men nackdelen är att jag har två interupts och EN funktion. Kan man ha så?
Det är lite sökigt med värderna.

Kod: Markera allt

// When we got a measurement
void HAL_SDADC_InjectedConvCpltCallback(SDADC_HandleTypeDef *hsdadc){
  /* Get conversion value */
	// SD ADC 1
	uint32_t CHANNEL = 4;
	SD_ADC_VALUES[0] = HAL_SDADC_InjectedGetValue(&hsdadc1, &CHANNEL);
	CHANNEL = 8;
	D_SD_ADC_VALUES[0] = HAL_SDADC_InjectedGetValue(&hsdadc1, &CHANNEL);
	CHANNEL = 6;
	D_SD_ADC_VALUES[1] = HAL_SDADC_InjectedGetValue(&hsdadc1, &CHANNEL);

	// Same channel value as before
	SD_ADC_VALUES[1] = HAL_SDADC_InjectedGetValue(&hsdadc3, &CHANNEL);
	CHANNEL = 8;
	D_SD_ADC_VALUES[2] = HAL_SDADC_InjectedGetValue(&hsdadc3, &CHANNEL);
}
hummel
Inlägg: 2259
Blev medlem: 28 november 2009, 10:40:52
Ort: Stockholm

Re: Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av hummel »

Det går att ha en funktion som tar hand om två olika avbrott, se då till att funktionen kan skilja på dom två avbrotten.

Min fråga blir varför gör du så?
DanielM
Inlägg: 2166
Blev medlem: 5 september 2019, 14:19:58

Re: Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av DanielM »

Jag tittade på ett exempel som ser ut så här.
https://github.com/STMicroelectronics/S ... Src/main.c

Så jag kopierade över bara, utan att förstå vad jag gjorde. Nej, ni får inte skälla på mig för detta.
Jag börjar med att få saker och ting att hända först. Där efter dyker jag djupare in i konfigureringen.

Exemplet ovan har bara EN interupt, trots att en STM32 F373 klarar utav 2 stycken ADC 16-bit och 3 stycken 16-bit ADC för differential, samtidigt.

Bilden nedan visar när jag lägger 0 volt på en singel ingång. Vet inte varför den pulsar så mycket. Jag sätter ju alla analoga till GND då jag mäter 4-20mA.
Markering_043.png
Jag har en idé på hur jag kan lösa detta!
Varje gång denna kodrad anropas

Kod: Markera allt

void HAL_SDADC_InjectedConvCpltCallback(SDADC_HandleTypeDef *hsdadc){
Då borde jag via hsdadc avgöra vilken interrupt som anropas? Eller?

Edit:

Okej! Det är tydligen så här man ska göra. Men jag prickar något fel när det kommer till arrayer.

Kod: Markera allt

// When we got a measurement
void HAL_SDADC_InjectedConvCpltCallback(SDADC_HandleTypeDef *hsdadc){
	if(hsdadc->Instance == SDADC1){
		// SD ADC 1
		if(CHANNEL == 4)
			SD_ADC_VALUES[0] = HAL_SDADC_InjectedGetValue(hsdadc, &CHANNEL);
		else if(CHANNEL == 8)
			D_SD_ADC_VALUES[0] = HAL_SDADC_InjectedGetValue(hsdadc, &CHANNEL);
		else if(CHANNEL == 6)
			D_SD_ADC_VALUES[1] = HAL_SDADC_InjectedGetValue(hsdadc, &CHANNEL);
	}else if(hsdadc->Instance == SDADC3){
		if(CHANNEL == 6)
			SD_ADC_VALUES[1] = HAL_SDADC_InjectedGetValue(hsdadc, &CHANNEL);
		else if(CHANNEL == 8)
			D_SD_ADC_VALUES[2] = HAL_SDADC_InjectedGetValue(hsdadc, &CHANNEL);
	}
}
Markering_045.png
Edit:

Nu har jag fått 2 stycken 16-bit ADC singel och 3 stycken 16-bit ADC differential att fungera. Mycket bra saker!
Singeln går från -32768 till +32768. Vid "vilande" signal så är det -32768.
Differentialen går från -32768 till +32768. Vid "vilande" signal så är det 0.

:tumupp: :D
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
DanielM
Inlägg: 2166
Blev medlem: 5 september 2019, 14:19:58

Re: Tips och förslag innan man börjar med Sigma-Delta ADC?

Inlägg av DanielM »

Förresten!

Har ni varit med om att när en signal neutral, dvs 0 "effekt" på ingången, så visar den 32768, dvs 0x8000. När full signalstryka appliceras, så visas det häften utav 32768, dvs 16384.

Men när man gör om det från unsined int till singed int, så får man hela spannet -32768 till +32768.

Försökte verkligen kalibrera i processorn så att Sigma Delta ADC single zero reference skulle visa 0 när det är 0 volt på ingången. Nej nej, den visar 32768.

Kanske är en speciell teknik det här?

Det lustiga är att formeln för ekvationen stämmer också.

Kod: Markera allt

Vin = SDADCx_AINyP = (ReadData + 32767) * Vref/(gain x 65535)
Om Vin = 0, Gain = 1, Vref = 3.3, så måste ReadData vara -32768.
Om Vin = 3.3, Gain = 1, Vref = 3.3, så måste 32768.

Detta stämmer när jag konverterar uint16_t till int i Java. Men när jag tittar på STM32CubeIDE Debug så visas det uint16_t = 32768 vid Vin = 0 och uint16_t = 16384, vid Vin = 3.3.

Svårt att förklara iallafall. Men det är inget problem då det fungerar.
Skriv svar