あの装置用

Dependencies:   ADXL345_I2C QEI SDFileSystem mbed

main.cpp

Committer:
ojityan
Date:
2017-03-24
Revision:
8:9059f95fc498
Parent:
7:0e3fac3c6a6a

File content as of revision 8:9059f95fc498:

#include "mbed.h"
#include "ADXL345_I2C.h"
#include <stdio.h>
#include <stdlib.h>

void savedata(void);
void flipB(void);
void ADXL_config(void);
void read_current(double *C);
void controller(double *v,float *duty_output,double *acce_device, double *acce_output, double *F);
void makefile(void);
void weight_init(void);
void INA226config(void);

DigitalOut dir(p25);
PwmOut duty(p24);
I2C i2c(p28, p27);

ADXL345_I2C accelerometer(p9, p10);
Serial debug(USBTX,USBRX);
//QEI wheel (p21, p22, p23, 1000);

DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
DigitalOut myled4(LED4);
DigitalIn  sensorA(p17);
DigitalIn  sensorB(p18);
DigitalIn  sensorC(p19);
DigitalIn  sensorD(p20);
InterruptIn sensorB_(p18);

int flag = 0;
int flipB_ = 0;
Ticker save;
FILE *fp;
Timer t;
int intrrupt_cnt = 0;

static char i2c_addr = 0x80;



int main()
{
    char buffer[100][150];
    int i,j;
    double C;
    float duty_output;
    int loop_break;
    double acce_device;
    double acce_output;
    int readings[3] = {0, 0, 0};
    double v;
    double F_output;

    myled1 = 1; //起動の確認
    ADXL_config();
    myled2 = 1;
//    makefile();
    myled3 = 1;
    INA226config();
    myled4 = 1;
    wait(3.0);
    myled1 = 0;
    myled2 = 0;
    myled3 = 0;
    myled4 = 0;


//---PWNの周期を設定---
    duty_output = 0.6;
    duty.period(0.00005);
//    NVIC_SetPriority(0, 1);


/////////////////////
//---制御開始---
/////////////////////
    while(1) {
        t.reset();
        i = 0;
        loop_break = 0;
        debug.printf("writing OK!\n");

        weight_init(); //慣性力発生用おもりを初期位置に移動させる

//---加速度を感知したら移動開始---
        flipB_ = 0;
        dir = 1;

        while (1) {
            accelerometer.getOutput(readings);
            if( abs((int16_t)readings[0]) > 25) {
                myled3 = 1;
                break;
            }
        }
        save.attach(&savedata, 0.01 ); //割り込み開始
        t.start();
        
        duty.write(duty_output);


        while(t.read() <= 0.80) { //内部タイマーが0.80秒に達するまで制御
            if(flag) {
                flag = 0;
                controller( &v, &duty_output, &acce_device, &acce_output, &F_output);
                read_current( &C);
                if(1) {
                    sprintf(buffer[i],"%f10,%f10,%f10,%f10,%f10,%f10",t.read(),C,acce_device,C,duty_output,F_output); //バッファにデータを溜めこみ終了時に吐き出す.
                    if( i > 299) {
                        loop_break = 1;
                        break;
                    }
                    i = i + 1;
                }

            }
            if(loop_break) {
                break;
            }

        }
        
        myled2 = 1; //0.80秒経過したらLED2を光らせる
        t.stop();
        save.detach();


        duty = 0.0f;

        myled1 = 1;
        for( j = 0; j < i; j++) {
            debug.printf("%s\n",buffer[j]);//シリアル通信でバッファにあるデータを相手に送信する
        }
        
        while(1) {
            myled1 = 1;
            wait(0.2);
            myled1 = 0;
            wait(0.2);
        }
    }
}




void savedata(void)//割り込み時の処理
{
    flag = 1;
    intrrupt_cnt++;

}


