buongiorno
Sono un pensionato con la decennale, perenne passione per l'informatica e la voglia di apprendere(!)
Sto sperimentando, senza un scopo preciso, le potenzialità di uno SP32.
Macchina incredibile, meravigliosa.
A seguito di alcuni problemi presentatisi ho casualmente notato dei tempi lunghi (da 45 a 80 usec) per una conversione ADC.
L'AD converter è un SAR a 12bits, una conversione dovrebbe durare 12 colpi di clock.
Domande:
come si spiega tutto questo tempo in più?
se è così, esiste un modo alternativo per accedere direttamente al SAR evitando tutti gli strati intermedi di software?
Allego un'estratto dello sketch utilizzato per eseguire le misure dei tempi
Grazie
#include <Arduino.h>
#include <driver/adc.h> // per usare adc1_get_raw() invece di analogRead()
#define GPIO_POT 36 // potenziometro su GPIO34 = pin3
#define GPIO_ADC1 39 // input analogico su GPIO39 = pin4
// per gli ADC
// Setta la precisione a 12 bits (0-4095) (4095 corrisponde a 3.3V)
// Setta la precisione a 8 bits (0-255) ( 255 corrisponde a 3.3V)
#define ADC_RESOLUTION 12
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#define ADC_LEGACY // per utilizzare analogRead()
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
///////////////////////////////////////////////////////////////////////
void setup(void)
{
Serial.begin(115200);
//---Setta la precisione del convertitore ADC----
#ifdef ADC_LEGACY
analogReadResolution(ADC_RESOLUTION);
#else
if (ADC_RESOLUTION==12)
{
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_12); // GPIO36 PER IL POTENZIOMETRO
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_12); // GPIO39 PER L'OSCILLATORE
}
else
{
adc1_config_width(ADC_WIDTH_BIT_9);
adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_6); // GPIO36 PER IL POTENZIOMETRO
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_6); // GPIO39 PER L'OSCILLATORE
}
#endif
}
///////////////////////////////////////////////////////////////////////
void loop(void)
{
static uint32_t nLoop = 0;
uint16_t nValueADC = 0;
uint16_t nValuePOT = 0;
unsigned long nMicros = 0;
unsigned long nDiff = 0;
#ifdef ADC_LEGACY
nMicros = micros();
nValuePOT = analogRead(GPIO_POT);
nDiff = micros() - nMicros;
nValueADC = analogRead(GPIO_ADC1);
#else
nMicros = micros();
nValuePOT = adc1_get_raw(ADC1_CHANNEL_0); // potenziometro su GPIO34
nDiff = micros() - nMicros;
nValueADC = adc1_get_raw(ADC1_CHANNEL_3);
#endif
if (ADC_RESOLUTION == 12) // 12 bit (0 ... 4095)
{
nValuePOT = map( nValuePOT & 0xFFF, 0, 4095, 100, 2000); // potenziometro su GPIO34
nValueADC = nValueADC & 0xFFF;
}
else // 8 bit (0 ... 255)
{
nValuePOT = map( nValuePOT & 0xFF, 0, 255, 100, 2000); // potenziometro su GPIO34
nValueADC = nValueADC & 0xFF;
}
nLoop++;
Serial.printf("%6d: nDiff=%4lu \n", nLoop, nDiff);
// Serial.printf("ADC1=%4d Pot=%4d \n", nValueADC, nValuePOT);
// Serial.printf("%6d: nDiff=%4lu \n", nLoop, nDiff);
delay(50);
}
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere solo in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato.
PS: credo che la durata di conversione dipenda anche dalla frequenza di conversione, anche se non ho indagato penso che la frequenza di conversione sia configurabile.
Di più non saprei suggeriti poiché conosco questa mcu marginalmente.
Le api sono facili da navigare almeno su github, tu in locale hai tutto il sorgente, ma dove si trova lo devi scoprire da te.
Di quale clock? Quasi certamente non quello dell'MCU, in genere le periferiche hanno il clock collegato ad un prescaler che divide il clock per 2/4/8/16/etc, quindi bisogna vedere cosa fa nel dettaglio l'ESP32 a tal riguardo.
Infatti, a maggior ragione, è proprio questo che non mi so spiegare.
Questa MCU ha un clock di 240Mhz, sicuramente il SAR non lo utilizzerà direttamente, ma se anche fosse quello prescalato a 1Mhz, certo non giustificherebbe 60usec per la conversione.
So che è un sofisma ma ormai mi ci sono impuntato
Cercherò una qualche documentazione in rete.....
grazie
L'ESP32 ha due modalità di acquisizione ADC:
la prima, che se non sbaglio è quella che stai usando tu, è la one shot che usa il modulo RTC come fonte di timing, modulo che è molto più lento del clock principale (mi pare 150Khz).
Nella modalità continuos reading invece viene usata la modalità DMA e il tempo di acquisizione è praticamente realtime.
grazie cotestatnt
avevo visto quella documentazione, ma non avevo capito (o non è precisato) che fosse diametralmente differente il modo di acquisizione.
Farò delle prove
Devo dire che di documentazione ce n'è tanta ma un pò "sparpagliata"
Va trovata quella giusta, nel posto giusto