I'm using the ADC of the ATmega328 for data acquisition, storing 1000 8-bit values in the buffer and then sending them through USB to the PC where they're read and interpreted by LabVIEW.
On the UNO everything works fine, but on the Nano the data starts lagging behind by a few seconds (~20 buffer transmissions). Sometimes it gets so behind LabVIEW is giving an error "an over run error occured during transfer. A character was not read from the hardware before the next character arrived".
Could the FTDI chip on the Nano be slower than the ATmega16U2?
void loop()
{
//----------------------------
// RUNNING SEQUENCE
//----------------------------
if ( stopDAQ )
{
//send buffer to serial in correct order
//Serial.write sends binary data, while Serial.print sends ASCII
Serial.write( (uint8_t*) ADCBuffer + ADCCounter, ADCBUFFERSIZE - ADCCounter);
Serial.write( (uint8_t*) ADCBuffer, ADCCounter );
Serial.print( DATAEND );
//turn off LED errorPin, digital 13
cbi( PORTB, PORTB5 );
//clear buffer
memset ( (uint8_t*) ADCBuffer, 0, sizeof(ADCBuffer) );
//resetting variables
stopDAQ = false;
bufferIndex = -1;
if(singleDAQ)
singleDAQ = false;
else
{
//restart the analog to digital converter
startADC();
//let the ADC buffer fill
delay(bufferTime);
//restart the comparator
startAnalogComparator();
}
}
And the interrupt handling:
#include "header.h"
//-----------------------------------------------
// ADC Conversion Interrupt
//-----------------------------------------------
// Triggers when bit ADIF in register ADCSRA (status register A) is set to 1
// ADIF is set to 1 each time a conversion completes, in Free Running Mode
ISR(ADC_vect)
{
// When ADCL is read, the ADC Data Register is not updated until ADCH
// is read. Consequently, if the result is left adjusted and no more
// than 8-bit precision is required, it is sufficient to read ADCH.
// Otherwise, ADCL must be read first, then ADCH.
ADCBuffer[ADCCounter++] = ADCH;
if ( ADCCounter >= ADCBUFFERSIZE ) ADCCounter = 0;
if ( bufferIndex == ADCCounter )
{
//stop DAQ and allow sending data to serial
//disable ADC
cbi(ADCSRA, ADEN);
stopDAQ = true;
}
}
//------------------------------------------------
// ANALOG COMPARATOR INTERRUPT
//------------------------------------------------
// Triggers when bit ACI in register ACSR is set to 1
ISR(ANALOG_COMP_vect)
{
// disable Analog Comparator interrupt
cbi(ACSR, ACIE);
// turn on LED errorPin
sbi( PORTB, PORTB5);
bufferIndex = ( ADCCounter + after_Trigger_Samples ) % ADCBUFFERSIZE;
}
I would write a simple program that sends data and try it at different baud rates. That obviously needs an appropriate program on the PC to receive the data.