Vai al contenuto
PLC Forum


Contatori veloci


roberto8303

Messaggi consigliati


  • Risposte 127
  • Created
  • Ultima risposta

Top Posters In This Topic

  • roberto8303

    56

  • ilguargua

    32

  • Livio Orsini

    26

  • GiRock

    9

e sul AREF devo dare i +5 volt esterni?non ho capito, In realta entro con 9 volt su VIN 

 non è che ci vuole un condensatore tra AREF e gnd per ridurre il '' rumore distrubi''? 

Link al commento
Condividi su altri siti

Tutti gli A/D necessitano di una tensione di riferimento.

Nel caso di arduino si può usare come riferimeto il +5V di alimentazione interno al micro, oppure dare un livllo di riferimento tramite un ingresso apposito.

SI usa o per espandere la scala o per avere un riferimento particolarmente stabile e preciso.

Ad esempio pensa al caso in cui devi leggere un trasduttore la cui uscita varia tra 0.5V e 1.8V. Se usi il riferimento interno di 5V hai 266 counts per tutta l'escursione; invece se dai il riferimentio esterno di 2V i counts diventano 665 per tutta l'escursione, con la misura quasi 3 volte più precisa

Link al commento
Condividi su altri siti

Grazie ora e tutto chiaro provo a dare i 5v anche sul vref e provero anche un condensatore da 100nf su :thumb_yello:vref e verso massa

grazie anche a te Ale per il suggerimento della media per ora provo prima cosi e vediamo se riesco a risolvere

Link al commento
Condividi su altri siti

7 minuti fa, roberto8303 scrisse:

Grazie ora e tutto chiaro provo a dare i 5v anche sul vref e provero anche un condensatore da 100nf su :thumb_yello:vref e verso massa

Ok per il condensatore, ma collegare i 5V sull Aref è inutile, nonchè pericoloso. Inutile perché non cambia niente rispetto al default (i 5V di alimentazione vengono collegati internamente), pericoloso perchè se cambi il codice per usare il riferimento interno, anche accidentalmente, metti fuori uso tutto l'ADC. Io comunque lavorerei meglio sul discorso scalatura, come ti ho già detto, a te serve un risultato a 4bit (0-15) contro quello a 10(0-1023), quindi non è eliminando la fluttuazione di pochi millivolt che risolvi.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

ora non posso provare, ma  quando alimento con 5v su Vin sul pin Vref ci sono gia i 5 volt? oppure è un pin aperto flottante?

Per la scalatura cosa intendi? fare la media? ho provato anche a dividere il segnale A0 per 100 in float poi convertirlo di nuovo in int  e mapparlo da 0-15 pensando di far andare fuori tutti i decimali e avere poi un numero arrotondato ma nulla comunque oscilla.

 

Link al commento
Condividi su altri siti

53 minuti fa, roberto8303 scrisse:

ho provato anche a dividere il segnale A0 per 100 in float poi convertirlo di nuovo in int  e mapparlo da 0-15 pensando di far andare fuori tutti i decimali e avere poi un numero arrotondato ma nulla comunque oscilla.

Per fare fuori tutti i numeri che non ti interessano devi togliere i primi 6 bit dal numero, già te l'ho scritto, è il sistema più veloce ed efficace.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

Se si usa una tnsione apposita, ed esclusivamente per i riferimenti, un certo miglioramento ci può essere.

Se poi la conversione interessa bassi valori di tensione, amaggior ragione conviene usare una tensione specifica per i riferimenti, magari basterebbe usare il 3.3V della scheda.

 

Ppi non c'è niente da fare. 5V quantizzati su 1024 livelli hanno un gradino pari a 4,88 mV quindi un'oscillazione di +/- 1 count è abbastanza probabile.

Link al commento
Condividi su altri siti

17 minuti fa, Livio Orsini scrisse:

5V quantizzati su 1024 livelli hanno un gradino pari a 4,88 mV quindi un'oscillazione di +/- 1 count è abbastanza probabile.

Vero, però se il valore viene scalato da 0-1024 (10bit) a 0-15 (4 bit) in quel caso il salto tra una cifra e l'altra diventa 4,88x64=312,32 mV, che come oscillazione mi sembra già cospicua. Secondo me, ripeto, il problema è nel codice, che però non ci è dato modo di vedere.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

void setup() {
   
  pinMode(8,INPUT);
  matrix.begin(0x70);
}

void loop() {
 matrix.clear();
 potenz=analogRead(0);
 pot=map(potenz,0,1023,1,6);
ingresso1=analogRead(2);
ingresso2=analogRead(7);

int pot1= map(ingresso1, 0,1023,0,15);
int pot2=map(ingresso2, 0,1023,0,15);
  int h1 = pot1 / 10;                                     // divido i numeri per poter leggere i 2 potenziometri su un display
  int h2 = pot1 - (h1 * 10);
  int m1 = pot2/ 10;
  int m2 = pot2 - (m1 * 10);
      
  /
      
      matrix.writeDigitNum(0, h1, false);  
      matrix.writeDigitNum(1, h2, false);
           matrix.drawColon(true);  // due punti centrali
      matrix.writeDigitNum(3, m1, false);
      matrix.writeDigitNum(4, m2, false);
      matrix.writeDisplay();    
 delay(1000);
  fari =digitalRead(8);
if (fari==1){
    matrix.setBrightness(pot);}
    else{
      matrix.setBrightness(6);}
 
}

 

 

