1

Dependencies:   RemoteIR TextLCD

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

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