20210420_monitor

Dependencies:   mbed SB1602E TextLCD MSCFILESytem FatFileSystemCpp

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 
00002 //20210722モニタリングシステム kikkawa //積算発電積算消費
00003 
00004 #include "mbed.h"                       // 必須
00005 #include "stdio.h"                      // ファイル操作
00006 #include "SB1602E.h"                    // デカ文字LCD
00007 #include "TextLCD.h"                    // 4*20LCD
00008 #include "MSCFileSystem.h"              // USBメモリ
00009 #include <string>                       // 文字列操作
00010 
00011 /* タイマの設定 */
00012 Timer tm1;                              // タイマー時間の初期化(処理時間計測に使用)   
00013 Timer time0t5s;                         // main関数での処理に使用
00014 Timer time0t2s;                         // main関数での処理に使用
00015                
00016 //Ticker tick;                          // 繰り返しタイマ割り込みの初期化
00017 TextLCD lcd1(p15,p16,p17,p18,p19,p20);  // 4行LCDのポート設定(RS,E,DB4,DB5,DB6,DB7)
00018 SB1602E lcd2(p28,p27);                  // デカ文字LCDのポート設定(SDA,SCL)
00019 Serial pc(USBTX,USBRX);                 // USBシリアルポートの設定
00020 Serial im920(p13, p14);                 // p13(tx),p14(rx)をIM920とのシリアル通信ポートに設定
00021 CAN can(p30, p29);                      // CANのポート設定
00022 
00023 DigitalOut led1(LED1);                  // LPC1768ボード上1番目のLEDの設定
00024 DigitalOut led2(LED2);                  // LPC1768ボード上2番目のLEDの設定
00025 DigitalOut led3(LED3);                  // LPC1768ボード上3番目のLEDの設定
00026 DigitalOut led4(LED4);                  // LPC1768ボード上4番目のLEDの設定
00027 
00028 /* 変数の宣言 */
00029 bool LED = 1;                           // 1のときLPC1768ボード上のLED(1~4)の点灯・点滅処理を実行. 0のとき点灯・点滅させない
00030 int MPPTerror=0;                        // MPPT1のエラー信号を格納する変数
00031 int MPPTerror_2=0;                      // MPPT2のエラー信号を格納する変数
00032 int direc=0;                            // 進行方向(direction)を格納する変数
00033 float Vmot=0, Cmot=0, Pmot=0;           // 消費電圧、電流、電力を格納する変数
00034 float Vsol=0, Csol=0, Psol=0;           // 発電電圧・電流・電力を格納する変数
00035 float Vbat=0,  Cbat=0, Pbat=0;          // バッテリ電圧・電流・電力を格納する変数
00036 float VcelMax=0,VcelAve=0,VcelMin=0;    // セル最大・平均・最小電圧を格納する変数
00037 float speed=0;                          // 走行速度を格納する変数
00038 signed char duty=0;                     // スロットル開度を格納する変数
00039 
00040 int cntTera = 0;
00041 
00042 /* ユーザ定義関数の宣言 */
00043 void init(void);                        // 初期化を行う関数を宣言
00044 void printTera(void);                   // Teraterm表示を行う関数を宣言
00045 
00046 //灯火類の設定
00047 /*
00048 DigitalIn indiR_IN(p15);            // 方向指示器(右)の入力の設定
00049 DigitalIn indiL_IN(p14);            // 方向指示器(左)の入力の設定
00050 DigitalIn head_IN(p13);            // ヘッドライトの入力の設定
00051 DigitalIn horn_IN(p12);            // ホーンの入力の設定
00052 DigitalIn brake_IN(p11);            // ブレーキランプの入力の設定
00053 
00054 PwmOut indiR_OUT(p20);              // 方向指示器(右)の出力の設定
00055 PwmOut indiL_OUT(p19);               // 方向指示器(左)の出力の設定
00056 PwmOut headt_OUT(p18);                   // ヘッドライトの出力の設定
00057 DigitalOut horn_OUT(p17);               // ホーンの出力の設定
00058 DigitalOut brake_OUT(p16);              // ブレーキランプの出力の設定
00059 */
00060 /* IM920(テレメトリ)の設定 */
00061 int cntIM920 = 0;
00062 void printIM920(void);                  // PC(teraterm), IM920(テレメトリシステム), LCDへのprintf処理を行う関数 
00063 
00064 /* LCDの設定 */
00065 int cntLCD=0;
00066 void printLCD(void);                    // LCDにデータ表示する関数
00067 
00068 /* CAN通信の設定 */
00069 char cntCAN = 0;                        // CAN受信でカウントアップする変数
00070 CANMessage bufCAN;             // CAN受信用バッファの初期化(バッファ(buf): データを一時的に格納するためのメモリー領域)
00071 //void readCAN(void);
00072 
00073 /* USBメモリ(MSC:マスストレージクラス)の設定 */
00074 MSCFileSystem msc("usb");       // Mount flash drive under the name "usb"
00075 char *str1 = "/usb/log";        // 保存先("usb")とファイル名の一部(log)を指定
00076 char *str2 = ".csv";            // ファイルの拡張子を指定
00077 char fileName[30];              // ファイル名を格納する配列
00078 char oxMSC;                     // 接続有無("o"か"x")を格納する変数(1文字用)
00079 int cntMSC=0;                   // 処理を行うごとにカウントアップする変数
00080 void initMSC(void);             // MSC(USB Mass Storage Class)の初期設定関数
00081 void saveMSC(void);             // MSCへデータを書き込む関数
00082 FILE *fp2;                      // ファイル構造体の定義
00083 
00084 void initMSC(){                                     // USBメモリの初期設定関数
00085     FILE *fp1;                                      // ファイル構造体を定義
00086     int fileNumber = 0;                             // csvファイル命名に使用する変数を宣言
00087     
00088     fp1 = fopen( "/usb/fileNumber.txt", "r" );      // USBメモリ内の"fileNumber.txt"を読み取りモードで開く
00089     if( fp1 == NULL ){                              // アクセスできなかったとき, ...error( "Could not open main0\n\r" );を入れても良い
00090         pc.printf("USB init error\n\r" );           // teratermに"USB ini error"を表示
00091         oxMSC = 'x';                                // MSCが接続されていないため"x"を格納(1文字なのでシングルクォーテーション)
00092     }
00093     else {                                          // アクセスできたとき ...sbhost_lpc17xx.cppでの処理につながる
00094         oxMSC = 'o';                                // 1文字だからシングルクォーテーションで囲む
00095         fscanf( fp1,"%d",&fileNumber );             // "fileNumber.txt"の数字を読み取り,変数"fileNumber"に格納する
00096         fclose( fp1 );                              // "fileNumber.txt"を閉じる
00097         
00098         fp1 = fopen( "/usb/fileNumber.txt", "w" );  // "fileNumber.txt"を書き込みモードで開く  //exit(1);でBlueLightsOfDeath
00099         fprintf( fp1,"%d\n", fileNumber+1 );        // 読み込んだ数値に+1してfileNumber.txtに書き込み
00100         fclose(fp1);
00101         
00102         sprintf(fileName,"%s%d%s\n", str1, fileNumber, str2);   // 文字列の結合(データログ用ファイル名の作成)
00103         pc.printf( "\n\rUSB fileName: %s\n\r", fileName );      // 作成したファイル名をteratermに表示
00104         
00105         fp2 = fopen( fileName, "w" );                           // ファイルの新規作成後書き込み, ファイルがある場合上書き
00106         if(fp2 != NULL){                                        // NULLじゃないとき(ファイルを開けた時)
00107             fprintf( fp2,"Speed(km/h),dutyCycle,Vmot(V),Cmot(A),Pmot(W),Vsol(V),Csol(A),Psol(W),Vbat(V),Cbat(A),Pbat(W),VcelMax(V),VcelAve(V),VcelMin(V)\n" ); //ファイル書き込み
00108             fclose(fp2);                                        // csvファイル1行目にデータ項目を入力してファイルを閉じる
00109         }  
00110     }
00111 }
00112 
00113 void saveMSC(){                             // 処理時間50ms以上(MBED Timerで計測,データ量による)
00114     ++cntMSC;                               // MSCカウンタをインクリメント
00115     if( cntMSC >= 255){ cntMSC = 0; }       // 255になったらリセット
00116     if( oxMSC == 'o' ){
00117         fp2 = fopen( fileName, "a");            // ファイルを上書きモードで開く(ファイルがなければ新規作成)
00118         if ( fp2 == NULL ){                     // ファイルを開けなかったとき,
00119             oxMSC = 'x';                        // MSCが接続されていないため"x"を格納(1文字なのでシングルクォーテーション)
00120         }else {                                 // USBメモリ内のファイルを開くことができたとき,
00121             fprintf( fp2,"%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",
00122                             speed, duty, Vmot, Cmot, Pmot, Vsol, Csol, Psol, Vbat, Cbat, Pbat, VcelMax, VcelAve, VcelMin ); 
00123             fclose(fp2);                                    // データを書き込んだ後,ファイルを閉じる
00124             pc.printf("MSC: %d\n", cntMSC);     //   
00125         }
00126     }
00127 }
00128 
00129 void readCAN(){                 // CANデータを受信したときに実行される関数(特定ID選択:https://os.mbed.com/questions/74230/about-ID-selectable-CAN-receive/, filter関数でも)
00130      ++cntCAN;                          // CANカウンタをインクリメント
00131     if( cntCAN >= 255 ){ cntCAN = 0; }    // 255を超えたらリセット
00132     
00133     if( can.read(bufCAN) ){                         // モタコンからデータが来たとき,    
00134         if( bufCAN.id == 0x20 ){                    // MPPTからデータがきたとき,
00135             if( LED ){ led2 = !led2; }              // led2を点滅させる処理. !はNOTの意味
00136             Vsol = ( (float)( (bufCAN.data[0]*100) + bufCAN.data[1]) ) / 10;            
00137             Csol = ( (float)( (signed int)((signed char)bufCAN.data[2]*100) + (signed char)bufCAN.data[3] ) + ((signed char)bufCAN.data[6]*100) + (signed char)bufCAN.data[7] ) / 100;   
00138             MPPTerror = bufCAN.data[4];
00139             MPPTerror_2 = bufCAN.data[5];
00140             Psol = Vsol * Csol;
00141         }
00142         else if( bufCAN.id == 0x10 ){
00143             if( LED ){ led1 = !led1; }              // led1を点滅させる(!はNOT)
00144             Vmot = ( (float)( (bufCAN.data[0]*100) + bufCAN.data[1]) ) / 10;        // 15 43を1500 43にして足すと「1543」となり、÷10すると154.3 [V]
00145             Cmot = ( (float)( ((signed char)bufCAN.data[2]*100) + (signed char)bufCAN.data[3] ) ) / 100; 
00146                                                                                     // 5 54を500 54にして足すと5「554」となり、÷100すると5.54 [A]
00147             Pmot = Vmot * Cmot;
00148             speed = ( (float)( (bufCAN.data[4]*100) + bufCAN.data[5]) ) / 10;       //「856」を85.6[km/h]にするため,÷10する
00149             duty = (signed char)bufCAN.data[6];     // アクセル開度は0~100表示のため,そのまま
00150             direc = (int)bufCAN.data[7];
00151         }
00152 
00153         else if( bufCAN.id == 0x30 ){                    // BMSからデータが来たとき,
00154             if( LED ){ led3 = !led3; }              // led3を点滅させる処理. !はNOTの意味
00155             Vbat = ( (float)( (bufCAN.data[0]*100) + bufCAN.data[1]) ) / 10;     
00156             Cbat = ( (float)( (signed int)((signed char)bufCAN.data[2]*100) + (signed char)bufCAN.data[3] ) ) / 100;
00157             Pbat = Vbat * Cbat;
00158             VcelMin = ( (float)( (bufCAN.data[4]*100) + bufCAN.data[5] ) ) / 100;      
00159             VcelMax = ( (float)( (bufCAN.data[6]*100) + bufCAN.data[7] ) ) / 100;    
00160             VcelAve = Vbat / 27;                    // バッテリ電圧をセルの直列数(20200807現在、27直列)で割って平均電圧を算出する
00161         }
00162     
00163     }
00164 }
00165 void printLCD(){                                                    // LCDにデータを表示する関数
00166      ++cntLCD;                                    // IM920カウンタをインクリメント
00167     if( cntLCD >= 255){ cntLCD = 0; }            // 255以上でリセット
00168     
00169     lcd1.locate(0, 0);                                              // 4行LCDの1行目1番目に表示位置を指定し,
00170     lcd1.printf("%5.3fv %5.3fv %5.3fv", VcelMax, VcelAve, VcelMin); // バッテリセルの最大・平均・最小の電圧を表示
00171     lcd1.locate(0, 1);                                              // 4行LCDの2行目1番目に表示位置を指定し,
00172     lcd1.printf("B:%5.1fv%5.1fA%5.0fw", Vbat, Cbat, Pbat);          // バッテリ電圧・電流・電力を表示
00173     lcd1.locate(0, 2);                                              // 4行LCDの3行目1番目に表示位置を指定し,
00174     lcd1.printf("M:%5.1fv%5.1fA  d:%d", Vmot, Cmot, direc);         // モータ電圧・電流, 進行方向を表示
00175     lcd1.locate(0, 3);                                              // 4行LCDの4行目1番目に表示位置を指定し,                           
00176     if( MPPTerror || MPPTerror_2 ){                                 // MPPTからエラー信号を受け取っていたとき,
00177         if( MPPTerror ){                                            // MPPT1がエラーなら
00178             lcd1.printf("S:X%2.1fv%5.1fA", Vsol, Csol);             // 先頭に"X"を入れて発電電圧・電流を表示
00179         }else{                                                      // MPPT2がエラーなら
00180             lcd1.printf("S:XX%1.1fv%5.1fA", Vsol, Csol);            // 先頭に"XX"を入れて発電電圧・電流を表示
00181         }
00182     }else{                                                          // MPPTからエラー信号を受け取っていないとき
00183         lcd1.printf("S:%5.1fv%5.1fA", Vsol, Csol);                  // 発電電力・電流を表示
00184     }
00185     lcd1.locate(15, 3);                                             // 4行LCDの4行目16番目に表示位置を指定し,
00186     lcd1.printf("USB:%c", oxMSC);                                   // USBの接続状態を表示("o"か"x") 
00187     lcd2.printf( 0, "%5.1fkm/h %5.1fv\r", speed, Vmot );            // デカ文字LCDの1行目1番目に表示(速度,システム電圧)
00188     lcd2.printf( 1, "%5.0fw %4.0fw %3d\r", Pmot, Psol, duty );      // デカ文字LCDの1行目2番目に表示(消費電力,発電電力,スロットル開度)
00189     pc.printf("LCD:%d\n",cntLCD);                  // 無線送信処理を行ったことをPC(teraterm)へ知らせる
00190 }
00191 
00192 void printIM920(){                                  // 処理時間16ms~(MBED Timerで計測)
00193      ++cntIM920;                                    // IM920カウンタをインクリメント
00194     if( cntIM920 >= 255 ){ cntIM920 = 0; }            // 255以上でリセット
00195     im920.printf("TXDA%.1f,%.3f,%.3f,%.3f,%.1f,%.1f,%.1f,%.1f,%d,%d\r",
00196         Vmot, VcelMax, VcelAve, VcelMin, Cbat, Cmot, Csol, speed, duty, cntIM920);  
00197                                                     // TXDAに続く文字が無線送信される. データ間を","で区切る. 最後に"\r"必須
00198     pc.printf("IM920:%d\n",cntIM920);                  // 無線送信処理を行ったことをPC(teraterm)へ知らせる
00199 }
00200 
00201 void printTera(){
00202     ++cntTera;                                    // Teratermカウンタをインクリメント
00203     if( cntTera >= 255){ cntTera = 0; }           // 255以上でリセット
00204     //pc.printf("Tera:%d\n",cntTera);                  // 無線送信処理を行ったことをPC(teraterm)へ知らせる
00205     pc.printf("SP:%.1f DT:%d Vm:%.1f Im:%.2f Pm:%.1f Vs:%.1f Is: %.2f Ps:%.1f\n\r", speed, duty, Vmot, Cmot, Pmot, Vsol, Csol, Psol );
00206     pc.printf("Vb:%.1f Cb:%.2f Pb:%.1f max:%.3f avg:%.3f min:%.3f\n\r", Vbat, Cbat, Pbat, VcelMax, VcelAve, VcelMin );  
00207 }
00208 
00209 void init(){                        // 初期化(初期設定)を行う関数
00210     pc.baud(115200);                // pcとのシリアル通信ボーレートを115200bpsに設定(数字が大きい方が通信速度高い)
00211     pc.printf("main() start\n");
00212     wait(3);                        // MBED電源投入から安定するまで3秒待つ(待たないと電源再投入後にUSBメモリの初期化・ファイル作成ができない)
00213     im920.baud(19200);              // IM920とのシリアル通信ボーレートを19200bpsに設定(19200はIM920の初期値)
00214     initMSC();                      // USBマスストレージクラス(USBメモリ)を初期化する関数を実行
00215 }
00216     
00217 int main() {
00218     init();                                 // 初期化関数を実行
00219 
00220     MPPTerror_2 = 0;
00221     Vmot=0;
00222     Cmot=0;
00223     Pbat=0;
00224     
00225     tm1.start();
00226     time0t5s.start();                       //https://os.mbed.com/media/uploads/yueee_yt/text_h24csee.pdf(p.21)
00227     time0t2s.start();                       //https://os.mbed.com/media/uploads/yueee_yt/text_h24csee.pdf(p.21)
00228     
00229     can.attach(&readCAN, CAN::RxIrq);     //CAN受信割り込みの設定
00230     while(1) {
00231         //readLights();
00232         if( time0t5s.read() < 0.5 ){
00233             //readCAN();                          // CANデータを読み込む関数を実行
00234             if( time0t2s.read() >= 0.2 ){  
00235                 time0t2s.reset();           // time0t2sをリスタートさせる
00236                 printLCD();               // LCDの表示を更新する関数を実行
00237                 printTera();                // Teratermに表示する関数を実行
00238             }
00239         }   
00240         if( time0t5s.read() >= 0.5 ){       // 0.5秒毎に実行する処理
00241             time0t5s.reset();               // time0t5sをリスタートさせる
00242             if( LED ){ led4 = !led4; }      // led4を点滅させる(!はNOT)
00243             pc.printf("TheTime: %d(us)\n", tm1.read_us());    // 処理時間確認用プログラム(1/2)
00244             tm1.reset();                                      // 処理時間確認用プログラム(2/2)
00245             saveMSC();                      // MSCにデータを保存する関数を実行
00246             printIM920();                   // IM920に無線送信させる関数を実行
00247         }
00248         
00249     }
00250 }