for CAN test for MonitoringSystem
Dependencies: mbed SB1602E MSCFILESytem FatFileSystemCpp
Diff: main.cpp
- 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