ボタンを押すと、 バッテリ更新を停止し、 他のボタンもロックさせる
Dependencies: RemoteIR TextLCD
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2019 ARM Limited 00003 * SPDX-License-Identifier: Apache-2.0 00004 */ 00005 00006 #include "mbed.h" 00007 #include "ReceiverIR.h" 00008 #include "rtos.h" 00009 #include <stdint.h> 00010 #include "platform/mbed_thread.h" 00011 #include "TextLCD.h" 00012 00013 RawSerial pc(USBTX, USBRX); 00014 00015 /* マクロ定義、列挙型定義 */ 00016 #define MIN_V 2.0 // 電圧の最小値 00017 #define MAX_V 2.67 // 電圧の最大値 00018 #define LOW 0 // モーターOFF 00019 #define HIGH 1 // モーターON 00020 #define NORMAL 0 // 普通 00021 #define FAST 1 // 速い 00022 #define VERYFAST 2 // とても速い 00023 00024 /* 操作モード定義 */ 00025 enum MODE{ 00026 READY = -1, // -1:待ち 00027 ADVANCE = 1, // 1:前進 00028 RIGHT, // 2:右折 00029 LEFT, // 3:左折 00030 BACK, // 4:後退 00031 STOP, // 5:停止 00032 LINE_TRACE, // 6:ライントレース 00033 AVOIDANCE, // 7:障害物回避 00034 SPEED, // 8:スピード制御 00035 }; 00036 00037 /* ピン配置 */ 00038 ReceiverIR ir(p5); // リモコン操作 00039 DigitalOut trig(p6); // 超音波センサtrigger 00040 DigitalOut pred(p16); 00041 DigitalOut pblue(p19); 00042 00043 DigitalIn echo(p7); // 超音波センサecho 00044 DigitalIn ss1(p8); // ライントレースセンサ(左) 00045 DigitalIn ss2(p9); // ライントレースセンサ 00046 DigitalIn ss3(p10); // ライントレースセンサ 00047 DigitalIn ss4(p11); // ライントレースセンサ 00048 DigitalIn ss5(p12); // ライントレースセンサ(右) 00049 RawSerial esp(p13, p14); // Wi-Fiモジュール(tx, rx) 00050 AnalogIn battery(p15); // 電池残量読み取り(Max 3.3V) 00051 PwmOut motorR2(p21); // 右モーター後退 00052 PwmOut motorR1(p22); // 右モーター前進 00053 PwmOut motorL2(p23); // 左モーター後退 00054 PwmOut motorL1(p24); // 左モーター前進 00055 PwmOut servo(p25); // サーボ 00056 I2C i2c_lcd(p28,p27); // LCD(tx, rx) 00057 00058 /* 変数宣言 */ 00059 int mode; // 操作モード 00060 int run; // 走行状態 00061 int beforeMode; // 前回のモード 00062 int flag_sp = 0; // スピード変化フラグ 00063 Timer viewTimer; // スピ―ド変更時に3秒計測タイマー 00064 float motorSpeed[9] = {0.4, 0.7, 0.8, 0.7, 0.8, 0.9, 0.8, 0.9, 1.0}; 00065 // モーター速度設定(後半はライントレース用) 00066 00067 Mutex mutex; // ミューテックス 00068 00069 /* decodeIR用変数 */ 00070 RemoteIR::Format format; 00071 uint8_t buf[32]; 00072 uint32_t bitcount; 00073 uint32_t code; 00074 00075 /* bChange, lcdbacklight用変数 */ 00076 TextLCD_I2C lcd(&i2c_lcd, (0x27 << 1), TextLCD::LCD16x2, TextLCD::HD44780); 00077 int b = 0; // バッテリー残量 00078 int flag_b = 0; // バックライト点滅フラグ 00079 int flag_t = 0; // バックライトタイマーフラグ 00080 00081 /* trace用変数 */ 00082 int sensArray[32] = {0,6,2,4,1,1,2,2, // ライントレースセンサパターン 00083 3,1,1,1,3,1,1,2, 00084 7,1,1,1,1,1,1,1, 00085 5,1,1,1,3,1,3,1}; 00086 00087 /* avoidance用変数 */ 00088 Timer timer; // 距離計測用タイマ 00089 int DT; // 距離 00090 int SC; // 正面 00091 int SL; // 左 00092 int SR; // 右 00093 int SLD; // 左前 00094 int SRD; // 右前 00095 int flag_a = 0; // 障害物有無のフラグ 00096 const int limit = 20; // 障害物の距離のリミット(単位:cm) 00097 int far; // 最も遠い距離 00098 int houkou; // 進行方向(1:前 2:左 3:右) 00099 int t1 = 0; 00100 00101 /*WiFi用変数*/ 00102 Timer time1; 00103 Timer time2; 00104 int bufflen, DataRX, ount, getcount, replycount, servreq, timeout; 00105 int bufl, ipdLen, linkID, weberror, webcounter,click_flag; 00106 float R1=100000, R2=10000; // resistor values to give a 10:1 reduction of measured AnalogIn voltage 00107 char webcount[8]; 00108 char type[16]; 00109 char channel[2]; 00110 char cmdbuff[32]; 00111 char replybuff[1024]; 00112 char webdata[1024]; // This may need to be bigger depending on WEB browser used 00113 char webbuff[4096]; // Currently using 1986 characters, Increase this if more web page data added 00114 int port =80; // set server port 00115 int SERVtimeout =5; // set server timeout in seconds in case link breaks. 00116 char ssid[32] = "mbed02"; // enter WiFi router ssid inside the quotes 00117 char pwd [32] = "0123456789a"; // enter WiFi router password inside the quotes 00118 00119 00120 /* プロトタイプ宣言 */ 00121 void decodeIR(/*void const *argument*/); 00122 void motor(/*void const *argument*/); 00123 void changeSpeed(); 00124 void avoidance(/*void const *argument*/); 00125 void trace(/*void const *argument*/); 00126 void watchsurrounding3(); 00127 void watchsurrounding5(); 00128 int watch(); 00129 char battery_ch[8]; 00130 void bChange(); 00131 void display(); 00132 void lcdBacklight(void const *argument); 00133 void SendCMD(),getreply(),ReadWebData(),startserver(),sendpage(),SendWEB(),sendcheck(); 00134 void wifi(/*void const *argument*/); 00135 Thread *deco_thread; // decodeIRをスレッド化 :+3 00136 Thread *wifi_thread; 00137 //wifi_thread(wifi,NULL,osPriorityHigh); // wifiをスレッド化 00138 Thread *motor_thread; // motorをスレッド化 :+2 00139 //Thread avoi_thread(avoidance, NULL, osPriorityHigh); // avoidanceをスレッド化:+2 00140 //Thread trace_thread(trace, NULL, osPriorityHigh); // traceをスレッド化 :+2 00141 RtosTimer bTimer(lcdBacklight, osTimerPeriodic); // lcdBacklightをタイマー割り込みで設定 00142 //Ticker bTimer; 00143 Thread *avoi_thread; 00144 Thread *trace_thread; 00145 00146 DigitalOut led1(LED1); 00147 DigitalOut led2(LED2); 00148 DigitalOut led3(LED3); 00149 DigitalOut led4(LED4); 00150 00151 void setup(){ 00152 deco_thread = new Thread(decodeIR); 00153 deco_thread -> set_priority(osPriorityRealtime); 00154 motor_thread = new Thread(motor); 00155 motor_thread -> set_priority(osPriorityHigh); 00156 wifi_thread -> set_priority(osPriorityRealtime); 00157 display(); 00158 } 00159 00160 /* リモコン受信スレッド */ 00161 void decodeIR(/*void const *argument*/){ 00162 while(1){ 00163 // 受信待ち 00164 if (ir.getState() == ReceiverIR::Received){ // コード受信 00165 bitcount = ir.getData(&format, buf, sizeof(buf) * 8); 00166 if(bitcount > 1){ // 受信成功 00167 code=0; 00168 for(int j = 0; j < 4; j++){ 00169 code+=(buf[j]<<(8*(3-j))); 00170 } 00171 if(mode != SPEED){ // スピードモード以外なら 00172 beforeMode=mode; // 前回のモードに現在のモードを設定 00173 } 00174 switch(code){ 00175 case 0x40bf27d8: // クイック 00176 //pc.printf("mode = SPEED\r\n"); 00177 mode = SPEED; // スピードモード 00178 changeSpeed(); // 速度変更 00179 display(); // ディスプレイ表示 00180 mode = beforeMode; // 現在のモードに前回のモードを設定 00181 break; 00182 case 0x40be34cb: // レグザリンク 00183 //pc.printf("mode = LINE_TRACE\r\n"); 00184 if(trace_thread->get_state() == Thread::Deleted){ 00185 delete trace_thread; 00186 trace_thread = new Thread(trace); 00187 trace_thread -> set_priority(osPriorityHigh); 00188 } 00189 mode=LINE_TRACE; // ライントレースモード 00190 display(); // ディスプレイ表示 00191 break; 00192 case 0x40bf6e91: // 番組表 00193 //pc.printf("mode = AVOIDANCE\r\n"); 00194 if(avoi_thread->get_state() == Thread::Deleted){ 00195 delete avoi_thread; 00196 avoi_thread = new Thread(avoidance); 00197 avoi_thread -> set_priority(osPriorityHigh); 00198 } 00199 flag_a = 0; 00200 mode=AVOIDANCE; // 障害物回避モード 00201 run = ADVANCE; // 前進 00202 display(); // ディスプレイ表示 00203 break; 00204 case 0x40bf3ec1: // ↑ 00205 //pc.printf("mode = ADVANCE\r\n"); 00206 mode = ADVANCE; // 前進モード 00207 run = ADVANCE; // 前進 00208 display(); // ディスプレイ表示 00209 break; 00210 case 0x40bf3fc0: // ↓ 00211 //pc.printf("mode = BACK\r\n"); 00212 mode = BACK; // 後退モード 00213 run = BACK; // 後退 00214 display(); // ディスプレイ表示 00215 break; 00216 case 0x40bf5fa0: // ← 00217 //pc.printf("mode = LEFT\r\n"); 00218 mode = LEFT; // 左折モード 00219 run = LEFT; // 左折 00220 display(); // ディスプレイ表示 00221 break; 00222 case 0x40bf5ba4: // → 00223 //pc.printf("mode = RIGHT\r\n"); 00224 mode = RIGHT; // 右折モード 00225 run = RIGHT; // 右折 00226 display(); // ディスプレイ表示 00227 break; 00228 case 0x40bf3dc2: // 決定 00229 //pc.printf("mode = STOP\r\n"); 00230 mode = STOP; // 停止モード 00231 run = STOP; // 停止 00232 display(); // ディスプレイ表示 00233 break; 00234 default: 00235 ; 00236 } 00237 if(mode != LINE_TRACE && trace_thread->get_state() != Thread::Deleted){ 00238 trace_thread->terminate(); 00239 } 00240 if(mode != AVOIDANCE && avoi_thread->get_state() != Thread::Deleted){ 00241 avoi_thread->terminate(); 00242 servo.pulsewidth_us(1450); // サーボを中央位置に戻す 00243 } 00244 } 00245 } 00246 if(viewTimer.read_ms()>=3000){ // スピードモードのまま3秒経過 00247 viewTimer.stop(); // タイマーストップ 00248 viewTimer.reset(); // タイマーリセット 00249 display(); // ディスプレイ表示 00250 } 00251 ThisThread::sleep_for(90); // 90ms待つ 00252 } 00253 } 00254 00255 /* モーター制御スレッド */ 00256 void motor(/*void const *argument*/){ 00257 while(1){ 00258 /* 走行状態の場合分け */ 00259 switch(run){ 00260 /* 前進 */ 00261 case ADVANCE: 00262 motorR1 = motorSpeed[flag_sp]; // 右前進モーターON 00263 motorR2 = LOW; // 右後退モーターOFF 00264 motorL1 = motorSpeed[flag_sp]; // 左前進モーターON 00265 motorL2 = LOW; // 左後退モーターOFF 00266 break; 00267 /* 右折 */ 00268 case RIGHT: 00269 motorR1 = LOW; // 右前進モーターOFF 00270 motorR2 = motorSpeed[flag_sp]; // 右後退モーターON 00271 motorL1 = motorSpeed[flag_sp]; // 左前進モーターON 00272 motorL2 = LOW; // 左後退モーターOFF 00273 break; 00274 /* 左折 */ 00275 case LEFT: 00276 motorR1 = motorSpeed[flag_sp]; // 右前進モーターON 00277 motorR2 = LOW; // 右後退モーターOFF 00278 motorL1 = LOW; // 左前進モーターOFF 00279 motorL2 = motorSpeed[flag_sp]; // 左後退モーターON 00280 break; 00281 /* 後退 */ 00282 case BACK: 00283 motorR1 = LOW; // 右前進モーターOFF 00284 motorR2 = motorSpeed[flag_sp]; // 右後退モーターON 00285 motorL1 = LOW; // 左前進モーターOFF 00286 motorL2 = motorSpeed[flag_sp]; // 左後退モーターON 00287 break; 00288 /* 停止 */ 00289 case STOP: 00290 motorR1 = LOW; // 右前進モーターOFF 00291 motorR2 = LOW; // 右後退モーターOFF 00292 motorL1 = LOW; // 左前進モーターOFF 00293 motorL2 = LOW; // 左後退モーターOFF 00294 break; 00295 } 00296 if(flag_sp > VERYFAST){ // スピード変更フラグが2より大きいなら 00297 flag_sp %= 3; // スピード変更フラグ調整 00298 } 00299 ThisThread::sleep_for(30); // 30ms待つ 00300 } 00301 } 00302 00303 /* スピード変更関数 */ 00304 void changeSpeed(){ 00305 if(flag_sp%3 == 2){ // スピード変更フラグを3で割った余りが2なら 00306 flag_sp -= 2; // スピード変更フラグを-2 00307 00308 }else{ // それ以外 00309 flag_sp = flag_sp + 1; // スピード変更フラグを+1 00310 } 00311 } 00312 00313 /* ライントレーススレッド */ 00314 void trace(){ 00315 while(1){ 00316 /* 各センサー値読み取り */ 00317 int sensor1 = ss1; 00318 int sensor2 = ss2; 00319 int sensor3 = ss3; 00320 int sensor4 = ss4; 00321 int sensor5 = ss5; 00322 pc.printf("%d %d %d %d %d \r\n",sensor1,sensor2,sensor3,sensor4,sensor5); 00323 int sensD = 0; 00324 00325 /* センサー値の決定 */ 00326 if(sensor1 > 0) sensD |= 0x10; 00327 if(sensor2 > 0) sensD |= 0x08; 00328 if(sensor3 > 0) sensD |= 0x04; 00329 if(sensor4 > 0) sensD |= 0x02; 00330 if(sensor5 > 0) sensD |= 0x01; 00331 00332 /* センサー値によって場合分け */ 00333 switch(sensArray[sensD]){ 00334 case 1: 00335 run = ADVANCE; // 低速で前進 00336 break; 00337 case 2: 00338 // flag_sp = flag_sp % 3 + 6; 00339 run = RIGHT; // 低速で右折 00340 break; 00341 case 3: 00342 // flag_sp = flag_sp % 3 + 6; 00343 run = LEFT; // 低速で左折 00344 break; 00345 case 4: 00346 flag_sp = flag_sp % 3 + 3; 00347 run = RIGHT; // 中速で右折 00348 break; 00349 case 5: 00350 flag_sp = flag_sp % 3 + 3; 00351 run = LEFT; // 中速で左折 00352 break; 00353 case 6: 00354 flag_sp = flag_sp % 3 + 6; 00355 run = RIGHT; // 高速で右折 00356 break; 00357 case 7: 00358 flag_sp = flag_sp % 3 + 6; 00359 run = LEFT; // 高速で左折 00360 break; 00361 default: 00362 break; // 前回動作を継続 00363 } 00364 ThisThread::sleep_for(30); // 30ms待つ 00365 } 00366 } 00367 00368 /* 障害物回避走行スレッド */ 00369 void avoidance(){ 00370 int i; 00371 while(1){ 00372 watchsurrounding3(); 00373 pc.printf("%d %d %d %d %d \r\n",SL,SLD,SC,SRD,SR); 00374 if(flag_a == 0){ // 障害物がない場合 00375 run = ADVANCE; // 前進 00376 }else{ // 障害物がある場合 00377 i = 0; 00378 if(SC < 15){ // 正面15cm以内に障害物が現れた場合 00379 servo.pulsewidth_us(1450); // サーボを中央位置に戻す 00380 ThisThread::sleep_for(100); // 100ms待つ 00381 run = BACK; // 後退 00382 int cnt_kyori=0; 00383 int kyori = watch(); 00384 while(kyori < limit){ // 正面20cm以内に障害物がある間 00385 if(kyori==-1){ 00386 cnt_kyori++; 00387 if(cnt_kyori>15){ 00388 cnt_kyori=0; 00389 break; 00390 } 00391 } 00392 kyori = watch(); 00393 } 00394 /*while(i < 30){ // 正面20cm以内に障害物がある間 00395 if(watch() < limit){ 00396 break; 00397 } 00398 i++; 00399 } 00400 i = 0;*/ 00401 run = STOP; // 停止 00402 } 00403 watchsurrounding5(); 00404 if(SC < limit && SLD < limit && SL < limit && SRD < limit && SR < limit){ // 全方向に障害物がある場合 00405 run = LEFT; // 左折 00406 while(i < 1){ // 進行方向確認 00407 if(watch() > limit){ 00408 i++; 00409 }else{ 00410 i = 0; 00411 } 00412 } 00413 run = STOP; // 停止 00414 }else { // 全方向以外 00415 far = SC; // 正面を最も遠い距離に設定 00416 houkou = 1; // 進行方向を前に設定 00417 if(far < SLD || far < SL){ // 左または左前がより遠い場合 00418 if(SL < SLD){ // 左前が左より遠い場合 00419 far = SLD; // 左前を最も遠い距離に設定 00420 }else{ // 左が左前より遠い場合 00421 far = SL; // 左を最も遠い距離に設定 00422 } 00423 houkou = 2; // 進行方向を左に設定 00424 } 00425 if(far < SRD || far < SR){ // 右または右前がより遠い場合 00426 if(SR < SRD){ // 右前が右より遠い場合 00427 far = SRD; // 右前を最も遠い距離に設定 00428 }else{ // 右が右前よりも遠い場合 00429 far = SR; // 右を最も遠い距離に設定 00430 } 00431 houkou = 3; // 進行方向を右に設定 00432 } 00433 switch(houkou){ // 進行方向の場合分け 00434 case 1: // 前の場合 00435 run = ADVANCE; // 前進 00436 ThisThread::sleep_for(500); // 0.5秒待つ 00437 break; 00438 case 2: // 左の場合 00439 run = LEFT; // 左折 00440 //int kyori = watch(); 00441 //int kyori_f=0; 00442 while(i < 20){ // 進行方向確認 00443 /*if(kyori > (far - 2) || kyori_f == 2){ // 正面の計測距離と最も遠い距離が一致したら(誤差-2cm) 00444 break; // ループ+ 00445 }else if(kyori==-1){ 00446 kyori_f++; 00447 }else{ 00448 kyori_f = 0; 00449 i++; 00450 }*/ 00451 if(watch() > (far - 2)){ // 正面の計測距離と最も遠い距離が一致したら(誤差-2cm) 00452 break; // ループ+ 00453 }else{ 00454 i++; 00455 } 00456 } 00457 run = STOP; // 停止 00458 break; 00459 case 3: // 右の場合 00460 run = RIGHT; // 右折 00461 //int kyori = watch(); 00462 //int kyori_f=0; 00463 while(i < 20){ // 進行方向確認 00464 /*if(kyori > (far - 2) || kyori_f == 2){ // 正面の計測距離と最も遠い距離が一致したら(誤差-2cm) 00465 break; // ループ+ 00466 }else if(kyori==-1){ 00467 kyori_f++; 00468 }else{ 00469 kyori_f = 0; 00470 i++; 00471 }*/ 00472 if(watch() > (far - 2)){ // 正面の計測距離と最も遠い距離が一致したら(誤差-2cm) 00473 break; // ループ+ 00474 }else{ 00475 i++; 00476 } 00477 } 00478 run = STOP; // 停止 00479 break; 00480 } 00481 } 00482 } 00483 flag_a = 0; // 障害物有無フラグを0にセット 00484 if(SLD < 29){ // 正面15cm以内に障害物が現れた場合 00485 run = RIGHT; // 右折 00486 ThisThread::sleep_for(200); // 100ms待つ 00487 run = STOP; // 停止 00488 }else if(SRD < 29){ 00489 run = LEFT; // 左折 00490 ThisThread::sleep_for(200); // 100ms待つ 00491 run = STOP; // 停止 00492 } 00493 } 00494 } 00495 00496 /* 距離計測関数 */ 00497 int watch(){ 00498 do{ 00499 trig = 0; 00500 ThisThread::sleep_for(5); // 5ms待つ 00501 trig = 1; 00502 ThisThread::sleep_for(15); // 15ms待つ 00503 trig = 0; 00504 timer.start(); 00505 t1=timer.read_ms(); 00506 while(echo.read() == 0 && t1<10){ 00507 t1=timer.read_ms(); 00508 led1 = 1; 00509 } 00510 timer.stop(); 00511 timer.reset(); 00512 /*if((t1-t2) >= 10){ 00513 run = STOP;*/ 00514 }while(t1 >= 10); 00515 timer.start(); // 距離計測タイマースタート 00516 while(echo.read() == 1){ 00517 } 00518 timer.stop(); // 距離計測タイマーストップ 00519 DT = (int)(timer.read_us()*0.01657); // 距離計算 00520 if(DT > 1000){ 00521 DT = -1; 00522 }else if(DT > 150){ // 検知範囲外なら100cmに設定 00523 DT = 150; 00524 } 00525 timer.reset(); // 距離計測タイマーリセット 00526 led1 = 0; 00527 return DT; 00528 } 00529 00530 /* 障害物検知関数 */ 00531 void watchsurrounding3(){ 00532 //servo.pulsewidth_us(1450); // サーボを中央位置に戻す 00533 //ThisThread::sleep_for(200); // 100ms待つ 00534 SC = watch(); 00535 if(SC < limit){ // 正面20cm以内に障害物がある場合 00536 if(SC!=-1){ 00537 run = STOP; // 停止 00538 flag_a = 1; 00539 return; 00540 } 00541 } 00542 servo.pulsewidth_us(1925); // サーボを左に40度回転 00543 ThisThread::sleep_for(100); // 250ms待つ 00544 SLD = watch(); 00545 if(SLD < limit){ // 左前20cm以内に障害物がある場合 00546 run = STOP; // 停止 00547 flag_a = 1; 00548 return; 00549 } 00550 servo.pulsewidth_us(1450); 00551 ThisThread::sleep_for(150); 00552 SC = watch(); 00553 if(SC < limit){ 00554 if(SC!=-1){ 00555 run = STOP; // 停止 00556 flag_a = 1; 00557 return; 00558 } 00559 } 00560 servo.pulsewidth_us(925); // サーボを右に40度回転 00561 ThisThread::sleep_for(100); // 250ms待つ 00562 SRD = watch(); 00563 if(SRD < limit){ // 右前20cm以内に障害物がある場合 00564 run = STOP; // 停止 00565 flag_a = 1; 00566 return; 00567 } 00568 servo.pulsewidth_us(1450); // サーボを中央位置に戻す 00569 ThisThread::sleep_for(100); // 100ms待つ 00570 /*if(SC < limit || SLD < limit || SL < limit || SRD < limit || SR < limit){ // 20cm以内に障害物を検知した場合 00571 flag_a = 1; // 障害物有無フラグに1をセット 00572 }*/ 00573 } 00574 00575 /* 障害物検知関数 */ 00576 void watchsurrounding5(){ 00577 //servo.pulsewidth_us(1450); // サーボを中央位置に戻す 00578 //ThisThread::sleep_for(200); // 100ms待つ 00579 SC = watch(); 00580 servo.pulsewidth_us(1925); // サーボを左に40度回転 00581 ThisThread::sleep_for(100); // 250ms待つ 00582 SLD = watch(); 00583 servo.pulsewidth_us(2400); // サーボを左に90度回転 00584 ThisThread::sleep_for(100); // 250ms待つ 00585 SL = watch(); 00586 servo.pulsewidth_us(1450); 00587 ThisThread::sleep_for(250); 00588 SC = watch(); 00589 servo.pulsewidth_us(925); // サーボを右に40度回転 00590 ThisThread::sleep_for(100); // 250ms待つ 00591 SRD = watch(); 00592 servo.pulsewidth_us(500); // サーボを右に90度回転 00593 ThisThread::sleep_for(100); // 250ms待つ 00594 SR = watch(); 00595 servo.pulsewidth_us(1450); // サーボを中央位置に戻す 00596 ThisThread::sleep_for(250); // 100ms待つ 00597 } 00598 00599 /* ディスプレイ表示関数 */ 00600 void display(){ 00601 mutex.lock(); // ミューテックスロック 00602 lcd.setAddress(0,1); 00603 00604 /* 操作モードによる場合分け */ 00605 switch(mode){ 00606 /* 前進 */ 00607 case ADVANCE: 00608 lcd.printf("Mode:Advance "); 00609 break; 00610 /* 右折 */ 00611 case RIGHT: 00612 lcd.printf("Mode:TurnRight "); 00613 break; 00614 /* 左折 */ 00615 case LEFT: 00616 lcd.printf("Mode:TurnLeft "); 00617 break; 00618 /* 後退 */ 00619 case BACK: 00620 lcd.printf("Mode:Back "); 00621 break; 00622 /* 停止 */ 00623 case STOP: 00624 lcd.printf("Mode:Stop "); 00625 break; 00626 /* 待ち */ 00627 case READY: 00628 lcd.printf("Mode:Ready "); 00629 break; 00630 /* ライントレース */ 00631 case LINE_TRACE: 00632 lcd.printf("Mode:LineTrace "); 00633 break; 00634 /* 障害物回避 */ 00635 case AVOIDANCE: 00636 lcd.printf("Mode:Avoidance "); 00637 break; 00638 /* スピード制御 */ 00639 case SPEED: 00640 /* スピードの状態で場合分け */ 00641 switch(flag_sp){ 00642 /* 普通 */ 00643 case(NORMAL): 00644 lcd.printf("Speed:Normal "); 00645 break; 00646 /* 速い */ 00647 case(FAST): 00648 lcd.printf("Speed:Fast "); 00649 break; 00650 /* とても速い */ 00651 case(VERYFAST): 00652 lcd.printf("Speed:VeryFast "); 00653 break; 00654 } 00655 viewTimer.reset(); // タイマーリセット 00656 viewTimer.start(); // タイマースタート 00657 break; 00658 } 00659 mutex.unlock(); // ミューテックスアンロック 00660 } 00661 00662 /* バックライト点滅 */ 00663 void lcdBacklight(void const *argument){ 00664 if(flag_b == 1){ // バックライト点滅フラグが1なら 00665 lcd.setBacklight(TextLCD::LightOn); // バックライトON 00666 }else{ // バックライト点滅フラグが0なら 00667 lcd.setBacklight(TextLCD::LightOff); // バックライトOFF 00668 } 00669 flag_b = !flag_b; // バックライト点滅フラグ切り替え 00670 } 00671 00672 /* バッテリー残量更新関数 */ 00673 void bChange(){ 00674 //pc.printf(" bChange1\r\n"); 00675 b = (int)(((battery.read() * 3.3 - MIN_V)/0.67)*10+0.5)*10; 00676 if(b <= 0){ // バッテリー残量0%なら全ての機能停止 00677 b = 0; 00678 //lcd.setBacklight(TextLCD::LightOff); 00679 //run = STOP; 00680 //exit(1); // 電池残量が5%未満の時、LCDを消灯し、モーターを停止し、プログラムを終了する。 00681 } 00682 mutex.lock(); // ミューテックスロック 00683 lcd.setAddress(0,0); 00684 lcd.printf("Battery:%3d%%",b); // バッテリー残量表示 00685 mutex.unlock(); // ミューテックスアンロック 00686 if(b <= 30){ // バッテリー残量30%以下なら 00687 if(flag_t == 0){ // バックライトタイマーフラグが0なら 00688 //bTimer.attach(lcdBacklight,0.5); 00689 bTimer.start(500); // 0.5秒周期でバックライトタイマー割り込み 00690 flag_t = 1; // バックライトタイマーフラグを1に切り替え 00691 } 00692 }else{ 00693 if(flag_t == 1){ // バックライトタイマーフラグが1なら 00694 //bTimer.detach(); 00695 bTimer.stop(); // バックライトタイマーストップ 00696 lcd.setBacklight(TextLCD::LightOn); // バックライトON 00697 flag_t = 0; // バックライトタイマーフラグを0に切り替え 00698 } 00699 } 00700 } 00701 00702 // Serial Interrupt read ESP data 00703 void callback() 00704 { 00705 //pc.printf("\n\r------------ callback is being called --------------\n\r"); 00706 led3=1; 00707 while (esp.readable()) { 00708 webbuff[ount] = esp.getc(); 00709 ount++; 00710 } 00711 if(strlen(webbuff)>bufflen) { 00712 pc.printf("\f\n\r------------ webbuff over bufflen --------------\n\r"); 00713 DataRX=1; 00714 led3=0; 00715 } 00716 } 00717 00718 void wifi(/*void const *argument*/) 00719 { 00720 pc.printf("\f\n\r------------ ESP8266 Hardware Reset psq --------------\n\r"); 00721 ThisThread::sleep_for(100); 00722 led1=1,led2=0,led3=0; 00723 timeout=6000; 00724 getcount=500; 00725 getreply(); 00726 esp.baud(115200); // ESP8266 baudrate. Maximum on KLxx' is 115200, 230400 works on K20 and K22F 00727 startserver(); 00728 00729 while(1) { 00730 if(DataRX==1) { 00731 pc.printf("\f\n\r------------ main while > if --------------\n\r"); 00732 click_flag = 1; 00733 ReadWebData(); 00734 pc.printf("\f\n\r------------ click_flag=%d --------------\n\r",click_flag); 00735 //if ((servreq == 1 && weberror == 0) && click_flag == 1) { 00736 if (servreq == 1 && weberror == 0) { 00737 pc.printf("\f\n\r------------ befor send page --------------\n\r"); 00738 sendpage(); 00739 } 00740 pc.printf("\f\n\r------------ send_check begin --------------\n\r"); 00741 00742 //sendcheck(); 00743 pc.printf("\f\n\r------------ ssend_check end--------------\n\r"); 00744 00745 esp.attach(&callback); 00746 pc.printf(" IPD Data:\r\n\n Link ID = %d,\r\n IPD Header Length = %d \r\n IPD Type = %s\r\n", linkID, ipdLen, type); 00747 pc.printf("\n\n HTTP Packet: \n\n%s\n", webdata); 00748 pc.printf(" Web Characters sent : %d\n\n", bufl); 00749 pc.printf(" -------------------------------------\n\n"); 00750 servreq=0; 00751 } 00752 ThisThread::sleep_for(100); 00753 } 00754 } 00755 // Static WEB page 00756 void sendpage() 00757 { 00758 // WEB page data 00759 00760 strcpy(webbuff, "<!DOCTYPE html>"); 00761 strcat(webbuff, "<html><head><title>RobotCar</title><meta name='viewport' content='width=device-width'/>"); 00762 //strcat(webbuff, "<meta http-equiv=\"refresh\" content=\"5\"; >"); 00763 strcat(webbuff, "<style type=\"text/css\">.noselect{ width:100px;height:60px;}.light{ width:100px;height:60px;background-color:#00ff66;}.load{ width: 50px; height: 30px;font-size:10px}</style>"); 00764 strcat(webbuff, "</head><body><center><p><strong>Robot Car Remote Controller"); 00765 strcat(webbuff, "</strong></p><td style='vertical-align:top;'><strong>Battery level "); 00766 /* 00767 if(b > 30) { //残電量表示 00768 sprintf(webbuff, "%s%3d", webbuff, b); 00769 } else { //30%より下の場合残電量を赤文字 00770 strcat(webbuff, "<font color=\"red\">"); 00771 sprintf(webbuff, "%s%3d", webbuff, b); 00772 strcat(webbuff, "</font>"); 00773 }*/ 00774 strcat(webbuff, "<input type=\"text\" id=\"leftms\" size=4 value=250>%</strong>"); 00775 strcat(webbuff, "<button id=\"reloadbtn\" type=\"button\" class=\"load\" onclick=\"rel()\">RELOAD</button>"); 00776 strcat(webbuff, "</td></p>"); 00777 strcat(webbuff, "<br>"); 00778 strcat(webbuff, "<table><tr><td></td><td>"); 00779 00780 switch(mode) { //ブラウザ更新時の現在の車の状態からボタンの点灯判定 00781 case ADVANCE: //前進 00782 strcat(webbuff, "<button id='gobtn' type='button' class=\"light\" value=\"GO\" onClick='send_mes(this.id,this.value)'>GO"); 00783 strcat(webbuff, "</button></td><td></td></tr><tr><td>"); 00784 strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.id,this.value)' >LEFT"); 00785 strcat(webbuff, "</button></td><td>"); 00786 strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.id,this.value)' >STOP"); 00787 strcat(webbuff, "</button></td><td>"); 00788 strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.id,this.value)' >RIGHT"); 00789 strcat(webbuff, "</button></td></tr><td></td><td>"); 00790 strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.id,this.value)' >BACK"); 00791 strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>"); 00792 strcat(webbuff, "<strong>Mode</strong>"); 00793 strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.id,this.value)' >"); 00794 strcat(webbuff, "AVOIDANCE</button></td><td>"); 00795 strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.id,this.value)' >LINE_TRACE"); 00796 break; 00797 case LEFT: //左折 00798 strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.id,this.value)'>GO"); 00799 strcat(webbuff, "</button></td><td></td></tr><tr><td>"); 00800 strcat(webbuff, "<button id='leftbtn' type='button' class=\"light\" value=\"LEFT\" onClick='send_mes(this.id,this.value)' >LEFT"); 00801 strcat(webbuff, "</button></td><td>"); 00802 strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.id,this.value)' >STOP"); 00803 strcat(webbuff, "</button></td><td>"); 00804 strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.id,this.value)' >RIGHT"); 00805 strcat(webbuff, "</button></td></tr><td></td><td>"); 00806 strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.id,this.value)' >BACK"); 00807 strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>"); 00808 strcat(webbuff, "<strong>Mode</strong>"); 00809 strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.id,this.value)' >"); 00810 strcat(webbuff, "AVOIDANCE</button></td><td>"); 00811 strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.id,this.value)' >LINE_TRACE"); 00812 break; 00813 case STOP: //停止 00814 strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.id,this.value)'>GO"); 00815 strcat(webbuff, "</button></td><td></td></tr><tr><td>"); 00816 strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.id,this.value)' >LEFT"); 00817 strcat(webbuff, "</button></td><td>"); 00818 strcat(webbuff, "<button id='stopbtn' type='button' class=\"light\" value=\"STOP\" onClick='send_mes(this.id,this.value)' >STOP"); 00819 strcat(webbuff, "</button></td><td>"); 00820 strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.id,this.value)' >RIGHT"); 00821 strcat(webbuff, "</button></td></tr><td></td><td>"); 00822 strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.id,this.value)' >BACK"); 00823 strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>"); 00824 strcat(webbuff, "<strong>Mode</strong>"); 00825 strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.id,this.value)' >"); 00826 strcat(webbuff, "AVOIDANCE</button></td><td>"); 00827 strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.id,this.value)' >LINE_TRACE"); 00828 break; 00829 case RIGHT: //右折 00830 strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.id,this.value)'>GO"); 00831 strcat(webbuff, "</button></td><td></td></tr><tr><td>"); 00832 strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.id,this.value)' >LEFT"); 00833 strcat(webbuff, "</button></td><td>"); 00834 strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.id,this.value)' >STOP"); 00835 strcat(webbuff, "</button></td><td>"); 00836 strcat(webbuff, "<button id='rightbtn' type='button' class=\"light\" value=\"RIGHT\" onClick='send_mes(this.id,this.value)' >RIGHT"); 00837 strcat(webbuff, "</button></td></tr><td></td><td>"); 00838 strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.id,this.value)' >BACK"); 00839 strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>"); 00840 strcat(webbuff, "<strong>Mode</strong>"); 00841 strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.id,this.value)' >"); 00842 strcat(webbuff, "AVOIDANCE</button></td><td>"); 00843 strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.id,this.value)' >LINE_TRACE"); 00844 break; 00845 case BACK: //後進 00846 strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.id,this.value)'>GO"); 00847 strcat(webbuff, "</button></td><td></td></tr><tr><td>"); 00848 strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.id,this.value)' >LEFT"); 00849 strcat(webbuff, "</button></td><td>"); 00850 strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.id,this.value)' >STOP"); 00851 strcat(webbuff, "</button></td><td>"); 00852 strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.id,this.value)' >RIGHT"); 00853 strcat(webbuff, "</button></td></tr><td></td><td>"); 00854 strcat(webbuff, "<button id='backbtn' type='button' class=\"light\" value=\"BACK\" onClick='send_mes(this.id,this.value)' >BACK"); 00855 strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr><td>"); 00856 strcat(webbuff, "<strong>Mode</strong>"); 00857 strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.id,this.value)' >"); 00858 strcat(webbuff, "AVOIDANCE</button></td><td>"); 00859 strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.id,this.value)' >LINE_TRACE"); 00860 break; 00861 case AVOIDANCE: //障害物回避 00862 strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.id,this.value)'>GO"); 00863 strcat(webbuff, "</button></td><td></td></tr><tr><td>"); 00864 strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.id,this.value)' >LEFT"); 00865 strcat(webbuff, "</button></td><td>"); 00866 strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.id,this.value)' >STOP"); 00867 strcat(webbuff, "</button></td><td>"); 00868 strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.id,this.value)' >RIGHT"); 00869 strcat(webbuff, "</button></td></tr><td></td><td>"); 00870 strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.id,this.value)' >BACK"); 00871 strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>"); 00872 strcat(webbuff, "<strong>Mode</strong>"); 00873 strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"light\" value=\"AVOIDANCE\" onClick='send_mes(this.id,this.value)' >"); 00874 strcat(webbuff, "AVOIDANCE</button></td><td>"); 00875 strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.id,this.value)' >LINE_TRACE"); 00876 break; 00877 case LINE_TRACE: //ライントレース 00878 strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.id,this.value)'>GO"); 00879 strcat(webbuff, "</button></td><td></td></tr><tr><td>"); 00880 strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.id,this.value)' >LEFT"); 00881 strcat(webbuff, "</button></td><td>"); 00882 strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.id,this.value)' >STOP"); 00883 strcat(webbuff, "</button></td><td>"); 00884 strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.id,this.value)' >RIGHT"); 00885 strcat(webbuff, "</button></td></tr><td></td><td>"); 00886 strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.id,this.value)' >BACK"); 00887 strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>"); 00888 strcat(webbuff, "<strong>Mode</strong>"); 00889 strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.id,this.value)' >"); 00890 strcat(webbuff, "AVOIDANCE</button></td><td>"); 00891 strcat(webbuff, "<button id='tracebtn' type='button' class=\"light\" value=\"LINE_TRACE\" onClick='send_mes(this.id,this.value)' >LINE_TRACE"); 00892 break; 00893 default: //その他 00894 strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.id,this.value)'>GO"); 00895 strcat(webbuff, "</button></td><td></td></tr><tr><td>"); 00896 strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.id,this.value)' >LEFT"); 00897 strcat(webbuff, "</button></td><td>"); 00898 strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.id,this.value)' >STOP"); 00899 strcat(webbuff, "</button></td><td>"); 00900 strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.id,this.value)' >RIGHT"); 00901 strcat(webbuff, "</button></td></tr><td></td><td>"); 00902 strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.id,this.value)' >BACK"); 00903 strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>"); 00904 strcat(webbuff, "<strong>Mode</strong>"); 00905 strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.id,this.value)' >"); 00906 strcat(webbuff, "AVOIDANCE</button></td><td>"); 00907 strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.id,this.value)' >LINE_TRACE"); 00908 break; 00909 } 00910 strcat(webbuff, "</button></td></tr></table>"); 00911 strcat(webbuff, "<strong>Speed</strong>"); 00912 strcat(webbuff, "<table><tr><td>"); 00913 //ready示速度だけ点灯 00914 switch (flag_sp) { //現在の速度のボタン表示 00915 case 0: //ノーマル 00916 strcat(webbuff, "<button id='sp1btn' type='button' class=\"light\" value=\"Normal\" onClick='send_mes_spe(this.id,this.value)' >Normal"); 00917 strcat(webbuff, "</button></td><td>"); 00918 strcat(webbuff, "<button id='sp2btn' type='button' class=\"noselect\" value=\"Fast\" onClick='send_mes_spe(this.id,this.value)' >Fast"); 00919 strcat(webbuff, "</button></td><td>"); 00920 strcat(webbuff, "<button id='sp3btn' type='button' class=\"noselect\" value=\"VeryFast\" onClick='send_mes_spe(this.id,this.value)' >VeryFast"); 00921 break; 00922 case 1: //ファスト 00923 strcat(webbuff, "<button id='sp1btn' type='button' class=\"noselect\" value=\"Normal\" onClick='send_mes_spe(this.id,this.value)' >Normal"); 00924 strcat(webbuff, "</button></td><td>"); 00925 strcat(webbuff, "<button id='sp2btn' type='button' class=\"light\" value=\"Fast\" onClick='send_mes_spe(this.id,this.value)' >Fast"); 00926 strcat(webbuff, "</button></td><td>"); 00927 strcat(webbuff, "<button id='sp3btn' type='button' class=\"noselect\" value=\"VeryFast\" onClick='send_mes_spe(this.id,this.value)' >VeryFast"); 00928 break; 00929 case 2: //ベリーファスト 00930 strcat(webbuff, "<button id='sp1btn' type='button' class=\"noselect\" value=\"Normal\" onClick='send_mes_spe(this.id,this.value)' >Normal"); 00931 strcat(webbuff, "</button></td><td>"); 00932 strcat(webbuff, "<button id='sp2btn' type='button' class=\"noselect\" value=\"Fast\" onClick='send_mes_spe(this.id,this.value)' >Fast"); 00933 strcat(webbuff, "</button></td><td>"); 00934 strcat(webbuff, "<button id='sp3btn' type='button' class=\"light\" value=\"VeryFast\" onClick='send_mes_spe(this.id,this.value)' >VeryFast"); 00935 break; 00936 default: //その他 00937 strcat(webbuff, "<button id='sp1btn' type='button' class=\"noselect\" value=\"Normal\" onClick='send_mes_spe(this.id,this.value)' >Normal"); 00938 strcat(webbuff, "</button></td><td>"); 00939 strcat(webbuff, "<button id='sp2btn' type='button' class=\"noselect\" value=\"Fast\" onClick='send_mes_spe(this.id,this.value)' >Fast"); 00940 strcat(webbuff, "</button></td><td>"); 00941 strcat(webbuff, "<button id='sp3btn' type='button' class=\"noselect\" value=\"VeryFast\" onClick='send_mes_spe(this.id,this.value)' >VeryFast"); 00942 break; 00943 } 00944 strcat(webbuff, "</button></td></tr></table>"); 00945 00946 strcat(webbuff, "</center>"); 00947 strcat(webbuff, "</body>"); 00948 strcat(webbuff, "</html>"); 00949 strcat(webbuff, "<script language=\"javascript\" type=\"text/javascript\">"); //機能 00950 00951 strcat(webbuff, "function rel(){"); 00952 strcat(webbuff, "location.reload();"); 00953 strcat(webbuff, "}"); 00954 00955 // 00956 strcat(webbuff, "var button_9 = document.getElementsByTagName(\"button\");"); 00957 00958 00959 00960 strcat(webbuff, "function htmlacs(url) {"); 00961 strcat(webbuff, "clearInterval(si);"); 00962 //0827 00963 strcat(webbuff, "for(var m=0;m<11;m++){"); 00964 strcat(webbuff, "button_9[m].disabled=true;}"); 00965 //0827 00966 strcat(webbuff, "var xhr = new XMLHttpRequest();"); 00967 strcat(webbuff, "xhr.open(\"GET\", url);"); 00968 00969 //0826 00970 strcat(webbuff, "xhr.onreadystatechange = function(){"); 00971 strcat(webbuff, "if(this.readyState == 4 && this.status == 200){"); 00972 strcat(webbuff, "console.log(\"apologize for\");"); 00973 ////0827 00974 strcat(webbuff, "for(var m=0;m<10;m++){"); 00975 strcat(webbuff, "button_9[m].disabled=false;}"); 00976 //0827 00977 strcat(webbuff, "var si = setInterval(battery_update,15000);"); 00978 00979 strcat(webbuff, "}"); 00980 strcat(webbuff, "};"); 00981 00982 00983 //0826 00984 00985 00986 strcat(webbuff, "xhr.send(\"\");"); 00987 strcat(webbuff, "}"); 00988 00989 00990 //0825 00991 // 00992 //0824 battery update auto 00993 strcat(webbuff, "function battery_update() {"); 00994 strcat(webbuff, "var url1 = \"http://\" + window.location.hostname+ \"/cargo?a=responseBattery\";"); 00995 strcat(webbuff, "var xhr1 = new XMLHttpRequest();"); 00996 strcat(webbuff, "xhr1.open(\"GET\", url1);"); 00997 //0820 00998 strcat(webbuff, "xhr1.onreadystatechange = function(){"); 00999 //strcat(webbuff, "console.log(\"onready function is being reload!\");"); 01000 strcat(webbuff, "if(this.readyState == 4 && this.status == 200){"); 01001 //strcat(webbuff, "console.log(\"state is being reload!\");"); 01002 strcat(webbuff, "var res1 = xhr1.responseText;"); 01003 01004 //color 01005 strcat(webbuff, "var battery_num=res1;"); 01006 strcat(webbuff, "if(battery_num>0 && battery_num<31){"); 01007 strcat(webbuff, "document.getElementById('leftms').style.color=\"red\";"); 01008 strcat(webbuff, "}"); 01009 strcat(webbuff, "if(battery_num>39 && battery_num<61){"); 01010 strcat(webbuff, "document.getElementById('leftms').style.color=\"orange\";"); 01011 strcat(webbuff, "}"); 01012 strcat(webbuff, "if(battery_num>69 && battery_num<101){"); 01013 strcat(webbuff, "document.getElementById('leftms').style.color=\"blue\";"); 01014 strcat(webbuff, "}"); 01015 //color 01016 strcat(webbuff, "document.getElementById('leftms').value=res1;}};"); 01017 01018 01019 //strcat(webbuff, "console.log(res);}};"); 01020 //0820 01021 01022 strcat(webbuff, "xhr1.send();"); 01023 strcat(webbuff, "}"); 01024 strcat(webbuff, "var si = setInterval(battery_update,15000);"); 01025 01026 //0824 battery update auto 01027 //0825 01028 01029 01030 strcat(webbuff, "function send_mes(btnmes,btnval){"); //mode変更ボタン入力時の点灯消灯判定 01031 strcat(webbuff, "console.log(btnval);"); 01032 01033 strcat(webbuff, "var url = \"http://\" + window.location.hostname + \"/cargo?a=\" + btnval;"); 01034 strcat(webbuff, "htmlacs(url);"); 01035 strcat(webbuff, "console.log(url);"); 01036 strcat(webbuff, "var buttons = document.getElementsByTagName(\"button\");"); 01037 strcat(webbuff, "for(var i=1;i<8;i++){"); 01038 strcat(webbuff, "if(buttons[i].value == btnval){"); 01039 strcat(webbuff, "buttons[i].className=\"light\";"); 01040 strcat(webbuff, "}else{"); 01041 strcat(webbuff, "buttons[i].className=\"noselect\";"); 01042 strcat(webbuff, "}"); 01043 strcat(webbuff, "}"); 01044 strcat(webbuff, "}"); 01045 01046 strcat(webbuff, "function send_mes_spe(btnmes,btnval){"); //speed変更ボタン入力時の点灯消灯判定 01047 strcat(webbuff, "var url = \"http://\" + window.location.hostname + \"/cargo?a=\" + btnval;"); 01048 strcat(webbuff, "htmlacs(url);"); 01049 strcat(webbuff, "console.log(url);"); 01050 strcat(webbuff, "var buttons = document.getElementsByTagName(\"button\");"); 01051 strcat(webbuff, "for(var i=8;i<11;i++){"); 01052 strcat(webbuff, "if(buttons[i].value == btnval){"); 01053 strcat(webbuff, "buttons[i].className=\"light\";"); 01054 strcat(webbuff, "}else{"); 01055 strcat(webbuff, "buttons[i].className=\"noselect\";"); 01056 strcat(webbuff, "}"); 01057 strcat(webbuff, "}"); 01058 strcat(webbuff, "}"); 01059 strcat(webbuff, "</script>"); 01060 // end of WEB page data 01061 bufl = strlen(webbuff); // get total page buffer length 01062 //sprintf(cmdbuff,"AT+CIPSEND=%d,%d\r\n", linkID, bufl); // send IPD link channel and buffer character length. 01063 01064 sprintf(cmdbuff,"AT+CIPSENDBUF=%d,%d\r\n", linkID, (bufl>2048?2048:bufl)); // send IPD link channel and buffer character length. 01065 timeout=500; 01066 getcount=40; 01067 SendCMD(); 01068 getreply(); 01069 pc.printf(replybuff); 01070 //pc.printf("\n++++++++++ AT+CIPSENDBUF=%d,%d+++++++++\r\n", linkID, (bufl>2048?2048:bufl)); 01071 01072 pc.printf("\n++++++++++ bufl is %d ++++++++++\r\n",bufl); 01073 01074 //pastthrough mode 01075 SendWEB(); // send web page 01076 pc.printf("\n++++++++++ webbuff clear ++++++++++\r\n"); 01077 01078 memset(webbuff, '\0', sizeof(webbuff)); 01079 sendcheck(); 01080 } 01081 01082 // Large WEB buffer data send 01083 void SendWEB() 01084 { 01085 int i=0; 01086 if(esp.writeable()) { 01087 while(webbuff[i]!='\0') { 01088 esp.putc(webbuff[i]); 01089 01090 //**** 01091 //output at command when 2000 01092 if(((i%2047)==0) && (i>0)) { 01093 //wait_ms(10); 01094 ThisThread::sleep_for(10); //0827 100 01095 sprintf(cmdbuff,"AT+CIPSENDBUF=%d,%d\r\n", linkID, (bufl-2048*(i/2047))>2048?2048:(bufl-2048*(i/2047))); // send IPD link channel and buffer character length. 01096 //pc.printf("\r\n++++++++++ AT+CIPSENDBUF=%d,%d ++++++++++\r\n", linkID, (bufl-2048)>2048?2048:(bufl-2048)); 01097 timeout=600; 01098 getcount=50; 01099 SendCMD(); 01100 getreply(); 01101 //pc.printf(replybuff); 01102 //pc.printf("\r\n+++++++++++++++++++\r\n"); 01103 } 01104 //**** 01105 i++; 01106 //pc.printf("%c",webbuff[i]); 01107 } 01108 } 01109 pc.printf("\n++++++++++ send web i= %dinfo ++++++++++\r\n",i); 01110 } 01111 01112 void sendpage2() 01113 { 01114 // WEB page data 01115 pred=!pred; 01116 //strcpy(webbuff, "<script language=\"javascript\" type=\"text/javascript\">"); 01117 //strcat(webbuff, "document.getElementById('leftms').value=\"100\";"); 01118 01119 sprintf(battery_ch,"%d",b); 01120 //sprintf(battery_ch,"%d",30); 01121 strcpy(webbuff, battery_ch); 01122 01123 //strcpy(webbuff, "document.getElementById('leftms').value=\"100\";"); 01124 01125 //strcat(webbuff, "</script>"); 01126 // end of WEB page data 01127 bufl = strlen(webbuff); // get total page buffer length 01128 //sprintf(cmdbuff,"AT+CIPSEND=%d,%d\r\n", linkID, bufl); // send IPD link channel and buffer character length. 01129 01130 sprintf(cmdbuff,"AT+CIPSENDBUF=%d,%d\r\n", linkID, (bufl>2048?2048:bufl)); // send IPD link channel and buffer character length. 01131 timeout=500; 01132 getcount=40; 01133 SendCMD(); 01134 getreply(); 01135 pc.printf(replybuff); 01136 pc.printf("\n++++++++++ AT+CIPSENDBUF=%d,%d+++++++++\r\n", linkID, (bufl>2048?2048:bufl)); 01137 01138 pc.printf("\n++++++++++ bufl is %d ++++++++++\r\n",bufl); 01139 01140 //pastthrough mode 01141 SendWEB(); // send web page 01142 pc.printf("\n++++++++++ webbuff clear ++++++++++\r\n"); 01143 01144 memset(webbuff, '\0', sizeof(webbuff)); 01145 sendcheck(); 01146 } 01147 01148 01149 void sendpage3() 01150 { 01151 // WEB page data 01152 pblue=!pblue; 01153 //strcpy(webbuff, "<script language=\"javascript\" type=\"text/javascript\">"); 01154 //strcat(webbuff, "document.getElementById('leftms').value=\"100\";"); 01155 01156 sprintf(battery_ch,"%d",b); 01157 //sprintf(battery_ch,"%d",30); 01158 strcpy(webbuff, battery_ch); 01159 01160 //strcpy(webbuff, "document.getElementById('leftms').value=\"100\";"); 01161 01162 //strcat(webbuff, "</script>"); 01163 // end of WEB page data 01164 bufl = strlen(webbuff); // get total page buffer length 01165 //sprintf(cmdbuff,"AT+CIPSEND=%d,%d\r\n", linkID, bufl); // send IPD link channel and buffer character length. 01166 01167 sprintf(cmdbuff,"AT+CIPSENDBUF=%d,%d\r\n", linkID, (bufl>2048?2048:bufl)); // send IPD link channel and buffer character length. 01168 timeout=500; 01169 getcount=40; 01170 SendCMD(); 01171 getreply(); 01172 pc.printf(replybuff); 01173 pc.printf("\n++++++++++ AT+CIPSENDBUF=%d,%d+++++++++\r\n", linkID, (bufl>2048?2048:bufl)); 01174 01175 pc.printf("\n++++++++++ bufl is %d ++++++++++\r\n",bufl); 01176 01177 //pastthrough mode 01178 SendWEB(); // send web page 01179 pc.printf("\n++++++++++ webbuff clear ++++++++++\r\n"); 01180 01181 memset(webbuff, '\0', sizeof(webbuff)); 01182 sendcheck(); 01183 } 01184 01185 01186 void sendcheck() 01187 { 01188 weberror=1; 01189 timeout=500; 01190 getcount=24; 01191 time2.reset(); 01192 time2.start(); 01193 01194 /* 01195 while(weberror==1 && time2.read() <5) { 01196 getreply(); 01197 if (strstr(replybuff, "SEND OK") != NULL) { 01198 weberror=0; // wait for valid SEND OK 01199 } 01200 } 01201 */ 01202 if(weberror==1) { // restart connection 01203 strcpy(cmdbuff, "AT+CIPMUX=1\r\n"); 01204 timeout=500; 01205 getcount=10; 01206 SendCMD(); 01207 getreply(); 01208 pc.printf(replybuff); 01209 sprintf(cmdbuff,"AT+CIPSERVER=1,%d\r\n", port); 01210 timeout=500; 01211 getcount=10; 01212 SendCMD(); 01213 getreply(); 01214 pc.printf(replybuff); 01215 } else { 01216 sprintf(cmdbuff, "AT+CIPCLOSE=%s\r\n",channel); // close current connection 01217 SendCMD(); 01218 getreply(); 01219 pc.printf(replybuff); 01220 } 01221 time2.reset(); 01222 } 01223 01224 // Reads and processes GET and POST web data 01225 void ReadWebData() 01226 { 01227 pc.printf("+++++++++++++++++Read Web Data+++++++++++++++++++++\r\n"); 01228 ThisThread::sleep_for(200); 01229 esp.attach(NULL); 01230 ount=0; 01231 DataRX=0; 01232 weberror=0; 01233 memset(webdata, '\0', sizeof(webdata)); 01234 int x = strcspn (webbuff,"+"); 01235 if(x) { 01236 strcpy(webdata, webbuff + x); 01237 weberror=0; 01238 int numMatched = sscanf(webdata,"+IPD,%d,%d:%s", &linkID, &ipdLen, type); 01239 //int i=0; 01240 pc.printf("+++++++++++++++++succed rec begin+++++++++++++++++++++\r\n"); 01241 pc.printf("%s",webdata); 01242 pc.printf("+++++++++++++++++succed rec end+++++++++++++++++++++\r\n"); 01243 01244 if( strstr(webdata, "responseBattery") != NULL ) { 01245 click_flag = 0; 01246 led4=!led4; 01247 pc.printf("\r\n++++++++++++++mode = LEFT++++++++++++++\r\n"); 01248 sendpage2(); 01249 } 01250 01251 if( strstr(webdata, "GO") != NULL ) { 01252 sendpage3(); 01253 01254 pc.printf("+++++++++++++++++前進+++++++++++++++++++++\r\n"); 01255 //delete avoi_thread; //障害物回避スレッド停止 01256 //delete trace_thread; //ライントレーススレッド停止 01257 run = ADVANCE; // 前進 01258 mode = ADVANCE; // モード変更 01259 display(); // ディスプレイ表示 01260 //0826 01261 led1=!led1; 01262 led2=!led2; 01263 led3=!led3; 01264 click_flag = 0; 01265 //0826 01266 } 01267 01268 01269 if( strstr(webdata, "Normal") != NULL ) { 01270 pc.printf("++++++++++++++++++Normal++++++++++++++++++++"); 01271 mode = SPEED; // スピードモード 01272 flag_sp = 0; 01273 display(); // ディスプレイ表示 01274 mode = beforeMode; // 現在のモードに前回のモードを設定 01275 }else if( strstr(webdata, "VeryFast") != NULL ) { 01276 pc.printf("+++++++++++++++++++VeryFast+++++++++++++++++++"); 01277 mode = SPEED; // スピードモード 01278 flag_sp = 2; 01279 display(); // ディスプレイ表示 01280 mode = beforeMode; // 現在のモードに前回のモードを設定 01281 }else if( strstr(webdata, "Fast") != NULL ) { 01282 pc.printf("++++++++++++++++++++Fast++++++++++++++++++"); 01283 mode = SPEED; // スピードモード 01284 flag_sp = 1; 01285 display(); // ディスプレイ表示 01286 mode = beforeMode; // 現在のモードに前回のモードを設定 01287 }else{ 01288 beforeMode = mode; 01289 } 01290 /* 01291 if( strstr(webdata, "GO") != NULL ) { 01292 sendpage3(); 01293 01294 pc.printf("+++++++++++++++++前進+++++++++++++++++++++\r\n"); 01295 //delete avoi_thread; //障害物回避スレッド停止 01296 //delete trace_thread; //ライントレーススレッド停止 01297 run = ADVANCE; // 前進 01298 mode = ADVANCE; // モード変更 01299 display(); // ディスプレイ表示 01300 //0826 01301 led1=!led1; 01302 led2=!led2; 01303 led3=!led3; 01304 click_flag = 0; 01305 //0826 01306 } 01307 */ 01308 if( strstr(webdata, "LEFT") != NULL ) { 01309 pc.printf("+++++++++++++++++左折+++++++++++++++++++++\r\n"); 01310 //delete avoi_thread; //障害物回避スレッド停止 01311 //delete trace_thread; //ライントレーススレッド停止 01312 run = LEFT; // 左折 01313 mode = LEFT; // モード変更 01314 display(); // ディスプレイ表示 01315 } 01316 01317 if( strstr(webdata, "STOP") != NULL ) { 01318 pc.printf("+++++++++++++++++停止+++++++++++++++++++++\r\n"); 01319 //delete avoi_thread; //障害物回避スレッド停止 01320 //delete trace_thread; //ライントレーススレッド停止 01321 run = STOP; // 停止 01322 mode = STOP; // モード変更 01323 display(); // ディスプレイ表示 01324 } 01325 01326 if( strstr(webdata, "RIGHT") != NULL ) { 01327 pc.printf("+++++++++++++++++右折+++++++++++++++++++++\r\n"); 01328 //delete avoi_thread; //障害物回避スレッド停止 01329 //delete trace_thread; //ライントレーススレッド停止 01330 run = RIGHT; // 右折 01331 mode = RIGHT; // モード変更 01332 display(); // ディスプレイ表示 01333 } 01334 01335 if( strstr(webdata, "BACK") != NULL ) { 01336 pc.printf("+++++++++++++++++後進+++++++++++++++++++++\r\n"); 01337 //delete avoi_thread; //障害物回避スレッド停止 01338 //delete trace_thread; //ライントレーススレッド停止 01339 run = BACK; // 後進 01340 mode = BACK; // モード変更 01341 display(); // ディスプレイ表示 01342 } 01343 pc.printf("+++++++++++++++++succed+++++++++++++++++++++"); 01344 01345 if( strstr(webdata, "AVOIDANCE") != NULL ) { 01346 pc.printf("+++++++++++++++++AVOIDANCE+++++++++++++++++++++"); 01347 if(avoi_thread->get_state() == Thread::Deleted) { 01348 delete avoi_thread; //障害物回避スレッド停止 01349 avoi_thread = new Thread(avoidance); 01350 avoi_thread -> set_priority(osPriorityHigh); 01351 } 01352 mode=AVOIDANCE; 01353 run = ADVANCE; 01354 display(); // ディスプレイ表示 01355 } 01356 if( strstr(webdata, "LINE_TRACE") != NULL ) { 01357 pc.printf("+++++++++++++++++LINET RACE+++++++++++++++++++++"); 01358 pc.printf("mode = LINE_TRACE\r\n"); 01359 if(trace_thread->get_state() == Thread::Deleted) { 01360 delete trace_thread; //ライントレーススレッド停止 01361 trace_thread = new Thread(trace); 01362 trace_thread -> set_priority(osPriorityHigh); 01363 } 01364 mode=LINE_TRACE; 01365 display(); // ディスプレイ表示 01366 } 01367 if(mode != LINE_TRACE && trace_thread->get_state() != Thread::Deleted){ 01368 trace_thread->terminate(); 01369 } 01370 if(mode != AVOIDANCE && avoi_thread->get_state() != Thread::Deleted){ 01371 avoi_thread->terminate(); 01372 servo.pulsewidth_us(1450); // サーボを中央位置に戻す 01373 } 01374 sprintf(channel, "%d",linkID); 01375 if (strstr(webdata, "GET") != NULL) { 01376 servreq=1; 01377 } 01378 if (strstr(webdata, "POST") != NULL) { 01379 servreq=1; 01380 } 01381 webcounter++; 01382 sprintf(webcount, "%d",webcounter); 01383 } else { 01384 memset(webbuff, '\0', sizeof(webbuff)); 01385 esp.attach(&callback); 01386 weberror=1; 01387 } 01388 } 01389 // Starts and restarts webserver if errors detected. 01390 void startserver() 01391 { 01392 pc.printf("++++++++++ Resetting ESP ++++++++++\r\n"); 01393 strcpy(cmdbuff,"AT+RST\r\n"); 01394 timeout=8000; 01395 getcount=1000; 01396 SendCMD(); 01397 getreply(); 01398 pc.printf(replybuff); 01399 pc.printf("%d",ount); 01400 if (strstr(replybuff, "OK") != NULL) { 01401 pc.printf("\n++++++++++ Starting Server ++++++++++\r\n"); 01402 strcpy(cmdbuff, "AT+CIPMUX=1\r\n"); // set multiple connections. 01403 timeout=500; 01404 getcount=20; 01405 SendCMD(); 01406 getreply(); 01407 pc.printf(replybuff); 01408 sprintf(cmdbuff,"AT+CIPSERVER=1,%d\r\n", port); 01409 timeout=500; 01410 getcount=20; 01411 SendCMD(); 01412 getreply(); 01413 pc.printf(replybuff); 01414 ThisThread::sleep_for(500); 01415 sprintf(cmdbuff,"AT+CIPSTO=%d\r\n",SERVtimeout); 01416 timeout=500; 01417 getcount=50; 01418 SendCMD(); 01419 getreply(); 01420 pc.printf(replybuff); 01421 ThisThread::sleep_for(5000); 01422 pc.printf("\n Getting Server IP \r\n"); 01423 strcpy(cmdbuff, "AT+CIFSR\r\n"); 01424 timeout=2500; 01425 getcount=200; 01426 while(weberror==0) { 01427 SendCMD(); 01428 getreply(); 01429 if (strstr(replybuff, "0.0.0.0") == NULL) { 01430 weberror=1; // wait for valid IP 01431 } 01432 } 01433 pc.printf("\n Enter WEB address (IP) found below in your browser \r\n\n"); 01434 pc.printf("\n The MAC address is also shown below,if it is needed \r\n\n"); 01435 replybuff[strlen(replybuff)-1] = '\0'; 01436 //char* IP = replybuff + 5; 01437 sprintf(webdata,"%s", replybuff); 01438 pc.printf(webdata); 01439 led2=1; 01440 bufflen=200; 01441 //bufflen=100; 01442 ount=0; 01443 pc.printf("\n\n++++++++++ Ready ++++++++++\r\n\n"); 01444 setup(); 01445 esp.attach(&callback); 01446 } else { 01447 pc.printf("\n++++++++++ ESP8266 error, check power/connections ++++++++++\r\n"); 01448 led1=1; 01449 led2=1; 01450 led3=1; 01451 led4=1; 01452 while(1) { 01453 led1=!led1; 01454 led2=!led2; 01455 led3=!led3; 01456 led4=!led4; 01457 ThisThread::sleep_for(1000); 01458 } 01459 } 01460 time2.reset(); 01461 time2.start(); 01462 } 01463 // ESP Command data send 01464 void SendCMD() 01465 { 01466 esp.printf("%s", cmdbuff); 01467 } 01468 // Get Command and ESP status replies 01469 void getreply() 01470 { 01471 memset(replybuff, '\0', sizeof(replybuff)); 01472 time1.reset(); 01473 time1.start(); 01474 replycount=0; 01475 while(time1.read_ms()< timeout && replycount < getcount) { 01476 if(esp.readable()) { 01477 replybuff[replycount] = esp.getc(); 01478 replycount++; 01479 } 01480 } 01481 time1.stop(); 01482 } 01483 01484 /* mainスレッド */ 01485 int main() { 01486 /* 初期設定 */ 01487 wifi_thread = new Thread(wifi); 01488 wifi_thread -> set_priority(osPriorityHigh); 01489 avoi_thread = new Thread(avoidance); 01490 avoi_thread->terminate(); 01491 trace_thread = new Thread(trace); 01492 trace_thread->terminate(); 01493 mode = READY; // 現在待ちモード 01494 beforeMode = READY; // 前回待ちモード 01495 run = STOP; // 停止 01496 flag_sp = NORMAL; // スピード(普通) 01497 lcd.setBacklight(TextLCD::LightOn); // バックライトON 01498 lcd.setAddress(0,1); 01499 lcd.printf("Mode:SetUp"); 01500 //display(); // ディスプレイ表示 01501 01502 while(1){ 01503 bChange(); // バッテリー残量更新 01504 } 01505 }
Generated on Mon Aug 8 2022 15:53:13 by 1.7.2