20200823_Motacon2020_ver5_kikkawa

Dependencies:   mbed FatFileSystemCpp INA226_abc BLDCmotorDriver_20200821_motacon_ver4

Revision:
1:47c28ece54ea
Parent:
0:3e0c71851fee
--- a/main.cpp	Mon Aug 03 03:20:27 2020 +0000
+++ b/main.cpp	Fri Aug 21 08:30:26 2020 +0000
@@ -1,129 +1,54 @@
-/*
-    Motacon 20200803 ver.2
-    ver.1: ブラシレスモータ(BLDC), USBメモリ書き込み, LM61(インバータ温度測定), INA226(インバータ電流電圧測定), CAN
-    ver.2 まともなプログラムになるように努力中
-*/
+//20200803 Kikkawa モタコン基板(緑色ver.1)での動作確認済み
+//BLDC, INA226, CAN
+
 #include "mbed.h"
-#include "MSCFileSystem.h"  //USBメモリ操作のため
-#include "INA226.hpp"       //INA226操作のため
-#include "RateLimiter.h"    //モータ加減速調整のため
-#include "BLDCmotorDriver.h"//BLDC操作のため
-
+#include "BLDCmotorDriver.h"
+#include "INA226.hpp"
+  
 /*定数の設定*/
 #define Vin1_LENGTH 20   //要素数(個数指定用の定数)
 #define Cin1_LENGTH 20   //要素数(個数指定用の定数)
-#define Vout1_LENGTH 20   //要素数(個数指定用の定数)
-#define Cout1_LENGTH 20   //要素数(個数指定用の定数)
-#define temp1_LENGTH 20   //要素数(個数指定用の定数)
-#define temp2_LENGTH 20   //要素数(個数指定用の定数)
+#define canSlaveID 0x10     //CAN通信IDを0x10に設定
 
-/*基本の設定*/
-Serial pc(USBTX, USBRX);
-DigitalOut myled(LED1); //
-DigitalOut led2(LED2);  //
-DigitalOut led3(LED3);  //
-bool flagPrintf = 0;    //main関数でのprintf処理のためのフラグ
-Ticker ticker1;     //割り込み設定用
-
-/*BLDC設定*/
+CAN canSlave(p30, p29);
 Timer timer;        //回転数計算用タイマ設定
-BLDCmotorDriver M(p26, p24, p22, p25, p23, p21, p14, p17, p18, LED1);
+Ticker ticker1;     //割り込み設定用
+Ticker ticker2;     //割り込み設定用
+
+Serial pc(USBTX, USBRX);
+BLDCmotorDriver M(p26, p24, p22, p25, p23, p21, p9, p8, p7, LED1);
 AnalogIn Pot(p20);
-InterruptIn HS_p16(p16);    
-InterruptIn DIRECTION_SW(p8);
-void initBLDC();  //BLDCの初期設定を行う関数
-float rpm = 0, speed = 0;
-double dc = 0.0;
-bool direction = 0;//方向を決める
-int begin, end; //
-int HS_timer = 0;   //速度検出のために使う変数 
-int HS_timer1 = 0;  //速度検出のために使う変数 
-int reset_cnt = 0;  //Timerをリセットするために使うカウンタ
+DigitalIn direction(p16);
+DigitalIn accel(p15);
+
+DigitalOut led2(LED2);  //CAN_check
+DigitalOut led3(LED3);  //direction_check
+DigitalOut led4(LED4);  //accel_check
 
-/*CANの設定*/
-CAN canSlave(p30, p29); //CANのピン設定
-void initCAN();  //CANの初期設定を行う関数
+double rpm = 0.0, speed = 0.0;   //モータ回転数、速度
+float dc = 0.0, dc_limit = 0.0;
+int sector = 0;
+
+bool flagPrintf = 0;    //main関数でのprintf処理のため
+
 int forSend = 0;        //データ送信時に一時的に使用する変数
 bool CANsendOK = 0;  //CAN受信完了時,セットする(mainでのprintfのため)
 CANMessage msgSlave;    //CAN送信用
-unsigned int  canSlaveID = 0x10;   //canSlaveの初期IDを0x10に設定  (モタコン:0x10, )
 void Handler_canSlaveSend();
 
