Sari la conținut
ELFORUM - Forumul electronistilor

Circuite si aplicatii cu ADC MCP3551, LTC2440 si DAC MCP4921, LTC1655 cu PIC, mikroC & Proteus


gsabac

Postări Recomandate

In topic sunt exemple complete, functionale, cu circuitele de precizie ADC MCP3551 22 biti si ADC LTC2440 24 biti precum si DAC MCP4921 12 biti si DAC LTC1655 16 biti, activate de catre microcontrolere PIC16Fxxxx sau PIC18Fxxxx si pot fi si in combinatie cu dispozitive USB. Circuitele externe tip ADC sau DAC se pot cupla cu uC prin intermediul procedurii seriale cu trei fire SPI si pe un uC se pot grupa cateva asemenea circuite, dar si mai multe afisoaare cu LCD simultan, care sa indice date diferite.

  Un exemplu complex de circuit este in poza. Click pentru marire.

      1982727534_ADCDACLCDKEYPADUSB.thumb.png.396a24a9b060859a266fba1a4c7198f7.png

 

Circuitele sunt utile pentru studiu sau constructia unor instrumente de precizie voltmetre, ampermetre, termometre, surse de precizie dar se pot folosi si cu diversi senzori in modul de lucru diferential sau monopolar. Mentionez ca nu am construit fizic circuite cu aceste componente, dar am studiat diverse surse cu exemple functionale sau nefunctionale si nu am gasit nici macar o aplicatie cu PIC care sa fie completa si propozabila de a fi aplicata. Sunt aplicatii cu alte tipuri de uC, dar si ele sunt incomplete.

 

@gsabac

Link spre comentariu

Am prevazut mai multe exemple si aplicatii pe care le voi prezenta gradual, dar pentru inceput voi aminti un program realizat de colegul nostru de forum @Thunderer, care reuseste sa cresca precizia unui ADC cu cativa biti. Nu am testat procedura, dar mi se pare interesanta si as dori niste explicatii din partea autorului, daca se poate.

'Code:  ************************************************************************************************
' * Project name:
'     ADC Oversampling (up to 16 bit)
' * Copyright:
'     (c) Thunderer (07/2014)
' * Revision History:
'     0 - 1st issue
' * Description:
'     See Mikrobasic forum: Florin YO2LIO post (Mikrobasic and Mikropascal)
' * Test configuration:
'     MCU:             PIC16F690
'     Oscillator:      INTOSC 8 MHz
'     Ext. Modules:    -
' *

program _16F690_ADC_Oversampling
' Declarations section
dim adc_rd0, adc_rd1,adc_rd2, adc_rd3     as longword
dim adc_res1, adc_res2, adc_res3          as longword
dim ch0, ch1, ch2, ch3                    as byte

' Lcd module connections
dim LCD_RS as sbit at RC5_bit
    LCD_EN as sbit at RC4_bit
    LCD_D4 as sbit at RC3_bit
    LCD_D5 as sbit at RC2_bit
    LCD_D6 as sbit at RC1_bit
    LCD_D7 as sbit at RC0_bit

    LCD_RS_Direction as sbit at TRISC5_bit
    LCD_EN_Direction as sbit at TRISC4_bit
    LCD_D4_Direction as sbit at TRISC3_bit
    LCD_D5_Direction as sbit at TRISC2_bit
    LCD_D6_Direction as sbit at TRISC1_bit
    LCD_D7_Direction as sbit at TRISC0_bit
' End Lcd module connections

'   Set-up the PIC
sub procedure InitMain()
    OPTION_REG =   0x80              ' Pull-up disabled PORTB
    INTCON     =   0x00              ' No INT

    CM1CON0    =   0x00              ' No COMP
    CM2CON0    =   0x00              ' No COMP
    CM2CON1    =   0x00              ' No COMP

    ANSEL      =   0x0F              ' PORTA Analog I/Os on AN0, 1, 2 and 3
    ANSELH     =   0x00              ' No Analog I/Os

    TRISA      =   0x17              ' Inputs RA0, 1, 2 and 4
    TRISB      =   0x00              ' All outputs
    TRISC      =   0x00              ' All outputs


    PORTA      =   0x00              ' Clear PORTA
    PORTB      =   0x00              ' Clear PORTB
    PORTC      =   0x00              ' Clear PORTC