void ADXL_config(void)//ADXL345の初期設定
{
    //初期設定開始
    accelerometer.setPowerControl(0x00);

    //精度
    accelerometer.setDataFormatControl(0x0B);

    //3.2kHz
    accelerometer.setDataRate(ADXL345_3200HZ);

    //計測開始
    accelerometer.setPowerControl(0x08);

    accelerometer.setOffset (0, 0);

}

void INA226config(void) //INA226の設定
{

    char p_addr = 0x00;
    char p_addr_i = 0x04;
    short Calibration_set = 0x0A00;
    char write_item[3];
//---ammeter setting---
    i2c.start();
    if(i2c.write(i2c_addr | 0,&p_addr,sizeof(p_addr)) == 0) {
        debug.printf("ERROR_write\n");
    }
    debug.printf("OK!\n");

    //rawWrite(0x05,0x0A00);

    short Config_set = 0x444F;//0x4A4F;//0x4E97;//0x4C97;
    write_item[0] = 0x00;
    write_item[1] = static_cast<char>((Config_set >> 8) & 0x00ff);
    write_item[2] = static_cast<char>(Config_set & 0x00ff);
    if(i2c.write(i2c_addr | 0,write_item,3) == 0) {
        debug.printf("OK!!\n");
    } else {
        debug.printf("OH!!\n");
    }



    write_item[0] = 0x05;
    write_item[1] = static_cast<char>((Calibration_set >> 8) & 0x00ff);
    write_item[2] = static_cast<char>(Calibration_set & 0x00ff);
    if(i2c.write(i2c_addr | 0,write_item,3) == 0) {
        debug.printf("OK!!\n");
    } else {
        debug.printf("OH!!\n");
    }
}

void weight_init(void) //慣性力発生用のおもりの位置の初期化
{
//---position reset---
    dir = 0;
    duty = 0.50f;
    while(!sensorB);
    duty = 0.0f;
    wait(2.0);
    myled1 = 1;
}

void controller(double *v,float *duty_output,double *acce_device, double *acce_output, double *F)//制御部
{

    double ka = 100;
    double kv = 100;

    int readings[3] = {0,0,0};
//    static double F;
    static double F_1;
    static double F_2;
    static double F_3;
    static int intrrupt_checker = 1;


//---加速度を読み取り変換する---
    accelerometer.getOutput(readings);
    *acce_device = (int16_t)readings[0] * 0.0383;
    *v = *v + *acce_device * 0.01;
    if( *acce_device < 0) {
        if(abs(*v) > 0) {
//---必要な力の算出(今回は不使用)---
            F_1 = -1 * ( ka * *acce_device) + (kv * *v);
            *F = 0.35 * F_1 + 0.4 * F_2 + 0.25 * F_3;
            *acce_output = *F / 8.5;
            if(*duty_output > 1.0) {
                *duty_output = 1.0;
                myled4 = 1;
            }
//---加速度を検知したら慣性力発生用おもりを加速させる---
            if(intrrupt_checker <= intrrupt_cnt){
                *duty_output = *duty_output + 0.04;
                intrrupt_checker = intrrupt_cnt + 1;
            }
            
            
            duty.write(*duty_output);

            F_3 = F_2;
            F_2 = *F;
        }
    }
}

void read_current(double *C) //電流量を測る
{
    char I[2];
    unsigned short read_item;
    char p_addr = 0x00;
    char p_addr_i = 0x04;
//---reading current---
    while(i2c.write(i2c_addr | 0,&p_addr_i,sizeof(p_addr_i)) != 0);
    while(i2c.read(i2c_addr | 0x01,I,sizeof(I)) != 0);
    read_item = static_cast<unsigned short>(I[0]);
    read_item = (read_item << 8) | static_cast<unsigned short>(I[1]);

    char *s_p = reinterpret_cast<char *>(&read_item);
    short d_s;
    char *d_p = reinterpret_cast<char *>(&d_s);
    *(d_p + 0) = *(s_p + 0);
    *(d_p + 1) = *(s_p + 1);
    *C = static_cast<double>(d_s) /* * 1.25 */;
}