20200821_motacon_ver4

Dependencies:   mbed FatFileSystemCpp INA226_abc BLDCmotorDriver_20200902_1

main.cpp

Committer:
MPPT51
Date:
2020-09-02
Revision:
2:24ee83f3d19e
Parent:
1:47c28ece54ea

File content as of revision 2:24ee83f3d19e:

//20200825 Kikkawa モタコン基板(緑色ver.1)での動作確認済み
//BLDC, INA226, CAN
#include "mbed.h"
#include "BLDCmotorDriver.h"
#include "INA226.hpp"
//#include "EthernetPowerControl.h"   //消費電力削減
/*基本ポート設定*/
Serial pc(USBTX, USBRX); // USBシリアルポートのインスタンス
BLDCmotorDriver M(p26, p24, p22, p25, p23, p21, p9, p8, p7, LED1);
DigitalOut led2(LED2);  //CAN_check
DigitalOut led3(LED3);  //direction_check
DigitalOut led4(LED4);  //accel_check
DigitalIn accel(p15);    
DigitalIn direction(p16);
DigitalOut P17(p17);    //see http://mbed.org/users/chris/notebook/Getting-best-ADC-performance/
DigitalOut P18(p18);    //also setting unused analog input pins to digital outputs reduces A/D noise a bit
DigitalOut P19(p19);
AnalogIn Pot(p20);

/*モータ駆動関係*/
float dc = 0.0;

/*CAN関係*/
CAN CAN1(p30, p29); //CANのピンの設定
int forSend = 0;        //データ送信時に一時的に使用する変数
CANMessage msgCAN;    //CAN送信用
void CAN1_send();

/*INA226関係*/    //GNDGND(G-G):0x80, Vs+Vs+(1-1):0x8A, SDASDA(D-D):0x94, SCLSCL(C-C):0x9E, GNDVs+(G-1):0x82
I2C i2c(p28,p27);
void initINA226();  //INA226の初期設定を行う関数
void INA226_init(); //INA226の初期設定用関数
INA226 VCmonitor(i2c); 
unsigned short val;
double V,C;

//printf用
char cnt_printf = 0;

void CAN1_send() { //CANでデータ送信する関数。  //CAN1.attach(&Handler_canSlaveRecieve, CAN::RxIrq); <== この文はCAN受信割り込みの設定。使いたい時に使えるようにここに書いておく。使うときはmain関数で1回実行する。
    msgCAN.id = 0x10; //送信するCANデータのIDを決める
    msgCAN.len = 7;   //CAN送信側で送るデータのバイト数
    
    forSend = (int)(V/100);
    msgCAN.data[0] = forSend / 100;    //forSend / 100 = 15あまり43 となり,答えの方がデータ格納される
    msgCAN.data[1] = forSend % 100;    //forSend / 100 = 15あまり43 となり,あまりの方がデータ格納される
    
    forSend = (int)(C/10);  //mAで取得した値を10で割り、char2分割で送り切れるようにする。(例: 測定電流が199.99Aのとき,C=199900.00となるため,forSend=19990となり,199と90で分割することで送信できる)
    msgCAN.data[2] = forSend / 100;   //forSend / 100 = 5あまり54 となり,答えの方がデータ格納される
    msgCAN.data[3] = forSend % 100;   //forSend % 100 = 5あまり54 となり,あまりの方がデータ格納される
    
    forSend = (int)(M.speed*10);  //speed * 10 = 856.5だが,intにするため,856が代入される 
    msgCAN.data[4] = forSend / 100;   //forSend / 100 = 8あまり56 となり,8がデータ格納される
    msgCAN.data[5] = forSend % 100;   //forSend % 100 = 8あまり56 となり,56がデータ格納される
    
    forSend = (int)(M.getDutyCycle()*100);  //0~1を0~100にする
    msgCAN.data[6] = forSend;   //charの最大値である255以下になるため,そのままデータ格納される
    
    if(CAN1.write(msgCAN)){   //格納したデータを送信する
    }
}

void INA226_init(){ //INA226の初期設定を行う関数
    pc.printf("\n\r");
    pc.printf("VCmonitor INA226 TEST Program. (BUILD:[" __DATE__ "/" __TIME__ "])\n\r");
    if(!VCmonitor.isExist()){ pc.printf("VCmonitor NOT FOUND "); }
    val = 0;
    if(VCmonitor.rawRead(0x00,&val) != 0){ pc.printf("VCmonitor READ ERROR "); }    //configResisterの値を読み取れるか確認(通信できてるか確認)
    VCmonitor.setConfigResister();  //configurationResisterの設定
    pc.printf("VCmonitor Reg 0x00 : 0x%04x\n\r",val);  //configResisterの値表示
    pc.printf("\n\r");
    VCmonitor.setCurrentCalibration();  //calibrationResisterの設定
}    

int main() {
    //PHY_PowerDown();    //Ethernet停止 消費電力削減
    pc.baud(115200);    //pcとのシリアル通信速度指定。なるべく早くしないとpc.printfの処理時間が長くなってしまうかも
    //ポート初期設定
    direction.mode(PullUp);                //進行方向スイッチ入力ピンをプルアップに設定
    accel.mode(PullUp);                //アクセルスイッチ入力ピンをプルアップに設定
    //INA226初期設定
    INA226_init();  //INA226の初期設定する関数に飛ぶ
       
    while(true) {  
        //ゲート信号デューティ比に使用する値をAD変換により取得
        dc = ( Pot.read()*8 - 0.3 );  //可変抵抗の値からduty比を設定 Pot.read()を8倍することで可変抵抗をたくさん回さなくても値が上昇する -0.3して回生の処理をしやすくなるようにしておく(dcが0未満の時回生にするなど)
        if( dc >= 1 ){ dc = 1; }
        M.setDutyCycle(dc);     //duty比の設定
               
        //IPMの入力電圧、入力電流の測定
        VCmonitor.getVoltage(&V);   //IPM電圧(mV)測定
        V = V * 14.825; //計算の仕方は「ソーラーカー電装品図(パワポ資料)」に書いてある 270kと20kで分圧したとき14.825をかける
        V = V * 0.996; //テスタ実測結果を反映して値を調整する
        VCmonitor.getCurrent(&C);   //IPM電流(mA)測定
        
        //アクセルがONかOFFか判定する
        if( !accel.read() ){    //accel.read()が0(スイッチがOFF)の時の処理
            led4 = 0;
            M.accel = 0;
        }
        if( accel.read() ){
            if( !direction.read() ){    //directionスイッチが0のとき
                led3 = 0;               //処理
            }
            else if( direction.read() ){     //directionスイッチが1のとき
                led3 = 1;
            }
            led4 = 1;
            M.accel = 1;
        }
        //シリアル通信でpc(teratermなど)に表示
        ++cnt_printf;
        if( cnt_printf >= 50 ){
            pc.printf("Duty: %.2f, Sector: %d, %.1f km/h, rpm: %1.2f, V: %.0f, C: %.0f, limit1: %.3f, HS_cnt: %d HS_usec %.2f\n\r", M.getDutyCycle(), M.getSector(), M.speed, M.rpm, V, C, M.dc_limit1, M.HS_cnt, M.HS_usec);
            cnt_printf = 0;
        }
        //CANデータ送信する
        CAN1_send(); //送信処理する関数に飛ぶ
    }
}