2021年3月伊豆大島共同打上実験の電装ミッションプログラム

Dependencies:   mbed ADS1015 PQ_LPS22HB SPS30 SDFileSystem

main.cpp

Committer:
kazuncho
Date:
2021-03-14
Revision:
0:976e8caa93f4

File content as of revision 0:976e8caa93f4:

#include "mbed.h"
#include <cmath>
#include "sps30.h"
#include "SDFileSystem.h"
#include "Adafruit_ADS1015.h"
#include "PQ_LPS22HB.h"

#define ADS1115_ADDR 0b1001000

FILE *fp;

I2C i2c(D4, D5);
Serial pc(USBTX, USBRX, 115200);
Sps30 sps(D4, D5, 100000);
SDFileSystem sd(D11, D12, D13, A3, "sd");
Adafruit_ADS1115 ads1115(&i2c, ADS1115_ADDR);
LPS22HB lps33hw(i2c, LPS22HB::SA0_HIGH);
LPS22HB lps22hb(i2c, LPS22HB::SA0_LOW);

DigitalOut switch_on(D0);
DigitalIn mission(D6);
DigitalIn relay(D3);

Timer mission_timer;
Timer flight_timer;
Timer sd_timer;
Ticker log_ticker;
Ticker read_ticker;

char file_name[64];
char f_inside_lps;
char f_outside_lps;

enum {
    READY,
    RISE,
    FALL,
    RECOVERY,
} phase;

bool recovery = false;

int mission_time;
int flight_time;
int sps_init;
int sps_poll;

float pitot_speed;
float density = 1.3;

float outside_press;
float outside_temp;
float inside_press;
float inside_temp;

float mass1p0;
float mass2p5;
float mass4p0;
float mass10p0;
float num0p5;
float num1p0;
float num2p5;
float num4p0;
float num10p0;
float typ_pm;

void init();
void read();
void pitot_tube();
void lps33hw_mission();
void lps22hb_mission();
void record();
void read_sps30();

int main()
{
    init();
    mission_timer.start();
    while(1) {
        pitot_tube();
        lps33hw_mission();
        lps22hb_mission();
        read_sps30();
        //read();
        if(mission and !relay) {    //リセット
            phase = READY;
            switch_on = 1;
            recovery = false;
            mission_timer.reset();
            mission_timer.start();
            flight_timer.reset();
            flight_timer.stop();
        }
        switch(phase) {
            case READY: //0
                if(mission and relay) {
                    phase = RISE;
                    flight_timer.reset();
                    flight_timer.start();
                }
                break;
            case RISE: //1
                if(!mission and relay) {
                    phase = FALL;
                }
                break;
            case FALL: //2
                if(!mission and !relay) {
                    phase = RECOVERY;
                    fclose(fp);
                    //flight_timer.stop();
                    //mission_timer.stop();
                    wait(1.0f);
                }
                break;
            case RECOVERY: //3
                if(!recovery) {
                    switch_on = 0;  //センサーへの電源供給停止
                    recovery = true;
                }
                break;
        }
        wait(0.5f);
    }
}

void init()
{
    pc.printf("---PQ_Hybrid_Mission---\r\n");
    switch_on = 1;  //センサーへ電源供給開始
    //recovery = false;
    wait(1.0f);
    lps22hb.begin();
    lps33hw.begin();

    sd.mount();
    mkdir("/sd", 0777);
    char file_name_format[] = "/sd/IZU2021_MISSION_%d.dat";
    int file_number = 1;
    while(1) {
        sprintf(file_name, file_name_format, file_number);
        fp = fopen(file_name, "r");
        if(fp != NULL) {
            fclose(fp);
            file_number++;
        } else {
            sprintf(file_name, "/sd/IZU2021_MISSION_%d.dat", file_number);
            break;
        }
    }
    fp = fopen(file_name, "w");
    sd_timer.start();
    if(fp) {
        fprintf(fp, "mission_time[s]\t");
        fprintf(fp, "flight_time[s]\t");
        fprintf(fp, "phase\t");
        fprintf(fp, "pitot_speed[m/s]\t");
        fprintf(fp, "pitot_speed[km/h]\t");
        fprintf(fp, "mass_1p0\t");
        fprintf(fp, "mass_2p5\t");
        fprintf(fp, "mass_4p0\t");
        fprintf(fp, "mass_10p0\t");
        fprintf(fp, "num_0p5\t");
        fprintf(fp, "num_1p0\t");
        fprintf(fp, "num_2p5\t");
        fprintf(fp, "num_4p0\t");
        fprintf(fp, "num_10p0\t");
        fprintf(fp, "typ_pm_size\t");
        fprintf(fp, "outside_press[Pa]\t");
        fprintf(fp, "outside_temp[degC]\t");
        fprintf(fp, "inside_press[Pa]\t");
        fprintf(fp, "inside_temp[degC]\t");
        fprintf(fp, "\r\n");
    }

    log_ticker.attach(record, 0.5f);
    //read_ticker.attach(read, 0.5f);
}

/*********************************************
/   MPXV5004DPの場合:(Differencial) = ((Vout / Vs) - 0.2) / 0.2
/   MPX5010DPの場合:(Differencial) = ((Vout / Vs) - 0.04) / 0.09
/   speed = root(2 * P / ρ)
/   pitot_paが負のときnanが返される
**********************************************/
void pitot_tube()
{
    float sum = 0;
    float voltage = 0;
    float pitot_pa = 0;
    float pitot_volt = 0;
    for(int i = 0; i < 10; i++) {
        int16_t val = ads1115.readADC_SingleEnded(0);
        voltage = val / 32768.0 * 6.144;
        sum += voltage;
    }
    float v_ave = sum / 10.0f;
    pitot_volt = voltage - v_ave + 0.2f;
    pitot_pa = (pitot_volt / 5.0f - 0.04f) / 0.09f;
    pitot_speed = sqrt(2 * pitot_pa * 1000 / density);
}