-/*INA226設定*/    //GNDGND(G-G):0x80, Vs+Vs+(1-1):0x8A, SDASDA(D-D):0x94, SCLSCL(C-C):0x9E, GNDVs+(G-1):0x82
+/*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);
-INA226 VCmonitor1(i2c,0x9E);        //GNDGND(G-G)に設定したINA226がVCmonitor1(1台目)
-INA226 VCmonitor2(i2c,0x94);        //Vs+Vs+(1-1)に設定したINA226がVCmonitor2(2台目)
 void initINA226();  //INA226の初期設定を行う関数
+void INA226_init(); //INA226の初期設定用関数
+INA226 VCmonitor(i2c); 
 unsigned short val;
-double V,C,Vin1,Cin1,Vout1,Cout1;
+double V,C;
 int count = 1;      //INA226動作確認用カウンタ
 float data_Vin1[Vin1_LENGTH] = {0.0, 0.0, 0.0, 0.0, 0.0};        //一時的データ格納配列
 float data_Cin1[Cin1_LENGTH] = {0.0, 0.0, 0.0, 0.0, 0.0};        //一時的データ格納配列
-float data_Vout1[Vout1_LENGTH] = {0.0, 0.0, 0.0, 0.0, 0.0};        //一時的データ格納配列
-float data_Cout1[Cout1_LENGTH] = {0.0, 0.0, 0.0, 0.0, 0.0};        //一時的データ格納配列
-void get_VCin1(void);
-void get_VCout1(void);
-
-/*温度測定(LM61)設定*/
-AnalogIn LM61(p15); ////set p15 to analog input to read LM61 sensor's voltage output
-float temp1 = 0.0, temp2 = 0.0;
-void get_temp(void);    //温度取得する関数
-float data_temp1[temp1_LENGTH] = {0.0, 0.0, 0.0, 0.0, 0.0};        //一時的データ格納配列
-float data_temp2[temp2_LENGTH] = {0.0, 0.0, 0.0, 0.0, 0.0};        //一時的データ格納配列
-
-/*ADCのピン設定*/    //also setting unused analog input pins to digital outputs reduces A/D noise a bit    //see http://mbed.org/users/chris/notebook/Getting-best-ADC-performance/
-DigitalOut P19(p19);
-    
- /*USBメモリの設定*/
-MSCFileSystem msc("usb"); // Mount flash drive under the name "msc"
-void write_toMSC(void); //MSC=USBメモリ
-FILE *fp;   //ファイルの設定
-
-//Timer timer;  //処理時間測定用タイマ デバッグに使用する
-int n = 0;  //移動平均算出に使うカウンタ
+void get_VCipm(void);   //IPMの電圧電流計測関数
 
-/*時間割り込み関数*/
-void handler_0t2s(){   //0.2秒毎の割り込み
-    if( direction == 0 ){    //正回転            
-        dc = Pot.read(); 
-    }
-    if( direction == 1 ){    //逆回転            
-        dc = -1 * Pot.read(); 
-    } 
-    reset_cnt++;
-    if( reset_cnt >= 6000 ){
-        timer.reset();
-        reset_cnt = 0;
-    }
-    //flagPrintf = 1;
-}
-/*ホールセンサの立ち上がりから立ち上がりまでの時間計測する関数*/
-void handler_HS(){  
-    if( HS_timer == 0 ){
-        begin = timer.read_us();
-        HS_timer1 = 0;
-    }
-    if( HS_timer == 1 ){
-        end = timer.read_us();
-        HS_timer1 = 1;
-    }
-    if( HS_timer1 == 0 ){
-        HS_timer = 1;
-    }
-    if( HS_timer1 == 1 ){
-        HS_timer = 0;
-        rpm = 3750 / (abs(end - begin) * 0.001);
-        speed = rpm * 0.10518;
-    }
-}
-/*Directionスイッチの割り込み 進行方向切り替え*/
-void handler_directionSW(){
-    if( dc <= 0 ){
-        direction = !direction;
-    }
-}
-/*CANでデータを送信する関数*/
-void Handler_canSlaveSend() { 
+void Handler_canSlaveSend() {
     forSend = (int)(V/100);
     msgSlave.data[0] = forSend / 100;    //forSend / 100 = 15あまり43 となり,答えの方がデータ格納される
     msgSlave.data[1] = forSend % 100;    //forSend / 100 = 15あまり43 となり,あまりの方がデータ格納される
@@ -143,115 +68,69 @@
         CANsendOK = 1;
     }
 }
