VertexのFMに使ったプログラムです.

Dependencies:   MPU6050 MS5607 SDFileSystem mbed

Files at this revision

API Documentation at this revision

Comitter:
naoki_westwell
Date:
Sun Nov 20 05:06:08 2016 +0000
Commit message:
Vertex FM

Changed in this revision

MPU6050.lib Show annotated file Show diff for this revision Revisions of this file
MS5607.lib Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 8483298c086d MPU6050.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MPU6050.lib	Sun Nov 20 05:06:08 2016 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/naoki_westwell/code/MPU6050/#52305bcb5cda
diff -r 000000000000 -r 8483298c086d MS5607.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MS5607.lib	Sun Nov 20 05:06:08 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/yamaguch/code/MS5607/#5760862143d1
diff -r 000000000000 -r 8483298c086d SDFileSystem.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.lib	Sun Nov 20 05:06:08 2016 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/mbed_official/code/SDFileSystem/#7b35d1709458
diff -r 000000000000 -r 8483298c086d main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Nov 20 05:06:08 2016 +0000
@@ -0,0 +1,430 @@
+#include "mbed.h"
+#include "MPU6050.h"
+#include "MS5607I2C.h"
+#include "SDFileSystem.h"
+#define MAX_RDATA       256         //最大受信コマンド
+#define MAX_TOTAL_DATA  256         //最大データフレーム
+#define DATA_BUNDLE     10          //SDへ1度に保存するデータフレーム
+#define DEPLOY_TIME_1   18000        //発射からの1回目のサーボ駆動(ミリ秒)  18秒
+#define DEPLOY_TIME_2   65500        //2回目のサーボ駆動(ミリ秒)           83.5-18秒    
+#define DEPLOY_ALT2     300         //パラ2開放高度(m)
+#define DUTY_BASE       0.0975        //デューティー比   ベース     136*0.001/2 + 0.03
+#define DUTY_1          0.084        //              開放1     108*0.001/2 + 0.03
+#define DUTY_2          0.069        //              開放2     78*0.001/2 + 0.03
+
+Serial sci(p9, p10);                   //通信線
+//Serial sci(USBTX, USBRX);                   
+BusOut myleds(LED1, LED2, LED3, LED4);  //LED
+//Serial pc(USBTX, USBRX);              //USB
+SDFileSystem sd(p5, p6, p7, p8, "sd");  //MicroSDCard
+Serial uar(p13,p14);                    //GPS
+I2C i2c(p28, p27);                      //音声合成
+const int tlk_addr = 0x2E<<1;           //音声合成LSIのアドレス
+MPU6050 mpu;                            //MPU6050(加速度ジャイロ)
+MS5607I2C ms5607(p28, p27, false);      //MS5607(気圧)
+Ticker ticker;                          //タイマー割り込み
+extern "C" void mbed_reset();           //リセット関数の宣言 
+Timer timer;                            //タイマ
+FILE *fp;                               //SDカード
+PwmOut servo(p21);                      //サーボモータ
+DigitalOut f_pin(p20);                   //フライトピン
+Timer xtimer;                           //打上時間通達用のタイマー
+Timer t;                                //デバッグ用
+
+unsigned int pre_cnt=0;                 //スタンバイモードのカウント
+unsigned int cnt=0;                     //カウント(ループ回数)
+int32_t press, temp;                    //気圧, 気温
+float altitude;                         //高度
+int16_t ax, ay, az;                     //3軸加速度
+int16_t acc;                            //合成加速度
+int16_t gx, gy, gz;                     //3軸ジャイロ
+unsigned int ms_time;                   //タイマー時間
+//unsigned int voice_state;             //喋っている状況
+unsigned int mode=0;                    //モード 0:スタンバイモード 1:フライトモード 2:発射 3or4:開放 5:着地
+
+//RTC
+struct tm rtc;
+time_t seconds;
+int time_h=0,time_m=0,time_s=0;
+int xtime_h=0,xtime_m=0,xtime_s=0;
+char time_buf[32];
+
+//gps
+int gps_i, rlock, stn;
+char gps_data[256];
+char ns,ew;
+float gps_time,hokui,tokei;
+unsigned int g_hokui, g_tokei;
+unsigned int htime, mtime, stime;
+
+const float R = 287.052; // specific gas constant R*/M0
+const float g = 9.80665; // standard gravity 
+const float t_grad = 0.0065; // gradient of temperature
+const float t0 = 273.15 + 15; // temperature at 0 altitude
+const float p0 = 101325; // pressure at 0 altitude
+
+unsigned int servo_duty;                //サーボデューティー比
+unsigned int launch_time;               //発射した時間
+unsigned int deploy_time_1;             //開放1した時間
+unsigned int deploy_time_2;             //開放2した時間
+float gnd_alt, gnd_temp;                //地上の高度
+float vertex=0.0;                       //最高高度
+int pre_acc, acc_sw;                    //前の合成加速度
+int dep_sw;                             //開放タイミング
+int silent=0;                           //サイレントモード
+int servo_sw=0;                         //サーボ保持やめるタイミング
+int servo_sw2=0;                        //開放2後一定間隔でサーボを動かすタイミング
+
+char total_data[256];                   //データフレーム
+char data_buffer[DATA_BUNDLE][256];     //データバッファ(SDへ一度に保存する)
+char Rdata[MAX_RDATA];                  //受信データfrom通信線
+
+char spk_line[][256] = {
+    "suta-toa,pu.\r",
+    "konnnichiwa.watashiwa,ti'-mu,;ba-te,ku'suno,ro/ke',toni,tousaisareteiru,jinnkouti'nou,ri',tu/de_su.;yorosiku.\r",
+    "ze'nnkaino,ri/se',to/kara <NUMK VAL=8 COUNTER=funn> <NUMK VAL=10 COUNTER=byo-> keikasimasi'ta.\r",
+    ";uchiageyotei,ji'kokumade,a'to <NUMK VAL=8 COUNTER=funn> <NUMK VAL=59 COUNTER=byo-> de_su.\r",
+    "rise,to.\r",
+    "esudhi-ka-/do,rise,to.\r",
+    "tijoukou'do/wo,sokuteityuude_su,sibara+ku,omachikudasa'i.\r",
+    "tijoukou'dono,so/kuteiga,kanryousimasi'ta.\r",
+    ";huraitomo-'do,;o'nn.\r",
+    ";de'-tano/kirokuto,keisokuga,kaisisarema'sita.\r",
+    ";rihuto,;o'hu rokextuxtu'toga,uchiagerarema'sita.\r",
+    "parashu-'to,ichi,hou+shutu.\r",
+    "parashu-'to,ni',hou+shutu.\r",
+    "sa-bomo-'ta-,kudo-.\r",
+    "rokextuxtu'towa,rakkatyuude_su.\r",
+    "rokextuxtu'tono,tyakutiwo,kakuninnsima'sita.\r",
+    ";uchiageyotei,ji'koku/wo,setteisima'sita.\r",
+    ";genzaiji'koku/wo,setteisima'sita.\r",
+    "huraito'pin,go'-.\r",
+    "huraito'pin,no-go'-.setuzokuwo/kakuninnsitekudasa'i.\r",
+    "sairento/mo'-do,o'hu.\r",
+    "ge'nzai,kaihousagyoutyuude'_su.\r",
+    "sintyokudo'ude_suka?\r",
+    "#J",
+    "#K",
+    };
+
+//プロトタイプ宣言
+void tick();                            //データ取得割り込み
+void sci_rx();                          //通信線コマンド割り込み
+void gps_rx();                          //GPS通信線コマンド割り込み
+void deployment();                      //開放アルゴリズム
+void talk_line(int num);                //指定したセリフを喋る
+void random_talk();                     //ランダムで喋る
+
+////////////
+//メイン関数//
+////////////
+int main() {
+    talk_line(0);
+    //Real Time Clock
+    rtc.tm_sec = 00;                        // 0-59
+    rtc.tm_min = 00;                        // 0-59
+    rtc.tm_hour = 00;                       // 0-23
+    rtc.tm_year = 115;                      // year since 1900
+    seconds = mktime(&rtc);                 //時刻生成
+    set_time(seconds);                      //時刻設定
+
+    servo.period_ms(20);                    //サーボ波長
+    servo = DUTY_BASE;                      //サーボをベース状態
+    wait(1); servo.pulsewidth_us(0);        //保持やめる
+    mpu.initialize();                       //MPU6050(加速度ジャイロ)初期
+    sci.attach(sci_rx, Serial::RxIrq);      //シリアル受信割り込み
+    uar.baud(4800);                         //GPS
+    uar.attach(gps_rx, Serial::RxIrq);      //GPS割り込み
+    timer.start();                          //タイマ開始
+    timer.reset();                          //タイマ初期化
+    xtimer.start();                          //タイマ開始
+    xtimer.reset();                          //タイマ初期化
+    for(int i=0;i<4;i++){myleds=myleds|1<<i;wait(0.4);} myleds=0x06;
+    sci.baud(9600);
+    sci.printf("\n\n******************************\n");
+    sci.printf("**********START UP!!**********\n");
+    sci.printf("******************************\n");
+    talk_line(1);
+    
+    while(1){
+        //RTC
+        seconds = time(NULL);
+        strftime(time_buf,sizeof(time_buf),"%H,%M,%S",localtime(&seconds));
+        sscanf(time_buf,"%d,%d,%d",&time_h,&time_m,&time_s);
+        if(mode==0){
+            pre_cnt++;
+            random_talk();
+            myleds=myleds^0xff; wait(0.1);
+        }
+        else
+        if(mode){
+            
+            //SDへの記録
+            
+            if(cnt%DATA_BUNDLE==DATA_BUNDLE-1){
+                fp = fopen("/sd/data.csv", "a");
+                if(fp==NULL){
+                    sci.printf("<!>Error<!> ---> Could not open file\r\n");
+                }else{
+                    for(int i=0; i<DATA_BUNDLE; i++){       //DATA_BUDLE分のフレームを一度に保存
+                        fprintf(fp, "%s", data_buffer[i]);
+                        sprintf(data_buffer[i], "");
+                    }
+                    fclose(fp); 
+                }
+            }
+            }
+    }
+}
+//////////////////
+//データ取得割り込み//
+//////////////////
+void tick(){
+    t.start();
+    t.reset();
+    ms_time = timer.read_ms();                                      //タイマー(ミリ秒)
+    
+    press = ms5607.getPressure();                                       //気圧取得
+    temp = ms5607.getTemperature()*100;                                 //気温取得
+    altitude = t0/t_grad*(1-exp((t_grad*R/g)*log(press/p0)))-gnd_alt;   //高度取得
+    if(altitude<2000 && altitude>vertex) vertex=altitude;
+    if(vertex-altitude>2){dep_sw++;}else{dep_sw=0;}
+    deployment();
+    
+    mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);                   //加速度ジャイロ取
+
+    ax=float(ax); ay=float(ay); az=float(az);
+    gx=float(gx);   gy=float(gy);   gz=float(gz);
+    ax=float(ax)/2048*10000; ay=float(ay)/2048*10000; az=float(az)/2048*10000;
+    gx=float(gx)/65.5*100;   gy=float(gy)/65.5*100;   gz=float(gz)/65.5*100;
+    pre_acc = acc;
+    acc = int(sqrt(double(ax*ax+ay*ay+az*az)));                       //合成加速度
+    
+    //データフレームへ格納
+    sprintf(total_data,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%2d%2d%2d,%1d,%d,%2d%2d%2d,%d\r\n",
+        press,temp,ax,ay,az,gx,gy,gz,
+        g_hokui, g_tokei, htime, mtime, stime,
+        mode, ms_time, time_h, time_m, time_s, cnt
+        );
+    sprintf(data_buffer[cnt%DATA_BUNDLE],"%s",total_data);   //データバッファへ格納
+    //sci.printf("%s",total_data);                  //通信線へ
+    //pc.printf("%s",total_data);                   //PCへ
+    //LED Flip-flops
+    if(cnt%6<4) myleds = 1 << cnt%6;
+    else myleds = 4 >> (cnt%6-4);
+    cnt++;          //カウント
+    
+    //sci.printf("%f\r\n",t.read());
+}
+////////////////////
+//通信コマンド割り込み//
+////////////////////
+unsigned short sci_i=0;     //コマンドN文字目
+char cmd[3];                //コマンド命令
+char val[MAX_RDATA-3];      //コマンド引数
+void sci_rx () {
+    //受信データが大きすぎる場合
+    if(sci_i>MAX_RDATA-1){
+        sci_i = MAX_RDATA-1;
+        Rdata[sci_i]='\n';
+    }
+    Rdata[sci_i]=sci.getc();    //受信データの格納
+    if(Rdata[sci_i]=='\n'){     //受信データ区切り→コマンドごとの処理
+        Rdata[sci_i-1]='\0';
+        sci_i=0;
+        
+        sci.printf("\nReceved data: \"%s\" \r\n", Rdata);
+        sscanf(Rdata,"%3s %s", cmd, val);   //コマンドを命令と引数に分割
+        //リセット・コマンド
+        if(strcmp(cmd, "RST")==0){
+            sci.printf("---> Mbed reset \r\n"); talk_line(4);
+            wait(0.1); mbed_reset();
+        }else
+        //フライトモード・コマンド
+        if(strcmp(cmd, "FLT")==0){ 
+            sci.printf("---> Flight-Mode ON! \r\n"); talk_line(8);
+            mode=1;                                 //フライトモードオン!!
+            ticker.attach(&tick, 0.1);              //タイマー割り込み
+            timer.start();                          //タイマ開始
+            timer.reset();                          //タイマ初期化
+        }else
+        //SDリセット・コマンド
+        if(strcmp(cmd, "SDR")==0){
+            fp = fopen("/sd/data.csv", "w");
+            if(fp==NULL){ sci.printf("<!>Error<!> ---> Could not open file\r\n");}
+            else{ fprintf(fp, ""); fclose(fp); sci.printf("---> SDcard Reset \r\n"); talk_line(5);}
+            wait(0.1);
+        }else
+        //地上高度測定コマンド
+        if(strcmp(cmd, "ALT")==0){
+            sci.printf("---> Measureing state of rest\r\n"); talk_line(6);
+            for(int i=0;i<100;i++){
+                gnd_alt += t0/t_grad*(1-exp((t_grad*R/g)*log(ms5607.getPressure()/p0)));
+                if(i%10==9){ sci.printf("@"); myleds=myleds^0xff; }
+                wait(0.1);
+            }
+            gnd_alt/=100;
+            sci.printf("\n---> Measurement Complete\r\n"); talk_line(7);
+        }else
+        //現在時刻設定
+        if(strcmp(cmd, "SCT")==0){
+            sci.printf("---> Set Current Time\r\n"); talk_line(17);
+            rtc.tm_hour = int(atof(val)/10000);   // 0-23
+            rtc.tm_min = int((atof(val)-rtc.tm_hour*10000)/100);    // 0-59
+            rtc.tm_sec = int(atof(val)-rtc.tm_hour*10000-rtc.tm_min*100);    // 0-59
+            seconds = mktime(&rtc);
+            set_time(seconds);
+        }else    
+        //打上時刻設定設定
+        if(strcmp(cmd, "SXT")==0){
+            sci.printf("---> Set Launch Time\r\n"); talk_line(16);
+            xtime_h = int(atof(val)/10000);   // 0-23
+            xtime_m = int((atof(val)-xtime_h*10000)/100);    // 0-59
+            xtime_s = int(atof(val)-xtime_h*10000-xtime_m*100);    // 0-59
+        }else
+        //パルス設定プログラム
+        if(strcmp(cmd, "PWM")==0){
+            servo = atof(val)*0.001/2 + 0.03;
+            wait(1); servo.pulsewidth_us(0);
+            sci.printf("\n---> Set Pulse Width\r\n"); talk_line(13);
+        }else
+        //フライトピンチェック
+        if(strcmp(cmd, "FPC")==0){
+            if(f_pin){sci.printf("---> Flight Pin Go !\r\n");talk_line(18);}
+            else{sci.printf("<!><!><!> Flight Pin No Go <!><!><!>\r\n");talk_line(19);}
+        }else
+        //サイレントモード
+        if(strcmp(cmd, "SLT")==0){
+            if(silent==0){sci.printf("---> Silent Mode On !\r\n");silent=1;}
+            else{sci.printf("---> Silent Mode OFF \r\n");silent=0;talk_line(20);}
+        }else
+        //スピーク・コマンド
+        if(strcmp(cmd, "SPK")==0){
+            int line_num = atoi(val);
+            sci.printf("---> Now talking \"%s\" \r\n", spk_line[line_num]);
+            talk_line(line_num);
+        }else
+        //トーク・コマンド
+        if(strcmp(cmd, "TLK")==0){
+            if(strlen(val)+4 > MAX_RDATA-3){
+                sci.printf("<!>Error<!> ---> Exceeds size limit\r\n");
+            }else{
+                sci.printf("---> Now talking \"%s\" \r\n", val);
+                strcat(val, ".\r");
+                i2c.write(tlk_addr, val, strlen(val));
+            }
+        }else{
+        //エラー
+            sci.printf("<!>Error<!> ---> Unknown command \r\n");
+        }
+        strcpy(cmd, ""); strcpy(val, "");
+    }else{                      //受信データ区切りでないなら格納続ける
+        sci_i++;
+    }
+}
+
+//番号を指定してセリフを喋るよ
+void talk_line(int num){
+    if(silent==0) i2c.write(tlk_addr, spk_line[num], strlen(spk_line[num]));
+}
+
+void gps_rx () {//I2C Interrupt RX
+    if( (gps_data[gps_i]=uar.getc()) != '$'){
+        gps_i++;
+    }else{
+        gps_data[gps_i]='\0';
+        if ( sscanf(gps_data, "GPGGA,%f,%f,%c,%f,%c,%d,%d",&gps_time,&hokui,&ns,&tokei,&ew,&rlock,&stn) >= 1) {
+            g_hokui=(int(hokui/100)+(hokui-int(hokui/100))/60)*1000000;
+            g_tokei=(int(tokei/100)+(tokei-int(tokei/100))/60)*1000000;
+
+            //time set
+            htime=int(gps_time/10000); mtime=int((gps_time-htime*10000)/100); stime=int(gps_time-htime*10000-mtime*100);
+            htime=htime+9;//UTC =>JST
+        }
+        gps_i=0;
+        sprintf(gps_data,"");
+    }
+}
+
+void random_talk(){
+    int rnd = timer.read_us()%6;
+    char msg[128];
+    if(silent==0 && pre_cnt%600==0){
+        if(rnd>=0 && rnd<=1){
+            float nishitime=((xtime_h*3600+xtime_m*60+xtime_s)-(time_h*3600+time_m*60+time_s));
+            int ato_m = int(nishitime/60); int ato_s = int(nishitime-ato_m*60);
+            sprintf(msg,";uchiageyotei,ji'kokumade,a'to <NUMK VAL=%d COUNTER=funn> <NUMK VAL=%d COUNTER=byo-> de_su.\r",
+            ato_m, ato_s);
+        }else
+        if(rnd>=2 && rnd<=3){
+            sprintf(msg,";uchiageyotei,ji'kokuwa <NUMK VAL=%d COUNTER=ji> <NUMK VAL=%d COUNTER=funn> <NUMK VAL=%d COUNTER=byo-> de_su.\r",
+            xtime_h, xtime_m, xtime_s);
+        }else
+        if(rnd==4){
+            sprintf(msg,"sintyokuwa,;do'ude_suka?ganbattekudasai\r");
+        }else
+        if(rnd==5){
+            sprintf(msg,"watasini'wa,joukuude,hutatu'no,parashu-'towo,houshutusuru'toiu,sekininngaarima_su.mina'sann,o-enn,yorosikuonegaisima_su.\r");
+        }
+        i2c.write(tlk_addr, msg, strlen(msg));
+    }
+}
+
+void deployment(){
+    //サーボ保持解除
+    if(servo_sw){
+        servo_sw++;
+        if(servo_sw>10) {
+            servo.pulsewidth_us(0);
+            servo_sw=0;
+        }
+    }
+    //発射判定
+    if(mode==1){
+         if(acc > 30000){
+             mode=2; talk_line(10); sci.printf("Lift off!! (accel)\r\n"); timer.reset();
+             launch_time = timer.read_ms();
+         }else
+         if(f_pin==0){
+             mode=3; talk_line(10); sci.printf("Lift off!! (flight pin)\r\n"); timer.reset();
+             launch_time = timer.read_ms();
+         }
+    }else
+    //開放判定1
+    if(mode==2 || mode==3){
+        if(ms_time-launch_time > DEPLOY_TIME_1){  //タイマー開放
+            mode=4; servo = DUTY_1; servo_sw++;
+            sci.printf("Parachute1 deployed (timer)\r\n");
+            deploy_time_1 = timer.read_ms(); talk_line(11);
+        }else
+        if(ms_time-launch_time>8000 && dep_sw==2){       //高度開放
+            mode=5; servo = DUTY_1; servo_sw++;
+            sci.printf("Parachute1 deployed (altitude)\r\n");
+            deploy_time_1 = timer.read_ms(); talk_line(11);
+        }
+    }else
+    //開放判定2
+    if(mode==4 || mode==5){
+        if(ms_time-deploy_time_1 > DEPLOY_TIME_2){  //タイマー開放
+            mode=6; servo = DUTY_2; servo_sw++;
+            sci.printf("Parachute2 deployed (timer)\r\n");
+            deploy_time_2 = timer.read_ms(); talk_line(12);
+        }else
+        if(ms_time-deploy_time_1>8000 && altitude<DEPLOY_ALT2){
+            mode=7; servo = DUTY_2; servo_sw++;
+            sci.printf("Parachute2 deployed (altitude)\r\n");
+            deploy_time_2 = timer.read_ms(); talk_line(12);
+        }
+    }else
+    //着地判定
+    if(mode==6 || mode==7){
+        servo_sw2++;
+        if(servo_sw2%10==0) { servo = DUTY_2; servo_sw++; }
+        if(abs(acc-pre_acc)<1000){
+            acc_sw++;
+        }else{acc_sw=0;}
+        if(acc_sw==10){
+            sci.printf("Rocket Landing! \r\n"); talk_line(15); mode=8;
+        }
+    }
+}
\ No newline at end of file
diff -r 000000000000 -r 8483298c086d mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Nov 20 05:06:08 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/9ad691361fac
\ No newline at end of file