I need to send in 6 variables through the serial port in the Mega. The variables are 4 ints and 2 floats. The ints are between -180 and +180, the floats are Latitude and Longitude from GPS, both are 7 digit numbers. Now i've set up everything and everything works like a charm. But, i want to get my program to execute at least 200Hz, and the bottleneck is the serial communication. Without it , my program runs near 500Hz, but with the serial i can only get 100Hz.

It takes about 3-4ms for the Serial to send everything i want, while my program executes about 1-1.5ms. Is there a way i can make the serial much faster, at least twice as fast? My baudrate is already at 115200.

I would like to only send only 6 (no more than 6) variables as well, so i am clueless how to go about increasing the speed.

The program on the computer side, reads the serial buffer 6 times and stores the values. Then i do some graphical stuff with the data, "real time". So every time i am sending data it must be 6 variables, no less no more.

I am thinking of sending the data through I2C to another Arduino that then sends its to my computer. Acting something like a Register (pipeline). That way my mega can continue to run. Not sure if it work they way i think it would... So while i am working on that, i thought that i would ask for help.

Some things i've tried, but failed: Sending the GPS data only when it was available ( 1 Hz). It works until the gps data needs to be send. I am using a timer interrupt, so for 200 Hz, the timer interrupt is set at 5ms. As soon I send the GPS data , the thing farts and crashes... Converting the floats to a long, but the converted long takes longer to send so not really an improvement.

Summary of my problem: Takes too long to send what i want. Goal is to have the program execute at least at 200Hz, and sending everything (the 6 variables mentioned above). Is it realistically possible? If so do you guys have any ideas how?

I read twice through your question. I still do not understand why you want to send the same data 200 times to the PC? There is no change to the GPS data!

So it needs to find why your program crashed....There is no need for a timer at all. How is the GPS connected? NewSoftwareSerial? So you haveto check when the 80 NMEA bytes arrive. you are ready after the CR/NL arrives and can send the data to the PC....

I read twice through your question. I still do not understand why you want to send the same data 200 times to the PC? There is no change to the GPS data!

So it needs to find why your program crashed....There is no need for a timer at all. How is the GPS connected? NewSoftwareSerial? So you haveto check when the 80 NMEA bytes arrive. you are ready after the CR/NL arrives and can send the data to the PC....

I know there is no change in the GPS, but i have some other sensors that can update at 200Hz or faster, ( accelerometer,Gyro scope and later a Magnetometer) I am using the timer interrupt to precisely get the other sensor data. The program crashes because the interrupt is triggered before everything is executed.

Quote

WHY? Nothing you can attach this to moves fast enough to warrant that update speed. And no GPS updates that fast, either.

I've set up the program to stabilize a quadrotor helicopter. 200Hz would be enough to stabilize it, but i am not sure if 100Hz is good enough. Reason i want it faster is because i will be adding more functions.

So any ideas?

Currently i can get everything to execute faster than 200Hz, but i need the data. The quadrotor will be controlled from "distance",( Joystick on the PC). Everything is displayed on my PC. Attitude ( roll,pitch,yaw) as well its current heading and possition. Later on i will add altitude to ground, but for now i just want to get it as fast as possible with just the 6 variables . (Roll,Pitch,Yaw,Latitude,Longitude,Other) Roll and Pitch is in between +-180 ( hopefully it will never get near +- 50 degrees though)

Yaw is +-180

Latitude is the floating point in degrees dd.ddddLongitude is again the floating point number in degrees ddd.ddddd

I will be maintaining eye contract with the thing itself, but i want to be able to see its Attitude and everything i mentioned above on my PC, (sort of like a cockpit). Later on, maybe for my undergrad project i was thinking of making it a completed UAV...

Quote

Relying on off-board computing to keep the helicopter flying is a guaranteed way of crashing it.

No, everything is computed on the arduino ( on board) no calculations are done on the PC.

But now the only thing slowing me down is the Serial. Everything else works great. Without the Serial it would fly like a charm, but i want Serial Communication (obviously wireless ) for my project.

deSilva: I calculate the angles on the Arduino with no noise i then pass them along to the PC, i am not sending the ADC values. Same with the GPS, i get the GPS NMEA line and covert the Lat and Long to degrees. Then i send it. I am avoiding floating math until the last steps so it all executes quite fast ( under 1.5ms).

