for CAN test for MonitoringSystem

Dependencies:   mbed SB1602E MSCFILESytem FatFileSystemCpp

Dependents:   Monitor2020_ver5

Revision:
1:93775378e5d9
Parent:
0:78ab42fa3942
Child:
2:14b832fdd69f
--- a/main.cpp	Sun Mar 08 07:30:33 2020 +0000
+++ b/main.cpp	Thu Aug 27 08:14:30 2020 +0000
@@ -1,124 +1,180 @@
-//モタコンとモニタ間通信を想定したテストプログラム      //モタコンID: 0x10 MPPTID: 0x20 BMSID: 0x30 とする //モニタIDは 0x10 0x20 0x30を通信相手に合わせて変更する 
-//Ver.1 2019/12/20 Kikkawa
+//20200807モニタリングシステム kikkawa
+//CAN,  dekaLCD, 4*20LCD
+#include "stdio.h"
 #include "mbed.h"
-#define time1 0.5
- 
+#include "SB1602E.h"    //デカ文字LCD
+#include "TextLCD.h"    //4*20LCD
+#include "MSCFileSystem.h"  //USBメモリ
+#include <string>
+
+TextLCD lcd1(p15, p16, p17, p18, p19, p20);  // RS, E, DB4, DB5, DB6, DB7  //4*20LCDのピン設定
+SB1602E lcd2( p28, p27 );  //  SDA, SCL  //デカ文字LCDのピン設定
+Serial pc(USBTX, USBRX); // USBシリアルポートのインスタンス
+
 Ticker ticker;  //タイマ割り込み設定
 DigitalOut led1(LED1);
 DigitalOut led2(LED2);
-CAN canSlave(p9, p10);  //slave //CANはマスターとスレーブという関係ではないが動作を分かりやすくするためSlaveとする
-CAN canMaster(p30, p29); //master   //CANはマスターとスレーブという関係ではないが動作を分かりやすくするためmasterとする
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+CAN can1(p30, p29); //CANのピン設定
 
-float Vmotor = 0.0;       //モタコンから送られてきた電圧データを入れる変数
-float Cmotor = 0.0;       //モタコンから送られてきた電流データを入れる変数
+//printf用
+char cnt_printf = 0;
+Timer timer1;   //いろんなprintf表示用のタイマー
+Timer timer2;   //処理時確認用タイマー
+/*テレメトリシステム(XBee)の設定*/
+Serial xbee(p13,p14);   //XBeeとシリアル通信するピンの設定
+/*LCDの設定*/
+void LCD_write(void);   //USBへデータを書き込む関数
+float Vmotor = 0.0, Cmotor = 0.0, Pmotor = 0.0;       //モタコンからの電圧、電流、電力を代入する変数
 float speed = 0.0;        //モタコンから送られてきた速度データを入れる変数
-float dutylatio = 0;    //モタコンから送られてきたアクセル開度データを入れる変数
-float dutylatio_ = 0;
-float Vsolar = 0.0;       //MPPTから送られてきた電圧データを入れる変数
-float Csolar = 0.0;       //MPPTから送られてきた電流データを入れる変数
-float Vbatt = 0.0;       //BMSから送られてきた電圧データを入れる変数
-float Cbatt = 0.0;       //BMSから送られてきた電流データを入れる変数
-
-bool CANrecieveOK = 0;  //CAN受信完了時,セットする(mainでのprintfのため)
+signed char dutylatio = 0;        //モタコンから送られてきたアクセル開度データを入れる変数
+float Vsolar = 0.0, Csolar = 0.0, Psolar = 0.0;       //MPPTからの電圧、電流、電力を代入する変数
+float Vbatt = 0.0, Vbatt_max = 0.0, Vbatt_avg = 0.0, Vbatt_min = 0.0, Cbatt = 0.0;   //BMSからの電圧、電流を入れる変数
+float Pbatt = 0.0;
+/*CANの設定*/
+bool CANrecieveOK = 0;  //CAN受信完了時,セットする(mainでのprintfのため入れているが、無くても問題ない)
+CANMessage msgCAN;         //CANで受信したデータがmsgCANに入る
+/*USBメモリの設定*/
+MSCFileSystem msc("usb"); // Mount flash drive under the name "msc"
+void MSC_init(void);   //USBの初期設定関数
+void write_MSC(void);   //USBへデータを書き込む関数
+FILE *fp;  
+FILE *fp1;  
+char running = 0;   //running==1(走行中)のとき、USBメモリにデータを保存する
+short fileNumber;  //既存データが消えないように。保存ファイルを任意に切り替えられるように
+int r = 5;
+char nunu[5] = {0,0,0,0,0};
+char cary[30] = {};
+bool usbCheck = 0;  //USBメモリが接続されているかいないか判定する変数 
+bool USBcheck = 0;
 
