Buongiorno a tutti, ho creato un semplice sketch che deve leggere un valore di tensione da 0 a 24V,ed inviarlo tramite seriale ad un pc dove gira un programma in python che crea un file csv con questo dato.
i segnali che devo leggere possono raggiungere anche una frequenza di 250Hz.
vorrei capire posso sfruttare di più la velocità di arduino o se il collo di bottiglia è la comunicazione seriale.
const int analogPin = A0 ;
void setup() {
// Setup serial connection
Serial.begin(115200);
}
// variabile temporale
int i = 0;
void loop() {
// Read analog pin
int val = analogRead(analogPin);
//convert the value in voltage 0 - 24v
int voltage = map( val, 0, 1023, 0, 24000);
//Print voltage value to serial port
String tempo = String(i);
String tensione = String(voltage);
Serial.println(tempo+';'+tensione);
i++;
}
Quelle istanze di String oltre a rallentare l'esecuzione dello sketch, sono del tutto inutili.
void loop() {
// Read analog pin
int val = analogRead(analogPin);
//convert the value in voltage 0 - 24v
int voltage = map( val, 0, 1023, 0, 24000);
//Print voltage value to serial port
Serial.print(i++);
Serial.print(";");
Serial.println(volltage);
}
P.S.
Stai usando un partitore di tensione sull'ingresso analogico, immagino?!
P.S.S.
Non hai fatto le presentazioni come previsto dal regolamento. Corri a farla prima che l'admin se ne accorga
si utilizzo un partitore analogico con un piccolo diodo a protezione di tensioni inverse.
il programma python mi legge la stringa e scrive in un file. in questo modo non ci mette più tempo ad inviare il dato?
Ho fatto un pò di prove utilizzando i vostri suggerimenti.
Spezzando la stringa in 3 print non aumentano i campioni. rispetto all'originale.
A questo punto potrei rinunciare alla numerazione dei campioni ed al ";" inviando solo un valore attraverso il println. così facendo triplico il numero di campioni utili.
ho provato a tenere e togliere il map e non cambia nulla in numero campioni.
ho fatto anche delle prove a salire con la velocità sulla seriale e oltre i 115200 e qualcosa migliora ma non vorrei mettere in difficoltà la comunicazione.
mi viene da dire che siamo al limite delle possibilità tecniche di arduino.
Che significa "i segnali possono raggiungere una frequenza di 250Hz"? A che velocità vuoi campionarli?
Che velocità sei riuscito a raggiungere?
Credo che con la seriale a 115200 potresti arrivare a 4kHz.
Altrimenti potresti fare più letture di seguito, scriverle in un array e inviarle periodicamente, accettando le pause periodiche per la trasmissione.
devo andare a campionare segnali dalla continua ai 250Hz (limite imposto da progetto).
voglio campionarli alla frequenza massima raggiungibile da arduino.
alla fine facendo due conti sui campioni a spanne sono a circa 4KHz quindi teorema di Shannon più che rispettato.
il discorso dell'array non va bene per il progetto. perchè non sono segnali costanti e periodici.
comunque attualmente con le ultime modifiche ho raggiunto dei buoni risultati. volevo solo capire se stessi sbagliando qualcosa o se ci fosse una soluzione più efficace e e che sfruttasse al massimo l'hardware.
Un'evoluzione del progetto dovrebbe essere la possibilità di acquisire del rumore fino a 1000Hz.
Però li faccio farica a capire se i valori sono corretti.
Occhi che analogRead() non permette di configurare il convertitore ADC. Lo si può fare manipolando i registri.
Si può anche acquisire con IRQ in modo continuo con auto-trigger.
piccolo aggiornamento. mi sono accorto che senza un minimo delay al programam in arduino, la lettura via seriale in python perdeva qualche colpo e mi dava errori in letura (tipo dati mancanti o sovrapposti in valori) quindi ho dovuto aggiungere 600 microsecondi di delay, valore scelto dopo diverse prove a scalare.Quindi dovrò anche rivedere meglio la parte in python.
Puoi sempre usare il baudrate a 57600 che è la metà di 115200. Non posso provare ma con pyserial e vari arduino non ho mai avuto questi problemi. Ne ho avuti invece con le schedine usb to serial e vagamente ho risolto modificando leggermente la formula per il baudrate.
Comunque una cosa è la frequenza di campionamento del convertitore ADC e una altra è il numero di campioni per secondo che ti serve inviare.
Insomma...
che senso avrebbe campionare misure che non usi (trasmetti)
poi certamente non puoi trasmettere campioni che non hai preso...
la cadenza dell'ADC deve essere almeno pari a quella di trasmissione
sarebbe inutile che fosse maggiore
quindi alla fine vedi che le due cose sono uguali...
Piuttosto sarebbe da analizzare la variazione tra un campione e il successivo
Nel caso si potrebbe ridurre la "massa dati" da ttasmettere trasmettendo solo la differenza
Magari in binario
Ni, cioè se invii i codici ascii del numero 1023 invii 4 byte, se invii 1023 come numero invii 2 byte.
Lato PC ovviamente dovrai ricavare da 2 byte il valore 1023.
Molto peggio se arduino fa calcoli con i campioni e ne ricava un float che invii come ascii.
Non vorrei darti troppe info che magari a te non servono, ma ho solo pochi minuti.
Se trasmetti a 115200 per ogni byte servono due bit aggiuntivi, quindi 115200/10 = 11520 byte al secondo.
1/11520 = 0,000086806s è la timeline per ogni byte
difatti 000086806 x 11520 = 1s
Ciao.