Go Down

Topic: Ardutester - Arduino Component Tester (INCOMPLETO) (Read 227676 times) previous topic - next topic

PaoloP

Le mie le ho prese meno di 20 gg fa.
Sembrano nuove e non ossidate: sono identiche a quelle di Guglielmo.

menniti

Allora succede qualcosa quando sono attraversate da correnti, potrebbero essere impedenze?
Manuale "Arduino e le tecniche di programmazione dei microcontrollori ATMEL"
http://www.michelemenniti.it/manuale_di_programmazione.html
http://www.michelemenniti.it/offerta.html
Articoli ElettronicaIN
http://www.michelemenniti.it/elettronica_in.html

PaoloP

How to work!

Nel setup l'Ardutester setta la Seriale e inizializza LCd, poi passa a inizializzare l'ADC e carica i valori di default della configurazione
Code: [Select]
 ADCSRA = (1 << ADEN) | ADC_CLOCK_DIV;          //Enable ADC and set clock divider
 MCUSR &= ~(1 << WDRF);                         //Reset watchdog flag
 wdt_disable();                                 //Disable watchdog
 
//Cycling
 RunsMissed = 0;
 RunsPassed = 0;

//Default offsets and values
 Config.Samples = ADC_SAMPLES;                  //Number of ADC samples
 Config.AutoScale = 1;                          //Enable ADC auto scaling
 Config.RefFlag = 1;                            //No ADC reference set yet
 analogReference(EXTERNAL);                     //Set Analog Reference to External
 pinMode(pushButton, INPUT_PULLUP);             //Set pin to input and turn on pullup resistors

imposta il riferimento esterno (si userà poi il riferimento interno a 1.1V) e il pulsante.

Nell loop, viene abilitato il watchdog a 2 secondi, resettate le variabili di riconoscimento di componenti e impostati tutti gli ingressi dell'ADc ad alta impedenza
Code: [Select]
 ADC_DDR &= ~(1<<TP1);                                                          
 ADC_DDR &= ~(1<<TP2);
 ADC_DDR &= ~(1<<TP3);

Viene letta poi la tensione di riferimento.
Code: [Select]
Config.U_Bandgap = ReadU(0x0e);                //Get voltage of bandgap reference

dove la funzione ReadU è:
Code: [Select]
//Read ADC and return voltage in mV (GOTO Free - Thanks to PaoloP)
unsigned int ReadU(byte Probe)
{
 unsigned int      U;                            //Return value (mV)
 byte              Counter;                      //Loop counter
 unsigned long     Value;                        //ADC value
 Probe |= (1 << REFS0);                          //Use internal reference anyway
 boolean cycle;
 do {
   cycle = false;                                // One Time cycle
   ADMUX = Probe;                                //Set input channel and U reference
   //If voltage reference has changed run a dummy conversion
   Counter = Probe & (1 << REFS1);               //Get REFS1 bit flag
   if (Counter != Config.RefFlag)
   {
     waitus(100);                                //Time for voltage stabilization
     ADCSRA |= (1 << ADSC);                      //Start conversion
     while (ADCSRA & (1 << ADSC));               //Wait until conversion is done
     Config.RefFlag = Counter;                   //Update flag
   }
   //Sample ADC readings
   Value = 0UL;                                  //Reset sampling variable
   Counter = 0;                                  //Reset counter
   while (Counter < Config.Samples)              //Take samples
   {
     ADCSRA |= (1 << ADSC);                      //Start conversion
     while (ADCSRA & (1 << ADSC));               //Wait until conversion is done
     Value += ADCW;                              //Add ADC reading
     //Auto-switch voltage reference for low readings
     if ((Counter == 4) && ((unsigned int)Value < 1024) && !(Probe & (1 << REFS1)) && (Config.AutoScale == 1))
     {
       Probe |= (1 << REFS1);                    //Select internal bandgap reference
       cycle = true;
       break;                                    //Re-run sampling
     }
     Counter++;                                  //One less to do
   }
 }
 while (cycle);
 //Convert ADC reading to voltage
 if (Probe & (1 << REFS1)) U = Config.U_Bandgap; //Bandgap reference
 else U = UREF_VCC;                              //Vcc reference  
 //Convert to voltage
 Value *= U;                                     //ADC readings U_ref
 //Value += 511 * Config.Samples;                //Automagic rounding
 Value /= 1024;                                  // / 1024 for 10bit ADC
 //De-sample to get average voltage
 Value /= Config.Samples;
 U = (unsigned int)Value;
 return U;
}