Ecco il codice, è molto semplice ed il video dove si vede l oscillazione i due punti nel display separano il potenziometro A: B ovviamente lo stesso programma è caricato su un altro arduino per l altro display con altri due potenziometri.

 

https://youtu.be/2zC4iAPUm64

Link al commento
Condividi su altri siti

ho provato con +5 su aref e lo fa sempre, con il condensatore lo stesso.

Alex mi puoi spiegare come fare il codice di programma per la risoluzione?

Link al commento
Condividi su altri siti

20 ore fa, ilguargua scrisse:

Prova a mettere un condensatore da 220nF sull'uscita del potenziometro, dovrebbe aiutare. Poi molto dipende anche da come fai la lettura, cerca di fare più letture e fai una media. Io in genere faccio così :

 


uint16_t readAdc(uint8_t ain)
{
    uint16_t ret=0; 
    analogRead(ain);
    for(uint8_t i=0;i<4;i++)
     {
       ret += analogRead(ain);  
     }
    return (ret >> 2); 
}

Poi se devi scalare il risultato da 0 a 15 basta che fai un ulteriore shifting di 6 bit e sei a posto.

 

Ciao, Ale.

Lo avevo già postato, lo riporto di nuovo. Per avere il valore scalato direttamente a 0-15 cambia l'ultima riga con return (ret >> 8); , nel tuo programma metti direttamente int pot1= readAdc(2), int pot2= readAdc(7) e sei a posto.

 

 

Ciao, Ale.

Link al commento
Condividi su altri siti

 

6 minuti fa, roberto8303 scrisse:

scusami ma analogread(ain);   questo ain cos è?devo dichiararlo?

No, è una variabile locale, il parametro passato alla funzione quando la richiami. E' già dichiarato : uint16_t readAdc(uint8_t ain)

 

Ciao, Ale.

Link al commento
Condividi su altri siti

30 minuti fa, ilguargua scrisse:

uint16_t readAdc(uint8_t ain)

lo devo inserire nel loop? perchè mi dice ain non dichiarato

usando questa funzione nel programma devo togliere anche la lettura del potenziometro fari? sulla porta A0 non collegata ai display

Link al commento
Condividi su altri siti

#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_7segment matrix = Adafruit_7segment();
// riferimento da 1°potenziometro mappato da 1-15
 //riferimento da 2°potenziometro mappato da 1-15

//lettura da A2 ed A7 analogico
int fari;
int pot;
int potenz;
#define CAMPreadings 10
#define CAMPreadings2 10
#define ingresso1 2
#define ingresso2 7
int letture[CAMPreadings];
int index=0;
int totale=0;
int media= 0;
int letture2[CAMPreadings2];
int index2=0;
int totale2=0;
int media2= 0;


void setup() {
  for(int i=0; i< CAMPreadings; i++){
  letture[i]=0;}
  pinMode(8,INPUT);
   for(int i=0; i< CAMPreadings2; i++){
  letture2[i]=0;}
  matrix.begin(0x70);
}

void loop() {

   totale-=letture[index];
   letture[index]=analogRead(ingresso1);
   totale+= letture[index];
   index=(index+1);
   if (index >=CAMPreadings){
    index=0;
   
   media=totale/CAMPreadings;}

 totale2-=letture2[index2];
   letture2[index2]=analogRead(ingresso2);
   totale2+= letture2[index2];
   index2=(index2 +1);
   if (index2 >=CAMPreadings2){
    index2=0;
   
   media2=totale2/CAMPreadings2;}

   

 matrix.clear();
 potenz=analogRead(0);
 pot=map(potenz,0,1023,1,6);

int pot1=map(media,0,1000,0,15);
int pot2=map(media2,0,1000,0,15);
  int h1 = pot1 / 10;
  int h2 = pot1 - (h1 * 10);
    int m1 = pot2/ 10;
  int m2 = pot2 - (m1 * 10);
  // Send data to display
      
    matrix.writeDigitNum(0, h1, false);  
     matrix.writeDigitNum(1, h2, false);
           matrix.drawColon(true);  // due punti centrali
     matrix.writeDigitNum(3, m1, false);
     matrix.writeDigitNum(4, m2, false);
     matrix.writeDisplay();    
 delay(100);
  fari =digitalRead(8);
if (fari==1){
    matrix.setBrightness(pot);}
    else{
      matrix.setBrightness(6);}
 
}

 

 

con questo programma ho campionato 10 valori e poi la media, ma qualche oscillazione c è ancora...

