hattori&ide

Dependencies:   mbed

Committer:
hattori_atsushi
Date:
Sun Dec 18 08:16:01 2022 +0000
Revision:
0:f77369cabd75
hattori

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hattori_atsushi 0:f77369cabd75 1 /*更新情報
hattori_atsushi 0:f77369cabd75 2 * 2016/01/20
hattori_atsushi 0:f77369cabd75 3 * LCD表示 現在時刻から経過時間へ変更
hattori_atsushi 0:f77369cabd75 4 * LCD表示 単位記号の位置変更
hattori_atsushi 0:f77369cabd75 5 *
hattori_atsushi 0:f77369cabd75 6 * 2016/01/29
hattori_atsushi 0:f77369cabd75 7 * postアドレス変更 TEST→myLogger
hattori_atsushi 0:f77369cabd75 8 *
hattori_atsushi 0:f77369cabd75 9 * 2016/01/30
hattori_atsushi 0:f77369cabd75 10 * サーバー送信データ変更,末尾にデータ取得時間追加
hattori_atsushi 0:f77369cabd75 11 *
hattori_atsushi 0:f77369cabd75 12 * 2016/02/08
hattori_atsushi 0:f77369cabd75 13 * 配列の要素数をconst定数化
hattori_atsushi 0:f77369cabd75 14 * LapUSBSaveDataのcsvデータがおかしかったので修正
hattori_atsushi 0:f77369cabd75 15 * ラップをラップタイムが3分30秒以内の場合は加算しないように修正
hattori_atsushi 0:f77369cabd75 16 * CalculateSet関数を分割
hattori_atsushi 0:f77369cabd75 17 *
hattori_atsushi 0:f77369cabd75 18 * 2016/02/22
hattori_atsushi 0:f77369cabd75 19 * 初期化ルーチンを関数に分割
hattori_atsushi 0:f77369cabd75 20 * GPS対応
hattori_atsushi 0:f77369cabd75 21 * データバックアップ,引き継ぎ機能追加,ファイル名を日付に変更
hattori_atsushi 0:f77369cabd75 22 *
hattori_atsushi 0:f77369cabd75 23 * 2016/02/24
hattori_atsushi 0:f77369cabd75 24 * エラー処理追加, メンテナンス
hattori_atsushi 0:f77369cabd75 25 *
hattori_atsushi 0:f77369cabd75 26 * 2016/04~
hattori_atsushi 0:f77369cabd75 27 * タイマー処理測定→http送信による遅延を無害化
hattori_atsushi 0:f77369cabd75 28 * 加速度センサデータ保存、モーター回転数から速度算出
hattori_atsushi 0:f77369cabd75 29 *
hattori_atsushi 0:f77369cabd75 30 * 2016/04/24
hattori_atsushi 0:f77369cabd75 31 * ラップスイッチ ピン変化割り込み化
hattori_atsushi 0:f77369cabd75 32 * 配列過剰書き込み 対策済み
hattori_atsushi 0:f77369cabd75 33
hattori_atsushi 0:f77369cabd75 34 * 2016/05/11
hattori_atsushi 0:f77369cabd75 35 * ファイル名変更 日付/各データ(ファイル構造化)
hattori_atsushi 0:f77369cabd75 36 * GPSセンテンス保存 走行ラインGoogle Earth等で閲覧可
hattori_atsushi 0:f77369cabd75 37 *
hattori_atsushi 0:f77369cabd75 38 * 2016/06/01
hattori_atsushi 0:f77369cabd75 39 * スタート前時,積算しないように設定(関数の引数で変更可)
hattori_atsushi 0:f77369cabd75 40 *
hattori_atsushi 0:f77369cabd75 41 * 2016/06/10
hattori_atsushi 0:f77369cabd75 42 * INA226設定レジスタ変更
hattori_atsushi 0:f77369cabd75 43 * wait変更
hattori_atsushi 0:f77369cabd75 44 *
hattori_atsushi 0:f77369cabd75 45 * 2016/06/15
hattori_atsushi 0:f77369cabd75 46 * MITSUBA CANデータ対応 回転数データ取得
hattori_atsushi 0:f77369cabd75 47 *
hattori_atsushi 0:f77369cabd75 48 * 2016/07/03
hattori_atsushi 0:f77369cabd75 49 * INA226 異常データ対策
hattori_atsushi 0:f77369cabd75 50 * 絶縁監視(漏れ電流)エラー出力機能追加
hattori_atsushi 0:f77369cabd75 51 *
hattori_atsushi 0:f77369cabd75 52 * 2016/07/11
hattori_atsushi 0:f77369cabd75 53 * DriverEmergency機能追加
hattori_atsushi 0:f77369cabd75 54 *
hattori_atsushi 0:f77369cabd75 55 * 2016/07/17
hattori_atsushi 0:f77369cabd75 56 * Web送信データ変更 平均→積算
hattori_atsushi 0:f77369cabd75 57 * LAP送信データ追加 コントロールライン通過時刻
hattori_atsushi 0:f77369cabd75 58 *
hattori_atsushi 0:f77369cabd75 59 * 2016/07/25
hattori_atsushi 0:f77369cabd75 60 * Webデータ送信 桁数一部変更
hattori_atsushi 0:f77369cabd75 61 * CalculateSet関数修正
hattori_atsushi 0:f77369cabd75 62 *
hattori_atsushi 0:f77369cabd75 63 * 2016/08/02
hattori_atsushi 0:f77369cabd75 64 * ReadyStartLCD()にGPSがfixしたらGPS OKと表示するようにした
hattori_atsushi 0:f77369cabd75 65 *
hattori_atsushi 0:f77369cabd75 66 * 2017/08/02
hattori_atsushi 0:f77369cabd75 67 * INA226 測定平均回数 16 → 128
hattori_atsushi 0:f77369cabd75 68 * 2017/08/05 12:00:00自動スタート
hattori_atsushi 0:f77369cabd75 69 *
hattori_atsushi 0:f77369cabd75 70 * 2021/07/10
hattori_atsushi 0:f77369cabd75 71 * バッテリー容量を3.6 * 3.35 * 30 * 14から3.6 * 3.45 * 26 * 16 に変更
hattori_atsushi 0:f77369cabd75 72 *
hattori_atsushi 0:f77369cabd75 73 */
hattori_atsushi 0:f77369cabd75 74
hattori_atsushi 0:f77369cabd75 75 #include "mbed.h"
hattori_atsushi 0:f77369cabd75 76 #include "INA226.hpp"
hattori_atsushi 0:f77369cabd75 77 #include "TextOLED.h"
hattori_atsushi 0:f77369cabd75 78 #include "MSCFileSystem.h"
hattori_atsushi 0:f77369cabd75 79 #include "EthernetNetIf.h"
hattori_atsushi 0:f77369cabd75 80 #include "TCPSocket.h"
hattori_atsushi 0:f77369cabd75 81 #include "TinyHTTP.h"
hattori_atsushi 0:f77369cabd75 82 #include "NTPClient.h"
hattori_atsushi 0:f77369cabd75 83 #include "RTC.h"
hattori_atsushi 0:f77369cabd75 84 #include "MBed_Adafruit_GPS.h"
hattori_atsushi 0:f77369cabd75 85 #include "MITSUBA_CAN.h"
hattori_atsushi 0:f77369cabd75 86 //#include "MMA8652.h"
hattori_atsushi 0:f77369cabd75 87
hattori_atsushi 0:f77369cabd75 88 // INA226用I2Cアドレス I2Cアドレスはmbedの場合1ビット左シフトしたアドレスになる
hattori_atsushi 0:f77369cabd75 89 const int batteryMonitorAddress = 0x80; // 0b10000000 (GG)
hattori_atsushi 0:f77369cabd75 90 const int panelMonitorAddress = 0x82; // 0b10000010 (G1)
hattori_atsushi 0:f77369cabd75 91 const int motorMonitorAddress = 0x9E; // 0b10011110 (CC)
hattori_atsushi 0:f77369cabd75 92 const unsigned short configuration = 0x4897; // 平均化処理やタイミング
hattori_atsushi 0:f77369cabd75 93
hattori_atsushi 0:f77369cabd75 94 /*------------------------------設定変更厳禁------------------------------*/
hattori_atsushi 0:f77369cabd75 95 const double voltageCalibration = 10 / 1.1; // 分圧比(10倍に補正)
hattori_atsushi 0:f77369cabd75 96 const unsigned short calibration = 0x1400; // シャント電圧補正係数
hattori_atsushi 0:f77369cabd75 97 const unsigned short calibrationPanel = 0x2800; // シャント電圧補正係数(パネル)
hattori_atsushi 0:f77369cabd75 98 const double currentCalibration[] = {1.5, 0.5, 1.5};
hattori_atsushi 0:f77369cabd75 99 // [0]: バッテリ [1]: パネル [2]: モータ
hattori_atsushi 0:f77369cabd75 100 /*------------------------------設定変更厳禁------------------------------*/
hattori_atsushi 0:f77369cabd75 101
hattori_atsushi 0:f77369cabd75 102 const double batteryCapacity = 3.6 * 3.45 * 26 * 16; // 公称電圧*電流容量*直列数*並列数←2021鈴鹿仕様に変更
hattori_atsushi 0:f77369cabd75 103
hattori_atsushi 0:f77369cabd75 104 const int offsetTime = 60 * 60 * 9; // 9時間(標準時との時差) = 日本時間
hattori_atsushi 0:f77369cabd75 105 const int storageTime = 8; // 8秒ごとにサーバーへ送信 10秒はサイズ的に厳しい
hattori_atsushi 0:f77369cabd75 106 const int storageOffset = 5; // 5秒間分余分に配列を用意しておく
hattori_atsushi 0:f77369cabd75 107 const int lapTime_limit = 60 * 4; // LAPタイム 4分00秒以内はキャンセル
hattori_atsushi 0:f77369cabd75 108 const double kmph = 1.852; // 1ノット = 1.852 km/h
hattori_atsushi 0:f77369cabd75 109 const double pulseConvert = 0.1303; // 車速パルス -> 速度変換係数
hattori_atsushi 0:f77369cabd75 110 const double rpmConvert = 0.104399; // rpm -> km/h 変換係数
hattori_atsushi 0:f77369cabd75 111
hattori_atsushi 0:f77369cabd75 112 /*各配列要素数*/
hattori_atsushi 0:f77369cabd75 113 const int RealtimeData_i = 3;
hattori_atsushi 0:f77369cabd75 114 const int RealtimeData_j = 5;
hattori_atsushi 0:f77369cabd75 115 const int LapoutData_i = 3;
hattori_atsushi 0:f77369cabd75 116 const int LapoutData_j = 3;
hattori_atsushi 0:f77369cabd75 117 const int timeStr_i = 6;
hattori_atsushi 0:f77369cabd75 118 const int preLapdata_i = 3;
hattori_atsushi 0:f77369cabd75 119 const int preLapdata_j = 2;
hattori_atsushi 0:f77369cabd75 120
hattori_atsushi 0:f77369cabd75 121 // バッファーサイズ
hattori_atsushi 0:f77369cabd75 122 const int RequestStr_maxsize = 1210; // 1600とかでは送信できない メモリ破壊?
hattori_atsushi 0:f77369cabd75 123 const int LapRequestStr_maxsize = 110;
hattori_atsushi 0:f77369cabd75 124 const int SerialSendStr_maxsize = 200;
hattori_atsushi 0:f77369cabd75 125 const int timeStr_maxsize = 32;
hattori_atsushi 0:f77369cabd75 126 const int fileName_maxsize = 32;
hattori_atsushi 0:f77369cabd75 127
hattori_atsushi 0:f77369cabd75 128 Serial debug(USBTX, USBRX);
hattori_atsushi 0:f77369cabd75 129 Serial Xbee(p13, p14);
hattori_atsushi 0:f77369cabd75 130 Serial gpsSerial(p28, p27);
hattori_atsushi 0:f77369cabd75 131 Adafruit_GPS myGPS(&gpsSerial);
hattori_atsushi 0:f77369cabd75 132
hattori_atsushi 0:f77369cabd75 133 CAN mitsuba_can(p30, p29);
hattori_atsushi 0:f77369cabd75 134 MITSUBA canlog(mitsuba_can, 250000);
hattori_atsushi 0:f77369cabd75 135 //MMA8652 acc(p9, p10); // sda, scl
hattori_atsushi 0:f77369cabd75 136
hattori_atsushi 0:f77369cabd75 137 DigitalOut sublogger_sec(p24);
hattori_atsushi 0:f77369cabd75 138 DigitalOut sublogger_min(p25);
hattori_atsushi 0:f77369cabd75 139 // 引数は(rs,e,d4,d5,d6,d7) 接続しないピンはGNDに落としておくと安定する
hattori_atsushi 0:f77369cabd75 140 TextOLED lcd(p15, p16, p17, p18, p19, p20, TextOLED::LCD20x4);
hattori_atsushi 0:f77369cabd75 141
hattori_atsushi 0:f77369cabd75 142 I2C i2c(p9, p10); // sda, scl
hattori_atsushi 0:f77369cabd75 143 INA226 BatteryMonitor(i2c, batteryMonitorAddress, 10000);
hattori_atsushi 0:f77369cabd75 144 INA226 PanelMonitor(i2c, panelMonitorAddress, 10000);
hattori_atsushi 0:f77369cabd75 145 INA226 MotorMonitor(i2c, motorMonitorAddress, 10000);
hattori_atsushi 0:f77369cabd75 146
hattori_atsushi 0:f77369cabd75 147 MSCFileSystem msc("usb"); // USBメモリには/usb/...でアクセス
hattori_atsushi 0:f77369cabd75 148
hattori_atsushi 0:f77369cabd75 149 EthernetNetIf eth;
hattori_atsushi 0:f77369cabd75 150 NTPClient ntp;
hattori_atsushi 0:f77369cabd75 151
hattori_atsushi 0:f77369cabd75 152 DigitalOut isoError(p6); // 絶縁監視エラー出力
hattori_atsushi 0:f77369cabd75 153
hattori_atsushi 0:f77369cabd75 154 InterruptIn lapSw(p7); // lapスイッチ ON: 0, OFF:1
hattori_atsushi 0:f77369cabd75 155 InterruptIn motorPulse(p12); // モーターパルス
hattori_atsushi 0:f77369cabd75 156
hattori_atsushi 0:f77369cabd75 157 struct LogData {
hattori_atsushi 0:f77369cabd75 158 char timeStr[timeStr_i][timeStr_maxsize];
hattori_atsushi 0:f77369cabd75 159 /* [0]:タイムスタンプ 20160801121356
hattori_atsushi 0:f77369cabd75 160 [1]:現在時刻 12:13:56
hattori_atsushi 0:f77369cabd75 161 [2]:経過時間 00:13:56
hattori_atsushi 0:f77369cabd75 162 [3]:カウント用 00:01:30
hattori_atsushi 0:f77369cabd75 163 [4]:LCD用ラップタイム 05:15
hattori_atsushi 0:f77369cabd75 164 [5]:通過時刻 12:05:00*/
hattori_atsushi 0:f77369cabd75 165 unsigned int lap; // ラップ数
hattori_atsushi 0:f77369cabd75 166 unsigned int lapTime; // ラップタイム
hattori_atsushi 0:f77369cabd75 167 int totalTime; // 経過時間
hattori_atsushi 0:f77369cabd75 168 double RealtimeData[RealtimeData_i][RealtimeData_j]; // 1秒毎の測定データ
hattori_atsushi 0:f77369cabd75 169 double LapoutData[LapoutData_i][LapoutData_j]; // ラップ平均等
hattori_atsushi 0:f77369cabd75 170 double batteryVoltage; // バッテリー電圧
hattori_atsushi 0:f77369cabd75 171 double remainBatteryParcent; // バッテリー残量[%]
hattori_atsushi 0:f77369cabd75 172 double remainBatteryWh; // バッテリー残量[Wh]
hattori_atsushi 0:f77369cabd75 173 double motorSpeed; // モーター速度[km/h] CAN
hattori_atsushi 0:f77369cabd75 174 double motorSpeed_pulse; // モーター速度[km/h] パルス
hattori_atsushi 0:f77369cabd75 175 double motorAngle;
hattori_atsushi 0:f77369cabd75 176 double gpsSpeed; // GPS速度[km/h]
hattori_atsushi 0:f77369cabd75 177 // float accData[3]; // 3軸加速度 0:x, 1:y, 2:z[何Gか]
hattori_atsushi 0:f77369cabd75 178 double latitude; // 緯度
hattori_atsushi 0:f77369cabd75 179 double longitude; // 経度
hattori_atsushi 0:f77369cabd75 180 };
hattori_atsushi 0:f77369cabd75 181
hattori_atsushi 0:f77369cabd75 182 // グローバル変数
hattori_atsushi 0:f77369cabd75 183 bool secTimer = false;
hattori_atsushi 0:f77369cabd75 184 bool lapSave = false;
hattori_atsushi 0:f77369cabd75 185 bool lapSave_forsub=false;
hattori_atsushi 0:f77369cabd75 186 bool emergency = false;
hattori_atsushi 0:f77369cabd75 187 time_t startUnixTime = 0;
hattori_atsushi 0:f77369cabd75 188 struct LogData logdata = {0};
hattori_atsushi 0:f77369cabd75 189 struct LogData Postdata[storageTime + storageOffset] = {0}; // storageTimeかつかつはまずい?
hattori_atsushi 0:f77369cabd75 190 unsigned int postcount = 0; // logdataを貯める時間をカウント
hattori_atsushi 0:f77369cabd75 191 unsigned int lapTimeValue = 0; // スイッチ判定用のラップタイム
hattori_atsushi 0:f77369cabd75 192 unsigned int pulseCount = 0; // 車速パルスカウント
hattori_atsushi 0:f77369cabd75 193 time_t prelapUnixTime = 0; // 前のラップタイムのUNIXタイム
hattori_atsushi 0:f77369cabd75 194 double preLapdata[preLapdata_i][preLapdata_j] = {0}; // 前のラップデータ
hattori_atsushi 0:f77369cabd75 195
hattori_atsushi 0:f77369cabd75 196 // プロトタイプ宣言
hattori_atsushi 0:f77369cabd75 197 void SetTimer(void);
hattori_atsushi 0:f77369cabd75 198 void MainFuncTimer(void);
hattori_atsushi 0:f77369cabd75 199 void SwFuncInterrupt(void);
hattori_atsushi 0:f77369cabd75 200 void MotorPulseCount(void);
hattori_atsushi 0:f77369cabd75 201 void print(const char *str, int row, int col);
hattori_atsushi 0:f77369cabd75 202 int SetupINA226(void);
hattori_atsushi 0:f77369cabd75 203 int SetupEthernet(void);
hattori_atsushi 0:f77369cabd75 204 int SetupUSB(struct LogData *data, char name[][fileName_maxsize]);
hattori_atsushi 0:f77369cabd75 205 int ReadBackup(struct LogData *data, double predata[][preLapdata_j], time_t *preTime);
hattori_atsushi 0:f77369cabd75 206 int FetchGPSdata(const char name[][fileName_maxsize]);
hattori_atsushi 0:f77369cabd75 207 void CalculateSet(struct LogData *data, bool run);
hattori_atsushi 0:f77369cabd75 208 unsigned int CalculateTimeSet(struct LogData *data, time_t preTime);
hattori_atsushi 0:f77369cabd75 209 void LapCalculateSet(struct LogData *data, double predata[][preLapdata_j], time_t *preTime);
hattori_atsushi 0:f77369cabd75 210 int httpPost(const struct LogData postdata[], int *httpRes);
hattori_atsushi 0:f77369cabd75 211 void LaphttpPost(const struct LogData *data, int *httpRes);
hattori_atsushi 0:f77369cabd75 212 void EmergencyhttpPost(const struct LogData *data);
hattori_atsushi 0:f77369cabd75 213 void LCD(const struct LogData *data);
hattori_atsushi 0:f77369cabd75 214 void ReadyStartLCD(const struct LogData *data);
hattori_atsushi 0:f77369cabd75 215 int USBSaveData(const struct LogData postdata[], const char name[][fileName_maxsize]);
hattori_atsushi 0:f77369cabd75 216 int LapUSBSaveData(const struct LogData *data, const char name[][fileName_maxsize]);
hattori_atsushi 0:f77369cabd75 217 int SaveBackup(const struct LogData *data, const double predata[][preLapdata_j], time_t preTime);
hattori_atsushi 0:f77369cabd75 218 void XbeeSerial(const struct LogData *data);
hattori_atsushi 0:f77369cabd75 219 void InsulateMonitor(const struct LogData *data);
hattori_atsushi 0:f77369cabd75 220
hattori_atsushi 0:f77369cabd75 221 int main(){
hattori_atsushi 0:f77369cabd75 222 int httpResponce = 0; // httpリクエスト送信時のレスポンス
hattori_atsushi 0:f77369cabd75 223 int LaphttpResponce = 0;
hattori_atsushi 0:f77369cabd75 224 char fileName[3][fileName_maxsize] = {0}; // USBファイル名 [0]:LOG, [1]:LAP, [2]:GPS
hattori_atsushi 0:f77369cabd75 225
hattori_atsushi 0:f77369cabd75 226 debug.baud(9600);
hattori_atsushi 0:f77369cabd75 227 Xbee.baud(57600); // 安心と信頼()の57600bps
hattori_atsushi 0:f77369cabd75 228 myGPS.begin(9600);
hattori_atsushi 0:f77369cabd75 229 myGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
hattori_atsushi 0:f77369cabd75 230 myGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
hattori_atsushi 0:f77369cabd75 231 myGPS.sendCommand(PGCMD_ANTENNA);
hattori_atsushi 0:f77369cabd75 232
hattori_atsushi 0:f77369cabd75 233 lcd.cls();
hattori_atsushi 0:f77369cabd75 234
hattori_atsushi 0:f77369cabd75 235 sublogger_sec=0;
hattori_atsushi 0:f77369cabd75 236 sublogger_min=0;
hattori_atsushi 0:f77369cabd75 237
hattori_atsushi 0:f77369cabd75 238 // エラー時は自動的にリセット
hattori_atsushi 0:f77369cabd75 239
hattori_atsushi 0:f77369cabd75 240 if(SetupINA226()) {
hattori_atsushi 0:f77369cabd75 241 NVIC_SystemReset();
hattori_atsushi 0:f77369cabd75 242 return -1;
hattori_atsushi 0:f77369cabd75 243 }
hattori_atsushi 0:f77369cabd75 244
hattori_atsushi 0:f77369cabd75 245 if(SetupEthernet()) {
hattori_atsushi 0:f77369cabd75 246 NVIC_SystemReset();
hattori_atsushi 0:f77369cabd75 247 return -1;
hattori_atsushi 0:f77369cabd75 248 }
hattori_atsushi 0:f77369cabd75 249
hattori_atsushi 0:f77369cabd75 250 // Host server(IpAddr(), 123, "ntp.jst.mfeed.ad.jp"); // NTP時刻取得 調子悪い?
hattori_atsushi 0:f77369cabd75 251 Host server(IpAddr(), 123, "ntp.nict.jp");
hattori_atsushi 0:f77369cabd75 252 ntp.setTime(server); // RTCにセット
hattori_atsushi 0:f77369cabd75 253
hattori_atsushi 0:f77369cabd75 254 if(SetupUSB(&logdata, fileName)) {
hattori_atsushi 0:f77369cabd75 255 NVIC_SystemReset();
hattori_atsushi 0:f77369cabd75 256 return -1;
hattori_atsushi 0:f77369cabd75 257 }
hattori_atsushi 0:f77369cabd75 258
hattori_atsushi 0:f77369cabd75 259 wait(1.0);
hattori_atsushi 0:f77369cabd75 260 lcd.cls();
hattori_atsushi 0:f77369cabd75 261
hattori_atsushi 0:f77369cabd75 262 RTC::attach(&SetTimer, RTC::Second); // SetTimer()を1秒毎に実行する
hattori_atsushi 0:f77369cabd75 263
hattori_atsushi 0:f77369cabd75 264 // スタート前ループ
hattori_atsushi 0:f77369cabd75 265 // 初回起動時 backup.csvが存在していないときのみ実行
hattori_atsushi 0:f77369cabd75 266 if(ReadBackup(&logdata, preLapdata, &prelapUnixTime)) {
hattori_atsushi 0:f77369cabd75 267 while(1) {
hattori_atsushi 0:f77369cabd75 268 if(!lapSw || time(NULL) == 1564801200) { // 2019/8/3/12:00:00 自動スタート←2年前になってたかも
hattori_atsushi 0:f77369cabd75 269 startUnixTime = time(NULL) + offsetTime+600; // スタート時刻取得
hattori_atsushi 0:f77369cabd75 270 break;
hattori_atsushi 0:f77369cabd75 271 }
hattori_atsushi 0:f77369cabd75 272 if(secTimer) {
hattori_atsushi 0:f77369cabd75 273 CalculateTimeSet(&logdata, prelapUnixTime);
hattori_atsushi 0:f77369cabd75 274 CalculateSet(&logdata, false);
hattori_atsushi 0:f77369cabd75 275 ReadyStartLCD(&logdata);
hattori_atsushi 0:f77369cabd75 276 InsulateMonitor(&logdata);
hattori_atsushi 0:f77369cabd75 277 secTimer = false;
hattori_atsushi 0:f77369cabd75 278 }
hattori_atsushi 0:f77369cabd75 279 }
hattori_atsushi 0:f77369cabd75 280 }
hattori_atsushi 0:f77369cabd75 281 /*
hattori_atsushi 0:f77369cabd75 282 else {
hattori_atsushi 0:f77369cabd75 283 // NTP時刻が異常な時(スタートから5時間以上) 自動的にリセット
hattori_atsushi 0:f77369cabd75 284 if(labs(startUnixTime - (time(NULL) + offsetTime)) > 5 * 3600) {
hattori_atsushi 0:f77369cabd75 285 print("NTP Time isoError\n", 0, 0);
hattori_atsushi 0:f77369cabd75 286 RTC::detach(RTC::Second);
hattori_atsushi 0:f77369cabd75 287 NVIC_SystemReset();
hattori_atsushi 0:f77369cabd75 288 return -1;
hattori_atsushi 0:f77369cabd75 289 }
hattori_atsushi 0:f77369cabd75 290 }
hattori_atsushi 0:f77369cabd75 291 */
hattori_atsushi 0:f77369cabd75 292 lapSw.fall(&SwFuncInterrupt); // ピン立ち下がり割り込みに設定
hattori_atsushi 0:f77369cabd75 293 motorPulse.fall(&MotorPulseCount);
hattori_atsushi 0:f77369cabd75 294
hattori_atsushi 0:f77369cabd75 295 RTC::detach(RTC::Second);
hattori_atsushi 0:f77369cabd75 296 lcd.cls();
hattori_atsushi 0:f77369cabd75 297 wait(0.5); // lapSwが0になるのを待つ
hattori_atsushi 0:f77369cabd75 298
hattori_atsushi 0:f77369cabd75 299 RTC::attach(&MainFuncTimer, RTC::Second); // MainFuncTimerを1秒ごとに実行
hattori_atsushi 0:f77369cabd75 300
hattori_atsushi 0:f77369cabd75 301 // メインループ
hattori_atsushi 0:f77369cabd75 302 while(1) {
hattori_atsushi 0:f77369cabd75 303 FetchGPSdata(fileName); // GPSセンテンス取得・解析
hattori_atsushi 0:f77369cabd75 304 if(emergency) {
hattori_atsushi 0:f77369cabd75 305 EmergencyhttpPost(&logdata);
hattori_atsushi 0:f77369cabd75 306 emergency = false;
hattori_atsushi 0:f77369cabd75 307 }
hattori_atsushi 0:f77369cabd75 308 if(lapSave) {
hattori_atsushi 0:f77369cabd75 309 LaphttpPost(&logdata, &LaphttpResponce); // LAPデータ送信
hattori_atsushi 0:f77369cabd75 310 LapUSBSaveData(&logdata, fileName);
hattori_atsushi 0:f77369cabd75 311 lapSave = false;
hattori_atsushi 0:f77369cabd75 312 }
hattori_atsushi 0:f77369cabd75 313 if(secTimer) { // fopen関連は割り込みで実行できない
hattori_atsushi 0:f77369cabd75 314 SaveBackup(&logdata, preLapdata, prelapUnixTime); // バックアップ
hattori_atsushi 0:f77369cabd75 315 secTimer = false;
hattori_atsushi 0:f77369cabd75 316 }
hattori_atsushi 0:f77369cabd75 317 if(postcount >= storageTime) { // storageTime個のデータが集まったら
hattori_atsushi 0:f77369cabd75 318 postcount = 0;
hattori_atsushi 0:f77369cabd75 319 USBSaveData(Postdata, fileName); // USBにデータ保存
hattori_atsushi 0:f77369cabd75 320 httpPost(Postdata, &httpResponce);
hattori_atsushi 0:f77369cabd75 321 // debug.printf("\n%d\n", httpResponce);
hattori_atsushi 0:f77369cabd75 322 }
hattori_atsushi 0:f77369cabd75 323 }
hattori_atsushi 0:f77369cabd75 324 }
hattori_atsushi 0:f77369cabd75 325
hattori_atsushi 0:f77369cabd75 326 /*--------------------------割り込み実行の関数 ここから-------------------------------*/
hattori_atsushi 0:f77369cabd75 327 // RTCタイマーで1秒ごとに実行(スタート前)
hattori_atsushi 0:f77369cabd75 328 void SetTimer(){
hattori_atsushi 0:f77369cabd75 329 secTimer = true;
hattori_atsushi 0:f77369cabd75 330 }
hattori_atsushi 0:f77369cabd75 331
hattori_atsushi 0:f77369cabd75 332 // RTCタイマーで1秒ごとに実行(走行時)
hattori_atsushi 0:f77369cabd75 333 void MainFuncTimer(){
hattori_atsushi 0:f77369cabd75 334 secTimer = true;
hattori_atsushi 0:f77369cabd75 335 canlog.GetCanData(FRAME0); // FRAME0のデータを取得
hattori_atsushi 0:f77369cabd75 336 lapTimeValue = CalculateTimeSet(&logdata, prelapUnixTime); // 時間に関するデータを計算
hattori_atsushi 0:f77369cabd75 337 CalculateSet(&logdata, true); // データ取得・計算し,格納
hattori_atsushi 0:f77369cabd75 338 LCD(&logdata); // LCDにデータ表示
hattori_atsushi 0:f77369cabd75 339 Postdata[postcount++] = logdata; // 蓄積
hattori_atsushi 0:f77369cabd75 340 if(postcount >= storageTime + storageOffset) { // 配列上限超えると強制リセット
hattori_atsushi 0:f77369cabd75 341 postcount = 0;
hattori_atsushi 0:f77369cabd75 342 }
hattori_atsushi 0:f77369cabd75 343 InsulateMonitor(&logdata);
hattori_atsushi 0:f77369cabd75 344 }
hattori_atsushi 0:f77369cabd75 345
hattori_atsushi 0:f77369cabd75 346 // スイッチ割り込み
hattori_atsushi 0:f77369cabd75 347 // lapTime_limit未満は緊急スイッチとして動作→非表示に(2019.8.1)
hattori_atsushi 0:f77369cabd75 348 void SwFuncInterrupt(){
hattori_atsushi 0:f77369cabd75 349 if(lapTimeValue >= lapTime_limit) {
hattori_atsushi 0:f77369cabd75 350 LapCalculateSet(&logdata, preLapdata, &prelapUnixTime); // LAPデータ計算
hattori_atsushi 0:f77369cabd75 351 XbeeSerial(&logdata); // LAPデータをxbeeで送信
hattori_atsushi 0:f77369cabd75 352 lapSave = true; // Web 送信,USB保存のフラグ
hattori_atsushi 0:f77369cabd75 353 lapSave_forsub=true;
hattori_atsushi 0:f77369cabd75 354 }
hattori_atsushi 0:f77369cabd75 355 else{
hattori_atsushi 0:f77369cabd75 356 //lcd.cls();
hattori_atsushi 0:f77369cabd75 357 //print("Driver Emergency", 2, 1);
hattori_atsushi 0:f77369cabd75 358 wait(1.0);
hattori_atsushi 0:f77369cabd75 359 lcd.cls();
hattori_atsushi 0:f77369cabd75 360 emergency = true; // 緊急スイッチ,web送信フラグ
hattori_atsushi 0:f77369cabd75 361 }
hattori_atsushi 0:f77369cabd75 362 }
hattori_atsushi 0:f77369cabd75 363
hattori_atsushi 0:f77369cabd75 364 void MotorPulseCount(){
hattori_atsushi 0:f77369cabd75 365 pulseCount++; // ストリーム等でデバックすると遅延で正確にパルス数を測定できない
hattori_atsushi 0:f77369cabd75 366 }
hattori_atsushi 0:f77369cabd75 367
hattori_atsushi 0:f77369cabd75 368 /*--------------------------割り込み実行の関数 ここまで-------------------------------*/
hattori_atsushi 0:f77369cabd75 369
hattori_atsushi 0:f77369cabd75 370 /*-------------------------------ユーザー定義関数-------------------------------------*/
hattori_atsushi 0:f77369cabd75 371
hattori_atsushi 0:f77369cabd75 372 /** 全てのストリーム系に文字列を出力
hattori_atsushi 0:f77369cabd75 373 * @param const char *str 送信文字列
hattori_atsushi 0:f77369cabd75 374 * @param int row 列
hattori_atsushi 0:f77369cabd75 375 * @param int col 行
hattori_atsushi 0:f77369cabd75 376 */
hattori_atsushi 0:f77369cabd75 377 void print(const char *str, int row, int col){
hattori_atsushi 0:f77369cabd75 378 debug.printf("%s", str);
hattori_atsushi 0:f77369cabd75 379 Xbee.printf("%s", str);
hattori_atsushi 0:f77369cabd75 380 lcd.locate(row, col);
hattori_atsushi 0:f77369cabd75 381 lcd.printf("%s", str);
hattori_atsushi 0:f77369cabd75 382 }
hattori_atsushi 0:f77369cabd75 383
hattori_atsushi 0:f77369cabd75 384 /** INA226 レジスタ書き込み等
hattori_atsushi 0:f77369cabd75 385 * @return 0:成功 -1:失敗
hattori_atsushi 0:f77369cabd75 386 */
hattori_atsushi 0:f77369cabd75 387 int SetupINA226(){
hattori_atsushi 0:f77369cabd75 388 unsigned short val_1 = 0;
hattori_atsushi 0:f77369cabd75 389 unsigned short val_2 = 0;
hattori_atsushi 0:f77369cabd75 390 unsigned short val_3 = 0;
hattori_atsushi 0:f77369cabd75 391
hattori_atsushi 0:f77369cabd75 392 // INA226の存在を確認
hattori_atsushi 0:f77369cabd75 393 if(!BatteryMonitor.isExist()) {
hattori_atsushi 0:f77369cabd75 394 print("INA226B not found!\n", 0, 0);
hattori_atsushi 0:f77369cabd75 395 }
hattori_atsushi 0:f77369cabd75 396 if(!PanelMonitor.isExist()) {
hattori_atsushi 0:f77369cabd75 397 print("INA226P not found!\n", 0, 1);
hattori_atsushi 0:f77369cabd75 398 }
hattori_atsushi 0:f77369cabd75 399 if(!MotorMonitor.isExist()) {
hattori_atsushi 0:f77369cabd75 400 print("INA226M not found!\n", 0, 2);
hattori_atsushi 0:f77369cabd75 401 return -1;
hattori_atsushi 0:f77369cabd75 402 }
hattori_atsushi 0:f77369cabd75 403
hattori_atsushi 0:f77369cabd75 404 // INA226のレジスタの値を正しく読めるか確認
hattori_atsushi 0:f77369cabd75 405 if(BatteryMonitor.rawRead(0x00, &val_1) != 0) {
hattori_atsushi 0:f77369cabd75 406 print("INA226B read Error!\n", 0, 0);
hattori_atsushi 0:f77369cabd75 407 return -1;
hattori_atsushi 0:f77369cabd75 408 }
hattori_atsushi 0:f77369cabd75 409 if(PanelMonitor.rawRead(0x00, &val_2) != 0) {
hattori_atsushi 0:f77369cabd75 410 print("INA226P read Error!\n", 0, 1);
hattori_atsushi 0:f77369cabd75 411 return -1;
hattori_atsushi 0:f77369cabd75 412 }
hattori_atsushi 0:f77369cabd75 413 if(MotorMonitor.rawRead(0x00, &val_3) != 0) {
hattori_atsushi 0:f77369cabd75 414 print("INA226M read Error!\n", 0, 2);
hattori_atsushi 0:f77369cabd75 415 return -1;
hattori_atsushi 0:f77369cabd75 416 }
hattori_atsushi 0:f77369cabd75 417
hattori_atsushi 0:f77369cabd75 418 // 各INA226にレジスタ値を書き込む
hattori_atsushi 0:f77369cabd75 419 BatteryMonitor.setConfiguration(configuration);
hattori_atsushi 0:f77369cabd75 420 PanelMonitor.setConfiguration(configuration);
hattori_atsushi 0:f77369cabd75 421 MotorMonitor.setConfiguration(configuration);
hattori_atsushi 0:f77369cabd75 422 BatteryMonitor.setCurrentCalibration(calibration);
hattori_atsushi 0:f77369cabd75 423 PanelMonitor.setCurrentCalibration(calibrationPanel);
hattori_atsushi 0:f77369cabd75 424 MotorMonitor.setCurrentCalibration(calibration);
hattori_atsushi 0:f77369cabd75 425
hattori_atsushi 0:f77369cabd75 426 print("INA226 OK!\n", 0, 0);
hattori_atsushi 0:f77369cabd75 427 return 0;
hattori_atsushi 0:f77369cabd75 428 }
hattori_atsushi 0:f77369cabd75 429
hattori_atsushi 0:f77369cabd75 430 /** ネット関連 初期化
hattori_atsushi 0:f77369cabd75 431 * @return 0: 成功 -1: 失敗
hattori_atsushi 0:f77369cabd75 432 */
hattori_atsushi 0:f77369cabd75 433 int SetupEthernet(){
hattori_atsushi 0:f77369cabd75 434 EthernetErr ethErr = eth.setup();
hattori_atsushi 0:f77369cabd75 435 if(ethErr) {
hattori_atsushi 0:f77369cabd75 436 debug.printf("Error %d in setup.\n", ethErr);
hattori_atsushi 0:f77369cabd75 437 Xbee.printf("Error %d in setup.\n", ethErr);
hattori_atsushi 0:f77369cabd75 438 lcd.locate(0, 1);
hattori_atsushi 0:f77369cabd75 439 lcd.printf("Setup Error %d", ethErr);
hattori_atsushi 0:f77369cabd75 440 return -1;
hattori_atsushi 0:f77369cabd75 441 }
hattori_atsushi 0:f77369cabd75 442
hattori_atsushi 0:f77369cabd75 443 print("Ethernet OK!\n", 0, 1);
hattori_atsushi 0:f77369cabd75 444 return 0;
hattori_atsushi 0:f77369cabd75 445 }
hattori_atsushi 0:f77369cabd75 446
hattori_atsushi 0:f77369cabd75 447 /** USBメモリ書き込み初期化 ファイル名設定
hattori_atsushi 0:f77369cabd75 448 * @param struct LogData LogData 構造体
hattori_atsushi 0:f77369cabd75 449 * @param char name ファイル名が書き込まれる配列
hattori_atsushi 0:f77369cabd75 450 *
hattori_atsushi 0:f77369cabd75 451 * @return 0: 成功 -1: 失敗
hattori_atsushi 0:f77369cabd75 452 */
hattori_atsushi 0:f77369cabd75 453 int SetupUSB(struct LogData *data, char name[][fileName_maxsize]){
hattori_atsushi 0:f77369cabd75 454 time_t createdTime = time(NULL) + offsetTime;
hattori_atsushi 0:f77369cabd75 455 // 日付がファイル名
hattori_atsushi 0:f77369cabd75 456 strftime(name[0], fileName_maxsize, "/usb/%y%m%d_log.csv", localtime(&createdTime));
hattori_atsushi 0:f77369cabd75 457 strftime(name[1], fileName_maxsize, "/usb/%y%m%d_LAPdata.csv", localtime(&createdTime));
hattori_atsushi 0:f77369cabd75 458 strftime(name[2], fileName_maxsize, "/usb/%y%m%d_GPSNMEA.log", localtime(&createdTime));
hattori_atsushi 0:f77369cabd75 459
hattori_atsushi 0:f77369cabd75 460 FILE *fp = fopen(name[0], "a");
hattori_atsushi 0:f77369cabd75 461 if(fp == NULL) {
hattori_atsushi 0:f77369cabd75 462 print("USB can\'t be opened!\n", 0, 2);
hattori_atsushi 0:f77369cabd75 463 return -1;
hattori_atsushi 0:f77369cabd75 464 }
hattori_atsushi 0:f77369cabd75 465 else{
hattori_atsushi 0:f77369cabd75 466 strftime(data->timeStr[0], timeStr_maxsize, "%Y%m%d%H%M%S", localtime(&createdTime));
hattori_atsushi 0:f77369cabd75 467 fprintf(fp, "%s\n", data->timeStr[0]); // 試しに現在時刻を書き込み
hattori_atsushi 0:f77369cabd75 468 }
hattori_atsushi 0:f77369cabd75 469 fclose(fp);
hattori_atsushi 0:f77369cabd75 470
hattori_atsushi 0:f77369cabd75 471 print("USB OK!\n", 0, 2);
hattori_atsushi 0:f77369cabd75 472 return 0;
hattori_atsushi 0:f77369cabd75 473 }
hattori_atsushi 0:f77369cabd75 474
hattori_atsushi 0:f77369cabd75 475 /** バックアップデータを読み込み,LogData構造体に格納
hattori_atsushi 0:f77369cabd75 476 * @param struct LogData バックアップからLogData 構造体に書き込む
hattori_atsushi 0:f77369cabd75 477 * @param double predata バックアップから前のラップタイムデータを書き込む
hattori_atsushi 0:f77369cabd75 478 * @param time_t *preTime バックアップから前のラップタイムを書き込む
hattori_atsushi 0:f77369cabd75 479 *
hattori_atsushi 0:f77369cabd75 480 * @return 0:成功 1:バックアップデータが存在していない
hattori_atsushi 0:f77369cabd75 481 */
hattori_atsushi 0:f77369cabd75 482 int ReadBackup(struct LogData *data, double predata[][preLapdata_j], time_t *preTime){
hattori_atsushi 0:f77369cabd75 483 int i;
hattori_atsushi 0:f77369cabd75 484 FILE *fp_back = fopen("/usb/backup.csv", "r");
hattori_atsushi 0:f77369cabd75 485 if(fp_back == NULL) {
hattori_atsushi 0:f77369cabd75 486 debug.printf("Backup File No Exist\n");
hattori_atsushi 0:f77369cabd75 487 return 1; // 初回起動時 backup.csvはSaveBackup関数が実行された時に作成される
hattori_atsushi 0:f77369cabd75 488 }
hattori_atsushi 0:f77369cabd75 489 else{
hattori_atsushi 0:f77369cabd75 490 fscanf(fp_back, "%d,%d,%d,%d", &(data->lap), &(data->lapTime), &startUnixTime, preTime);
hattori_atsushi 0:f77369cabd75 491 for(i = 0; i < RealtimeData_i; i++) {
hattori_atsushi 0:f77369cabd75 492 fscanf(fp_back, "%lf,%lf,", &(data->RealtimeData[i][2]), &(data->RealtimeData[i][3])); // 電流和,電力和
hattori_atsushi 0:f77369cabd75 493 }
hattori_atsushi 0:f77369cabd75 494 for(i = 0; i < preLapdata_i; i++) {
hattori_atsushi 0:f77369cabd75 495 fscanf(fp_back, "%lf,%lf,", &predata[i][0], &predata[i][1]);
hattori_atsushi 0:f77369cabd75 496 }
hattori_atsushi 0:f77369cabd75 497 }
hattori_atsushi 0:f77369cabd75 498 fclose(fp_back);
hattori_atsushi 0:f77369cabd75 499 return 0;
hattori_atsushi 0:f77369cabd75 500 }
hattori_atsushi 0:f77369cabd75 501
hattori_atsushi 0:f77369cabd75 502 /** シリアルGPSデータを解析,保存
hattori_atsushi 0:f77369cabd75 503 * @param const char name ファイル名が保存されている配列
hattori_atsushi 0:f77369cabd75 504 *
hattori_atsushi 0:f77369cabd75 505 * @return 0:成功 -1:失敗
hattori_atsushi 0:f77369cabd75 506 */
hattori_atsushi 0:f77369cabd75 507 int FetchGPSdata(const char name[][fileName_maxsize]){
hattori_atsushi 0:f77369cabd75 508 // char c;
hattori_atsushi 0:f77369cabd75 509 while(1) {
hattori_atsushi 0:f77369cabd75 510 myGPS.read(); // ただ読むだけでなくて,GPSセンテンスを文字列化している
hattori_atsushi 0:f77369cabd75 511 // if (c) debug.printf("%c", c);
hattori_atsushi 0:f77369cabd75 512 if (myGPS.newNMEAreceived()) { // センテンスが一文取得できたかどうか
hattori_atsushi 0:f77369cabd75 513 if (!myGPS.parse(myGPS.lastNMEA())) { // 解析が完了したかどうか していない場合はもう一度ループ(breakスキップ)
hattori_atsushi 0:f77369cabd75 514 continue;
hattori_atsushi 0:f77369cabd75 515 }
hattori_atsushi 0:f77369cabd75 516 break; // 解析終了した場合はループを抜ける
hattori_atsushi 0:f77369cabd75 517 }
hattori_atsushi 0:f77369cabd75 518 }
hattori_atsushi 0:f77369cabd75 519 // 直前のGPSセンテンスをUSBに保存
hattori_atsushi 0:f77369cabd75 520 FILE *fp = fopen(name[2], "a");
hattori_atsushi 0:f77369cabd75 521 if(fp == NULL) {
hattori_atsushi 0:f77369cabd75 522 debug.printf("USB Error\n");
hattori_atsushi 0:f77369cabd75 523 return -1;
hattori_atsushi 0:f77369cabd75 524 }
hattori_atsushi 0:f77369cabd75 525 else{
hattori_atsushi 0:f77369cabd75 526 fprintf(fp, "%s", myGPS.lastNMEA());
hattori_atsushi 0:f77369cabd75 527 }
hattori_atsushi 0:f77369cabd75 528 fclose(fp);
hattori_atsushi 0:f77369cabd75 529 return 0;
hattori_atsushi 0:f77369cabd75 530 }
hattori_atsushi 0:f77369cabd75 531
hattori_atsushi 0:f77369cabd75 532 /** 1秒毎に電圧・電流測定,計算後のデータを構造体に格納
hattori_atsushi 0:f77369cabd75 533 * @param struct LogData
hattori_atsushi 0:f77369cabd75 534 * @param bool run : true 積算する false 積算しない
hattori_atsushi 0:f77369cabd75 535 */
hattori_atsushi 0:f77369cabd75 536 void CalculateSet(struct LogData *data, bool run){
hattori_atsushi 0:f77369cabd75 537 int i;
hattori_atsushi 0:f77369cabd75 538 bool retry = false;
hattori_atsushi 0:f77369cabd75 539 int count = 0;
hattori_atsushi 0:f77369cabd75 540
hattori_atsushi 0:f77369cabd75 541 double voltage_tmp = 0; // 仮に電圧,電流データを保存しておく
hattori_atsushi 0:f77369cabd75 542 double current_tmp[RealtimeData_i] = {0};
hattori_atsushi 0:f77369cabd75 543
hattori_atsushi 0:f77369cabd75 544 // 異常な値の場合は,再度データを取り直す
hattori_atsushi 0:f77369cabd75 545 do {
hattori_atsushi 0:f77369cabd75 546 retry = false;
hattori_atsushi 0:f77369cabd75 547 BatteryMonitor.getVoltage(&voltage_tmp); // 電圧
hattori_atsushi 0:f77369cabd75 548 BatteryMonitor.getCurrent(&current_tmp[0]); // バッテリー電流
hattori_atsushi 0:f77369cabd75 549 PanelMonitor.getCurrent(&current_tmp[1]); // パネル電流
hattori_atsushi 0:f77369cabd75 550 MotorMonitor.getCurrent(&current_tmp[2]); // モーター電流
hattori_atsushi 0:f77369cabd75 551
hattori_atsushi 0:f77369cabd75 552 if(voltage_tmp > 200) retry = true; // 電圧が200V以上は異常
hattori_atsushi 0:f77369cabd75 553 for(i = 0; i < RealtimeData_i; i++) {
hattori_atsushi 0:f77369cabd75 554 if(current_tmp[i] > 200) retry = true; // 電流が200A以上は異常
hattori_atsushi 0:f77369cabd75 555 }
hattori_atsushi 0:f77369cabd75 556 count++;
hattori_atsushi 0:f77369cabd75 557 } while(retry && count < 5); // 5回とっても異常な場合はさすがにループを抜ける
hattori_atsushi 0:f77369cabd75 558
hattori_atsushi 0:f77369cabd75 559 // 0割の有無を確認した後,配列に格納する
hattori_atsushi 0:f77369cabd75 560 if(data->totalTime != 0) {
hattori_atsushi 0:f77369cabd75 561 data->batteryVoltage = voltage_tmp * voltageCalibration; // 分圧電圧を補正
hattori_atsushi 0:f77369cabd75 562 for(i = 0; i < RealtimeData_i; i++) {
hattori_atsushi 0:f77369cabd75 563 data->RealtimeData[i][0] = current_tmp[i] * currentCalibration[i]; // 電流補正
hattori_atsushi 0:f77369cabd75 564 data->RealtimeData[i][1] = data->batteryVoltage * data->RealtimeData[i][0]; // 電力
hattori_atsushi 0:f77369cabd75 565 if(run) data->RealtimeData[i][2] += data->RealtimeData[i][0]; // 電流の和
hattori_atsushi 0:f77369cabd75 566 if(run) data->RealtimeData[i][3] += data->RealtimeData[i][1]; // 電力の和
hattori_atsushi 0:f77369cabd75 567 data->RealtimeData[i][4] = data->RealtimeData[i][3] / 3600; // 積算電力
hattori_atsushi 0:f77369cabd75 568 }
hattori_atsushi 0:f77369cabd75 569 data->remainBatteryWh = batteryCapacity - data->RealtimeData[0][4]; // バッテリー残量[Wh]
hattori_atsushi 0:f77369cabd75 570 data->remainBatteryParcent = (data->remainBatteryWh / batteryCapacity) * 100; // バッテリー残量[%]
hattori_atsushi 0:f77369cabd75 571 data->motorSpeed = canlog.rpmMotor * rpmConvert; // CAN通信で回転数取得 km/h変換
hattori_atsushi 0:f77369cabd75 572 data->motorAngle = canlog.angle; // 進角
hattori_atsushi 0:f77369cabd75 573 debug.printf("angle:%.2f\n", canlog.angle);
hattori_atsushi 0:f77369cabd75 574 data->motorSpeed_pulse = pulseCount * pulseConvert; // 1秒間でカウントしたパルスを速度に変換
hattori_atsushi 0:f77369cabd75 575 pulseCount = 0;
hattori_atsushi 0:f77369cabd75 576 data->gpsSpeed = myGPS.speed * kmph; // GPS速度
hattori_atsushi 0:f77369cabd75 577 data->latitude = myGPS.latitude; // GPS緯度
hattori_atsushi 0:f77369cabd75 578 data->longitude = myGPS.longitude; // GPS経度
hattori_atsushi 0:f77369cabd75 579 //acc.ReadXYZ(data->accData); // 3軸加速度
hattori_atsushi 0:f77369cabd75 580 }
hattori_atsushi 0:f77369cabd75 581 }
hattori_atsushi 0:f77369cabd75 582
hattori_atsushi 0:f77369cabd75 583 /** 時刻関連のデータを計算,格納
hattori_atsushi 0:f77369cabd75 584 * @param struct LogData
hattori_atsushi 0:f77369cabd75 585 * @param time_t preTime 前のラップタイム
hattori_atsushi 0:f77369cabd75 586 *
hattori_atsushi 0:f77369cabd75 587 * @return unsigned int ラップタイム
hattori_atsushi 0:f77369cabd75 588 */
hattori_atsushi 0:f77369cabd75 589 unsigned int CalculateTimeSet(struct LogData *data, time_t preTime){
hattori_atsushi 0:f77369cabd75 590 time_t nowTime; // 現在時刻
hattori_atsushi 0:f77369cabd75 591 time_t laptime_temp; // ラップタイム算出用
hattori_atsushi 0:f77369cabd75 592 time_t totalTime_temp; // 経過時間用
hattori_atsushi 0:f77369cabd75 593
hattori_atsushi 0:f77369cabd75 594 nowTime = time(NULL) + offsetTime; // RTCからUNIXタイムを取得し,日本時間に修正 現在時刻
hattori_atsushi 0:f77369cabd75 595 totalTime_temp = nowTime - startUnixTime; // 経過時間 (現在時刻とスタート時刻の差)
hattori_atsushi 0:f77369cabd75 596 data->totalTime = (int) totalTime_temp; // 経過時間(秒)
hattori_atsushi 0:f77369cabd75 597 if(!data->lap) {
hattori_atsushi 0:f77369cabd75 598 if(nowTime < startUnixTime){
hattori_atsushi 0:f77369cabd75 599 laptime_temp = 0;
hattori_atsushi 0:f77369cabd75 600 }
hattori_atsushi 0:f77369cabd75 601 else{
hattori_atsushi 0:f77369cabd75 602 laptime_temp = nowTime - startUnixTime;
hattori_atsushi 0:f77369cabd75 603 } // 現在時刻とスタート時刻の差 = 初回のラップタイム
hattori_atsushi 0:f77369cabd75 604 }
hattori_atsushi 0:f77369cabd75 605 else{
hattori_atsushi 0:f77369cabd75 606 laptime_temp = nowTime - preTime; // 現在時刻と前のラップタイムの時刻の差 = ラップタイム
hattori_atsushi 0:f77369cabd75 607 }
hattori_atsushi 0:f77369cabd75 608 if(laptime_temp<0){
hattori_atsushi 0:f77369cabd75 609 laptime_temp = 0;
hattori_atsushi 0:f77369cabd75 610 }
hattori_atsushi 0:f77369cabd75 611 // strftimeでUNIXタイムを適切にフォーマット
hattori_atsushi 0:f77369cabd75 612 strftime(data->timeStr[0], timeStr_maxsize, "%Y%m%d%H%M%S", localtime(&nowTime)); // PHP,USB用
hattori_atsushi 0:f77369cabd75 613 strftime(data->timeStr[1], timeStr_maxsize, "%T", localtime(&nowTime)); // LCDの現在時刻用
hattori_atsushi 0:f77369cabd75 614 strftime(data->timeStr[2], timeStr_maxsize, "%T", localtime(&totalTime_temp)); // LCDの経過時間用
hattori_atsushi 0:f77369cabd75 615 strftime(data->timeStr[3], timeStr_maxsize, "%M\'%S", localtime(&laptime_temp)); // LCDのラップ経過時刻用
hattori_atsushi 0:f77369cabd75 616
hattori_atsushi 0:f77369cabd75 617
hattori_atsushi 0:f77369cabd75 618 if(lapSave_forsub==true){
hattori_atsushi 0:f77369cabd75 619 sublogger_min=1;
hattori_atsushi 0:f77369cabd75 620 lapSave_forsub=false;
hattori_atsushi 0:f77369cabd75 621 }
hattori_atsushi 0:f77369cabd75 622 else{ sublogger_min=0;}
hattori_atsushi 0:f77369cabd75 623 sublogger_sec=1;
hattori_atsushi 0:f77369cabd75 624 sublogger_sec=0;
hattori_atsushi 0:f77369cabd75 625
hattori_atsushi 0:f77369cabd75 626
hattori_atsushi 0:f77369cabd75 627
hattori_atsushi 0:f77369cabd75 628 return (unsigned int) laptime_temp;
hattori_atsushi 0:f77369cabd75 629 }
hattori_atsushi 0:f77369cabd75 630
hattori_atsushi 0:f77369cabd75 631 /** ラップ平均・積算値を計算し構造体に格納
hattori_atsushi 0:f77369cabd75 632 * @param struct LogData
hattori_atsushi 0:f77369cabd75 633 * @param double predata 前のラップタイムのデータ
hattori_atsushi 0:f77369cabd75 634 * @param time_t *preTime 前のラップタイムを書き込む
hattori_atsushi 0:f77369cabd75 635 */
hattori_atsushi 0:f77369cabd75 636 void LapCalculateSet(struct LogData *data, double predata[][preLapdata_j], time_t *preTime){
hattori_atsushi 0:f77369cabd75 637 int i, j;
hattori_atsushi 0:f77369cabd75 638 time_t laptime_temp;
hattori_atsushi 0:f77369cabd75 639
hattori_atsushi 0:f77369cabd75 640 // 0周目から1周目になるときの動作
hattori_atsushi 0:f77369cabd75 641 if(!data->lap) {
hattori_atsushi 0:f77369cabd75 642 data->lapTime = (int)(time(NULL) + offsetTime - startUnixTime);
hattori_atsushi 0:f77369cabd75 643 if(time(NULL) + offsetTime - startUnixTime<0){
hattori_atsushi 0:f77369cabd75 644 laptime_temp = 0;
hattori_atsushi 0:f77369cabd75 645 }
hattori_atsushi 0:f77369cabd75 646 else{
hattori_atsushi 0:f77369cabd75 647 laptime_temp = time(NULL) + offsetTime - startUnixTime;
hattori_atsushi 0:f77369cabd75 648 } // 現在時刻とスタート時刻の差 = 初回のラップタイム
hattori_atsushi 0:f77369cabd75 649 strftime(data->timeStr[4], timeStr_maxsize, "%M\'%S", localtime(&laptime_temp)); // LCD用にフォーマット
hattori_atsushi 0:f77369cabd75 650 }
hattori_atsushi 0:f77369cabd75 651 // それ以外の動作
hattori_atsushi 0:f77369cabd75 652 else{
hattori_atsushi 0:f77369cabd75 653 data->lapTime = (unsigned int)(time(NULL) + offsetTime - *preTime);
hattori_atsushi 0:f77369cabd75 654 laptime_temp = time(NULL) + offsetTime - *preTime;
hattori_atsushi 0:f77369cabd75 655 strftime(data->timeStr[4], timeStr_maxsize, "%M\'%S", localtime(&laptime_temp));
hattori_atsushi 0:f77369cabd75 656 }
hattori_atsushi 0:f77369cabd75 657 data->lap = data->lap + 1; // ラップ加算
hattori_atsushi 0:f77369cabd75 658 *preTime = time(NULL) + offsetTime; // 現在時刻を前のラップタイムのUNIXタイムとする
hattori_atsushi 0:f77369cabd75 659 strftime(data->timeStr[5], timeStr_maxsize, "%T", localtime(preTime)); // コントロールライン通過時刻
hattori_atsushi 0:f77369cabd75 660
hattori_atsushi 0:f77369cabd75 661 // 0割の有無を確認した後,配列に格納 前のデータとの差で一周分を算出
hattori_atsushi 0:f77369cabd75 662 if(data->lapTime) {
hattori_atsushi 0:f77369cabd75 663 for(i = 0; i < LapoutData_i; i++) {
hattori_atsushi 0:f77369cabd75 664 data->LapoutData[i][0] = (data->RealtimeData[i][2] - predata[i][0]) / data->lapTime; // ラップ平均電流
hattori_atsushi 0:f77369cabd75 665 data->LapoutData[i][1] = (data->RealtimeData[i][3] - predata[i][1]) / data->lapTime; // ラップ平均電力
hattori_atsushi 0:f77369cabd75 666 data->LapoutData[i][2] = (data->RealtimeData[i][3] - predata[i][1]) / 3600; // ラップ電力量
hattori_atsushi 0:f77369cabd75 667 }
hattori_atsushi 0:f77369cabd75 668 for(i = 0; i < preLapdata_i; i++) {
hattori_atsushi 0:f77369cabd75 669 for(j = 0; j < preLapdata_j; j++) {
hattori_atsushi 0:f77369cabd75 670 predata[i][j] = data->RealtimeData[i][j + 2]; // 前のデータを記憶しておく
hattori_atsushi 0:f77369cabd75 671 }
hattori_atsushi 0:f77369cabd75 672 }
hattori_atsushi 0:f77369cabd75 673 }
hattori_atsushi 0:f77369cabd75 674 }
hattori_atsushi 0:f77369cabd75 675
hattori_atsushi 0:f77369cabd75 676 /*この関数では構造体を引数に,httpリクエスト文を作成しサーバーにポストします
hattori_atsushi 0:f77369cabd75 677 * リクエスト文(POSTデータ) key[]=value1&key[]=value2&...
hattori_atsushi 0:f77369cabd75 678 * keyがp[]でvalueがカンマで結合した1秒間データ(8秒分なので8個作ることになる)
hattori_atsushi 0:f77369cabd75 679 * keyをkey[]形式にするとphp側で添字配列として受け取ることができる
hattori_atsushi 0:f77369cabd75 680 ---骨格---
hattori_atsushi 0:f77369cabd75 681 構造体のデータをchar型に変換してsnprintfでフォーマットしていく(追記方式)
hattori_atsushi 0:f77369cabd75 682 そうして,httpRequest関数に渡す
hattori_atsushi 0:f77369cabd75 683 */
hattori_atsushi 0:f77369cabd75 684 /** データをネット送信
hattori_atsushi 0:f77369cabd75 685 * @param const struct LogData
hattori_atsushi 0:f77369cabd75 686 * @param *httpRes HTTPレスポンスコード
hattori_atsushi 0:f77369cabd75 687 */
hattori_atsushi 0:f77369cabd75 688 int httpPost(const struct LogData postdata[], int *httpRes){
hattori_atsushi 0:f77369cabd75 689 IpAddr ip(133, 68, 205, 140);
hattori_atsushi 0:f77369cabd75 690 Host host;
hattori_atsushi 0:f77369cabd75 691 host.setName("solar-car.club.nitech.ac.jp");
hattori_atsushi 0:f77369cabd75 692 host.setIp(ip);
hattori_atsushi 0:f77369cabd75 693
hattori_atsushi 0:f77369cabd75 694 int i, j, k;
hattori_atsushi 0:f77369cabd75 695 char RequestStr[RequestStr_maxsize] = {0};
hattori_atsushi 0:f77369cabd75 696
hattori_atsushi 0:f77369cabd75 697 // リクエスト文を作成していく
hattori_atsushi 0:f77369cabd75 698 for(k = 0; k < storageTime; k++) {
hattori_atsushi 0:f77369cabd75 699 snprintf(RequestStr, RequestStr_maxsize, "%sp[]=%s,%d,%d,%d,%.2f", // pがkey
hattori_atsushi 0:f77369cabd75 700 RequestStr,
hattori_atsushi 0:f77369cabd75 701 postdata[k].timeStr[1],
hattori_atsushi 0:f77369cabd75 702 postdata[k].lap,
hattori_atsushi 0:f77369cabd75 703 postdata[k].lapTime,
hattori_atsushi 0:f77369cabd75 704 postdata[k].totalTime,
hattori_atsushi 0:f77369cabd75 705 postdata[k].batteryVoltage);
hattori_atsushi 0:f77369cabd75 706 for(j = 0; j < 2; j++) {
hattori_atsushi 0:f77369cabd75 707 for(i = 0; i < RealtimeData_i; i++) {
hattori_atsushi 0:f77369cabd75 708 snprintf(RequestStr, RequestStr_maxsize, "%s,%.1f", RequestStr, postdata[k].RealtimeData[i][j]); // 電流,電力
hattori_atsushi 0:f77369cabd75 709 }
hattori_atsushi 0:f77369cabd75 710 }
hattori_atsushi 0:f77369cabd75 711 for(i = 0; i < RealtimeData_i; i++) {
hattori_atsushi 0:f77369cabd75 712 snprintf(RequestStr, RequestStr_maxsize, "%s,%.1f", RequestStr, postdata[k].RealtimeData[i][4]); // 積算電力
hattori_atsushi 0:f77369cabd75 713 }
hattori_atsushi 0:f77369cabd75 714 snprintf(RequestStr, RequestStr_maxsize, "%s,%.2f,%.2f,%.1f,%.4f,%.4f,%s",
hattori_atsushi 0:f77369cabd75 715 RequestStr,
hattori_atsushi 0:f77369cabd75 716 postdata[k].remainBatteryParcent,
hattori_atsushi 0:f77369cabd75 717 postdata[k].remainBatteryWh,
hattori_atsushi 0:f77369cabd75 718 postdata[k].motorSpeed,
hattori_atsushi 0:f77369cabd75 719 postdata[k].latitude,
hattori_atsushi 0:f77369cabd75 720 postdata[k].longitude,
hattori_atsushi 0:f77369cabd75 721 postdata[k].timeStr[0]);
hattori_atsushi 0:f77369cabd75 722 if(k < (storageTime - 1)) {
hattori_atsushi 0:f77369cabd75 723 snprintf(RequestStr, RequestStr_maxsize, "%s&", RequestStr); // 最後のデータの末尾には&は不要
hattori_atsushi 0:f77369cabd75 724 }
hattori_atsushi 0:f77369cabd75 725 }
hattori_atsushi 0:f77369cabd75 726 *httpRes = httpRequest(METHOD_POST, 8000, &host,"/myLogger/Get/GetRealtimeData.php", "Content-Type: application/x-www-form-urlencoded\r\n", RequestStr);
hattori_atsushi 0:f77369cabd75 727 // debug.printf("%s", RequestStr);
hattori_atsushi 0:f77369cabd75 728
hattori_atsushi 0:f77369cabd75 729 return 0;
hattori_atsushi 0:f77369cabd75 730 }
hattori_atsushi 0:f77369cabd75 731
hattori_atsushi 0:f77369cabd75 732 void LaphttpPost(const struct LogData *data, int *httpRes){
hattori_atsushi 0:f77369cabd75 733 IpAddr ip(133, 68, 205, 140);
hattori_atsushi 0:f77369cabd75 734 Host host;
hattori_atsushi 0:f77369cabd75 735 host.setName("solar-car.club.nitech.ac.jp");
hattori_atsushi 0:f77369cabd75 736 host.setIp(ip);
hattori_atsushi 0:f77369cabd75 737
hattori_atsushi 0:f77369cabd75 738 char LapRequestStr[LapRequestStr_maxsize] = {0};
hattori_atsushi 0:f77369cabd75 739 int i, j;
hattori_atsushi 0:f77369cabd75 740
hattori_atsushi 0:f77369cabd75 741 snprintf(LapRequestStr, LapRequestStr_maxsize, "q=%s,%d,%d", data->timeStr[5], data->lap, data->lapTime);
hattori_atsushi 0:f77369cabd75 742 for(j = 0; j < LapoutData_j; j++) {
hattori_atsushi 0:f77369cabd75 743 for(i = 0; i < LapoutData_i; i++) {
hattori_atsushi 0:f77369cabd75 744 snprintf(LapRequestStr, LapRequestStr_maxsize, "%s,%.2f", LapRequestStr, data->LapoutData[i][j]); // 列に関して出力
hattori_atsushi 0:f77369cabd75 745 }
hattori_atsushi 0:f77369cabd75 746 }
hattori_atsushi 0:f77369cabd75 747 snprintf(LapRequestStr, LapRequestStr_maxsize, "%s,%s", LapRequestStr, data->timeStr[0]);
hattori_atsushi 0:f77369cabd75 748 *httpRes = httpRequest(METHOD_POST, HTTP_TIMEOUT, &host, "/myLogger/Get/GetLapoutData.php", "Content-Type: application/x-www-form-urlencoded\r\n", LapRequestStr);
hattori_atsushi 0:f77369cabd75 749 // debug.printf("%s", LapRequestStr);
hattori_atsushi 0:f77369cabd75 750 }
hattori_atsushi 0:f77369cabd75 751
hattori_atsushi 0:f77369cabd75 752 void EmergencyhttpPost(const struct LogData *data){
hattori_atsushi 0:f77369cabd75 753 IpAddr ip(133, 68, 205, 140);
hattori_atsushi 0:f77369cabd75 754 Host host;
hattori_atsushi 0:f77369cabd75 755 host.setName("solar-car.club.nitech.ac.jp");
hattori_atsushi 0:f77369cabd75 756 host.setIp(ip);
hattori_atsushi 0:f77369cabd75 757
hattori_atsushi 0:f77369cabd75 758 char sendStr[32] = {0};
hattori_atsushi 0:f77369cabd75 759
hattori_atsushi 0:f77369cabd75 760 snprintf(sendStr, 32, "p=%s,%s", data->timeStr[1], data->timeStr[0]);
hattori_atsushi 0:f77369cabd75 761 httpRequest(METHOD_POST, HTTP_TIMEOUT, &host, "/myLogger/Get/GetEmergency.php", "Content-Type: application/x-www-form-urlencoded\r\n", sendStr);
hattori_atsushi 0:f77369cabd75 762 }
hattori_atsushi 0:f77369cabd75 763
hattori_atsushi 0:f77369cabd75 764 /*LCDへのデータ表示を行う locate関数は0行0列からはじまり,引数は(列,行)*/
hattori_atsushi 0:f77369cabd75 765 void LCD(const struct LogData *data){
hattori_atsushi 0:f77369cabd75 766 lcd.locate(0, 0);
hattori_atsushi 0:f77369cabd75 767 lcd.printf("SP");
hattori_atsushi 0:f77369cabd75 768 lcd.locate(3, 0);
hattori_atsushi 0:f77369cabd75 769 lcd.printf("%3.0f", data->motorSpeed);
hattori_atsushi 0:f77369cabd75 770 lcd.locate(7, 0);
hattori_atsushi 0:f77369cabd75 771 lcd.printf("km/h");
hattori_atsushi 0:f77369cabd75 772 lcd.locate(12, 0);
hattori_atsushi 0:f77369cabd75 773 lcd.printf("%s", data->timeStr[1]);
hattori_atsushi 0:f77369cabd75 774
hattori_atsushi 0:f77369cabd75 775 lcd.locate(0, 1);
hattori_atsushi 0:f77369cabd75 776 lcd.printf("B");
hattori_atsushi 0:f77369cabd75 777 lcd.locate(3, 1);
hattori_atsushi 0:f77369cabd75 778 lcd.printf("%5.1f", data->remainBatteryParcent);
hattori_atsushi 0:f77369cabd75 779 lcd.locate(9, 1);
hattori_atsushi 0:f77369cabd75 780 lcd.printf("%%");
hattori_atsushi 0:f77369cabd75 781 lcd.locate(15, 1);
hattori_atsushi 0:f77369cabd75 782 lcd.printf("%s", data->timeStr[3]);
hattori_atsushi 0:f77369cabd75 783
hattori_atsushi 0:f77369cabd75 784 lcd.locate(0, 2);
hattori_atsushi 0:f77369cabd75 785 lcd.printf("V");
hattori_atsushi 0:f77369cabd75 786 lcd.locate(3, 2);
hattori_atsushi 0:f77369cabd75 787 lcd.printf("%5.1f", data->batteryVoltage);
hattori_atsushi 0:f77369cabd75 788 lcd.locate(9, 2);
hattori_atsushi 0:f77369cabd75 789 lcd.printf("V");
hattori_atsushi 0:f77369cabd75 790 lcd.locate(12, 2);
hattori_atsushi 0:f77369cabd75 791 lcd.printf("LAP");
hattori_atsushi 0:f77369cabd75 792 lcd.locate(15, 2);
hattori_atsushi 0:f77369cabd75 793 lcd.printf("%s", data->timeStr[4]);
hattori_atsushi 0:f77369cabd75 794
hattori_atsushi 0:f77369cabd75 795 lcd.locate(0, 3);
hattori_atsushi 0:f77369cabd75 796 lcd.printf("M");
hattori_atsushi 0:f77369cabd75 797 lcd.locate(1, 3);
hattori_atsushi 0:f77369cabd75 798 lcd.printf("%7.1f", data->RealtimeData[2][1]);
hattori_atsushi 0:f77369cabd75 799 lcd.locate(9, 3);
hattori_atsushi 0:f77369cabd75 800 lcd.printf("W");
hattori_atsushi 0:f77369cabd75 801 lcd.locate(12, 3);
hattori_atsushi 0:f77369cabd75 802 lcd.printf("%3.0f", data->LapoutData[2][2]);
hattori_atsushi 0:f77369cabd75 803 lcd.locate(15, 3);
hattori_atsushi 0:f77369cabd75 804 lcd.printf("Wh");
hattori_atsushi 0:f77369cabd75 805 lcd.locate(18, 3);
hattori_atsushi 0:f77369cabd75 806 lcd.printf("%d", data->lap);
hattori_atsushi 0:f77369cabd75 807 }
hattori_atsushi 0:f77369cabd75 808
hattori_atsushi 0:f77369cabd75 809 void ReadyStartLCD(const struct LogData *data){
hattori_atsushi 0:f77369cabd75 810 lcd.locate(2, 0);
hattori_atsushi 0:f77369cabd75 811 lcd.printf(">>Push to Start<<");
hattori_atsushi 0:f77369cabd75 812
hattori_atsushi 0:f77369cabd75 813 lcd.locate(0, 1);
hattori_atsushi 0:f77369cabd75 814 lcd.printf("B");
hattori_atsushi 0:f77369cabd75 815 lcd.locate(2, 1);
hattori_atsushi 0:f77369cabd75 816 lcd.printf("%5.1f", data->remainBatteryParcent);
hattori_atsushi 0:f77369cabd75 817 lcd.locate(8, 1);
hattori_atsushi 0:f77369cabd75 818 lcd.printf("%%");
hattori_atsushi 0:f77369cabd75 819 lcd.locate(11, 1);
hattori_atsushi 0:f77369cabd75 820 lcd.printf("Now Time");
hattori_atsushi 0:f77369cabd75 821
hattori_atsushi 0:f77369cabd75 822 lcd.locate(0, 2);
hattori_atsushi 0:f77369cabd75 823 lcd.printf("V");
hattori_atsushi 0:f77369cabd75 824 lcd.locate(2, 2);
hattori_atsushi 0:f77369cabd75 825 lcd.printf("%5.1f", data->batteryVoltage);
hattori_atsushi 0:f77369cabd75 826 lcd.locate(8, 2);
hattori_atsushi 0:f77369cabd75 827 lcd.printf("V");
hattori_atsushi 0:f77369cabd75 828 lcd.locate(11, 2);
hattori_atsushi 0:f77369cabd75 829 lcd.printf("%s", data->timeStr[1]);
hattori_atsushi 0:f77369cabd75 830
hattori_atsushi 0:f77369cabd75 831 lcd.locate(0, 3);
hattori_atsushi 0:f77369cabd75 832 lcd.printf("P");
hattori_atsushi 0:f77369cabd75 833 lcd.locate(1, 3);
hattori_atsushi 0:f77369cabd75 834 lcd.printf("%6.1f", data->RealtimeData[0][1]);
hattori_atsushi 0:f77369cabd75 835 lcd.locate(8, 3);
hattori_atsushi 0:f77369cabd75 836 lcd.printf("W");
hattori_atsushi 0:f77369cabd75 837 if(myGPS.fix) {
hattori_atsushi 0:f77369cabd75 838 lcd.locate(11, 3);
hattori_atsushi 0:f77369cabd75 839 lcd.printf("GPS OK");
hattori_atsushi 0:f77369cabd75 840 }
hattori_atsushi 0:f77369cabd75 841 }
hattori_atsushi 0:f77369cabd75 842
hattori_atsushi 0:f77369cabd75 843 /*構造体のデータをUSBメモリへデータを保存(csvファイル)*/
hattori_atsushi 0:f77369cabd75 844 int USBSaveData(const struct LogData postdata[], const char name[][fileName_maxsize]){
hattori_atsushi 0:f77369cabd75 845 int i, j, k;
hattori_atsushi 0:f77369cabd75 846 FILE *fp = fopen(name[0], "a");
hattori_atsushi 0:f77369cabd75 847
hattori_atsushi 0:f77369cabd75 848 if(fp == NULL) {
hattori_atsushi 0:f77369cabd75 849 debug.printf("USB can\'t open\n");
hattori_atsushi 0:f77369cabd75 850 return -1;
hattori_atsushi 0:f77369cabd75 851 }
hattori_atsushi 0:f77369cabd75 852 else{
hattori_atsushi 0:f77369cabd75 853 for(k = 0; k < storageTime; k++) {
hattori_atsushi 0:f77369cabd75 854 fprintf(fp, "%s,%d,%d,%d,%.2f,", postdata[k].timeStr[1], postdata[k].lap, postdata[k].lapTime, postdata[k].totalTime, postdata[k].batteryVoltage);
hattori_atsushi 0:f77369cabd75 855 for(j = 0; j < RealtimeData_j; j++) {
hattori_atsushi 0:f77369cabd75 856 for(i = 0; i < RealtimeData_i; i++) {
hattori_atsushi 0:f77369cabd75 857 fprintf(fp, "%.3f,", postdata[k].RealtimeData[i][j]); // 列に関して出力(全データ)
hattori_atsushi 0:f77369cabd75 858 }
hattori_atsushi 0:f77369cabd75 859 }
hattori_atsushi 0:f77369cabd75 860 fprintf(fp, "%.2f,%.2f,%.2f,%.2f,%.2f,%.2f\n", postdata[k].remainBatteryParcent, postdata[k].remainBatteryWh, postdata[k].motorSpeed, postdata[k].motorSpeed_pulse, postdata[k].gpsSpeed, postdata[k].motorAngle);
hattori_atsushi 0:f77369cabd75 861 /*
hattori_atsushi 0:f77369cabd75 862 for(i = 0; i < 3; i++) {
hattori_atsushi 0:f77369cabd75 863 if(i == 2) {
hattori_atsushi 0:f77369cabd75 864 fprintf(fp, "%.5f\n", postdata[k].accData[i]);
hattori_atsushi 0:f77369cabd75 865 }
hattori_atsushi 0:f77369cabd75 866 else{
hattori_atsushi 0:f77369cabd75 867 fprintf(fp, "%.5f,", postdata[k].accData[i]);
hattori_atsushi 0:f77369cabd75 868 }
hattori_atsushi 0:f77369cabd75 869 }
hattori_atsushi 0:f77369cabd75 870 */
hattori_atsushi 0:f77369cabd75 871 }
hattori_atsushi 0:f77369cabd75 872 }
hattori_atsushi 0:f77369cabd75 873 fclose(fp);
hattori_atsushi 0:f77369cabd75 874 return 0;
hattori_atsushi 0:f77369cabd75 875 }
hattori_atsushi 0:f77369cabd75 876
hattori_atsushi 0:f77369cabd75 877 int LapUSBSaveData(const struct LogData *data, const char name[][fileName_maxsize]){
hattori_atsushi 0:f77369cabd75 878 int i, j;
hattori_atsushi 0:f77369cabd75 879
hattori_atsushi 0:f77369cabd75 880 FILE *fp = fopen(name[1], "a");
hattori_atsushi 0:f77369cabd75 881 if(fp == NULL) {
hattori_atsushi 0:f77369cabd75 882 debug.printf("USB can\'t open\n");
hattori_atsushi 0:f77369cabd75 883 return -1;
hattori_atsushi 0:f77369cabd75 884 }
hattori_atsushi 0:f77369cabd75 885 else{
hattori_atsushi 0:f77369cabd75 886 fprintf(fp, "\n%s,%d,%d,%d", data->timeStr[5], data->lap, data->lapTime, data->totalTime);
hattori_atsushi 0:f77369cabd75 887 for(j = 0; j < LapoutData_j; j++) {
hattori_atsushi 0:f77369cabd75 888 for(i = 0; i < LapoutData_i; i++) {
hattori_atsushi 0:f77369cabd75 889 fprintf(fp, ",%7.2f", data->LapoutData[i][j]); // 列に関して(ラップ平均等の全データ)
hattori_atsushi 0:f77369cabd75 890 }
hattori_atsushi 0:f77369cabd75 891 }
hattori_atsushi 0:f77369cabd75 892 }
hattori_atsushi 0:f77369cabd75 893 fclose(fp);
hattori_atsushi 0:f77369cabd75 894
hattori_atsushi 0:f77369cabd75 895 return 0;
hattori_atsushi 0:f77369cabd75 896 }
hattori_atsushi 0:f77369cabd75 897
hattori_atsushi 0:f77369cabd75 898 /** 蓄積されているデータをcsvファイルにバックアップ
hattori_atsushi 0:f77369cabd75 899 * @param const strct LogData
hattori_atsushi 0:f77369cabd75 900 * @param const double predata
hattori_atsushi 0:f77369cabd75 901 * @param time_t preTime
hattori_atsushi 0:f77369cabd75 902 */
hattori_atsushi 0:f77369cabd75 903 int SaveBackup(const struct LogData *data, const double predata[][preLapdata_j], time_t preTime){
hattori_atsushi 0:f77369cabd75 904 int i, j;
hattori_atsushi 0:f77369cabd75 905
hattori_atsushi 0:f77369cabd75 906 FILE *fp_back = fopen("/usb/backup.csv", "w");
hattori_atsushi 0:f77369cabd75 907 if(fp_back == NULL) {
hattori_atsushi 0:f77369cabd75 908 debug.printf("USB can\'t open!\n");
hattori_atsushi 0:f77369cabd75 909 return -1;
hattori_atsushi 0:f77369cabd75 910 }
hattori_atsushi 0:f77369cabd75 911 else{
hattori_atsushi 0:f77369cabd75 912 fprintf(fp_back, "%d,%d,%d,%d\r\n", data->lap, data->totalTime, (unsigned int)startUnixTime, (unsigned int)preTime);
hattori_atsushi 0:f77369cabd75 913 for(i = 0; i < RealtimeData_i; i++) {
hattori_atsushi 0:f77369cabd75 914 for(j = 0; j < 2; j++) {
hattori_atsushi 0:f77369cabd75 915 fprintf(fp_back, "%f,", data->RealtimeData[i][j+2]); // 電流和,電力和
hattori_atsushi 0:f77369cabd75 916 }
hattori_atsushi 0:f77369cabd75 917 fprintf(fp_back, "\r\n");
hattori_atsushi 0:f77369cabd75 918 }
hattori_atsushi 0:f77369cabd75 919 for(i = 0; i < preLapdata_i; i++) {
hattori_atsushi 0:f77369cabd75 920 for(j = 0; j < preLapdata_j; j++) {
hattori_atsushi 0:f77369cabd75 921 fprintf(fp_back, "%f,", predata[i][j]);
hattori_atsushi 0:f77369cabd75 922 }
hattori_atsushi 0:f77369cabd75 923 fprintf(fp_back, "\r\n");
hattori_atsushi 0:f77369cabd75 924 }
hattori_atsushi 0:f77369cabd75 925 }
hattori_atsushi 0:f77369cabd75 926 fclose(fp_back);
hattori_atsushi 0:f77369cabd75 927
hattori_atsushi 0:f77369cabd75 928 return 0;
hattori_atsushi 0:f77369cabd75 929 }
hattori_atsushi 0:f77369cabd75 930
hattori_atsushi 0:f77369cabd75 931 /*基本はhttp通信を使いますが,何かあったときにシリアル通信できるようにしておきます
hattori_atsushi 0:f77369cabd75 932 *送信データは基本的にラップ数,ラップタイム,LapoutData
hattori_atsushi 0:f77369cabd75 933 */
hattori_atsushi 0:f77369cabd75 934 void XbeeSerial(const struct LogData *data){
hattori_atsushi 0:f77369cabd75 935 int i, j;
hattori_atsushi 0:f77369cabd75 936 char SerialSendStr[SerialSendStr_maxsize] = {0};
hattori_atsushi 0:f77369cabd75 937
hattori_atsushi 0:f77369cabd75 938 snprintf(SerialSendStr, SerialSendStr_maxsize, "\nLAP: %d, %s, BV:%6.2f[V],%6.2f[%%],%7.2f[Wh],\n",
hattori_atsushi 0:f77369cabd75 939 data->lap,
hattori_atsushi 0:f77369cabd75 940 data->timeStr[4],
hattori_atsushi 0:f77369cabd75 941 data->batteryVoltage,
hattori_atsushi 0:f77369cabd75 942 data->remainBatteryParcent,
hattori_atsushi 0:f77369cabd75 943 data->remainBatteryWh);
hattori_atsushi 0:f77369cabd75 944 snprintf(SerialSendStr, SerialSendStr_maxsize, "%s Battery, Panel, Motor\nAllAve[W]: ", SerialSendStr);
hattori_atsushi 0:f77369cabd75 945 for(i = 0; i < RealtimeData_i; i++) {
hattori_atsushi 0:f77369cabd75 946 snprintf(SerialSendStr, SerialSendStr_maxsize, "%s%7.2f,", SerialSendStr, data->RealtimeData[i][4]); // 平均電力
hattori_atsushi 0:f77369cabd75 947 }
hattori_atsushi 0:f77369cabd75 948 snprintf(SerialSendStr, SerialSendStr_maxsize, "%s\nlapAve[W]: ", SerialSendStr); // 改行
hattori_atsushi 0:f77369cabd75 949 for(j = 1; j < LapoutData_j; j++) {
hattori_atsushi 0:f77369cabd75 950 for(i = 0; i < LapoutData_i; i++) {
hattori_atsushi 0:f77369cabd75 951 snprintf(SerialSendStr, SerialSendStr_maxsize, "%s%7.2f,", SerialSendStr, data->LapoutData[i][j]); // ラップ平均,積算
hattori_atsushi 0:f77369cabd75 952 }
hattori_atsushi 0:f77369cabd75 953 if(j == 1) snprintf(SerialSendStr, SerialSendStr_maxsize, "%s\nlapWh[Wh]: ", SerialSendStr); // 改行
hattori_atsushi 0:f77369cabd75 954 }
hattori_atsushi 0:f77369cabd75 955 Xbee.printf("%s\n", SerialSendStr); // Xbeeでシリアル送信
hattori_atsushi 0:f77369cabd75 956 }
hattori_atsushi 0:f77369cabd75 957
hattori_atsushi 0:f77369cabd75 958 // 絶縁監視機能(漏れ電流測定)
hattori_atsushi 0:f77369cabd75 959 // 電流の値が0.5A以下の場合は例外
hattori_atsushi 0:f77369cabd75 960 // バッテリ+パネル電流ーモータ電流が1A以上になった場合、エラー出力
hattori_atsushi 0:f77369cabd75 961 void InsulateMonitor(const struct LogData *data){
hattori_atsushi 0:f77369cabd75 962 bool stopDecison = false;
hattori_atsushi 0:f77369cabd75 963
hattori_atsushi 0:f77369cabd75 964 for(int i = 0; i < RealtimeData_i; i++) {
hattori_atsushi 0:f77369cabd75 965 if(data->RealtimeData[i][0] < 0.5) {
hattori_atsushi 0:f77369cabd75 966 stopDecison = true;
hattori_atsushi 0:f77369cabd75 967 break;
hattori_atsushi 0:f77369cabd75 968 }
hattori_atsushi 0:f77369cabd75 969 }
hattori_atsushi 0:f77369cabd75 970 if(!stopDecison) {
hattori_atsushi 0:f77369cabd75 971 if((data->RealtimeData[0][0] + data->RealtimeData[1][0] - data->RealtimeData[2][0]) < 1) {
hattori_atsushi 0:f77369cabd75 972 isoError = 0; // 正常
hattori_atsushi 0:f77369cabd75 973 }
hattori_atsushi 0:f77369cabd75 974 else{
hattori_atsushi 0:f77369cabd75 975 // isoError = 1; // エラー
hattori_atsushi 0:f77369cabd75 976 }
hattori_atsushi 0:f77369cabd75 977 }
hattori_atsushi 0:f77369cabd75 978 }
hattori_atsushi 0:f77369cabd75 979