Analizziamo bene la ReadU...

PaoloP

#393
Jul 07, 2013, 12:53 pm Last Edit: Jul 07, 2013, 01:04 pm by PaoloP Reason: 1
La funzione inizializza per primo il valore U che sarà poi quello restituito.
Viene impostato il riferimento interno dell'ADC
Code: [Select]
Probe |= (1 << REFS0);                          //Use internal reference anyway
Inizia il ciclo e viene scelto il canale dell'mux
Code: [Select]
ADMUX = Probe;                                //Set input channel and U reference
canale 14 ovvero la tensione interna a 1.1V (nuovo datasheet pag 255 --> http://www.atmel.com/Images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet.pdf)
Siamo ancora nella fase di inizializzazione dei valori e non nella lettura delle sonde esterne.

il ciclo completo è
Code: [Select]
 boolean cycle;
 do {
   cycle = false;                                // One Time cycle
   ADMUX = Probe;                                //Set input channel and U reference
   //If voltage reference has changed run a dummy conversion
   Counter = Probe & (1 << REFS1);               //Get REFS1 bit flag
   if (Counter != Config.RefFlag)
   {
     waitus(100);                                //Time for voltage stabilization
     ADCSRA |= (1 << ADSC);                      //Start conversion
     while (ADCSRA & (1 << ADSC));               //Wait until conversion is done
     Config.RefFlag = Counter;                   //Update flag
   }
   //Sample ADC readings
   Value = 0UL;                                  //Reset sampling variable
   Counter = 0;                                  //Reset counter
   while (Counter < Config.Samples)              //Take samples
   {
     ADCSRA |= (1 << ADSC);                      //Start conversion
     while (ADCSRA & (1 << ADSC));               //Wait until conversion is done
     Value += ADCW;                              //Add ADC reading
     //Auto-switch voltage reference for low readings
     if ((Counter == 4) && ((unsigned int)Value < 1024) && !(Probe & (1 << REFS1)) && (Config.AutoScale == 1))
     {
       Probe |= (1 << REFS1);                    //Select internal bandgap reference
       cycle = true;
       break;                                    //Re-run sampling
     }
     Counter++;                                  //One less to do
   }
 }
 while (cycle);


Si controlla che il riferimento non sia cambiato e nel caso si effettua una lettura a vuoto
Code: [Select]
 //If voltage reference has changed run a dummy conversion
   Counter = Probe & (1 << REFS1);               //Get REFS1 bit flag
   if (Counter != Config.RefFlag)

se invece il riferimento non e stato modifica si esegue la lettura reale con un numero di lettura pari a Config.Samples (in questo caso 200).
Config.RefFlag è posto a 1 nel setup.

PaoloP

Nel ciclo while interno
Code: [Select]
while (Counter < Config.Samples)              //Take samples
    {
      ADCSRA |= (1 << ADSC);                      //Start conversion
      while (ADCSRA & (1 << ADSC));               //Wait until conversion is done
      Value += ADCW;                              //Add ADC reading
      //Auto-switch voltage reference for low readings
      if ((Counter == 4) && ((unsigned int)Value < 1024) && !(Probe & (1 << REFS1)) && (Config.AutoScale == 1))
      {
        Probe |= (1 << REFS1);                    //Select internal bandgap reference
        cycle = true;
        break;                                    //Re-run sampling
      }
      Counter++;                                  //One less to do
    }


è letto il valore dell'ADC a 16 bit, a differenze dell'analogread che legge 2 byte e poi li unisce
Code: [Select]
// start the conversion
sbi(ADCSRA, ADSC);

// ADSC is cleared when the conversion finishes
while (bit_is_set(ADCSRA, ADSC));

// we have to read ADCL first; doing so locks both ADCL
// and ADCH until ADCH is read.  reading ADCL second would
// cause the results of each conversion to be discarded,
// as ADCL and ADCH would be locked when it completed.
low  = ADCL;
high = ADCH;
#else
// we dont have an ADC, return 0
low  = 0;
high = 0;
#endif
// combine the two bytes
return (high << 8) | low;


ADC è definito nelle lib AVR come
Code: [Select]
#define ADCW    _SFR_MEM16(0x78)

PaoloP

Alla 4° lettura, se il valore è inferiore a 1024, quindi meno di 256 a lettura e se è stato settato l'autoscale con riferimento normale (5V)
Code: [Select]
if ((Counter == 4) && ((unsigned int)Value < 1024) && !(Probe & (1 << REFS1)) && (Config.AutoScale == 1))
     {
       Probe |= (1 << REFS1);                    //Select internal bandgap reference
       cycle = true;
       break;                                    //Re-run sampling
     }

viene impostato il rifermento a 1.1V, la variabile cycle è vera e il ciclo ricomincia. (prima qui c'era un orribile goto.  :smiley-mr-green:
Così migliora la risoluzione in lettura.
Terminato il campionamento, le solite operazioni.
Code: [Select]
if (Probe & (1 << REFS1)) U = Config.U_Bandgap; //Bandgap reference
 else U = UREF_VCC;                              //Vcc reference  
 //Convert to voltage
 Value *= U;                                     //ADC readings U_ref
 //Value += 511 * Config.Samples;                //Automagic rounding
 Value /= 1024;                                  // / 1024 for 10bit ADC
 //De-sample to get average voltage
 Value /= Config.Samples;
 U = (unsigned int)Value;
 return U;

Il valore viene moltiplicato per il valore di riferimento, 1.1V o 5V, diviso per 1024 (dovrebbe essere 1023??), e diviso per il numero di campioni.

Tutto questo, la prima volta, dovrebbe restituire 1100 mV.

PaoloP

Nel loop(), una volta stabilita la tensione di riferimento interna con la migliore accuratezza possibile si passa alla scarica di eventuali componenti collegati (come i condensatori), poi al controllo dei cortocircuiti tra le sonde e se tutto va bene si passa all'analisi dei componenti collegati alle sonde, vero cuore dell'ArduTester.
Code: [Select]
//Try to discharge any connected component
 DischargeProbes();
 if (CompFound == COMP_ERROR)                   //Discharge failed
 {
   ErrFnd=4;                                    //Skip all other checks
 }
 //Short-circuit
 if (AllProbesShorted() == 3)
 {
   ErrFnd=3;                                    //New cycle after job is is done
 }
 else
 {
   //Check all 6 combinations of the 3 probes
   CheckProbes(TP1, TP2, TP3);
   CheckProbes(TP2, TP1, TP3);
   CheckProbes(TP1, TP3, TP2);
   CheckProbes(TP3, TP1, TP2);
   CheckProbes(TP2, TP3, TP1);
   CheckProbes(TP3, TP2, TP1);

La scarica dei componenti è semplice, vengono portati a massa tutte le resistenze (pull-down) effettuando dei cicli di lettura della tensione e controllando fino a un valore inferiore ad una soglia preimpostata.
Dopo la scarica, viene effettuato il test per verificare il corto delle sonde e in caso positivo si passa al sefttest interno, altrimenti si procede con la funzione CheckProbes. (che vedremo dopo mangiato)  :smiley-mr-green:

Etemenanki

Viste cosi a occhio, quelle sembrano le resistenze che produceva la Welwyn per i tester analogici ... credo che esista ancora ...

Di migliori credo ci siano solo quelle a strato metallico della Vishay da 0,01%, laser trimmed ... ma l'ultima volta che ho visto uno dei loro listini, costavano come se fossero state fatte d'oro massiccio :P  :smiley-eek-blue:

E usarle SMD ? ... ci sono anche le 1206 allo 0,1% ...
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

PaoloP


pighixxx

Ho acquistato da Digikey queste:

A103210CT-ND
A103233CT-ND

Alla modica cifra di 124€ per reel (1.000 pezzi)

gpb01

Allego il datasheet delle mie ... sono CAR7 allo 0,1% di precisione ... e costano un occhio (4 € cad ... del resto ... quando ne compri 10 e te le spediscono in 24 ore in ufficio ... paghi anche il servizio)  XD XD XD

Guglielmo
Search is Your friend ... or I am Your enemy !

pighixxx

La prossima settimana arriva la regina del Fablab e poi produrre le schedine in SMD sarà un gioco da ragazzi...

La regina è questa  :D
http://www.youtube.com/watch?v=5G17RgXVq38

Etemenanki

Ce l'ho anch'io ... solo che la mia occupa meno spazio



:P XD XD XD

(... come ti odio ... scherzo, ovviamente :P)
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

pighixxx


(... come ti odio ... scherzo, ovviamente :P)


:smiley-mr-green:
Adesso devo trovare un service pcb in zona a buon mercato e dopo è fatta.

Chiuso OT, meglio concentrarsi sull'Ardutester.

PaoloP

Più tardi descrivo come funziona la CheckProbe.
Pazientate.  :smiley-red:

Go Up