Hello,
I'm working on a program which will publish 1 float data (3 floating points) for every each 10 ms (approximately) to the Serial Monitor. Everything is working well, but after 3 minutes, the Serial Monitor stops publishing the data. Moreover, I notice that about 10 last data published on the Serial Monitor are not correct (For example, my correct value is 1.212, and it publishes 0.053). I tried Serial.flush() but it doesn't get much better. When I change to lower baudrate, Arduino can send data for a longer period but still stops after a while.
Here is my Arduino code (it is quite long but just ignore how I process my data value):
#include <Math.h>
uint8_t temp;
uint8_t i, j = 0;
unsigned long previous = 0;
int mod_11k = 12;
int mod_17k = 13;
int16_t data_toSend[6]={0,0,0,0,0,0};
float s1_11k;
float s2_11k;
float s1_17k;
float s2_17k;
float P1[4];float P2[4];float P3[4]; float P4[4];float P5[4];float P6[4];
float xprec1[2];float xprec2[2];float xprec3[2];float xprec4[2];float xprec5[2];float xprec6[2];
float *sol1;float *sol2;float *sol3; float *sol4;float *sol5;float *sol6;
float *sf_11k;
float *sf_17k;
float Te;
float Tbeg;
float temp_var1;
float temp_var2;
float temp_var;
float height;
void setup() {
pinMode(mod_11k,OUTPUT);
pinMode(mod_17k,OUTPUT);
digitalWrite(mod_11k,LOW);
digitalWrite(mod_17k,LOW);
Serial.begin(9600);
//---------------------------------------------------Initialize Kalman Filter---------------------------------//
float qkf = 0.0005;
P1[0] = qkf; P1[1] =0; P1[2] =0; P1[3] = qkf;
P2[0] = qkf; P2[1] =0; P2[2] =0; P2[3] = qkf;
P3[0] = qkf; P3[1] =0; P3[2] =0; P3[3] = qkf;
P4[0] = qkf; P4[1] =0; P4[2] =0; P4[3] = qkf;
P5[0] = qkf; P5[1] =0; P5[2] =0; P5[3] = qkf;
P6[0] = qkf; P6[1] =0; P6[2] =0; P6[3] = qkf;
xprec1[0] =0; xprec1[1] =0;
xprec2[0] =0; xprec2[1] =0;
xprec3[0] =0; xprec3[1] =0;
xprec4[0] =0; xprec4[1] =0;
xprec5[0] =0; xprec5[1] =0;
xprec6[0] =0; xprec6[1] =0;
Tbeg = millis();
//Get raw ANALOG DATA
digitalWrite(mod_11k,HIGH);
delayMicroseconds(4000);
data_toSend[0] = analogRead(0);
data_toSend[1] = analogRead(1);
data_toSend[2] = analogRead(2);
digitalWrite(mod_11k,LOW);
delayMicroseconds(200);
digitalWrite(mod_17k,HIGH);
delayMicroseconds(4000);
data_toSend[3] = analogRead(0);
data_toSend[4] = analogRead(1);
data_toSend[5] = analogRead(2);
digitalWrite(mod_17k,LOW);
delayMicroseconds(200);
//Save raw ANALOG data
xprec1[0] = data_toSend[0];
xprec2[0] = data_toSend[1];
xprec3[0] = data_toSend[2];
xprec4[0] = data_toSend[3];
xprec5[0] = data_toSend[4];
xprec6[0] = data_toSend[5];
//Filter with Kalman
Te = (millis() - Tbeg)/1000;
sol1 = Fkalman(xprec1,data_toSend[0],P1,Te);
sol2 = Fkalman(xprec2,data_toSend[1],P2,Te);
sol3 = Fkalman(xprec3,data_toSend[2],P3,Te);
sol4 = Fkalman(xprec4,data_toSend[3],P4,Te);
sol5 = Fkalman(xprec5,data_toSend[4],P5,Te);
sol6 = Fkalman(xprec6,data_toSend[5],P6,Te);
Tbeg= millis();
}
void loop()
{
tick();
}
void tick() {
P1[0] =sol1[2]; P1[1] =sol1[3]; P1[2] =sol1[4]; P1[3] =sol1[5];
P2[0] =sol2[2]; P2[1] =sol2[3]; P2[2] =sol2[4]; P2[3] =sol2[5];
P3[0] =sol3[2]; P3[1] =sol3[3]; P3[2] =sol3[4]; P3[3] =sol3[5];
P4[0] =sol4[2]; P4[1] =sol4[3]; P4[2] =sol4[4]; P4[3] =sol4[5];
P5[0] =sol5[2]; P5[1] =sol5[3]; P5[2] =sol5[4]; P5[3] =sol5[5];
P6[0] =sol6[2]; P6[1] =sol6[3]; P6[2] =sol6[4]; P6[3] =sol6[5];
xprec1[0] =sol1[0]; xprec1[1] =sol1[1];
xprec2[0] =sol2[0]; xprec2[1] =sol2[1];
xprec3[0] =sol3[0]; xprec3[1] =sol3[1];
xprec4[0] =sol4[0]; xprec4[1] =sol4[1];
xprec5[0] =sol5[0]; xprec5[1] =sol5[1];
xprec6[0] =sol6[0]; xprec6[1] =sol6[1];
free(sol1); // Free the stocking space of KalmanFilter function variable
free(sol2);
free(sol3);
free(sol4); // Free the stocking space of KalmanFilter function variable
free(sol5);
free(sol6);
//Get raw ANALOG data
digitalWrite(mod_11k,HIGH);
delayMicroseconds(4000);
data_toSend[0] = analogRead(0); //phi1 11k
data_toSend[1] = analogRead(1); //phi2 11k
data_toSend[2] = analogRead(2);
digitalWrite(mod_11k,LOW);
delayMicroseconds(200);
digitalWrite(mod_17k,HIGH);
delayMicroseconds(4000);
data_toSend[3] = analogRead(0);
data_toSend[4] = analogRead(1);
data_toSend[5] = analogRead(2);
digitalWrite(mod_17k,LOW);
delayMicroseconds(200);
Te = (millis() - Tbeg)/1000;
//Kalman Filter
sol1 = Fkalman(xprec1,data_toSend[0],P1,Te); // Filtrage des mesures led1
sol2 = Fkalman(xprec2,data_toSend[1],P2,Te);
sol3 = Fkalman(xprec3,data_toSend[2],P3,Te);
sol4 = Fkalman(xprec4,data_toSend[3],P4,Te); // Filtrage des mesures led2
sol5 = Fkalman(xprec5,data_toSend[4],P5,Te);
sol6 = Fkalman(xprec6,data_toSend[5],P6,Te);
Tbeg= millis();
data_toSend[0] = sol1[0];
data_toSend[1] = sol2[0];
data_toSend[2] = sol3[0];
data_toSend[3] = sol4[0];
data_toSend[4] = sol5[0];
data_toSend[5] = sol6[0];
//Processing filtered analog data
sf_11k = traitement1(data_toSend[0],data_toSend[1],data_toSend[2]);
sf_17k = traitement1(data_toSend[3],data_toSend[4],data_toSend[5]);
s1_11k = sf_11k[0];
s2_11k = sf_11k[1];
s1_17k = sf_17k[0];
s2_17k = sf_17k[1];
temp_var1 = -24.946*((tan(s1_11k)-tan(s1_17k))*(tan(s1_11k)-tan(s1_17k)))+7.9023*(tan(s1_11k)-tan(s1_17k))-0.3583;
temp_var2 = -8.0096*((tan(s2_11k)-tan(s2_17k))*(tan(s2_11k)-tan(s2_17k)))+0.4445*(tan(s2_11k)-tan(s2_17k))-0.1195;
temp_var = sqrt(temp_var1*temp_var1+temp_var2*temp_var2);
height = 0.2/temp_var;
//Send height value to Serial
Serial.print(height,3);
Serial.print('\n');
}
float *Fkalman(float xprec[2],float ymes,float P[4],float Te){
float *sol = NULL ;
sol = (float*) malloc (sizeof(float) * 6);
float xpred[2];
float Ppred[4] ;
float Kf[2] ;
float q = 0.0005;
float r = 30;
//x prediction
xpred[0] = xprec[0] + Te*xprec[1];
xpred[1] = xprec[1];
//P_pred = F.P.F'+Q
Ppred[0] = q + P[0]+ Te*(P[2] +P[1]+Te*P[3]);
Ppred[1] = P[1] + Te*P[3];
Ppred[2] = P[2] + Te*P[3] ;
Ppred[3] = q+ P[3];
//Kf = (P_pred.C').inv(C.P_pred.C'+R)
Kf[0] = (Ppred[0]/(r+Ppred[0]));
Kf[1] = (Ppred[2]/(r+Ppred[0]));
//X_est
sol[0] = xpred[0] + Kf[0]*(ymes-xpred[0]);
sol[1] = xprec[1] + Kf[1]*(ymes-xprec[0]);
//P_est = (I-Kf*C)*P_pred
sol[2] = Ppred[0]*(1-Kf[0]);
sol[3] = Ppred[1]*(1-Kf[0]);
sol[4] = -Kf[1]*Ppred[0]+Ppred[2];
sol[5] = -Kf[1]*Ppred[1]+Ppred[3];
return sol;
}
float *traitement1(float mes1,float mes2,float mes3)
{
float *sol11 = NULL ;
sol11 = (float*) malloc (sizeof(float) * 2);
sol11[0] = (mes1-mes2)/(mes1+mes2);
sol11[1] = (((mes1+mes2)/2)-mes3)/(((mes1+mes2)/2)+mes3);
return sol11;
}
Does anyone have some idea about this problem? I guess the memory or buffer are filling due to some variables?
Thank you