Come aumentare la frequenza di campionamento dell'adc di arduino?

Salve,avrei bisogno di campionare dei dati provenienti da un sensore analogico,in tempi rapidissimi che verranno poi scritti su una sd.Il tempo complessivo ora e circa 20ms,ma vorrei abbassarlo ulteriormente.Ho letto che e’ possibile cambiare la frequenza di campionamento tramite le funzioni:

bitClear(ADCSRA,ADPS0) ;
bitClear(ADCSRA,ADPS1) ;
bitSet(ADCSRA,ADPS2) ;

http://www.robotplatform.com/knowledge/ADC/adc_tutorial_2.html

Ecco lo sketch d’esempio in cui viene utilizzata suddetta funzione:

const int sensorPin = 0;             // pin the receiver is connected to
const int numberOfEntries = 100;

unsigned long microseconds;
unsigned long duration;

int results[numberOfEntries];

void setup()
{
  Serial.begin(9600);

  // standard analogRead performance (prescale =  128)
  microseconds = micros();
  for(int i = 0; i < numberOfEntries; i++)
  {
      results[i] = analogRead(sensorPin);
  }
  duration = micros() - microseconds;
  Serial.print(numberOfEntries);
  Serial.print(" readings took ");
  Serial.println(duration);

 // running with high speed clock (set prescale to 16)
  bitClear(ADCSRA,ADPS0) ;
  bitClear(ADCSRA,ADPS1) ;
  bitSet(ADCSRA,ADPS2) ;
  microseconds = micros();
  for(int i = 0; i < numberOfEntries; i++)
  {
      results[i] = analogRead(sensorPin);
  }
  duration = micros() - microseconds;
  Serial.print(numberOfEntries);
  Serial.print(" readings took ");
  Serial.println(duration);
}

void loop()
{
}

Orbene io l’ho inserita nel mio sketch ma i tempi sono rimasti invariati,dove sbaglio?
Ecco il mio codice:

#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include "ADXL335.h"

ADXL335 accelerometer;

RTC_DS1307 RTC;

File Dati; // La variabile di tipo file che useremo per il log

const int chipSelect =10;

 //static char  axb[100];
//static char  ayb[100];
float ax,ay,az;

unsigned long time; // serve per misurare il tempo di esecuzione

void setup ()

{
  Serial.begin(115200);
  
 
  Wire.begin(); // inizializziamo la libreria WIRE per usare
  RTC.begin(); //il Real Time clock basato su ds1307
  accelerometer.begin();
  
  if (! RTC.isrunning()) 
  
  {
    Serial.println("RTC NON STA FUNZIONANDO");
    
    //LA SEGUENTE ISTRUZIONE SERVE SOLO PER REGOLARE L'OROLOGIO.ATTIVARE SOLO SE NECESSARIO.
  //  RTC.adjust (DateTime(__DATE__, __TIME__)); //imposta ora e data
    }
    
    
    bitClear(ADCSRA,ADPS0) ;
    bitClear(ADCSRA,ADPS1) ;
    bitSet(ADCSRA,ADPS2) ;
    
   Serial.print("\nSto verificando la presenza della scheda..\n");
  pinMode(10, OUTPUT); // fa funzionare la sdlib
  
  if (!SD.begin(chipSelect))
  
  {
     Serial.println("SD card non trovata");
     return;
     
  }
 else 
   {
     Serial.println("Scheda inserita e funzionante");
     Serial.println();
    
   }
}
void loop ()

{
  // MISURO IL TEMPO DI ESECUZIONE 
  Serial.print("Time: ");
  time = millis();
  //prints time since program started
  Serial.println(time);
  
   
    DateTime now = RTC.now(); // leggiamo l'ora
    accelerometer.getAcceleration(&ax,&ay,&az);
  
   Serial.print(ax,3);
   Serial.print("g");
   Serial.print(",");
   Serial.print(ay,3);
   Serial.print("g");
   Serial.print("\t");
   
   // ORA E DATA
   Serial.print(now.day(), DEC);
   Serial.print('/');
   Serial.print(now.month(), DEC);
   Serial.print('/');
   Serial.print(now.year(), DEC);
   Serial.print(' ');
   Serial.print(now.hour(), DEC);
   Serial.print(':');
   Serial.print(now.minute(), DEC);
   Serial.print(':');
   Serial.print(now.second(), DEC);
   Serial.print("\n");
   
   Dati = SD.open("datalog.txt", FILE_WRITE); // apriamo il file in scrittura
  
  if (Dati)
  {


  // SCRITTURA DEI DATI DEL SENSORE
   Dati.print(ax,3);
   Dati.print("g");
   Dati.print(",");
   Dati.print(ay,3);
   Dati.print("g");
   Dati.print("\t");
   
   // SCRITTURA ORA E DATA
   Dati.print(now.day(), DEC);
   Dati.print('/');
   Dati.print(now.month(), DEC);
   Dati.print('/');
   Dati.print(now.year(), DEC);
   Dati.print(' ');
   Dati.print(now.hour(), DEC);
   Dati.print(':');
   Dati.print(now.minute(), DEC);
   Dati.print(':');
   Dati.print(now.second(), DEC);
   Dati.println(); 
   
   Dati.close();     // chiudiamo e trasferiamo su SD
   Serial.print("Dati rilevati \t");
   
  }
  else
  {
    Serial.println("Errore nell'apertura di datalog.txt");
  } 
  delay (0);  // cadenza dellascrittura dei dati
  Serial.println(time);
  }