-/*CAN通信相手から送信要求がきたとき実行される*/
-void Handler_canSlaveRecieve(){ //CANの通信相手から,送信要求がきたときに実行される関数
+/*
+void Handler_canSlaveRecieve(){ //canMasterから送信要求が来たとき,データ送信するための関数
     if( canSlave.read( msgSlave ) ){ //msgに送られたデータが入る   
         led2 = !led2;
         if( msgSlave.id == canSlaveID ){ //IDがcanSlaveIDであれば処理する   
-            Handler_canSlaveSend(); //送信処理をする関数に飛ぶ
+            Handler_canSlaveSend(); //送信処理を開始する
         }
     }
 }
-/*電圧と電流測定する関数*/
-void get_VCin1(){
-    if((VCmonitor1.getVoltage(&V) == 0) && (VCmonitor1.getCurrent(&C) == 0)){     //1台目INA226の電圧電流測定
-        Vin1 -= data_Vin1[n];    //移動平均処理
-        Cin1 -= data_Cin1[n];    //移動平均処理
-        data_Vin1[n] = V/Vin1_LENGTH;   //移動平均処理
-        data_Cin1[n] = C/Cin1_LENGTH;   //移動平均処理
-        Vin1 += data_Vin1[n];   //移動平均処理
-        Cin1 += data_Cin1[n];   //移動平均処理
-        pc.printf("\n%d, Vin1: %f, Cin1: %f\n",count,Vin1,Cin1);
-    }
-}
-/*温度測定する関数*/
-void get_temp(){
-    temp1 -= data_temp1[n];     //移動平均処理
-    data_temp1[n] = ( ((LM61*3.3)-0.600)*100.0 ) / temp1_LENGTH;    //移動平均処理
-    temp1 += data_temp1[n];     //移動平均処理
-    pc.printf("temp1:%5.2F C temp2:%5.2F C \n\r", temp1, temp2);
-}
-void write_toMSC(){
-    if ( (fp= fopen( "/usb/MPPT.csv", "a")) == NULL ){  //ファイルを開く, aは上書きの命令(ファイルが存在しなければ新規作成する)
-        pc.printf("USB error\r\n");
-        exit(1);
-    }
-    pc.printf("USB file write!\r\n");
-    //timer.start();    //書き込み時間測定開始
-    fprintf(fp,"%f,%f,%f,%f,%f,%f\n", Vin1, Cin1, Vout1, Vout1, temp1, temp2);  //ファイル書き込み
-    //timer.stop();     //書き込み時間測定終了    
-    fclose(fp);         //ファイルを閉じる  
-    //pc.printf("write time :%f\n\n\n",timer.read());  
-}
+*/
+void INA226_init(){ //INA226初期設定を行う関数
+    printf("\n\r");
+    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の設定
+    printf("VCmonitor Reg 0x00 : 0x%04x\n\r",val);  //configResisterの値表示
+    printf("\n\r");
+    VCmonitor.setCurrentCalibration();  //calibrationResisterの設定
+}    
 
-/*INA226の初期設定*/
-void initINA226(){
-    //  1台目の設定
-    if ( !VCmonitor1.isExist() ){
-        pc.printf("VCmonitor1 INA226 Not Found.\n");
-    }
-    val = 0;
-    if ( VCmonitor1.rawRead(0x00,&val) != 0){
-        pc.printf("VCmonitor1 INA226 Read Error\n");
-    }
-    pc.printf("VCmonitor1 Reg 0x00 : 0x%04x\r\n",val);
-    VCmonitor1.setCurrentCalibration();
-}
-/*CANの初期設定*/
-void initCAN(){
-    canSlave.attach(&Handler_canSlaveRecieve, CAN::RxIrq);   //CAN受信割り込みの設定
+int main() {
+    /*ポート初期設定*/
+    direction.mode(PullUp);                //進行方向スイッチ入力ピンをプルアップに設定
+    accel.mode(PullUp);                //アクセルスイッチ入力ピンをプルアップに設定
+    
+    /*INA226初期設定*/
+    INA226_init();  //INA226の初期設定する関数に飛ぶ
+    
+    /*CAN初期設定*/
+//    canSlave.attach(&Handler_canSlaveRecieve, CAN::RxIrq);   //CAN受信割り込みの設定
     msgSlave.id = canSlaveID; //CAN送信側(slave)のIDを決定
     msgSlave.len = 7;   //CAN送信側で送るデータのバイト数
-}
-void initBLDC(){
-    timer.start();      //回転数計算用タイマスタート
-    DIRECTION_SW.mode(PullUp);                //directionスイッチのモード設定
-    DIRECTION_SW.fall(&handler_directionSW);  //directionスイッチの立ち上がり割り込み設定
-    DIRECTION_SW.rise(&handler_directionSW);  //directionスイッチの立ち下がり割り込み設定   どちらも同じ関数に飛ぶ
-    led3 = DIRECTION_SW.read();
-//    HS_p16.rise(&handler_HS);       //ホールセンサ立ち上がり割り込み設定
-}
-
-/*メイン関数*/
-int main()
-{
-    initINA226();        //INA226の初期設定
-    initCAN();
-    initBLDC();     //BLDC制御のための初期設定
-    ticker1.attach(&handler_0t2s, 0.3); //0.3秒毎に飛ぶ「handler_0t3s」関数
-    
-    while(1) {
-        get_VCin1();    //Vipm(IPMへの入力電圧)とCipm(IPMへの入力電流)を取得
-        get_temp();     //温度測定
-//        write_toMSC();  //データをUSBメモリに保存
-
-        n++;
-        if( n >= Vin1_LENGTH ){ //カウンタがサンプル数を超えたら,0に戻り,移動平均算出を続ける           
-            n = 0;
+       
+    while(true) {  
+        dc = ( Pot.read()-0.5 )*2;  //可変抵抗の値からduty比を設定
+//        dc_limit = -0.0147 * speed * speed + 2.6842 * speed + 29.885;    //加速側制限.elsxの式
+//        dc = dc * dc_limit;
+        
+        VCmonitor.getVoltage(&V);   //IPM電圧(mV)測定
+        VCmonitor.getCurrent(&C);   //IPM電流(mA)測定
+        
+        if( !accel.read() ){
+            led4 = 0;
+            M.setDutyCycle(0);     //duty比の設定 duty比を0にする
         }
-        
-        M.setDutyCycle(dc);     //モータを駆動する関数    引数dcは,PWMのデューティ比
-        flagPrintf = 1;
-        if( flagPrintf ){   //flagPrntfが1なら,以下を処理する
-            flagPrintf = 0;
-            pc.printf("Duty Cycle: %1.2f, Sector: %d\n\r",dc, M.getSector());
-            pc.printf("Toggle the led takes %d us\n", abs(end - begin));
-            pc.printf("%f rpm\n",rpm);
-            pc.printf("%f km/h\n",speed);
-            pc.printf("V,%f,C,%f\n",V,C);
+        if( accel.read() ){
+            if( !direction.read() ){    //directionスイッチが0のとき
+                led3 = 0;               //処理
+            }
+            else if( direction.read() ){     //directionスイッチが1のとき
+                led3 = 1;
+            }
+            led4 = 1;
+            M.setDutyCycle(dc);     //duty比の設定
+            sector = M.getSector();
+            //get_VCipm();    //Vin1とCin1を取得する
+            //pc.printf("HS_cnt: %d HS_usec %d\n", M.HS_cnt, M.HS_usec);  //デバッグ用            
         }
-        /*
-        if( CANsendOK ) {
-            CANsendOK = 0;     
-            printf("Data in msgSlave.data[0] : %d\n\r", msgSlave.data[0]);    //CANで送信したデータをそのまま表示
-            printf("Data in msgSlave.data[1] : %d\n\r", msgSlave.data[1]);    //上に同じ
-            printf("Data in msgSlave.data[2] : %d\n\r", msgSlave.data[2]);    //上に同じ
-            printf("Data in msgSlave.data[3] : %d\n\r", msgSlave.data[3]);    //上に同じ
-            printf("Data in msgSlave.data[4] : %d\n\r", msgSlave.data[4]);    //上に同じ
-            printf("Data in msgSlave.data[5] : %d\n\r", msgSlave.data[5]);    //上に同じ
-            printf("Data in msgSlave.data[6] : %d\n\r", msgSlave.data[6]);    //上に同じ
-            printf("\n\r");
-        }
-        */  
+        rpm = 3750 / (M.HS_usec * 0.001);   //ミリ秒に直して逆数を3750に掛けるああ  //BLDCmotorDriver.cpp(.h)で使っている変数をmainで使う場合は「M.」を付ける。「M」なのはmainの上の方でそう設定してるから。usecはmicro second:マイクロ秒
+        speed = rpm * 0.10518;                  //3750とか0.010518は、excelで計算している。ファイル名「」
+        pc.printf("Duty: %.2f, Sector: %d, %.1f km/h, rpm: %1.2f, V: %.0f, C: %.0f\n\r",dc, sector, speed, rpm, V, C);
+        Handler_canSlaveSend(); //送信処理を開始する
     }
-}
+}
\ No newline at end of file