end sub

sub function Adc_Read_Ext_Res(dim resolution, ch_ as byte) as longword
dim i as longword
    j as byte

  result = 0
  if resolution < 11 then exit end if ' minimum resolution is 11 bits
  resolution = resolution - 10
  j = resolution - 1
  i = 4
  while j > 0
    i = i << 2
    dec(j)
  wend
  while i > 0
    result = result + Adc_Read(ch_)
    dec(i)
  wend
  result = result >> resolution
end sub

'   Main program
Main:
  InitMain()
  Lcd_Init()                     ' Initialize Lcd
  Lcd_Cmd(_LCD_CLEAR)            ' Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF)       ' Cursor off

  ADC_Init()                     ' Initialize ADC module

' Display static text
  Lcd_Out(1,1," 0:")
  Lcd_Out(1,9," 2:")
  Lcd_Out(2,1," 4:")
'  Lcd_Out(2,9," 6:")


' The measurement
Measure:
  while (TRUE)
' Voltage ADC_10b
ADC0:
    adc_rd0 = ADC_read(0) * 48.82813
    ch0 = adc_rd0 div 10000
    Lcd_Chr(1, 4, 48+ch0)
    ch0 = (adc_rd0 div 1000) mod 10
    Lcd_Chr(1, 5, 48+ch0)
    ch0 = (adc_rd0 div 100) mod 10
    Lcd_Chr(1, 6, 48+ch0)
    ch0 = (adc_rd0 div 10) mod 10
    Lcd_Chr(1, 7, 48+ch0)
    ch0 = (adc_rd0 div 1) mod 10
    Lcd_Chr(1, 8, 48+ch0)
    Delay_ms(100)

' Voltage ADC_12b
ADC1:
    adc_res1 = Adc_Read_Ext_Res(12,1)  ' 12 bit resolution, channel 1
    adc_rd1 = adc_res1 * 12.20703
    ch1 = adc_rd1 div 10000
    Lcd_Chr(1, 12, 48+ch1)
    ch1 = (adc_rd1 div 1000) mod 10
    Lcd_Chr(1, 13, 48+ch1)
    ch1 = (adc_rd1 div 100) mod 10
    Lcd_Chr(1, 14, 48+ch1)
    ch1 = (adc_rd1 div 10) mod 10
    Lcd_Chr(1, 15, 48+ch1)
    ch1 = (adc_rd1 div 1) mod 10
    Lcd_Chr(1, 16, 48+ch1)

' Voltage ADC_14b
ADC2:
    adc_res2 = Adc_Read_Ext_Res(14,2)  ' 14 bit resolution, channel 2
    adc_rd2 = adc_res2 * 3.05176
    ch2 = adc_rd1 div 10000
    Lcd_Chr(2, 4, 48+ch2)
    ch2 = (adc_rd2 div 1000) mod 10
    Lcd_Chr(2, 5, 48+ch2)
    ch2 = (adc_rd2 div 100) mod 10
    Lcd_Chr(2, 6, 48+ch2)
    ch2 = (adc_rd2 div 10) mod 10
    Lcd_Chr(2, 7, 48+ch2)
    ch2 = (adc_rd2 div 1) mod 10
    Lcd_Chr(2, 8, 48+ch2)

'' Voltage ADC_16b
'ADC3:
'    adc_res3 = Adc_Read_Ext_Res(16,3)  ' 16 bit resolution, channel 3
'    adc_rd3 = adc_res3 * 0.76294
'    ch3 = adc_rd3 div 10000
'    Lcd_Chr(2, 12, 48+ch3)
'    ch3 = (adc_rd3 div 1000) mod 10
'    Lcd_Chr(2, 13, 48+ch3)
'    ch3 = (adc_rd3 div 100) mod 10
'    Lcd_Chr(2, 14, 48+ch3)
'    ch3 = (adc_rd3 div 10) mod 10
'    Lcd_Chr(2, 15, 48+ch3)
'    ch3 = (adc_rd3 div 1) mod 10
'    Lcd_Chr(2, 16, 48+ch3)
wend

'***************************************************************************************

