Arduino Mega 2560 as DAQ at 500Hz problem

My final goal is to read the 16 a2d ports and send the data over the serial port to a laptop at a frequency of 500 Hz. I wrote a python script to read the data. 99% of the time the software works on both ends; however, every once in a while the script will just skip either 15 messages or thousands of messages (3-8 seconds of data). I can confirm on the python side that it is working, and am suspect of the aduino side. Any help would be appreciated.

This is my first post so I tried to attach both codes.

Fast_Analog_Read_on_board.ino (3.47 KB)

serialreader.txt (3.32 KB)

500 times a second?

what is your baud rate?

how many characters are you sending for each channel?

You need to do some calculations to see if what you want is feasible.

Also Windows is not a real-time operating system when it comes to serial ports.
You'll want to read up on that.

.

16 ADC ports 500 times a second is 8000 readings/second. Assuming fully packed data that's 160 bits = 20 bytes not including packet/frame overhead, so 200 serial bits 500 times a second, so the minimum possible
baud rate is 100k, making 115200 borderline at best.

Given there will be buffering in various places with various sized buffers, I suggest trying non-standard
baudrate such as 250k or 500k, assuming the Python serial driver can handle that - might even be able
to squeeze packet acknowledge/retry logic in then.

I am unsure on how to paste code and make it look nice but it is below attached. I am running at 2MHz baud rate and each reading is 10 bit so essentially 2 byte.

You will notice that in my code below I even tried it by removing the analog read portion of the code but have same type of behavior. This is my first Arduino code so definitely could be something simple that I am missing. Am I trying to do too much with the Arduino?

Thank you for taking the time to read the post.

#include <Wire.h>
float currentTime=0;

int timer1_counter;
bool print_values, zeroByte;
int count;
unsigned long beginTime, endTime, totalTime,firstFour,secondFour,temp;
/*******************************************************************************
Setup
*******************************************************************************/
void setup()
{
//*****************changing ADC prescale to get a ADC of 1MHz and sampling rate of ~77KHz
#ifndef cbi
#define cbi(sfr,bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr,bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
//set prescale to 16
sbi(ADCSRA,ADPS2);
cbi(ADCSRA,ADPS1);
cbi(ADCSRA,ADPS0);
//************************************END of ADC prescale and sampling clock
beginTime=0;
endTime=0;
totalTime=0;
Serial.begin(2000000);

print_values = false;
TCCR1A=0;//set register to 0
TCCR1B=0;//set register to 0
timer1_counter=65505;//500hz//49911;//initialize timer counter to 65535-X
//P.S. presaler is 1024 or 256 etc.
//C.F. is clock frequency 16 MHz
// (CF/(P.S.frequency desired)) -1
//65380=65535-(16000000/(1024
100))-1 ->100 Hz
TCNT1=timer1_counter;
TCCR1B |= (1<<WGM12); //these two lines set the registry values to select the prescale value
TCCR1B |= (1<<CS12)| (1<<CS10); //the |= is a bitwise or command to select certain bits without TIMSK1 |= (1<<TOIE1); //ENABLE TIMER COMPARE INTERRUPT
}

//***************ISR
ISR(TIMER1_OVF_vect) //interrupt service routine for interrup 1
{
print_values = true;
TCNT1=timer1_counter;

}

/*******************************************************************************
Main Loop
*******************************************************************************/
void loop()
{
byte fullValue=0;
byte lowValue=0;
byte highValue=0;
byte counter=0;
byte zeroByteTime=0;
byte oneByteTime=0;
byte twoByteTime=0;
byte threeByteTime=0;
int i=0;
int temp=0;
unsigned int b;
b=0;
char measurements[32];
int index=0;
temp=0;

if (print_values==1){
for(i=0; i<16; i++){
//b=analogRead(i);
b=0xFF;
highValue=b>>8;
temp=b<<8;
lowValue=temp>>8;
if(i==1){
Serial.write("z");
//Serial.write(lowValue);
//Serial.write(highValue);
}
if(i==15){
//Serial.write(lowValue);
//Serial.write(highValue);
totalTime=micros();
threeByteTime = (totalTime & 0xFF000000)>>24;//msb
twoByteTime = (totalTime & 0x00FF0000)>>16;
oneByteTime = (totalTime & 0x0000FF00)>>8;
zeroByteTime = (totalTime & 0x000000FF);
Serial.write(zeroByteTime);
Serial.write(oneByteTime);
Serial.write(twoByteTime);
Serial.write(threeByteTime);
Serial.write("end");

}
else{
//Serial.write(lowValue);
//Serial.write(highValue);
print_values=0;
}
}//for loop

}//if print values == 1

}//end of file

Use the </> code button to post code. Have you read the how-to-post guide?

This

Serial.write("end");

should be this

Serial.print("end");