-CANMessage msgMaster;         //CAN受信用
-unsigned int  canMasterID = 0x10;   //canMasterの初期IDを0x10に設定        //通信相手によって変更する必要あり モタコンID: 0x10 MPPTID: 0x20 BMSID: 0x30
-unsigned int  canSlaveID = 0x10;   //canMasterの初期IDを0x10に設定         //通信相手によって変更する必要あり モタコンID: 0x10 MPPTID: 0x20 BMSID: 0x30
-char CAN_ID = 0;    //0で0x10, 1で0x20, 2で0x30
-bool canReading = 0;
-
-void Handler_canMasterSend() {//canSlaveに送信要求を送る関数
-    if( !canReading ){  //canReadingが0のとき(受信待ちをしていないとき)
-        switch( CAN_ID ){
-            case 0:
-                msgMaster.id = 0x10;     //モタコンを選択
-                printf("CAN Request to PCU\n\r");
-                break;
-            case 1:
-                msgMaster.id = 0x20;     //MPPTを選択
-                printf("CAN Request to MPPT\n\r");
-                break;
-            case 2:
-                msgMaster.id = 0x30;     //BMSを選択
-                printf("CAN Request to BMS\n\r");
-                break;
+void MSC_init(){    //USBメモリの初期設定関数
+    pc.printf("\n\r" );
+    pc.printf("USBstart\n\r" );
+    fp = fopen( "/usb/fileNumber.txt", "r" );     //ファイル名を変更するための番号txtファイルを読み込む
+    if( fp == NULL ){   //error( "Could not open main0\n\r" ); //error()の関数を使うと動作止まるので使わない。。
+        pc.printf("USB init error\n\r" );
+        //LCDにUSB:×を表示させる処理
+        lcd1.locate(15, 3);  //4*20LCDの4行目に表示 //lcd1.locate(横方向, 縦方向)
+        lcd1.printf("USB:x");
+    }
+    else {  //usbhost_lpc17xx.cppでの処理につながる
+        usbCheck = 1;
+        //LCDにUSB:×を表示させる処理
+        lcd1.locate(15, 3);  //4*20LCDの4行目に表示 //lcd1.locate(横方向, 縦方向)
+        lcd1.printf("USB:o");
+        //USBに保存してるファイル番号管理txtから数字を読み取る
+        fscanf( fp, "%d",&fileNumber );
+        fclose(fp);
+        pc.printf("fileNumber: %d\n\r",fileNumber );
+        fp = fopen( "/usb/fileNumber.txt", "w" );    //ファイルを開く  //exit(1);でプログラムを終了できる(BlueLightsOfDeath)
+        ++fileNumber;   //flieNumber.txtで読み取った番号に+1して、ファイル名が被らないようにする(上書きされないように)
+        sprintf(nunu, "%5d", fileNumber);     //文字列(string)「nunu 」に数値(char)「fileNumber 」を入れる //"%5d"みたいに5(数値)を入れると5桁分確保できる   //charをstringに変換する
+        pc.printf( "FileNumber==> %s\n\r", nunu ); //
+        fprintf( fp,"%d\n", fileNumber );       //変えた番号をfileNumber.txtに書き込み
+        fclose(fp);
+        std::string str_1 = "/usb/Monitor";     //char* c_str = filename.c_str();
+        str_1 += nunu[0]; str_1 += nunu[1]; str_1 += nunu[2]; str_1 += nunu[3]; str_1 += nunu[4];
+        str_1 += ".csv";
+        str_1.copy( cary, 30 );
+        pc.printf( "USB==> %s\n\r", cary );
+        fp1 = fopen( cary, "w" );   //データログ用のファイルを開く
+        if(fp1 == NULL){;}   
+        fprintf( fp1,"Speed(km/h),dutyCycle,Vmotor(V),Cmotor(A),Pmotor(W),Vsolar(V),Csolar(A),Psolar(W),Vbatt(V),Cbatt(A),Pbatt(W),Vbatt_max(V),Vbatt_avg(V),Vbatt_min(V)\n" ); //ファイル書き込み
+        fclose(fp1);                 //ファイルを閉じる  
+    }
+}     
+void Handler_can1Recieve(){
+    if( can1.read( msgCAN ) ){   //msgCANに送られたデータが入る    
+        if( msgCAN.id == 0x10 ){ //送られてきたデータのIDが0x10であればデータ処理する  モタコンID: 0x10  
+            Vmotor = ( (float)( (msgCAN.data[0]*100) + msgCAN.data[1]) ) / 10; //15 43を1500 43にして足すと「1543」となり、÷10すると154.3 [V]
+            Cmotor = ( (float)( ((signed char)msgCAN.data[2]*100) + (signed char)msgCAN.data[3] ) ) / 100;  //5 54を500 54にして足すと5「554」となり、÷100すると5.54 [A]
+            Pmotor = Vmotor * Cmotor;
+            speed = ( (float)( (msgCAN.data[4]*100) + msgCAN.data[5]) ) / 10;      //「856」を85.6[km/h]にするため,÷10する
+            dutylatio = (signed char)msgCAN.data[6];                            //アクセル開度は0~100表示のため,そのまま
         }
-        msgMaster.data[0] = 255;    //適当に255としておく  
-//        canMaster.reset();
-        if(canMaster.write(msgMaster)){    //送信
-            canReading = 1;
-            CAN_ID++;
-            if( CAN_ID >= 3 ){  //3台での通信の場合,CAN_IDが3を超えたらカウンタをリセットする
-                CAN_ID = 0; 
-            }
-            led1 = !led1;
+        else if( msgCAN.id == 0x20 ){    //送られてきたデータのIDが0x20であればデータ処理する    MPPTID: 0x20
+            Vsolar = ( (float)( (msgCAN.data[0]*100) + msgCAN.data[1]) ) / 10; 
+            Csolar = ( (float)( (signed int)((signed char)msgCAN.data[2]*100) + (signed char)msgCAN.data[3] ) ) / 100;   
+            Psolar = Vsolar * Csolar;
         }
-    }
-    else if( canReading ){   //canReadingが1のとき(受信待ちをしているのに送信要求をした場合)
-        switch( CAN_ID ){
-            case 0:     //0x30と通信できなかったときここの処理
-                printf("BMS Error\n\n\r");
-                break;
-            case 1:     //0x10が通信できなかったときここの処理
-                printf("PCU Error\n\n\r");  //PCU = モータコントローラ
-                break;
-            case 2:     //0x20が通信できなかったときここの処理
-                printf("MPPT Error 0x20\n\n\r");
-                break;
-        }
-        canReading = 0;
-    }   
-}
-void Handler_canMasterRecieve(){
-    if( canMaster.read( msgMaster ) ){   //msgに送られたデータが入る    //IDがcanMasterIDと一致していればデータ処理する   
-        if( msgMaster.id == 0x10 ){
-            Vmotor = ( (float)( (msgMaster.data[0]*100) + msgMaster.data[1] ) ) / 10;     //「1543」を154.3[V]にするため,÷10する
-            Cmotor = ( (float)( (msgMaster.data[2]*100) + msgMaster.data[3] ) ) / 100;      //「554」を5.54[A]にするため,÷100する
-            speed = ( (float)( (msgMaster.data[4]*100) + msgMaster.data[5] ) ) / 10;      //「856」を85.6[km/h]にするため,÷10する
-            dutylatio = msgMaster.data[6];                            //アクセル開度は0~100表示のため,そのまま
-            dutylatio_ = msgMaster.data[7];                            //アクセル開度は0~100表示のため,そのまま
-        }
-        else if( msgMaster.id == 0x20 ){
-            Vsolar = ( (float)( (msgMaster.data[0]*100) + msgMaster.data[1] ) ) / 10;     //「1543」を154.3[V]にするため,÷10する
-            Csolar = ( (float)( (msgMaster.data[2]*100) + msgMaster.data[3] ) ) / 100;      //「554」を5.54[A]にするため,÷100する
-        }
-        else if( msgMaster.id == 0x30 ){
-            Vbatt = ( (float)( (msgMaster.data[0]*100) + msgMaster.data[1] ) ) / 10;     //「1543」を154.3[V]にするため,÷10する
-            Cbatt = ( (float)( (msgMaster.data[2]*100) + msgMaster.data[3] ) ) / 100;      //「554」を5.54[A]にするため,÷100する
+        else if( msgCAN.id == 0x30 ){    //送られてきたデータのIDが0x10であればデータ処理する   BMSID: 0x30
+            Vbatt = ( (float)( (msgCAN.data[0]*100) + msgCAN.data[1]) ) / 10;     
+            Cbatt = ( (float)( (signed int)((signed char)msgCAN.data[2]*100) + (signed char)msgCAN.data[3] ) ) / 100;
+            Pbatt = Vbatt * Cbatt;
+            Vbatt_min = ( (float)( (msgCAN.data[4]*100) + msgCAN.data[5] ) ) / 100;      
+            Vbatt_max = ( (float)( (msgCAN.data[6]*100) + msgCAN.data[7] ) ) / 100;    
+            Vbatt_avg = Vbatt / 27; //バッテリ電圧をセルの直列数(20200807現在、27直列)で割って平均電圧を算出する
         }
         led2 = !led2;
         CANrecieveOK = 1;
-        canReading = 0; //受信完了したため,受信待ち状態を解除し,データ送信を行える状態にする
     }
 }
-void Handler_canMasterError(){
-    printf("CAN BUS Error\n\r");
+void LCD_write(){   //LCDにデータを表示させる関数
+    //4行LCDへの表示 //lcd1.locate(横方向, 縦方向)
+    lcd1.locate(0, 0);  //4*20LCDの一番上の行に表示
+    lcd1.printf("%5.3fv %5.3fv %5.3fv", Vbatt_max, Vbatt_avg, Vbatt_min);   //バッテリ セルの最大電圧平均電圧最小電圧を表示
+    lcd1.locate(0, 1);  //4*20LCDの2行目に表示
+    lcd1.printf("B:%5.1fv%5.1fA%5.0fw", Vbatt, Cbatt, Pbatt);     //-10.0Aとかでも表示の桁が変わらないように%5.1fにしている
+    lcd1.locate(0, 2);  //4*20LCDの3行目に表示
+    lcd1.printf("M:%5.1fA", Cmotor);
+    lcd1.locate(0, 3);  //4*20LCDの4行目に表示
+    lcd1.printf("S:%5.1fA", Csolar);
+    //デカ文字LCDへの表示
+    lcd2.printf( 0, "%5.1fkm/h %5.1fv\r", speed, Vmotor );    //  速度、IPM入力電圧(システム電圧)の表示
+    lcd2.printf( 1, "%5.0fw %4.0fw %3d\r", Pmotor, Psolar, dutylatio );  //消費電力、発電電力、バッテリ電圧の表示
+}
+void Handler_can1Error(){   //CANバスエラーが発生した際に実行する関数
+//    lcd1.locate(0, 3);  //4*20LCDの一番下の行の左端にエラーと表示する
+//    lcd1.printf("CAN_Error\n\r");
 }
 int main() {
-    printf("main()\n\r");
-    ticker.attach(&Handler_canMasterSend, time1);    //#defineで「time1」の値を指定  //「time1」秒ごとに設定した関数に飛ぶ
-    canMaster.attach(&Handler_canMasterRecieve, CAN::RxIrq);   //CAN受信割り込みの設定
-    canMaster.attach(&Handler_canMasterError, CAN::BeIrq );   //バスエラー時の割り込み設定
+    timer1.start(); //printf用タイマースタート
+    timer2.start(); //printf用タイマースタート
+    pc.baud(115200);  //9600bpsで150ms 115200bpsで13msくらい処理速度が違う(処理時間は送るデータ量にもよる)
+    xbee.baud(115200);
+    xbee.printf("XBee => OK\n\r");
+    can1.attach(&Handler_can1Recieve, CAN::RxIrq);   //CAN受信割り込みの設定
+    can1.attach(&Handler_can1Error, CAN::BeIrq );   //バスエラー時の割り込み設定
+    MSC_init(); //USBメモリ初期化
     
     while(1) {
-        if( CANrecieveOK ) {
-            CANrecieveOK = 0;     
-/*            printf("Data in msgMaster.data[0] : %d\n\r", msgMaster.data[0]);    //CANで送られてきたデータをそのまま表示
-            printf("Data in msgMaster.data[1] : %d\n\r", msgMaster.data[1]);    //上に同じ
-            printf("Data in msgMaster.data[2] : %d\n\r", msgMaster.data[2]);    //上に同じ
-            printf("Data in msgMaster.data[3] : %d\n\r", msgMaster.data[3]);    //上に同じ
-            printf("Data in msgMaster.data[4] : %d\n\r", msgMaster.data[4]);    //上に同じ
-            printf("Data in msgMaster.data[5] : %d\n\r", msgMaster.data[5]);    //上に同じ
-            printf("Data in msgMaster.data[6] : %d\n\r", msgMaster.data[6]);    //上に同じ
-*/          printf("Vmotor : %f\n\r", Vmotor);  //送られてきたデータから算出した電圧値を表示
-            printf("Cmotor : %f\n\r", Cmotor);  //送られてきたデータから算出した電流値を表示
-            printf("speed : %f\n\r", speed);    //送られてきたデータから算出した時速を表示
-            printf("dutylatio : %f\n\r", dutylatio);//送られてきたデータから算出したアクセル開度を表示
-            printf("dutylatio : %f\n\r", dutylatio_);//送られてきたデータから算出したアクセル開度を表示
-            printf("Vsolar : %f\n\r", Vsolar);  //送られてきたデータから算出した電圧値を表示
-            printf("Csolar : %f\n\r", Csolar);  //送られてきたデータから算出した電流値を表示
-            printf("\n\r");
-        } 
-        wait(0.1);
+        //PCへのシリアル通信処理(teratermなどへ表示)
+        if( timer1.read_ms() >= 50 && !cnt_printf ){  //0.1秒ごとにprintf処理をする
+            //xbee.printf("  timer1: %d  timer2: %d", timer1.read_ms(), timer2.read_ms());
+            xbee.printf("timer1: %d", timer1.read_ms() );
+            //printf("SPD:%5.1f DC:%3d Vmot:%5.1f Cmot:%6.2f Pmot:%6.1f Vsol:%5.1f Csol:%6.2f Psol:%5.1f Vbat:%5.1f Cbat:%6.2f Pbat:%6.1f Vmax:%5.3f Vavg:%5.3f Vmin:%5.3f\n\r", speed, dutylatio, Vmotor, Cmotor, Pmotor, Vsolar, Csolar, Psolar, Vbatt, Cbatt, Pbatt, Vbatt_max, Vbatt_avg, Vbatt_min );        
+            pc.printf("%5.1f km/h  Duty:%3d  Motor:%5.1f(V),%6.2f(A),%6.1f(W)   solar:%5.1f(V),%6.2f(A),%5.1f(W)", speed, dutylatio, Vmotor, Cmotor, Pmotor, Vsolar, Csolar, Psolar );
+            pc.printf("  bat:%5.1f(V),%6.2f(A),%6.1f(W),max:%5.3f,avg:%5.3f,min:%5.3f\n\r", Vbatt, Cbatt, Pbatt, Vbatt_max, Vbatt_avg, Vbatt_min );        
+            xbee.printf("  timer1: %d", timer1.read_ms() );
+            //xbee.printf("  timer1: %d  timer2: %d\n\r", timer1.read_ms(), timer2.read_ms());
+            //LCDへの書き込み処理
+            LCD_write();
+            cnt_printf = 1;
+        }
+        if( timer1.read_ms() >= 100 && cnt_printf ){  //0.1秒ごとにprintf処理をする
+            xbee.printf("  timer1: %d", timer1.read_ms() );
+            //USBが刺さっているかいないか確認し、データを書き込む処理
+            if( usbCheck ){ //初期設定時(プログラムスタート時)、USBが刺さっていればusbCheck==1(true)
+                fp1 = fopen( cary, "a");    //ファイルを開く, aは上書きの命令(ファイルが存在しなければ新規作成する)
+                if ( fp1 == NULL ){  //ファイルを開けなかった場合
+                    usbCheck = 0;   //USBが刺さってない(USBが抜けた)と判定する
+                    lcd1.locate(15, 3);  //4*20LCDの4行目に表示 //lcd1.locate(横方向, 縦方向)
+                    lcd1.printf("USB:x"); //LCDに、USBは未接続(X)と表示する
+                }
+                else {  //開けたらする処理
+                    //メモリへの書き込み
+                    fprintf( fp1,"%5.1f,%3d,%5.1f,%5.1f,%6.1f,%5.1f,%5.1f,%6.1f,%5.1f,%5.1f,%6.1f,%5.3f,%5.3f,%5.3f\n", speed, dutylatio, Vmotor, Cmotor, Pmotor, Vsolar, Csolar, Psolar, Vbatt, Cbatt, Pbatt, Vbatt_max, Vbatt_avg, Vbatt_min );   
+                    fclose(fp1);         //ファイルを閉じる  
+                }
+            }
+            xbee.printf("  timer1: %d\n\r", timer1.read_ms() );
+            cnt_printf = 0;
+            timer1.reset();
+        }
+        /*if( !running ){ data file change }
+        else if( running ){ write_MSC();    //USBメモリへ書き込む関数}*/
+        //CANrecieveOK = 0;  
     }
 }
\ No newline at end of file