Prima aplicatie este un Voltmetru 6 1/2 cu PIC16F877_MCP4921 cu schema prezentata in poza

    Click pentru marire.

   716161776_Voltmetru6cifrePIC16F877_MCP4921.thumb.png.a783fb44d7e19ddd89cadeb58a6720e7.png

Pe schema este prevazut un generator cu crestere lenta, pentru a se vedea evolutia masuratorilor la ultimele cifre mai putin semnificative. Intrarea in acest caz este diferentiala, de impedanta mica, dar aceasta se poate mari sau transforma intr-o intrare fata de masa. Deasemenea sensibilitatea se poate creste cu amplificatoare de intrare adecvate, ca in aplicatiile ce vor urma. In atasament se afla proiectul complet, functional in mikroC si Proteus.

Spor la clicaiala si comentarii!

 

@gsabac

MiliVoltmetru cu 6 cifre cu MCP3551 si PIC16F877A - Elforum.rar

Link spre comentariu

La final, mai afisezi un zero, sunt curios.. de ce il mai pui acolo?

Mi se pare putin confuz ca ai pus in acelasi post doua solutii diferite la aceasi problema, cu citirea pe ADC. Eu eram curios ca vad unde apare in schema generatorul de zgomot, ca sa vad ca e de fapt un ADC pe 22 de biti care nici nu mai are nevoie de oversampling. :)

Link spre comentariu

Asa cum colegul @core mentioneaza, un generator de zgomot e necesar, asta daca semnalul de masurat nu e destul de zgomotos din fire.

Codul de mai sus este un exemplu didactic comparativ, se vede ce si cum pe LCD. L-am testat doar ca sa vad latenta intre afisari (refresh-uri). Evident, cu cat ruleaza mai repede PIC-ul, cu atata si afisarea este mai rapida.

 

@gsabac, codul ii apartine lui YO2LIO. Postul lui original (poate): https://forum.mikroe.com/viewtopic.php?f=93&t=20393.

 

Microchip are AN1152 unde explica: https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en533730.

 

Evident ca folosirea unui ADC cu o rezolutie mai buna, plus o implementare analogica corespunzatoare, este mai potrivita decat orice oversampling. O implementare analogica necorespunzatoare face ca folosirea unui ADC de n>10b sa se comporte mai slab decat un prapadit de 10b.

 

Cum functioneaza acest oversampling citind cu un ADC 10b, 1024 valori de la 0 la 1023:

1. Semnalul este destul de stabil intre 500 si 501 => media este 500.5.

2. Semnalul este mai putin stabil intre 500 si 502 => media este dupa 5 citiri 500.5 si dupa alte 5 este 501.5. Media finala este 501.

3. Semnalul este foarte instabil intre 500 si 504 => media este dupa 3 citiri 501.5, dupa alte 3 citiri 502.5, dupa alte 3 citiri 503.5, si dupa 1 citire 504. Media finala este 503.25.

Editat de Thunderer
Link spre comentariu

Atata timp cat nu specifici marirea frecventei de esantionare, ce ai scris tu pare mediere.

Oversamplingul presupune cresterea ratei de esantionare (de 4 ori pentru fiecare bit "castigat"). Adica pentru fiecare bit, intre 2 masuraturi normale, mai faci 4 (3?) suplimentare. Abia pe astea le mediezi.

Editat de Liviu M
Link spre comentariu

Nu cresterea frecventei de esantionare fata de o esantionare data duce la marirea rezolutiei ci cresterea numarului de esantioane intre doua masuratori, cu conditia esentiala ca procesele sa fie pur aleatorii, ceea ce nu se intampla in cazul unui ADC unde precizia de +/- 1/2 LSB depinde de precizia imbinarilor rangurilor binare, unde apar discontinuitati.

In cazul unui ADC intern sau extern comandat de uC frecventa de esantionaare se poate seta in program, dar trebuie privit cum este mai avantajos, sa avem o frecventa de esantionare mica, de ex. 100 Hz pentru utilizare si 1024x100Hz=102,400 KHz pentru oversampling sau ADC-ul sa lucreze constant la 102,400KHz si sa se faca o mediere pe 1024 esantioane. Mie mi se pare ca procedeele cam sunt identice.

 

