Hello guys,
I am making a tricopter drone using Arduino Uno and a ESP8266 for communication.
The ESP receives the commands via WiFi and sends them to the Arduino via the hardware Serial. The Arduino proceses the received data and uses it for the PID controllers. However after a random amount of time (sometimes an hour, sometimes only 6 minutes) the Arduino stops responding. I suppose it is a UART problem because if I start the Arduino with the ESP disconnected the Arduino does not freeze.
This is the function I use to receive data:
#define MAX_DELAY 140000
#define DEBUG_COMM 0
int comm_count, thro=1000, yaw=1500, pitch=1500, roll=1500, thro_tmp, yaw_tmp, pitch_tmp, roll_tmp;
int comm_status = 0; // 0 - disconnected, 1 - connected, 2 - lost connection
int comm_errors = 0;
long time_delay = 0, time_load=0;
bool rdy=false;
void setup() {
Serial.begin(115200);
pinMode(13,OUTPUT);
pinMode(4,OUTPUT);
}
void loop() {
getCommands();
}
void getCommands() {
while (Serial.available()) {
if (Serial.peek() == '
The format of the commands is $|throttle|yaw|roll|pitch|, '#' is used as an "Arm" command and '!' as a "Disarm" command.
Please tell me if you see something that is not a good practice or something that does not look correct to you.
This function is called in the loop. It still freezes even if this is the only function in the code, so I think that this is what causes he problem.) {
Serial.read();
rdy=true;
time_delay=micros();
if(thro_tmp==0 || yaw_tmp==0 || pitch_tmp==0 || roll_tmp==0){
thro=1000;
yaw=1500;
pitch=1500;
roll=1500;
}
else{
thro=thro_tmp+1;
yaw = constrain(0.7yaw+0.3(yaw_tmp+1),1000,2000);
pitch = constrain(0.7pitch+0.3(pitch_tmp+1),1000,2000);
roll = constrain(0.7roll+0.3(roll_tmp+1),1000,2000);
if(yaw>=1492 && yaw<=1508){
yaw=1500;
}
if(pitch>=1492 && pitch<=1508){
pitch=1500;
}
if(roll>=1492 && roll<=1508){
roll=1500;
}
if(DEBUG_COMM){
Serial.print(thro);
Serial.print("\t");
Serial.print(yaw);
Serial.print("\t");
Serial.print(pitch);
Serial.print("\t");
Serial.println(roll);
}
}
thro_tmp=0;
yaw_tmp=0;
pitch_tmp=0;
roll_tmp=0;
comm_count = 0;
comm_errors = 0;
}
else if (Serial.peek() == '#') {
Serial.read();
comm_status = 1;
comm_errors=0;
time_delay=micros();
}
else if (Serial.peek() == '!') {
Serial.read();
comm_status = 0;
comm_errors=0;
}
else if(Serial.peek()>='0' && Serial.peek()<='9') {
while(Serial.peek()>='0' && Serial.peek()<='9'){
if (comm_count < 4) {
thro_tmp+=(Serial.read()-'0')*pow(10,(3-comm_count));
comm_count++;
}
else if(comm_count>=4 && comm_count<8){
yaw_tmp+=(Serial.read()-'0')*pow(10,(3-(comm_count-4)));
comm_count++;
}
else if(comm_count>=8 && comm_count<12){
roll_tmp+=(Serial.read()-'0')*pow(10,(3-(comm_count-8)));
comm_count++;
}
else if(comm_count>=12 && comm_count<16){
pitch_tmp+=(Serial.read()-'0')*pow(10,(3-(comm_count-12)));
comm_count++;
}
}
}
else{
while(Serial.available()){
Serial.read();
delayMicroseconds(500);
}
if(!rdy)time_load=millis();
}
}
if(!Serial.available()) {
if(comm_status==1 && micros()-time_delay>MAX_DELAY){
comm_status = 2;
Serial.end();
}
}
}
The format of the commands is $|throttle|yaw|roll|pitch|, '#' is used as an "Arm" command and '!' as a "Disarm" command.
Please tell me if you see something that is not a good practice or something that does not look correct to you.
This function is called in the loop. It still freezes even if this is the only function in the code, so I think that this is what causes he problem.