/*********************************************
/   水密外配置。リレーの条件に使用する。
**********************************************/
void lps33hw_mission()
{
    f_outside_lps = lps33hw.test();
    if(f_outside_lps) {
        outside_press = 0;
        outside_temp = 0;
        lps33hw.read_press(&outside_press);
        lps33hw.read_temp(&outside_temp);
    }
}

/*********************************************
/   水密内配置。水密になっているかの確認用。
**********************************************/
void lps22hb_mission()
{
    f_inside_lps = lps22hb.test();
    if(f_inside_lps) {
        inside_press = 0;
        inside_temp = 0;
        lps22hb.read_press(&inside_press);
        lps22hb.read_temp(&inside_temp);
    }
}

void read_sps30()
{
    sps_init = sps.InitSPS30();
    if(sps.PollSPS30() == 3) {
        mass1p0 = sps.mass_1p0_f;
        mass2p5 = sps.mass_2p5_f;
        mass4p0 = sps.mass_4p0_f;
        mass10p0 = sps.mass_10p0_f;
        num0p5 = sps.num_0p5_f;
        num1p0 = sps.num_1p0_f;
        num2p5 = sps.num_2p5_f;
        num4p0 = sps.num_4p0_f;
        num10p0 = sps.num_10p0_f;
        typ_pm = sps.typ_pm_size_f;
    }
}

void record()
{
    mission_time = mission_timer.read();
    flight_time = flight_timer.read();
    fprintf(fp, "%4d\t", mission_time);
    fprintf(fp, "%4d\t", flight_time);
    fprintf(fp, "%1d\t", phase);
    fprintf(fp, "%f\t", pitot_speed);
    fprintf(fp, "%f\t", pitot_speed * 3600 / 1000.0f);
    fprintf(fp, "%f\t", sps.mass_1p0_f);
    fprintf(fp, "%f\t", sps.mass_2p5_f);
    fprintf(fp, "%f\t", sps.mass_4p0_f);
    fprintf(fp, "%f\t", sps.mass_10p0_f);
    fprintf(fp, "%f\t", sps.num_0p5_f);
    fprintf(fp, "%f\t", sps.num_1p0_f);
    fprintf(fp, "%f\t", sps.num_2p5_f);
    fprintf(fp, "%f\t", sps.num_4p0_f);
    fprintf(fp, "%f\t", sps.num_10p0_f);
    fprintf(fp, "%f\t", sps.typ_pm_size_f);
    fprintf(fp, "%f\t", outside_press);
    fprintf(fp, "%f\t", outside_temp);
    fprintf(fp, "%f\t", inside_press);
    fprintf(fp, "%f\t", inside_temp);
    fprintf(fp, "\r\n");

    if(sd_timer.read_ms() >= 60*1000) { //1分ごとにリセット、開き直す。
        sd_timer.reset();
        sd_timer.start();
        if(fp) {
            fclose(fp);
            fp = fopen(file_name, "a"); //a:追加書き込みモード
        }
    }
}


void read()
{
    mission_time = mission_timer.read();
    flight_time = flight_timer.read();
    pc.printf("mission time:%d\t", mission_time);
    pc.printf("flight time:%d\t", flight_time);
    pc.printf("phase:%d\t", (int)phase);
    pc.printf("relay:%d", (int)switch_on);
    /*
    pc.printf("SPEED[m/s]:\t");
    pc.printf("SPEED[km/h]:\t");
    pc.printf("MASS_1P0\t");
    pc.printf("MASS_2P5\t");
    pc.printf("MASS_4P0\t");
    pc.printf("MASS_10P0\t");
    pc.printf("NUM_0P5\t");
    pc.printf("NUM_1P0\t");
    pc.printf("NUM_2P5\t");
    pc.printf("NUM_4P0\t");
    pc.printf("NUM_10P0\t");
    pc.printf("PM_SIZE\t");
    pc.printf("OUT_PRESS\t");
    pc.printf("OUT_TEMP\t");
    pc.printf("IN_PRESS\t");
    pc.printf("IN_TEMP\t");
    */
    pc.printf("\r\n");
    /*
    pc.printf("%f\t", pitot_speed);
    pc.printf("%f\t", pitot_speed * 3600 / 1000.0f);
    pc.printf("%.2f\t", mass1p0);
    pc.printf("%.2f\t", mass2p5);
    pc.printf("%.2f\t", mass4p0);
    pc.printf("%.2f\t", mass10p0);
    pc.printf("%.2f\t", num0p5);
    pc.printf("%.2f\t", num1p0);
    pc.printf("%.2f\t", num2p5);
    pc.printf("%.2f\t", num4p0);
    pc.printf("%.2f\t", num10p0);
    pc.printf("%.2f\t", typ_pm);
    pc.printf("%.2f\t", ground_press);
    pc.printf("%.2f\t", outside_press);
    pc.printf("%.1f\t", outside_temp);
    pc.printf("%.2f\t", inside_press);
    pc.printf("%.1f\t", inside_temp);
    pc.printf("\r\n");
    */
}