ecco il codice per fare le analogRead con prescaler a 16 (meno di 20 microsecondi a lettura)
ciò vuol dire ~8600 letture al secondo
notare che per loggare questa quantità di dati serve la seriale 760800 baud, una velocità quasi-standar. se non vi funziona provate a usare 921600.
Se non vi funziona nemmeno così, allora siete costretti a usare 115200 baud e accontentarsi di loggare a 2972Hz. (In questo caso aggiungete una Serial.flush() prima delle Serial.write(), in modo da non subire una lag sulle letture analizzate, che arriva tranquillamente a 30 secondi)
/*
Fast Analog Input
it read 3 analog pin with a 10bit precision. (until 200kHz of ADC's clock according to datasheet, but it will work at 1MHz)
Using a prescaler of 2 give 8MHz reading, but i've found value to be inconsistent. Haven't tryed other prescaler. Arduino use 200Hz ADC clock, so prescaler = 128
it will store the 3 read of 30bit into one unsigned long (32bit) and then print it to serial.
That way it use 4 byte instead of 6 to store the data, and because it will write 5 byte instead of 7 into serial, it is 1,4 times faster to write
If in 8bit mode, it will store the 3 read of 24bit + 8bit of '\n' into one unsigned long (32bit) and then print it to serial.
That way it use 3 byte instead of 6 to store the data, and because it will write 4 byte instead of 7 into serial, it is 1,75 times faster to write
End of String value is \n
it will use analog pin
A0 = 14
A1 = 15
A2 = 16
This code should work on all arduino IDE version, but faster on version > 1.0 because of asincronous serial communication.
That mean that serial will write data while you are reading the next one, but this also mean we cannot use the ADC noise canceller mode.
This code is tested on Atmega328P, but should work for:
Atmega48A
Atmega48PA
Atmega88A
Atmega88PA
Atmega168A
Atmega168PA
Atmega328
Atmega328P
Created by lesto for http://www.arduino.cc
12 June 2012
This example code is LPGL licence Version 3, 29 June 2007
you can find it on http://www.gnu.org/licenses/lgpl.html
*/
#define USE10BIT 1
void setup() {
// start serial (it is slow, change this to higher value)
Serial.begin(460800);//460800 is best value for prescaler @ 16
Serial.flush();
//just a bit of delay
delay(2000);
#if USE10BIT
Serial.println("10BIT");
#else
Serial.println("8BIT");
#endif
delay(2000);
ADCSRA &= B11111100; //prescaler to 16, about ~77 kHz sample rate
Serial.println(ADCSRA, DEC);
}
int i;
unsigned long ris;
void loop() {
//reset ris
ris=0;
for (int pin = A0; pin < A3; pin++){
#if USE10BIT
ris = ris << 10;
ris += analogRead(pin);
#else
ris = ris << 8;
ris += analogRead(pin)>>2; //remove 2 lower bit
#endif
}
#if USE10BIT
ris = ris<<2;
Serial.write(ris>>24);
Serial.write(ris>>16);
Serial.write(ris>>8);
Serial.write(ris);
Serial.print('\n');
#else
ris = ris<<8;
ris |='\n';
Serial.write(ris>>24);
Serial.write(ris>>16);
Serial.write(ris>>8);
Serial.write(ris);
#endif
// delay(100); //just for debug
}
e la controparte processing che salva i dati su file:
/**
* Simple Read Fast
*
* from lesto http://www.arduino.cc
*/
import processing.serial.*;
//START - you can saftely change this data
String portName = Serial.list()[0];
int baudRate = 460800; //best value for prescaler @ 16
//END - you can saftely change this data
long time;//to calculate read/s
String fileName;
void setup()
{
int i = 0;
do{
fileName = "savefile_"+year()+":"+month()+":"+day()+"_"+hour()+":"+minute()+":"+second()+"_"+i+".csv";
i++;
}while (loadStrings(fileName) != null); //until we don't find a file
try{
FileWriter pw = new FileWriter(fileName, false);
pw.close();
}catch(Exception e){
e.printStackTrace();
}
size(600, 200);
println(portName);
Serial myPort; // Create object from Serial class
myPort = new Serial(this, portName, baudRate);
//now attach an event (a software interrupt) to serial when a \n is readed
myPort.bufferUntil('\n'); // if newline launch event
time = millis();
}
boolean areYouSure = false;
static Object syncronizer = new Object(); //just for syncronization
float readXseconds=0, byteXseconds=0;
int x, y, z;
void draw()
{
synchronized(syncronizer){
background(0);
File a = new File(fileName);
text("Save file: "+a.toURI(), 15, 10);
text("Serial Port: "+portName, 15, 30);
text("Baud Rate: "+baudRate, 15, 50);
text("Read per Seconds: "+readXseconds, 15, 70);
text("Byte per Seconds: "+byteXseconds, 15, 90);
text("Bandwidth used: "+((byteXseconds*10)/baudRate)*100+"%", 15, 110);
text("Last Read X: "+x, 15, 140);
text("Last Read Y: "+y, 15, 160);
text("Last Read Z: "+z, 15, 180);
}
}
int read = 0;
long byteRead = 0;
int a=0, b=0, c=0;
final ArrayDeque<String> output = new ArrayDeque<String>();
String aCapo = System.getProperty("line.separator");
synchronized void serialEvent(Serial p){ //synchronized because we want process only one evet at time
long time2 = millis();
if ( (time2 - time) >= 1000 ){
synchronized(syncronizer){
float partialTime= ((time2 - time)/1000);
readXseconds = read / partialTime;
byteXseconds = byteRead / partialTime;
byteRead=read=0;
time = time2;
x = a;
y = b;
z = c;
saveData();
// println("read at seconds:"+readXseconds);
}
}
byte[] inBuffer = new byte[30];
int l = p.readBytesUntil('\n', inBuffer);
byteRead+=l;
/* FOR DEBUG
if (l != 0)
println("readed "+l);
*/
if (inBuffer != null && l == 5) {
read++;
// for (int i = 0; i < 4; i++){
// println(inBuffer[i]& 0xFF);
// }
a = ( inBuffer[0] & 0xFF)<<2; //all 0
a += ( inBuffer[1]& 0xFF) >>6; //and 2 first 2 bit of 1
b = ( (inBuffer[1]& 0xFF) & 63)<<4; //last 6bit of 1
b += ( (inBuffer[2]& 0xFF) >>4); //and first 4 bit of 2
c = ( (inBuffer[2])& 0xFF & 15)<<6; //last 4bit of if 2
c += ( inBuffer[3] & 0xFF) >> 2; //fisrt 6 bit of 3
// println("a:"+a+" b:"+b+" c:"+c);
output.add(a+","+b+","+c+aCapo);
}
if (inBuffer != null && l == 4) {
read++;
a = inBuffer[0] & 0xFF;
b = inBuffer[1] & 0xFF;
c = inBuffer[2] & 0xFF;
output.add(a+","+b+","+c+aCapo);
// println("a:"+a+" b:"+b+" c:"+c);
}
}
void saveData() { // Append data
FileWriter pw = null;
try{
pw = new FileWriter(fileName, true);
String tmp;
while( (tmp = output.poll()) != null ){
pw.write(tmp, 0, tmp.length());
}
}catch (IOException e) {
e.printStackTrace(); // Dump and primitive exception handling...
}finally{
if (pw != null){
try{
pw.close();
}catch (IOException e) {
e.printStackTrace(); // Dump and primitive exception handling...
}
}
}
}