Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Misura tensione con ADC Pierin

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] Misura tensione con ADC Pierin

Messaggioda Foto Utenteemacar » 18 ago 2014, 12:19

Buongiorno a tutti,
rieccomi qui mentre continuo a fare esperimenti col Pierin. Vorrei provare l'ADC per misurare la carica di una batteria. Premetto che non ho fissato specifiche particolari su precisione, portata ecc, per adesso mi interessa solo verificare che una batteria da 1,5 V sia carica o meno. In pratica vorrei semplicemente che per valori di tensione inferiori ad 1,3 V si accenda LD1 e per valori inferiori si accenda LD2.
Il programma che posterò ovviamente non funziona; viene compilato con successo ma rimane sempre accesso il led LD2 sia con batteria (carica) collegata che no. Per la connessione della batteria, connetto direttamente il terminale negativo della batteria al pin GND del Pierin ed il terminale positivo a RE2.
Non ho impostato il numero di bit da utilizzare per cui il PIC dovrebbe lavorare a 10 bit. Nel controllo però, con allineamento a sinistra, verifico solo il registro ADRESH per cui praticamente utilizzo solo 8 dei 10 bit ma, come ho già scritto, questa perdita di risoluzione non è un problema, l'importante è che funzioni!
Il controllo verifica che il valore in ADRESH sia più di 100. Infatti a 3,3 V dovrebbe corrispondere il fondoscala di 255, mentre a 1,3 V, valore che ho fissato come limite per la scarica, dovrebbe corrispondere 100.
Grazie in anticipo, di seguito il codice,
Emanuele
Codice: Seleziona tutto
// File di definizione dei registri del micro.
#include "p18f47j53.h"

// File di configurazione dei fuses
#include "configurazione.h"   

// Mappatura delle interrupt
#include "mappa_int.h"

// Header del main
#include "main.h"

//------------------------------------------------------------------------------
// Variabili globali
//------------------------------------------------------------------------------
#pragma udata

//------------------------------------------------------------------------------
// Funzione di servizio delle interrupt ad ALTA priorità
//------------------------------------------------------------------------------
#pragma code
#pragma interrupt highPriorityInterrupt
void highPriorityInterrupt()
{
  // Verifica quale flag ha causato l' interrupt
  // Esegui la parte di codice di servizio dell' interrupt
  // Azzera il flag che ha causato l' interrupt
  // ...
}

//------------------------------------------------------------------------------
// Funzione di servizio delle interrupt a BASSA priorità
//------------------------------------------------------------------------------
#pragma interruptlow lowPriorityInterrupt
void lowPriorityInterrupt()
{
     
}

//------------------------------------------------------------------------------
// Prototipi delle funzioni
//------------------------------------------------------------------------------
#pragma code

//------------------------------------------------------------------------------
// Funzioni
//------------------------------------------------------------------------------
#pragma code

//------------------------------------------------------------------------------
// MAIN FUNCTION
//------------------------------------------------------------------------------
void main(void)
{
 
  // -------- Inizializzazione delle periferiche --------

   // Imposto PORTD tutti ingressi e RD6 e RD7 come uscite RD5 e RD4 come ingressi
   LATD = 0x00;
   TRISD = 0b00111111;

  // Inizializza tutti i pin come digitali
  ANCON0 = 0xFF;
  ANCON1 = 0x1F;
 
  // Inizializza il pin AN7 (RE2) come ingresso analogico
  ANCON0bits.PCFG7 = 0;  // 12/08/2013 corretto BUG segnalato da c1b8
   
   // Imposto i riferimenti uguali all'alimentazione e a massa.
   ADCON0 = 0b00000000;
   
   // De-inizializzo ADCON1
   ADCON1 = 0b00000000;
   
   // Seleziona il tempo di conversione 20TAD
  ADCON1bits.ACQT = 7;
  // Clock di conversione FOSC/64
  ADCON1bits.ADCS = 6;
  // Formato del risultato allineato a sinistra (userò ADRESH per cui solo 8 bit su 10)
  ADCON1bits.ADFM = 0;
   
   // -------- Attivazione delle periferiche --------
 

  // -------- Ciclo infinito di funzionamento --------
  for(;;)
  {
     // Abilitazione A/D converter
      ADCON0bits.ADON = 1;
   
    // Calibrazione ADC
    //ADCON1bits.ADCAL = 1;
    //ADCON0bits.GO = 1;
    //while(ADCON0bits.GO);
    //ADCON1bits.ADCAL = 0;
   
    // Seleziona l' ingresso da misurare
    ADCON0bits.CHS = 7;
   
    // Fa partire la conversione 45 us.       
    ADCON0bits.GO = 1;
    // Aspetta la fine della conversione
    while(ADCON0bits.GO);
   
    //>100
    if (ADRESH>0b01100100)
    {
         LATDbits.LATD6 = 0;      
         LATDbits.LATD7 = 1;
    }
    else
     {
         LATDbits.LATD6 = 1;
         LATDbits.LATD7 = 0;         
    }

  }// Fine for
}// Fine main