By deltas do you mean just sending the data that changes? I've tried that, but i am using a timer interrupt to trigger my sampling, so when i am sending more data, the loop that is supposed to execute in less then say 5ms, (200Hz) would take longer and the interrupt interrupts and all the date goes down the drain.

I try again:(1) There is no need for interrupts in your application. In fact I have NEVER seen an issues here brought to the forum, where interrupt was needed, and - if used - had not made the situation even worse.. (2) You might have a THROUGHPUT problem. The bottleneck I see is attitude and control =2ms. Is this "control" really needed at high frequency?(3) Serial communication for HardwareSerial should not need processor time.. You could avoid the waiting involved in multicharacter sending by sending on a character by character basis with activities in between. This needs some coding of course...(4) There is also some hidden waiting in the analogRead() routine, which can be re-claimed by direct accessing the ADC..(5) By detats I mean: Just the differences! So you have 6 values (A,B,C,D,E,F) the old values already sent were (a,b,c,d,e,f)Now you send this:if (a-A !=0) "A" (a-A)if (b-B !=0) "B" (b-B)if (c-C !=0) "C" (c-C)if (d-D !=0) "D" (d-D)if (e-E !=0) "E" (e-E)if (f-F !=0) "F" (f-F)

As deSilva has pointed out, you're spending all that time blocking waiting on sending the data.

The way serial writes work is that the library routines take, say, a string and write it one character at a time, waiting for the serial transmit register to become empty before writing another character. In this time, the processor does nothing except read and test a UART status registerAs soon as the last character is written to the transmit register, the write routine routine returns.At 115200 bps, each character takes about 87us to transmit, and you're sending (I estimate) about 46 characters.So, don't send strings, send one character at a time, and use the 86 or so microseconds you gain not waiting for the tx register to become empty to do something more productive.

(PS pretty much the same story for the "analogRead"s)

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.Do not send technical questions via personal messaging - they will be ignored.

Posted by: deSilva Posted on: Today at 21:49:45I try again:(1) There is no need for interrupts in your application. In fact I have NEVER seen an issues here brought to the forum, where interrupt was needed, and - if used - had not made the situation even worse.. (2) You might have a THROUGHPUT problem. The bottleneck I see is attitude and control =2ms. Is this "control" really needed at high frequency?(3) Serial communication for HardwareSerial should not need processor time.. You could avoid the waiting involved in multicharacter sending by sending on a character by character basis with activities in between. This needs some coding of course...(4) There is also some hidden waiting in the analogRead() routine, which can be re-claimed by direct accessing the ADC..(5) By detats I mean: Just the differences! So you have 6 values (A,B,C,D,E,F) the old values already sent were (a,b,c,d,e,f)Now you send this:if (a-A !=0) "A" (a-A)if (b-B !=0) "B" (b-B)if (c-C !=0) "C" (c-C)if (d-D !=0) "D" (d-D)if (e-E !=0) "E" (e-E)if (f-F !=0) "F" (f-F)

Thank you. I will try it. I feel stupid for not thinking of doing it like that . I will see if the interrupt is really needed

I've actually not timed the control algorithm, just put a extremely worst case scenario, might never occur. A more accurate estimate would be around 500-700 us.

I will give your method a shot, as it doesn't require changing much of the PC program.

Again thank you .

Quote

As deSilva has pointed out, you're spending all that time blocking waiting on sending the data.

The way serial writes work is that the library routines take, say, a string and write it one character at a time, waiting for the serial transmit register to become empty before writing another character. In this time, the processor does nothing except read and test a UART status registerAs soon as the last character is written to the transmit register, the write routine routine returns.At 115200 bps, each character takes about 87us to transmit, and you're sending (I estimate) about 46 characters.So, don't send strings, send one character at a time, and use the 86 or so microseconds you gain not waiting for the tx register to become empty to do something more productive.

(PS pretty much the same story for the "analogRead"s)

Can you explain that a bit more? if i have variable int i=180 and doSerial.print(i); Serial.print(",");

i am sending 4 characters in total ?I lack a lot of knowledge about Serial Communication...

Thank you.

Problem solved: So i tried something different before i read DeSilva's reply and it worked, no need to change the PC program as well. here is what i did.