Secondo me non hai capito.
L’ADC a cui si riferisce l’articolo è il convertitore interno del microcontrollore di Arduino, mica quello del tuo sensore.
Infatti in quell’articolo si velocizza il comando analogRead(pinAnalogico)
Tu hai un sensore esterno che ha montato al suo interno un suo ADC.

Se vuoi abbassare i tempi dovresti togliere (commentare) tutto quello che hai in loop() che scrive su Serial.
Logicamente così facendo non puoi conoscere la tempistica.
La Serial rallenta molto.

nid69ita:
Secondo me non hai capito.
L’ADC a cui si riferisce l’articolo è il convertitore interno del microcontrollore di Arduino, mica quello del tuo sensore.
Infatti in quell’articolo si velocizza il comando analogRead(pinAnalogico)
Tu hai un sensore esterno che ha montato al suo interno un suo ADC.

Se vuoi abbassare i tempi dovresti togliere (commentare) tutto quello che hai in loop() che scrive su Serial.
Logicamente così facendo non puoi conoscere la tempistica.
La Serial rallenta molto.

Scusa forse mi sono perso qualcosa,ma arduino non ha ingressi e uscite digitali e in analogici?L’ingresso analogico non dovrebbe sfruttare un convertitore adc per acquisire i dati di un sensore analogico? (per la precisione sto utilizzando un adlx335).Altra cosa,quindi se tolgo tutto cioe che viene scritto dici che dovrei ottimizzare i tempi generali e di conseguenza anche di scrittura su sd?

Si, da quel che dice qui le 3 uscite sono un valore di tensione proporzionale alla posizione x,y,z quindi usi l'adc interno di Arduino (pensvo ne avesse uno su internamente il sensore ma sarebbe stato digitale, sorry).

Le tue Serial sono dopo il tuo conteggio, non dovrebbero rallentarlo.

Sei sicuro che quei registri e settaggi ADC vadano bene per il 328? Il link che hai fornito parla di Atmel8.

Ho provato a commentare tutto,cio' veniva scritto sulla serial,addirittura anche il serial.begin.Alla fine ho avuto un leggero miglioramento..sono passato da circa 20 ms a 18ms.Non so se ne vale la pena o no a sto punto

Ho il testo mostrato nel link,ed eseguendo lo sketch effettivamente funziona su arduino uno.quindi presumo che col 328 debba funzionare.Ecco qui:

http://books.google.it/books?id=56H-13NzsSQC&pg=PA625&lpg=PA625&dq=bitClear%28ADCSRA,ADPS0%29&source=bl&ots=loCGzDOt_4&sig=s6KVbl1S95xV94BLmrdJeB0Afww&hl=it&sa=X&ei=PhxYU4vqLqm7yAP22oB4&ved=0CEsQ6AEwAg#v=onepage&q=bitClear%28ADCSRA%2CADPS0%29&f=false

Anche dal datasheet leggo che quel registro è anche sul AtMega328. Compresi quei bit (come da tuo link).

L'esperto dei registri di queste MCU è Leo72, uno degli Admin. Magari prima o poi legge questo thread e ti può dare un parere.

mooger: Ho il testo mostrato nel link,ed eseguendo lo sketch effettivamente funziona su arduino uno.quindi presumo che col 328 debba funzionare.

Può funzionare anche con l'Atmega328P. Il registro ed i bit indicati sono identici e svolgono le stesse funzioni.

leo72:

mooger: Ho il testo mostrato nel link,ed eseguendo lo sketch effettivamente funziona su arduino uno.quindi presumo che col 328 debba funzionare.

Può funzionare anche con l'Atmega328P. Il registro ed i bit indicati sono identici e svolgono le stesse funzioni.

Ho provato ad inserire il codice nel mio sketch,ma non succede nulla.C'e' qualcosa che io sbaglio,o e' inutile nel mio sketch? :(

mooger: Ho provato ad inserire il codice nel mio sketch,ma non succede nulla.

Che vuol dire?

Nel senso che ottengo sempre 50 campioni al secondo.Se intervenissi direttamente nel registro mi aspetteri qualche variazione.Cambiando la frequenza di campionamento dovrei avere un sistema piu reattivo e performante giusto?

Come ti ho detto nell'altro thread, il dico che il tuo collo di bottiglia è la scrittura su SD.

Ho fatto dei test. L'ADC impostato dal core di Arduino mi prende circa 112 us (microsecondi) per una lettura. Con le istruzioni per aumentare la frequenza di campionamento che hai messo tu, scendo a 20 us.