P.S. non ho ben chiaro in mente come faccia il PIC ad autocalibrarsi per cui il relativo codice è commentato. Se qualcuno sapesse darmi qualche indicazione gliene sarei grato.
Avatar utente
Foto Utenteemacar
156 6
Frequentatore
Frequentatore
 
Messaggi: 145
Iscritto il: 3 dic 2013, 11:02

0
voti

[2] Re: Misura tensione con ADC Pierin

Messaggioda Foto Utenteemacar » 19 ago 2014, 15:16

Mi rispondo da solo...effettivamente mi sono accorto che funziona! Sono stato ingannato dal fatto che non collegando a niente il pin del PIC si comportava come se vi fosse applicata una tensione superiore alla soglia.
Ricapitolando: se collego il PIC a delle tensioni da 0 a 3,3 V funziona tutto correttamente. Se lo lascio scollegato si comporta come se vi fosse collegata una tensione superiore alla soglia; so che in questo caso ci possono essere dei disturbi che fanno comportare il circuito in modo strano ma qualcuno sa spiegarmi il motivo?
Emanuele
Avatar utente
Foto Utenteemacar
156 6
Frequentatore
Frequentatore
 
Messaggi: 145
Iscritto il: 3 dic 2013, 11:02

0
voti

[3] Re: Misura tensione con ADC Pierin

Messaggioda Foto UtenteEcoTan » 19 ago 2014, 16:40

Rispondo un po' OT perché proprio in questi giorni sono ammattito per dei disturbi nelle letture analogiche con una MCU AT8535L e proprio oggi mi pare di avere risolto empiricamente mettendo a massa gli ingressi analogici NON UTILIZZATI (?!)
Avatar utente
Foto UtenteEcoTan
7.720 4 12 13
Expert EY
Expert EY
 
Messaggi: 5421
Iscritto il: 29 gen 2014, 8:54

0
voti

[4] Re: Misura tensione con ADC Pierin

Messaggioda Foto Utenteemacar » 19 ago 2014, 21:47

Boo non mi hanno convinto molto questi disturbi. Spero che non sia invece qualcosa che mi sta sfuggendo o che sbaglio.
Avatar utente
Foto Utenteemacar
156 6
Frequentatore
Frequentatore
 
Messaggi: 145
Iscritto il: 3 dic 2013, 11:02

3
voti

[5] Re: Misura tensione con ADC Pierin

Messaggioda Foto UtenteTardoFreak » 19 ago 2014, 23:39

Con gli ingressi analogici bisogna adottare alcune accortezze.
Ovviamente non bisogna lasciarli "appesi", senza collegamento. Il funzionamento, in questi casi, è quanto di più assurdo ci possa essere.
Inoltre bisogna sempre ricordarsi che questi ingressi non sono il massimo in termini di elettronica analogica. Per carità, funzionano benissimo ma sarebbe bene sempre collegarli tramite un inseguitore di tensione.
Di comportamenti bizzarri ne ho visti tantissimi, e non solo sui PIC ma con i micro in generale.
Personalmente cerco di risolvere il problema a monte. Sugli ingressi ci metto sempre un operazionale di precisione (possibilmente con alimentazione duale, anche di poco eh!) che funga da stadio d' ingresso.
Sembra una caxxata ma elimina una marea di problemi. :mrgreen:
"La follia sta nel fare sempre la stessa cosa aspettandosi risultati diversi".
"Parla soltanto quando sei sicuro che quello che dirai è più bello del silenzio".
Rispondere è cortesia, ma lasciare l'ultima parola ai cretini è arte.
Avatar utente
Foto UtenteTardoFreak
73,9k 8 12 13
-EY Legend-
-EY Legend-
 
