roll dame pienn
Dependencies: mbed SDFileSystem BME280 MPU9250_2020NSE
main.cpp
- Committer:
- momoa
- Date:
- 2020-11-20
- Revision:
- 6:b450b73ff8fe
- Parent:
- 5:34760148ef4a
File content as of revision 6:b450b73ff8fe:
/* MPU9250から9軸データを取得してCAN送信・シリアル送信. ノルムは5回移動平均から算出. 生データも送る. 姿勢角を出す. <MPU9250ピン設定> CS~ : HIGH ADO : LOW SDA/SCL 10kΩでpullup BMP280から気圧・温度を取得してCAN送信・シリアル送信. 気圧->5回移動平均. <BMP280ピン設定> CSB : HIGH SDO : LOW */ #include "SDFileSystem.h" SDFileSystem sd(PA_7, PA_6, PA_5, PA_4, "sd"); // the pinout on the mbed Cool Components workshop board #include "mbed.h" #include "BME280.h" #include "MPU9250.h" Serial pc(PA_9,PA_10); //pin19,20 TX,RX BME280 bmp = BME280(PB_7, PB_6); // pin30,29 SDA,SCL MPU9250 mpu = MPU9250(PB_7, PB_6); // pin30,29 SDA,SCL CAN can(PA_11, PA_12,100000); //pin21,22 rd,td #define PI 3.14159265358979323846f #define N 5 // 5回移動平均 #define sampleFreq 100.0f #define beta 0.33f // gain(大きいと加速度による補正が早い) Timer timea; DigitalOut myled(PF_0); union Float2Byte{ float _float; char _byte[4]; }; typedef union Float2Byte Float2Byte; union Int2Byte{ unsigned short _int; char _byte[2]; }; typedef union Int2Byte Int2Byte; float pressure_ave = 0.0f; // 気圧[hPa] float pressure_new = 0.0f; float buff_p[N]; float sum = 0.0f; int cnt = 0; float tem = 0.0f; // 温度[C] float psi=0.0f, cta=0.0f, eta=0.0f; float psi_f=0.0f, cta_f=0.0f, eta_f=0.0f; float cal_x=0.0f,cal_y=0.0f,cal_z=0.0f; float world_time; int fpin = 0; //フライトピン判定 FILE *fp; CANMessage msg; void mpu_init(){ uint8_t whoami_MPU9250, whoami_AK8963; float mag_init[3]; whoami_MPU9250 = mpu.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250); whoami_AK8963 = mpu.readByte(AK8963_ADDRESS, WHO_AM_I_AK8963); pc.printf("MPU9250 IS 0x%x\n\r", whoami_MPU9250); // 0x71で正常 pc.printf("AK8963 IS 0x%x\n\r", whoami_AK8963); // 0x48で正常 if (whoami_MPU9250 == 0x71 || whoami_AK8963 == 0x48){ pc.printf("MPU9250 is detected.\n\r"); wait(0.1); mpu.resetMPU9250(); mpu.initMPU9250(); wait(0.1); mpu.initAK8963(mag_init); mpu.getGres(); mpu.getAres(); mpu.getMres(); wait(0.1); } else{ pc.printf("Could not detect MPU9250.\n\r"); pc.printf("whoami_MPU9250 = 0x%x\n\rwhoami_AK8963 = 0x%x\r\n", whoami_MPU9250, whoami_AK8963); while(1); } } void send2(unsigned short senddata1,unsigned short senddata2,unsigned short senddata3,int id){ //pc.printf("Master send()\n\r"); /*ID: 0x01*/ Int2Byte sendInt; sendInt._int = senddata1; //ここに送りたい値を入れる. char serialData[6]; serialData[0] = sendInt._byte[0]; serialData[1] = sendInt._byte[1]; //pc.printf("send_char: %d\n\r", serialData[i]); sendInt._int = senddata2; serialData[2] = sendInt._byte[0]; serialData[3] = sendInt._byte[1]; sendInt._int = senddata3; serialData[4] = sendInt._byte[0]; serialData[5] = sendInt._byte[1]; //pc.printf("sendFloat: %f\n\r", sendFloat._float); if(can.write(CANMessage(id, serialData, 6))){ //pc.printf("Send.\n\r"); } } void receive(){ Float2Byte getFloat; Int2Byte getInt; myled = 0; if(can.read(msg)){ //ID: 0x01 if(msg.id == 0x01){ //pc.printf("ID: 0x01\n\r"); for(int i=0;i<4;++i){ getFloat._byte[i] = msg.data[i]; //pc.printf("get_char: %d\n\r", getFloat._byte[i]); } world_time = getFloat._float; //pc.printf("world_time:%.2f\r\n", world_time); } if(msg.id == 0x02){ //pc.printf("ID: 0x02\n\r"); getInt._byte[0] = msg.data[0]; getInt._byte[1] = msg.data[1]; cal_x=(float)getInt._int /10.0f; //pc.printf("Mag:%.2f", cal_x); getInt._byte[0] = msg.data[2]; getInt._byte[1] = msg.data[3]; cal_y=(float)getInt._int /10.0f; //pc.printf(",%.2f", cal_y); getInt._byte[0] = msg.data[4]; getInt._byte[1] = msg.data[5]; cal_z=(float)getInt._int /10.0f; //pc.printf(",%.2f\r\n", cal_z); fpin++; } } } int main(){ myled = 1; can.attach(receive, CAN::RxIrq); fp = fopen("/sd/log.txt","a"); if(fp != NULL){ fprintf(fp,"Start.\n\r"); fprintf(fp,"time, ax_new, ay_new, az_new, gx_new, gy_new, gz_new, psi, cta, eta, pre, tem\n\r"); fclose(fp); } else{ pc.printf("Failed.\n\r"); } int16_t acc[3], gyr[3], mag[3]; int cntsd = 0; float ax_new = 0.0f, ay_new = 0.0f, az_new = 0.0f; float gx_new = 0.0f, gy_new = 0.0f, gz_new = 0.0f; float psi_ax = 0.0f, cta_ay = 0.0f, eta_az = 0.0f; float psi_gx = 0.0f, cta_gy = 0.0f, eta_gz = 0.0f; float psi_drift = -5.2473f, cta_drift = 5.8882f, eta_drift = -1.8256f; bool dt_b = 0; float time[3]; float dt = 0.0f; float gRes = 1000.0/32768.0; int cnt = 0; wait(0.1); mpu_init(); bmp.initialize(); wait(2.0); // 静止させるまで待つ // 初期値 for(int i=0;i<N;i++){ mpu.readGyroData(gyr); mpu.readAccelData(acc); mpu.readMagData(mag); buff_p[i] = bmp.getPressure(); sum += buff_p[i]; } wait(0.1); timea.start(); pc.printf("Start.\n\r"); int i = 0; time[0] = 0.0f; while(1){ myled =! myled ; mpu.readGyroData(gyr); mpu.readAccelData(acc); mpu.readMagData(mag); ax_new = acc[0] / 2049.81; ay_new = acc[1] / 2049.81; az_new = acc[2] / 2049.81; gx_new = gyr[0] * gRes; //[deg/s] gy_new = gyr[1] * gRes; gz_new = gyr[2] * gRes; cnt++; if(cnt == N) cnt = 0; /*姿勢計算*/ dt_b =! dt_b; time[dt_b]=timea.read(); if(fpin == 1){//フライトピンが抜けた瞬間,姿勢0 psi = 0.0f; cta = 0.0f; eta = 0.0f; time[2]=timea.read(); }else{ dt = (time[0]-time[1]); if(dt > 0) dt = dt; else dt = -dt; psi_ax = atan2f(ay_new , az_new) * 180/PI; //[deg] cta_ay = atan2f(ax_new , sqrt(ay_new*ay_new + az_new*az_new)) * 180/PI; psi_gx = psi + gx_new * dt - (time[dt_b] - time[2]) * psi_drift;//[deg] cta_gy = cta + gy_new * dt - (time[dt_b] - time[2]) * cta_drift; eta_gz = eta + gz_new * dt - (time[dt_b] - time[2]) * eta_drift; psi_f = (0.8f * psi + 0.2f * psi_ax ) ; //[deg] cta_f = (0.8f * cta + 0.2f * cta_ay ) ; eta_f = (0.8f * eta + 0.2f * eta_gz ) ; psi = (float)((int)(psi_f*1000000.0f) % 360000000) / 1000000.0f; //0~360[deg] cta = (float)((int)(cta_f*1000000.0f) % 360000000) / 1000000.0f; eta = (float)((int)(eta_f*1000000.0f) % 360000000) / 1000000.0f; } if(i == 5){ send2((unsigned short)(psi*10.0f),(unsigned short)(cta*10.0f),(unsigned short)(eta*10.0f),4); i = 0; pc.printf("cansend"); } pc.printf("angle:%f,%f,%f\n\r",psi,cta,eta); i++; /*気圧・気温計算*/ sum = sum - buff_p[cnt]; pressure_new = bmp.getPressure(); buff_p[cnt] = pressure_new; sum = sum + pressure_new; cnt++; if(cnt == N) cnt = 0; pressure_ave = sum/N; tem = bmp.getTemperature(); /*SD保存*/ if (cntsd == 0){ fp = fopen("/sd/log.txt","a"); } if(fp != NULL){ fprintf(fp,"%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n\r",timea.read(),ax_new, ay_new, az_new, gx_new, gy_new, gz_new, psi, cta, eta, pressure_ave, tem); cntsd++; if(cntsd == 10){ fclose(fp); pc.printf("SDSave.\n\r"); cntsd = 0; } }else{ pc.printf("SDFailed.\n\r"); } } }