Un alt procedeu interesant, este jonglarea analogica cu tensiunea de referinta, la uC-urile care permit aceasta procedura si se castiga astfel un bit, din 10 creste precizia la 11, adica in loc de 1024 de trepte se pot utiliza 2048.

    www.elektronikbilim.wordpress.com
    www.profahmet.wordpress.com

 image.thumb.png.899c75cddb9a84b38881bfb12e127449.png

 

Codul original este C si Proteus-ISIS si este in atasament. Am verificat monotonia la jonctiuni si este perfecta.

 

@gsabac

PIC16F886 smecherie LCD cu 11Bit_ADC precizie in loc de 10.rar

Link spre comentariu
Acum 5 ore, gsabac a spus:

 ci cresterea numarului de esantioane intre doua masuratori,

Pai daca cresti numarul de esantioane , nu inseamna ca cresti frecventa de esantionare?

Link spre comentariu

 Asa este, dar in mod normal, frecventa de esantionare este la maximum posibil, de ex. 100KHz si nu se mai poate mari, dar daca se micsoreaza voit la 100Hz, o fecventa utila  pentru aplicatii vizuale, ca apoi sa se faca oversampling,  cred ca este o complicatie inutila. La acest procedeu, pentru rezultate bune, trebuie sa se foloseasca si niste filtraje pe iesire corespunzatoare, dar si rejectia semnalelor perturbatoare de 50 sau 60Hz, asa cum o fac circuitele ADC de 22 saau 24 de biti.

 

In alta ordine de idei, eu am aplicat oversampling la reconstructia unui semnal analogic digitalizat cu rezultate bune pana la circa 90% din frecventa Nyquist prin folosirea metodei simple spline, dar si prin metoda ferestrelor Rectangle, Blackman, Hanning si Hamming. Frecventa de esantionare a uC-ului era la maximum, dar procesarea am facut-o pe PC deoarece are potenta, cu transmisie prin USB a esantioanelor.

 

@gsabac

Link spre comentariu
Acum 44 minute, gsabac a spus:

 Asa este, dar in mod normal, frecventa de esantionare este la maximum posibil,

Exact de aia i-am zis lui Thunderer ca pentru a avea oversampling e necesara marirea frecventei de esantionare (ceea ce nu e intotdeauna posibil pentru toti bitii suplimentari).

Daca nu maresti frecventa, nu mai e oversamplig.

Link spre comentariu

In viziune mea, procedura prezentata de @Thunderer este tot oversampling, deoarece se refera de ex. la o esantionare finala de 100Hz. Chestia este cum se vede procedeul, de la cap la coada sau de la coada la cap. Pentru ca tot disecam ce si cum, as fi foarte curios, bineanteles daca doriti sa ne aratati, care ar fi in viziunea dvs. procedeul  de oversampling cu ajutorul unui uC, printr-o schema bloc sau un flow-chart posibil de realizat si fizic.

 

Am sa continui topicul cu un milivoltmetru inedit, care anuleaza erorile rail to rail, prezentate de producator de circa 100mV fata de masa.

   Click pentru marire.

          milivoltmetru.thumb.png.ec96a591c9ff3a968161af7f0c88e32f.png

 Aceasta se realizeaza prin introducerea unei tensiuni pozitive de circa 120mV la modul comun, in circuitul diferential format din U4 si U5 si translatarea modului diferential la modul monopolar fata de masa. Grupul divizor de intrare poate fi de tipul CADDOK 1776-6101 cu o precizie de 0,1% si comutatorul unul de calitate.

 Partea de simulare este in atasament si prezentarea ca drept cu 6 cifre este exagerata si limitata de precizia componentelor si inexistenta unor proceduri de reglaj pe zero.

 

@gsabac

MiliVoltmetru cu MCP3551 si PIC16F877A cu amplificator si comutator.rar

Link spre comentariu

De ce ar fi nevoie sa fac eu desene noi cand articolul de pe wikipedia si pdf-ul de la microchip (linkul postat de Thunderer) sustin/documenteaza aspectul asta chiar nu m-am prins.

Uite un citat din pdf:

Citat

One way of reducing the PSD is by reducing the numerator (i.e., the LSb value), which can be achieved by adding more bit resolution to the ADC. Another method of reducing PSD is by increasing the denominator (i.e., by increasing the sampling frequency),which leads to oversampling.