Messaggi: 15754
Iscritto il: 16 dic 2009, 11:10
Località: Torino - 3° pianeta del Sistema Solare

0
voti

[6] Re: Misura tensione con ADC Pierin

Messaggioda Foto Utenteemacar » 19 ago 2014, 23:45

Grazie mille per la risposta Foto UtenteTardoFreak. Sicuramente me me ricorderò al prossimo utilizzo degli ingressi analogici. Ho visto che in un articolo hai utilizzato l'autocalibrazione, sai se esiste qualche documento microchip che spieghi come fisicamente il Micro corregga i vari errori di offset, guadagno ecc tramite essa?
Emanuele
Avatar utente
Foto Utenteemacar
156 6
Frequentatore
Frequentatore
 
Messaggi: 145
Iscritto il: 3 dic 2013, 11:02

2
voti

[7] Re: Misura tensione con ADC Pierin

Messaggioda Foto UtenteTardoFreak » 19 ago 2014, 23:52

L' unico documento è il datasheet del componente. Leggendolo con attenzione (comprese le caratteristiche elettriche) si scopre tutto quello che c'è da scoprire.
Un pizzico di sperimentazione ed un cucchiaio di esperienze altrui fanno il resto del lavoro. ;-)

E' sufficiente non fare i ragni (ad esempio scegliendo l' LM338 solo per risparmiare :roll: ) per l' inseguitore di tensione ed utilizzare un operazionale a basso offset e di buona precisione per ottenere risultati eccellenti e ... grandi soddisfazioni. :ok:
"La follia sta nel fare sempre la stessa cosa aspettandosi risultati diversi".
"Parla soltanto quando sei sicuro che quello che dirai è più bello del silenzio".
Rispondere è cortesia, ma lasciare l'ultima parola ai cretini è arte.
Avatar utente
Foto UtenteTardoFreak
73,9k 8 12 13
-EY Legend-
-EY Legend-
 
Messaggi: 15754
Iscritto il: 16 dic 2009, 11:10
Località: Torino - 3° pianeta del Sistema Solare

0
voti

[8] Re: Misura tensione con ADC Pierin

Messaggioda Foto Utenteemacar » 20 ago 2014, 7:51

Perfetto grazie
Avatar utente
Foto Utenteemacar
156 6
Frequentatore
Frequentatore
 
Messaggi: 145
Iscritto il: 3 dic 2013, 11:02

0
voti

[9] Re: Misura tensione con ADC Pierin

Messaggioda Foto UtenteEcoTan » 25 ago 2014, 17:36

TardoFreak ha scritto:Con gli ingressi analogici bisogna adottare alcune accortezze.
Ovviamente non bisogna lasciarli "appesi", senza collegamento. Il funzionamento, in questi casi, è quanto di più assurdo ci possa essere.

Continuo ad avere qualche problema, magari sarà la batteria ma in questi casi si comincia a fantasticare..
Nella MCU AT8535 c'è un registro di un byte ADMUX dove i bit più significativi impostano il riferimento di tensione, il left adjust e altre cosine mentre i 3 bit meno significativi impostano il canale analogico per il solito flying capacitor.
Dovendo scandire 4 ingressi sugli 8 disponibili, il mio programma scrive su ADMUX per cambiare il canale, ma ovviamente mentre cambia il canale va a riscrivere anche i bit più significativi, peraltro senza modificarli. Il programma è in Basic, ma anche se fosse in Assembler non mi pare che ci sia modo di impostare soltanto alcuni bit senza toccare gli altri dello stesso registro. Ciò avviene in un momento opportuno, quasi subito dopo l'interrupt di fine conversione, ma vai a sapere. E' un problema da.. porsi? Occorre adottare altre soluzioni?
Avatar utente
Foto UtenteEcoTan
7.720 4 12 13
Expert EY
Expert EY
 
Messaggi: 5421
Iscritto il: 29 gen 2014, 8:54

0
voti

[10] Re: Misura tensione con ADC Pierin

Messaggioda Foto Utenteemacar » 26 ago 2014, 12:28

Se ho capito bene potresti fare un OR bit a bit lasciando a zero i bit da non variare oppure un AND lasciando a 1 i bit da non toccare. Dipende se devi settare a 1 o a 0 il bit in questione.
Avatar utente
Foto Utenteemacar
156 6
Frequentatore
Frequentatore
 
Messaggi: 145
Iscritto il: 3 dic 2013, 11:02


Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 7 ospiti