ALex perchè il tuo programma mi da errore ain non è dichiarato? vorrei provare la tua soluzione

 

 

 

Link al commento
Condividi su altri siti

uint16_t readAdc(uint8_t ain)
{
    uint16_t ret=0; 
    analogRead(ain);
    for(uint8_t i=0;i<4;i++)
     {
       ret += analogRead(ain);  
     }
    return (ret >> 8); 
}


void setup() {
   
  pinMode(8,INPUT);
  //matrix.begin(0x70);
}

void loop() {
 //matrix.clear();
 //potenz=analogRead(0);
 //pot=map(potenz,0,1023,1,6);


int pot1= readAdc(2);//map(ingresso1, 0,1023,0,15);
int pot2= readAdc(7);//map(ingresso2, 0,1023,0,15);
  int h1 = pot1 / 10;                                     // divido i numeri per poter leggere i 2 potenziometri su un display
  int h2 = pot1 - (h1 * 10);
  int m1 = pot2/ 10;
  int m2 = pot2 - (m1 * 10);
      
  /*
      
      matrix.writeDigitNum(0, h1, false);  
      matrix.writeDigitNum(1, h2, false);
           matrix.drawColon(true);  // due punti centrali
      matrix.writeDigitNum(3, m1, false);
      matrix.writeDigitNum(4, m2, false);
      matrix.writeDisplay();    
 */
 delay(1000);
 // fari =digitalRead(8);
/*
if (fari==1){
    matrix.setBrightness(pot);}
    else{
      matrix.setBrightness(6);}
*/ 
}

Il codice che hai postato non si compila, perchè non è completo, quello sopra in cui ho dovuto commentare tutto quello che manca compila senza problemi, toglici i commenti e riprova.

 

Ciao, Ale.

 

Edit : mi hai preceduto con il codice completo, ora faccio qualche test.

Link al commento
Condividi su altri siti

 

 

ok l ho provato funziona!! è abbastanza stabile mi sa che vabbene anche cosi senza fare 10 campioni e poi la media.

Ma questo esempio che mi hai postato in sostanza quando dici di scalare 0-15 con ret >>8 come funziona esattamente?

 

Link al commento
Condividi su altri siti

20 minuti fa, roberto8303 scrisse:

ok l ho provato funziona!! è abbastanza stabile mi sa che vabbene anche cosi senza fare 10 campioni e poi la media.

Di campioni ne fa già 4, in genere sono sufficienti.

 

21 minuti fa, roberto8303 scrisse:

Ma questo esempio che mi hai postato in sostanza quando dici di scalare 0-15 con ret >>8 come funziona esattamente?

Si chiama bit-shifting, o scorrimento di bit, gli operatori << e >> indicano la direzione. Cerca qualche tutorial on-line, sicuramente troverai spiegazioni migliori di quella che potrei farti io. Prova altrimenti a scrivere su un foglio un numero in binario, partendo da destra (bit più basso) verso sinistra, poi prova a far scorrere i bit verso dx di una, due o più posizioni e vedi cosa accade, a me perlomeno viene facile pensarla così.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

1 ora fa, roberto8303 scrisse:

Livio ma con + 5v su aref non cambia molto purtroppo..

 

Perchè l'oscillazione non dipende da una variazione del livello di riferimento, o almeno dipende in misura trascurabile.

 

L'oscillazione dipende quasi esclusivamente dal "rumore di quantizzazione".

In qualsiasi conversione c'è sempre una zona d'indecisione tra due passi consecutivi. Uno risulta basso e l'altro alto rispetto al livello analogico. Ne consegue un'indecisione con conseguente pendolamento tra i 2 codici vicini.

 

Nel tuo caso converti su 10 bit però, se ho capito correttamente, visulazzi solo il livello corrispondente ai 4 più significativi.

Azzerando i 6 bits meno significativi dovresti avere una misura quasi sempre stabile perchè puoi trovare un livello la cui eventuale oscillazione rientra nei 307 mV "ciechi"; se non riesci a trovare una posizione del potenziometro a cui corrisponda un livello stabile, significa che sovrapposto al livello continuo hai un disturbo di ampiezza maggiore 307mVpp.

Il disturbo ce lo hai sull'alimentazione del potenziometro, o è captato dai fili di collegamento del potenziometro stesso.

Link al commento
Condividi su altri siti

 

 

con l azzeramento dei 6 bit adesso sono molto piu stabile e vabbene cosi:thumb_yello: ho notato anche che devo spostare un po in piu la corsa del potenziometro per far "scattare" la cifra avanti o dietro.

 grazie per l aiuto ad entrambi!!

 

Link al commento
Condividi su altri siti

Sono contento che tu abbia risolto, comunque, per l'uso che ne fai, avrei visto meglio un encoder rotativo piuttosto che un potenziometro, in quel caso calcolare la posizione senza incertezze è banale.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora

×
×
  • Crea nuovo/a...