Eu am zis ce aveam de zis, nu mai e treaba mea cum folositi diversii termeni.

Link spre comentariu

 Poate pozitia dvs. este corecta, de ce sa inventam roata cand ea exista si mai mult ca sigur eu am ramas cu handicapul tineretii cand nu aveam acces la documentatii, la componente de top si aparatura si eram obligat sa inventez ceva functional. Vremurile s-au schimbat, dar totusi in legatura cu topicul mi-ar fi placut o trecere sumara in revista a procedeului oversampling aplicat la ADC. Dar se pare ca teoria si circuitele avansate depasesc cadrul acestui forum, asa cum mi-au mai spus si alti useri direct sau printre randuri, asa ca trec mai departe la circuitul LTC2440 ADC delta sigma, de 24 biti, care se afla in librariile programelor.

   O schema initiala de aplicatie este in poza. Click pentru marire.

      234308599_milivoltmetrucuLTC2440.thumb.png.7bb03cd75e78244841074e1d9aa07a2b.png

Circuitul LTC2440 are un amplificator diferential intern, de aceea sensibilitatea schemei este de 100mV si practic a treia cifra dupa punctul zecimal este la nivelul microvoltilor si este influentata de zgomotul propriu al circuitelor, care este implementat in modelul Proteus. Exista si circuitul LTC2400 cu intrare fata de masa dar nu are librarii pentru studiu. Circuitul LTC2440 comunica cu uC-ul prin SPI, prin 4 grupe de semnal de cate 8 biti. Grupa 4 este complexa si doar un singur bit este utilizat pentru valoarea citita, restul sunt prezentati in documentatie si se pare ca se pot seta prin program. Nu am aprofundat, doar am preluat un program, l-am convertit in mikroC si sunt utilizati doar 23 de biti din cei 24 disponibili.

            http://www.steveluce.com/24bits/Applications of the LTC 24 bit ADC.html#reference_source

Pe global, desi ultimele doua cifre sunt fluctuante, se obtin aaproape 6 cifre semnificative constante si programele sunt in atasament.

PS. Pretul acestor circuite ADC este in jur de 50 de lei.

 

@gsabac

 

MiliVoltmetru cu 6 cifre cu LTC2440 si PIC16F877A.rar

Link spre comentariu
Acum 14 ore, gsabac a spus:

 de ce sa inventam roata cand ea exista

Nu e vorba de inventat roata, e vorba doar de modul cum prezentam roata.

Eu doar am atras atentia ca pentru ADC-uri oversamplingul e definit ca "marirea software a "numarului de biti" prin marirea de 4 ori a frecventei de esantionare pentru fiecare bit castigat".

Deci nu orice mediere reprezinta un oversampling.

Sigur, daca folosim ADC-ul intr-o sursa DC, orice marire a numarului de esantioane se poate considera oversampling, da' daca avem un semnal ceva mai saltaret ne cam trage Nyquist de maneca.

Pe de alta parte ai si tu dreptate, eu fac doar teoria chibritului, practic nu pot arata nimic, ca n-am ce.

 

 

Spor,

Liviu

 

PS Pe forum suntem colegi si "egali", drept care prefer adresarea cu tu.

 

Link spre comentariu
La 20.11.2019 la 8:12, gsabac a spus:

Dar se pare ca teoria si circuitele avansate depasesc cadrul acestui forum, asa cum mi-au mai spus si alti useri direct sau printre randuri, asa ca trec mai departe la circuitul LTC2440 ADC delta sigma, de 24 biti, care se afla in librariile programelor.

Parerea mea este ca din contra, exact asta ar trebui sa constituie materialul prezentat pe forum.

Ca hai sa fim seriosi, de lipit "3 piese" si copiat un soft gata scris de pe net, e multa lume in stare.

Apropo de asta si sper sa nu fie cu suparare, copierea librariilor din diverse surse, mai mult sau mai putin "credibile", mi se pare ca intra tot la capitolul "casa pionierilor"... :) .

Personal am "muscat-o" de atatea ori incat prefer sa scriu eu "librariile" bazandu-ma pe datasheet... dureaza dar macar stii ce si de ce se intampla.  

Editat de informer
Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum
×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări