Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: RemoteIR TextLCD
Diff: main.cpp
- Revision:
- 0:4c4775017e8a
diff -r 000000000000 -r 4c4775017e8a main.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed Sep 23 01:45:03 2020 +0000
@@ -0,0 +1,1310 @@
+
+/* mbed Microcontroller Library
+ * Copyright (c) 2019 ARM Limited
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "mbed.h"
+#include "ReceiverIR.h"
+#include "rtos.h"
+#include <stdint.h>
+#include "platform/mbed_thread.h"
+#include "TextLCD.h"
+
+RawSerial pc(USBTX, USBRX);
+
+/* マクロ定義、列挙型定義 */
+#define MIN_V 2.0 // 電圧の最小値
+#define MAX_V 2.67 // 電圧の最大値
+#define LOW 0 // モーターOFF
+#define HIGH 1 // モーターON
+#define NORMAL 0 // 普通
+#define FAST 1 // 速い
+#define VERYFAST 2 // とても速い
+
+#define SLOW 0.8
+#define REVERSE 0.5
+
+#define MBED04 0.781//Mbed04号機の左右のモーター速度比(R:L = 1: 0.781)
+#define MBED05 0.953//Mbed05号機の左右のモーター速度比(R:L = 1: 0.953)
+#define MSR0 0.6
+#define MSR1 0.65
+#define MSR2 0.7
+#define MSR3 0.75
+#define MSR4 0.8
+#define MSR5 0.85
+#define MSR6 0.9
+#define MSR7 0.95
+#define MSR8 1
+#define MSL0 MSR0
+#define MSL1 MSR1
+#define MSL2 MSR2//*MBED05
+#define MSL3 MSR3//*MBED05
+#define MSL4 MSR4//*MBED05
+#define MSL5 MSR5//*MBED05
+#define MSL6 MSR6//*MBED05
+#define MSL7 MSR7//*MBED05
+#define MSL8 MSR8//*MBED05
+
+/* 操作モード定義 */
+enum MODE{
+ READY = -1, // -1:待ち
+ ADVANCE = 1, // 1:前進
+ RIGHT, // 2:右折
+ LEFT, // 3:左折
+ BACK, // 4:後退
+ STOP, // 5:停止
+ LINE_TRACE, // 6:ライントレース
+ AVOIDANCE, // 7:障害物回避
+ SPEED, // 8:スピード制御
+};
+
+/* ピン配置 */
+ReceiverIR ir(p5); // リモコン操作
+DigitalOut trig(p6); // 超音波センサtrigger
+DigitalIn echo(p7); // 超音波センサecho
+DigitalIn ss1(p8); // ライントレースセンサ(左)
+DigitalIn ss2(p9); // ライントレースセンサ
+DigitalIn ss3(p10); // ライントレースセンサ
+DigitalIn ss4(p11); // ライントレースセンサ
+DigitalIn ss5(p12); // ライントレースセンサ(右)
+RawSerial esp(p13, p14); // Wi-Fiモジュール(tx, rx)
+AnalogIn battery(p15); // 電池残量読み取り(Max 3.3V)
+PwmOut motorR2(p22); // 右モーター後退
+PwmOut motorR1(p21); // 右モーター前進
+PwmOut motorL2(p23); // 左モーター後退
+PwmOut motorL1(p24); // 左モーター前進
+PwmOut servo(p25); // サーボ
+I2C i2c_lcd(p28,p27); // LCD(tx, rx)
+
+
+
+/* 変数宣言 */
+int mode; // 操作モード
+int run; // 走行状態
+int beforeRun = STOP; // 前回の走行状態
+int beforeMode; // 前回のモード
+int flag_sp = 0; // スピード変化フラグ
+Timer viewTimer; // スピ―ド変更時に3秒計測タイマー
+
+float motorSpeedR1[9] = {MSR0, MSR1, MSR2, MSR3 , MSR4 , MSR5 , MSR6 , MSR7 , MSR8 };
+//float motorSpeedR2[9] = {MSR0, MSR1, MSR2, MSR3*REVERSE, MSR4*REVERSE, MSR5*REVERSE, MSR6*REVERSE, MSR7*REVERSE, MSR8*REVERSE};
+float motorSpeedR2[9] = {MSR0, MSR1, MSR2, MSR3, MSR4, MSR5, MSR6, MSR7, MSR8};
+float motorSpeedL1[9] = {MSL0, MSL1, MSL2, MSL3 , MSL4 , MSL5 , MSL6 , MSL7 , MSL8 };
+//float motorSpeedL2[9] = {MSL0, MSL1, MSL2, MSL3*REVERSE, MSL4*REVERSE, MSL5*REVERSE, MSL6*REVERSE, MSL7*REVERSE, MSL8*REVERSE};
+float motorSpeedL2[9] = {MSL0, MSL1, MSL2, MSL3, MSL4, MSL5, MSL6, MSL7, MSL8};
+ // モーター速度設定(後半はライントレース用)
+ // 0,1,2:基準速度
+ // 3,4,5:低速
+ // 6,7,8:高速
+ // R1 : 右前, R2 : 右後, L1 : 左前, L2 : 左後
+
+Mutex mutex; // ミューテックス
+
+/* decodeIR用変数 */
+RemoteIR::Format format;
+uint8_t buf[32];
+uint32_t bitcount;
+uint32_t code;
+
+/* bChange, lcdbacklight用変数 */
+TextLCD_I2C lcd(&i2c_lcd, (0x27 << 1), TextLCD::LCD16x2, TextLCD::HD44780);
+int b = 0; // バッテリー残量
+int flag_b = 0; // バックライト点滅フラグ
+int flag_t = 0; // バックライトタイマーフラグ
+
+/* trace用変数 */
+int sensArray[32] = {0,6,2,4,1,2,1,4, // ライントレースセンサパターン
+ 3,6,1,6,1,1,1,6, // 0:前回動作継続
+ 7,1,7,1,3,1,1,1, // 1:高速前進
+ 5,1,7,1,5,1,7,1}; // 2:低速右折
+ // 3:低速左折
+ // 4:中速右折
+ // 5:中速左折
+ // 6:高速右折
+ // 7:高速左折
+
+//int sensArray[32] = {0,6,0,4,1,0,1,4, // ライントレースセンサパターン
+// 0,6,1,6,1,1,1,6, // 0:前回動作継続
+// 7,1,7,1,0,1,1,1, // 1:高速前進
+// 5,1,7,1,5,1,7,1}; // 2:低速右折
+// // 3:低速左折
+// // 4:中速右折
+// // 5:中速左折
+// // 6:高速右折
+// // 7:高速左折
+
+/* avoidance用変数 */
+Timer timer; // 距離計測用タイマ
+int DT; // 距離
+int SC; // 正面
+int SL; // 左
+int SR; // 右
+int SLD; // 左前
+int SRD; // 右前
+int flag_a = 0; // 障害物有無のフラグ
+const int limit = 17; // 障害物の距離のリミット(単位:cm)
+int far; // 最も遠い距離
+int houkou; // 進行方向(1:前 2:左 3:右)
+int t1 = 0;
+
+/*WiFi用変数*/
+Timer time1;
+Timer time2;
+int bufflen, DataRX, ount, getcount, replycount, servreq, timeout;
+int bufl, ipdLen, linkID, weberror, webcounter,click_flag;
+float R1=100000, R2=10000; // resistor values to give a 10:1 reduction of measured AnalogIn voltage
+char webcount[8];
+char type[16];
+char channel[2];
+char cmdbuff[32];
+char replybuff[1024];
+char webdata[1024]; // This may need to be bigger depending on WEB browser used
+char webbuff[4096]; // Currently using 1986 characters, Increase this if more web page data added
+int port =80; // set server port
+int SERVtimeout =5; // set server timeout in seconds in case link breaks.
+char ssid[32] = "mbed05"; // enter WiFi router ssid inside the quotes
+char pwd [32] = "0123456789a"; // enter WiFi router password inside the quotes
+
+/* プロトタイプ宣言 */
+void decodeIR(/*void const *argument*/);
+void motor(/*void const *argument*/);
+void changeSpeed();
+void avoidance(/*void const *argument*/);
+void trace(/*void const *argument*/);
+void watchsurrounding3();
+void watchsurrounding5();
+int watch();
+char battery_ch[8];
+void bChange();
+void display();
+void lcdBacklight(void const *argument);
+void SendCMD(),getreply(),ReadWebData(),startserver(),sendpage(),SendWEB(),sendcheck();
+void wifi(/*void const *argument*/);
+Thread *deco_thread; // decodeIRをスレッド化 :+3
+Thread *wifi_thread;
+//wifi_thread(wifi,NULL,osPriorityHigh); // wifiをスレッド化
+Thread *motor_thread; // motorをスレッド化 :+2
+RtosTimer bTimer(lcdBacklight, osTimerPeriodic); // lcdBacklightをタイマー割り込みで設定
+Thread *avoi_thread; // avoidanceをスレッド化:+2
+Thread *trace_thread; // traceをスレッド化 :+2
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+void setup(){
+ deco_thread = new Thread(decodeIR);
+ deco_thread -> set_priority(osPriorityRealtime);
+ motor_thread = new Thread(motor);
+ motor_thread -> set_priority(osPriorityHigh);
+ //wifi_thread -> set_priority(osPriorityRealtime);
+ display();
+}
+
+/* リモコン受信スレッド */
+void decodeIR(/*void const *argument*/){
+ while(1){
+ // 受信待ち
+ if (ir.getState() == ReceiverIR::Received){ // コード受信
+ bitcount = ir.getData(&format, buf, sizeof(buf) * 8);
+ if(bitcount > 1){ // 受信成功
+ code=0;
+ for(int j = 0; j < 4; j++){
+ code+=(buf[j]<<(8*(3-j)));
+ }
+ if(mode != SPEED){ // スピードモード以外なら
+ beforeMode=mode; // 前回のモードに現在のモードを設定
+ }
+ switch(code){
+ case 0x40bf27d8: // クイック
+ ////*-*-*-5("mode = SPEED\r\n");
+ mode = SPEED; // スピードモード
+ changeSpeed(); // 速度変更
+ display(); // ディスプレイ表示
+ mode = beforeMode; // 現在のモードに前回のモードを設定
+ break;
+ case 0x40be34cb: // レグザリンク
+ ////*-*-*-5("mode = LINE_TRACE\r\n");
+ if(trace_thread->get_state() == Thread::Deleted){
+ delete trace_thread;
+ trace_thread = new Thread(trace);
+ trace_thread -> set_priority(osPriorityHigh);
+ }
+ mode=LINE_TRACE; // ライントレースモード
+ display(); // ディスプレイ表示
+ break;
+ case 0x40bf6e91: // 番組表
+ ////*-*-*-5("mode = AVOIDANCE\r\n");
+ if(avoi_thread->get_state() == Thread::Deleted){
+ delete avoi_thread;
+ avoi_thread = new Thread(avoidance);
+ avoi_thread -> set_priority(osPriorityHigh);
+ }
+ flag_a = 0;
+ mode=AVOIDANCE; // 障害物回避モード
+ run = ADVANCE; // 前進
+ display(); // ディスプレイ表示
+ break;
+ case 0x40bf3ec1: // ↑
+ ////*-*-*-5("mode = ADVANCE\r\n");
+ mode = ADVANCE; // 前進モード
+ run = ADVANCE; // 前進
+ display(); // ディスプレイ表示
+ break;
+ case 0x40bf3fc0: // ↓
+ ////*-*-*-5("mode = BACK\r\n");
+ mode = BACK; // 後退モード
+ run = BACK; // 後退
+ display(); // ディスプレイ表示
+ break;
+ case 0x40bf5fa0: // ←
+ ////*-*-*-5("mode = LEFT\r\n");
+ mode = LEFT; // 左折モード
+ run = LEFT; // 左折
+ display(); // ディスプレイ表示
+ break;
+ case 0x40bf5ba4: // →
+ ////*-*-*-5("mode = RIGHT\r\n");
+ mode = RIGHT; // 右折モード
+ run = RIGHT; // 右折
+ display(); // ディスプレイ表示
+ break;
+ case 0x40bf3dc2: // 決定
+ ////*-*-*-5("mode = STOP\r\n");
+ mode = STOP; // 停止モード
+ run = STOP; // 停止
+ display(); // ディスプレイ表示
+ break;
+ default:
+ ;
+ }
+ if(mode != LINE_TRACE && trace_thread->get_state() != Thread::Deleted){
+ trace_thread->terminate();
+ }
+ if(mode != AVOIDANCE && avoi_thread->get_state() != Thread::Deleted){
+ avoi_thread->terminate();
+ servo.pulsewidth_us(1450); // サーボを中央位置に戻す
+ }
+ }
+ }
+ if(viewTimer.read_ms()>=3000){ // スピードモードのまま3秒経過
+ viewTimer.stop(); // タイマーストップ
+ viewTimer.reset(); // タイマーリセット
+ display(); // ディスプレイ表示
+ }
+ ThisThread::sleep_for(90); // 90ms待つ
+ }
+}
+
+/* モーター制御スレッド */
+void motor(/*void const *argument*/){
+ while(1){
+ /* 走行状態の場合分け */
+ switch(run){
+ /* 前進 */
+ case ADVANCE:
+ motorR1 = motorSpeedR1[flag_sp]; // 右前進モーターON
+ motorR2 = LOW; // 右後退モーターOFF
+ motorL1 = motorSpeedL1[flag_sp]; // 左前進モーターON
+ motorL2 = LOW; // 左後退モーターOFF
+ break;
+ /* 右折 */
+ case RIGHT:
+ motorR1 = LOW; // 右前進モーターOFF
+ motorR2 = motorSpeedR2[flag_sp]; // 右後退モーターON
+ motorL1 = motorSpeedL1[flag_sp]; // 左前進モーターON
+ motorL2 = LOW; // 左後退モーターOFF
+
+ break;
+ /* 左折 */
+ case LEFT:
+ motorR1 = motorSpeedR1[flag_sp]; // 右前進モーターON
+ motorR2 = LOW; // 右後退モーターOFF
+ motorL1 = LOW; // 左前進モーターOFF
+ motorL2 = motorSpeedL2[flag_sp]; // 左後退モーターON
+
+ break;
+ /* 後退 */
+ case BACK:
+ motorR1 = LOW; // 右前進モーターOFF
+ motorR2 = motorSpeedR2[flag_sp]; // 右後退モーターON
+ motorL1 = LOW; // 左前進モーターOFF
+ motorL2 = motorSpeedL2[flag_sp]; // 左後退モーターON
+ break;
+ /* 停止 */
+ case STOP:
+ motorR1 = LOW; // 右前進モーターOFF
+ motorR2 = LOW; // 右後退モーターOFF
+ motorL1 = LOW; // 左前進モーターOFF
+ motorL2 = LOW; // 左後退モーターOFF
+ break;
+ }
+ if(flag_sp > VERYFAST){ // スピード変更フラグが2より大きいなら
+ flag_sp %= 3; // スピード変更フラグ調整
+ }
+ ThisThread::sleep_for(3); // 30ms待つ
+ }
+}
+
+/* スピード変更関数 */
+void changeSpeed(){
+ // それ以外
+ flag_sp = flag_sp + 3; // スピード変更フラグを+1
+ if(flag_sp>6)flag_sp=0;
+}
+
+/* ライントレーススレッド */
+void trace(){
+ while(1){
+ /* 各センサー値読み取り */
+ int sensor1 = ss1;
+ int sensor2 = ss2;
+ int sensor3 = ss3;
+ int sensor4 = ss4;
+ int sensor5 = ss5;
+ ////*-*-*-5("%d %d %d %d %d \r\n",sensor1,sensor2,sensor3,sensor4,sensor5);
+ int sensD = 0;
+ /* センサー値の決定 */
+ if(sensor1 > 0) sensD |= 0x10;
+ if(sensor2 > 0) sensD |= 0x08;
+ if(sensor3 > 0) sensD |= 0x04;
+ if(sensor4 > 0) sensD |= 0x02;
+ if(sensor5 > 0) sensD |= 0x01;
+ pc.printf("%d \r\n",sensArray[sensD]);
+ /* センサー値によって場合分け */
+ switch(sensArray[sensD]){
+ case 1:
+ flag_sp = 6;
+ beforeRun = run;
+ run = ADVANCE; // 高速で前進
+ break;
+ case 2:
+ flag_sp = 2;
+ beforeRun = run;
+ run = RIGHT;
+ break;
+ case 3:
+ flag_sp = 2;
+ beforeRun = run;
+ run = LEFT;
+ break;
+ case 4:
+ flag_sp = 0;
+ beforeRun = run;
+ run = RIGHT;
+ break;
+ case 5:
+ flag_sp = 0;
+ beforeRun = run;
+ run = LEFT;
+ break;
+ case 6:
+ flag_sp = 4;
+ beforeRun = run;
+ run = RIGHT;
+ break;
+ case 7:
+ flag_sp = 4;
+ beforeRun = run;
+ run = LEFT;
+ break;
+ default:
+ break;
+ }
+// ThisThread::sleep_for(30); // 30ms待つ
+ ThisThread::sleep_for(3);
+ }
+}
+
+/* 障害物回避走行スレッド */
+void avoidance(){
+ int i;
+ watchsurrounding3();
+ while(1){
+ if(flag_a==0){run=ADVANCE;watchsurrounding3();}
+ else{
+ i=0;
+ watchsurrounding5();
+ if(SLD>=SC&&SRD>=SC){
+ if(SL>=SR){
+ run = BACK;
+ ThisThread::sleep_for(200-flag_sp*10);
+
+ run = LEFT;
+ ThisThread::sleep_for(480-flag_sp*25);
+ run=STOP;
+ }
+ if(SL<SR){
+ run = BACK;
+ ThisThread::sleep_for(200-flag_sp*10);
+ run = RIGHT;
+ ThisThread::sleep_for(480-flag_sp*25);
+ run=STOP;}
+ }
+ if(SLD<SC){
+ run = BACK;
+ ThisThread::sleep_for(200-flag_sp*10);
+ run = RIGHT;
+ ThisThread::sleep_for(250-flag_sp*10);
+ run=STOP;
+ }
+ if(SRD<SC){
+ run = BACK;
+ ThisThread::sleep_for(200-flag_sp*10);
+ run = LEFT;
+ ThisThread::sleep_for(250-flag_sp*10);
+ run=STOP;
+ }
+
+ flag_a=0;
+
+}
+}
+}
+/* 距離計測関数 */
+int watch(){
+ do{
+ trig = 0;
+ ThisThread::sleep_for(5); // 5ms待つ
+ trig = 1;
+ ThisThread::sleep_for(15); // 15ms待つ
+ trig = 0;
+ timer.start();
+ t1=timer.read_ms();
+ while(echo.read() == 0 && t1<10){
+ t1=timer.read_ms();
+ led1 = 1;
+ }
+ timer.stop();
+ timer.reset();
+ /*if((t1-t2) >= 10){
+ run = STOP;*/
+ }while(t1 >= 10);
+ timer.start(); // 距離計測タイマースタート
+ while(echo.read() == 1){
+ }
+ timer.stop(); // 距離計測タイマーストップ
+ DT = (int)(timer.read_us()*0.01657); // 距離計算
+ if(DT > 1000){
+ DT = -1;
+ }else if(DT > 150){ // 検知範囲外なら100cmに設定
+ DT = 150;
+ }
+ timer.reset(); // 距離計測タイマーリセット
+ led1 = 0;
+ return DT;
+}
+
+/* 障害物検知関数 */
+void watchsurrounding3(){
+ //servo.pulsewidth_us(1450); // サーボを中央位置に戻す
+ //ThisThread::sleep_for(200); // 100ms待つ
+ SC = watch();
+ if(SC < limit){ // 正面20cm以内に障害物がある場合
+ if(SC!=-1){
+ run = STOP; // 停止
+ flag_a = 1;
+ return;
+ }
+ }
+ servo.pulsewidth_us(1925); // サーボを左に40度回転
+ ThisThread::sleep_for(100); // 250ms待つ
+ SLD = watch();
+ if(SLD < limit){ // 左前20cm以内に障害物がある場合
+ run = STOP; // 停止
+ flag_a = 1;
+ return;
+ }
+ servo.pulsewidth_us(1450);
+ ThisThread::sleep_for(150);
+ SC = watch();
+ if(SC < limit){
+ if(SC!=-1){
+ run = STOP; // 停止
+ flag_a = 1;
+ return;
+ }
+ }
+ servo.pulsewidth_us(925); // サーボを右に40度回転
+ ThisThread::sleep_for(100); // 250ms待つ
+ SRD = watch();
+ if(SRD < limit){ // 右前20cm以内に障害物がある場合
+ run = STOP; // 停止
+ flag_a = 1;
+ return;
+ }
+ servo.pulsewidth_us(1450); // サーボを中央位置に戻す
+ ThisThread::sleep_for(100); // 100ms待つ
+ /*if(SC < limit || SLD < limit || SL < limit || SRD < limit || SR < limit){ // 20cm以内に障害物を検知した場合
+ flag_a = 1; // 障害物有無フラグに1をセット
+ }*/
+}
+
+/* 障害物検知関数 */
+void watchsurrounding5(){
+ servo.pulsewidth_us(1450); // サーボを中央位置に戻す
+ ThisThread::sleep_for(200); // 100ms待つ
+ SC = watch();
+ servo.pulsewidth_us(1925); // サーボを左に40度回転
+ ThisThread::sleep_for(100); // 250ms待つ
+ SLD = watch();
+ servo.pulsewidth_us(2400); // サーボを左に90度回転
+ ThisThread::sleep_for(100); // 250ms待つ
+ SL = watch();
+ servo.pulsewidth_us(1450);
+ ThisThread::sleep_for(250);
+ SC = watch();
+ servo.pulsewidth_us(925); // サーボを右に40度回転
+ ThisThread::sleep_for(100); // 250ms待つ
+ SRD = watch();
+ servo.pulsewidth_us(500); // サーボを右に90度回転
+ ThisThread::sleep_for(100); // 250ms待つ
+ SR = watch();
+ servo.pulsewidth_us(1450); // サーボを中央位置に戻す
+ ThisThread::sleep_for(250); // 100ms待つ
+}
+
+/* ディスプレイ表示関数 */
+void display(){
+ mutex.lock(); // ミューテックスロック
+ lcd.setAddress(0,1);
+
+ /* 操作モードによる場合分け */
+ switch(mode){
+ /* 前進 */
+ case ADVANCE:
+ lcd.printf("Mode:Advance ");
+ break;
+ /* 右折 */
+ case RIGHT:
+ lcd.printf("Mode:TurnRight ");
+ break;
+ /* 左折 */
+ case LEFT:
+ lcd.printf("Mode:TurnLeft ");
+ break;
+ /* 後退 */
+ case BACK:
+ lcd.printf("Mode:Back ");
+ break;
+ /* 停止 */
+ case STOP:
+ lcd.printf("Mode:Stop ");
+ break;
+ /* 待ち */
+ case READY:
+ lcd.printf("Mode:Ready ");
+ break;
+ /* ライントレース */
+ case LINE_TRACE:
+ lcd.printf("Mode:LineTrace ");
+ break;
+ /* 障害物回避 */
+ case AVOIDANCE:
+ lcd.printf("Mode:Avoidance ");
+ break;
+ /* スピード制御 */
+ case SPEED:
+ /* スピードの状態で場合分け */
+ switch(flag_sp % 3){
+ /* 普通 */
+ case(NORMAL):
+ lcd.printf("Speed:Normal ");
+ break;
+ /* 速い */
+ case(FAST):
+ lcd.printf("Speed:Fast ");
+ break;
+ /* とても速い */
+ case(VERYFAST):
+ lcd.printf("Speed:VeryFast ");
+ break;
+ }
+ viewTimer.reset(); // タイマーリセット
+ viewTimer.start(); // タイマースタート
+ break;
+ }
+ mutex.unlock(); // ミューテックスアンロック
+}
+
+/* バックライト点滅 */
+void lcdBacklight(void const *argument){
+ if(flag_b == 1){ // バックライト点滅フラグが1なら
+ lcd.setBacklight(TextLCD::LightOn); // バックライトON
+ }else{ // バックライト点滅フラグが0なら
+ lcd.setBacklight(TextLCD::LightOff); // バックライトOFF
+ }
+ flag_b = !flag_b; // バックライト点滅フラグ切り替え
+}
+
+/* バッテリー残量更新関数 */
+void bChange(){
+ ////*-*-*-5(" bChange1\r\n");
+ b = (int)(((battery.read() * 3.3 - MIN_V)/0.67)*10+0.5)*10;
+ if(b <= 0){ // バッテリー残量0%なら全ての機能停止
+ b = 0;
+ //lcd.setBacklight(TextLCD::LightOff);
+ //run = STOP;
+ //exit(1); // 電池残量が5%未満の時、LCDを消灯し、モーターを停止し、プログラムを終了する。
+ }
+ mutex.lock(); // ミューテックスロック
+ lcd.setAddress(0,0);
+ lcd.printf("Battery:%3d%%",b); // バッテリー残量表示
+ mutex.unlock(); // ミューテックスアンロック
+ if(b <= 30){ // バッテリー残量30%以下なら
+ if(flag_t == 0){ // バックライトタイマーフラグが0なら
+ //bTimer.attach(lcdBacklight,0.5);
+ bTimer.start(500); // 0.5秒周期でバックライトタイマー割り込み
+ flag_t = 1; // バックライトタイマーフラグを1に切り替え
+ }
+ }else{
+ if(flag_t == 1){ // バックライトタイマーフラグが1なら
+ //bTimer.detach();
+ bTimer.stop(); // バックライトタイマーストップ
+ lcd.setBacklight(TextLCD::LightOn); // バックライトON
+ flag_t = 0; // バックライトタイマーフラグを0に切り替え
+ }
+ }
+}
+// Serial Interrupt read ESP data
+void callback()
+{
+ ////*-*-*-5("\n\r------------ callback is being called --------------\n\r");
+ led3=1;
+ while (esp.readable()) {
+ webbuff[ount] = esp.getc();
+ ount++;
+ }
+ if(strlen(webbuff)>bufflen) {
+// //*-*-*-5("\f\n\r------------ webbuff over bufflen --------------\n\r");
+ DataRX=1;
+ led3=0;
+ }
+}
+
+void wifi(/*void const *argument*/)
+{
+ //*-*-*-5("\f\n\r------------ ESP8266 Hardware Reset psq --------------\n\r");
+ ThisThread::sleep_for(100);
+ led1=1,led2=0,led3=0;
+ timeout=6000;
+ getcount=500;
+ getreply();
+ esp.baud(115200); // ESP8266 baudrate. Maximum on KLxx' is 115200, 230400 works on K20 and K22F
+ startserver();
+
+ while(1) {
+ if(DataRX==1) {
+ //*-*-*-5("\f\n\r------------ main while > if --------------\n\r");
+ click_flag = 1;
+ ReadWebData();
+ //*-*-*-5("\f\n\r------------ click_flag=%d --------------\n\r",click_flag);
+ //if ((servreq == 1 && weberror == 0) && click_flag == 1) {
+ if (servreq == 1 && weberror == 0) {
+ //*-*-*-5("\f\n\r------------ befor send page --------------\n\r");
+ sendpage();
+ }
+ //*-*-*-5("\f\n\r------------ send_check begin --------------\n\r");
+
+ //sendcheck();
+ //*-*-*-5("\f\n\r------------ ssend_check end--------------\n\r");
+
+ esp.attach(&callback);
+ //*-*-*-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);
+ //*-*-*-5("\n\n HTTP Packet: \n\n%s\n", webdata);
+ //*-*-*-5(" Web Characters sent : %d\n\n", bufl);
+ //*-*-*-5(" -------------------------------------\n\n");
+ servreq=0;
+ }
+ ThisThread::sleep_for(100);
+ }
+}
+// Static WEB page
+void sendpage()
+{
+// WEB page data
+
+ strcpy(webbuff, "<!DOCTYPE html>");
+ strcat(webbuff, "<html><head><title>RobotCar</title><meta name='viewport' content='width=device-width'/>");
+ //strcat(webbuff, "<meta http-equiv=\"refresh\" content=\"5\"; >");
+ 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>");
+ strcat(webbuff, "</head><body><center><p><strong>Robot Car Remote Controller");
+ strcat(webbuff, "</strong></p><td style='vertical-align:top;'><strong>Battery level ");
+ if(b > 30) { //残電量表示
+ sprintf(webbuff, "%s%3d", webbuff, b);
+ } else { //30%より下の場合残電量を赤文字
+ strcat(webbuff, "<font color=\"red\">");
+ sprintf(webbuff, "%s%3d", webbuff, b);
+ strcat(webbuff, "</font>");
+ }
+ strcat(webbuff, "%</strong>");
+ strcat(webbuff, "<button id=\"reloadbtn\" type=\"button\" class=\"load\" onclick=\"location.reload()\">RELOAD</button>");
+ strcat(webbuff, "</td></p>");
+ strcat(webbuff, "<br>");
+ strcat(webbuff, "<table><tr><td></td><td>");
+
+ switch(mode) { //ブラウザ更新時の現在の車の状態からボタンの点灯判定
+ case ADVANCE: //前進
+ strcat(webbuff, "<button id='gobtn' type='button' class=\"light\" value=\"GO\" onClick='send_mes(this.value)'>GO");
+ strcat(webbuff, "</button></td><td></td></tr><tr><td>");
+ strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.value)' >LEFT");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.value)' >STOP");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.value)' >RIGHT");
+ strcat(webbuff, "</button></td></tr><td></td><td>");
+ strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.value)' >BACK");
+ strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>");
+ strcat(webbuff, "<strong>Mode</strong>");
+ strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.value)' >");
+ strcat(webbuff, "AVOIDANCE</button></td><td>");
+ strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.value)' >LINE_TRACE");
+ break;
+ case LEFT: //左折
+ strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.value)'>GO");
+ strcat(webbuff, "</button></td><td></td></tr><tr><td>");
+ strcat(webbuff, "<button id='leftbtn' type='button' class=\"light\" value=\"LEFT\" onClick='send_mes(this.value)' >LEFT");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.value)' >STOP");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.value)' >RIGHT");
+ strcat(webbuff, "</button></td></tr><td></td><td>");
+ strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.value)' >BACK");
+ strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>");
+ strcat(webbuff, "<strong>Mode</strong>");
+ strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.value)' >");
+ strcat(webbuff, "AVOIDANCE</button></td><td>");
+ strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.value)' >LINE_TRACE");
+ break;
+ case STOP: //停止
+ strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.value)'>GO");
+ strcat(webbuff, "</button></td><td></td></tr><tr><td>");
+ strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.value)' >LEFT");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='stopbtn' type='button' class=\"light\" value=\"STOP\" onClick='send_mes(this.value)' >STOP");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.value)' >RIGHT");
+ strcat(webbuff, "</button></td></tr><td></td><td>");
+ strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.value)' >BACK");
+ strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>");
+ strcat(webbuff, "<strong>Mode</strong>");
+ strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.value)' >");
+ strcat(webbuff, "AVOIDANCE</button></td><td>");
+ strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.value)' >LINE_TRACE");
+ break;
+ case RIGHT: //右折
+ strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.value)'>GO");
+ strcat(webbuff, "</button></td><td></td></tr><tr><td>");
+ strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.value)' >LEFT");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.value)' >STOP");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='rightbtn' type='button' class=\"light\" value=\"RIGHT\" onClick='send_mes(this.value)' >RIGHT");
+ strcat(webbuff, "</button></td></tr><td></td><td>");
+ strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.value)' >BACK");
+ strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>");
+ strcat(webbuff, "<strong>Mode</strong>");
+ strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.value)' >");
+ strcat(webbuff, "AVOIDANCE</button></td><td>");
+ strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.value)' >LINE_TRACE");
+ break;
+ case BACK: //後進
+ strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.value)'>GO");
+ strcat(webbuff, "</button></td><td></td></tr><tr><td>");
+ strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.value)' >LEFT");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.value)' >STOP");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.value)' >RIGHT");
+ strcat(webbuff, "</button></td></tr><td></td><td>");
+ strcat(webbuff, "<button id='backbtn' type='button' class=\"light\" value=\"BACK\" onClick='send_mes(this.value)' >BACK");
+ strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr><td>");
+ strcat(webbuff, "<strong>Mode</strong>");
+ strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.value)' >");
+ strcat(webbuff, "AVOIDANCE</button></td><td>");
+ strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.value)' >LINE_TRACE");
+ break;
+ case AVOIDANCE: //障害物回避
+ strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.value)'>GO");
+ strcat(webbuff, "</button></td><td></td></tr><tr><td>");
+ strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.value)' >LEFT");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.value)' >STOP");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.value)' >RIGHT");
+ strcat(webbuff, "</button></td></tr><td></td><td>");
+ strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.value)' >BACK");
+ strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>");
+ strcat(webbuff, "<strong>Mode</strong>");
+ strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"light\" value=\"AVOIDANCE\" onClick='send_mes(this.value)' >");
+ strcat(webbuff, "AVOIDANCE</button></td><td>");
+ strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.value)' >LINE_TRACE");
+ break;
+ case LINE_TRACE: //ライントレース
+ strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.value)'>GO");
+ strcat(webbuff, "</button></td><td></td></tr><tr><td>");
+ strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.value)' >LEFT");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.value)' >STOP");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.value)' >RIGHT");
+ strcat(webbuff, "</button></td></tr><td></td><td>");
+ strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.value)' >BACK");
+ strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>");
+ strcat(webbuff, "<strong>Mode</strong>");
+ strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.value)' >");
+ strcat(webbuff, "AVOIDANCE</button></td><td>");
+ strcat(webbuff, "<button id='tracebtn' type='button' class=\"light\" value=\"LINE_TRACE\" onClick='send_mes(this.value)' >LINE_TRACE");
+ break;
+ default: //その他
+ strcat(webbuff, "<button id='gobtn' type='button' class=\"noselect\" value=\"GO\" onClick='send_mes(this.value)'>GO");
+ strcat(webbuff, "</button></td><td></td></tr><tr><td>");
+ strcat(webbuff, "<button id='leftbtn' type='button' class=\"noselect\" value=\"LEFT\" onClick='send_mes(this.value)' >LEFT");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='stopbtn' type='button' class=\"noselect\" value=\"STOP\" onClick='send_mes(this.value)' >STOP");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='rightbtn' type='button' class=\"noselect\" value=\"RIGHT\" onClick='send_mes(this.value)' >RIGHT");
+ strcat(webbuff, "</button></td></tr><td></td><td>");
+ strcat(webbuff, "<button id='backbtn' type='button' class=\"noselect\" value=\"BACK\" onClick='send_mes(this.value)' >BACK");
+ strcat(webbuff, "</button></td><td style='vertical-align:top; text-align:right;'></td></tr></table>");
+ strcat(webbuff, "<strong>Mode</strong>");
+ strcat(webbuff, "<table><tr><td><button id='avoidbtn' type='button' class=\"noselect\" value=\"AVOIDANCE\" onClick='send_mes(this.value)' >");
+ strcat(webbuff, "AVOIDANCE</button></td><td>");
+ strcat(webbuff, "<button id='tracebtn' type='button' class=\"noselect\" value=\"LINE_TRACE\" onClick='send_mes(this.value)' >LINE_TRACE");
+ break;
+ }
+ strcat(webbuff, "</button></td></tr></table>");
+ strcat(webbuff, "<strong>Speed</strong>");
+ strcat(webbuff, "<table><tr><td>");
+ //ready示速度だけ点灯
+ switch (flag_sp) { //現在の速度のボタン表示
+ case 0: //ノーマル
+ strcat(webbuff, "<button id='sp1btn' type='button' class=\"light\" value=\"Normal\" onClick='send_mes_spe(this.value)' >Normal");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='sp2btn' type='button' class=\"noselect\" value=\"Fast\" onClick='send_mes_spe(this.value)' >Fast");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='sp3btn' type='button' class=\"noselect\" value=\"VeryFast\" onClick='send_mes_spe(this.value)' >VeryFast");
+ break;
+ case 1: //ファスト
+ strcat(webbuff, "<button id='sp1btn' type='button' class=\"noselect\" value=\"Normal\" onClick='send_mes_spe(this.value)' >Normal");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='sp2btn' type='button' class=\"light\" value=\"Fast\" onClick='send_mes_spe(this.value)' >Fast");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='sp3btn' type='button' class=\"noselect\" value=\"VeryFast\" onClick='send_mes_spe(this.value)' >VeryFast");
+ break;
+ case 2: //ベリーファスト
+ strcat(webbuff, "<button id='sp1btn' type='button' class=\"noselect\" value=\"Normal\" onClick='send_mes_spe(this.value)' >Normal");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='sp2btn' type='button' class=\"noselect\" value=\"Fast\" onClick='send_mes_spe(this.value)' >Fast");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='sp3btn' type='button' class=\"light\" value=\"VeryFast\" onClick='send_mes_spe(this.value)' >VeryFast");
+ break;
+ default: //その他
+ strcat(webbuff, "<button id='sp1btn' type='button' class=\"noselect\" value=\"Normal\" onClick='send_mes_spe(this.value)' >Normal");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='sp2btn' type='button' class=\"noselect\" value=\"Fast\" onClick='send_mes_spe(this.value)' >Fast");
+ strcat(webbuff, "</button></td><td>");
+ strcat(webbuff, "<button id='sp3btn' type='button' class=\"noselect\" value=\"VeryFast\" onClick='send_mes_spe(this.value)' >VeryFast");
+ break;
+ }
+ strcat(webbuff, "</button></td></tr></table>");
+
+ strcat(webbuff, "</center>");
+ strcat(webbuff, "</body>");
+ strcat(webbuff, "</html>");
+
+ strcat(webbuff, "<script language=\"javascript\" type=\"text/javascript\">"); //機能
+
+ strcat(webbuff, "var button_9 = document.getElementsByTagName(\"button\");");
+
+//ボタン入力時それぞれの関数から呼び出されサーバーとの通信を行う
+ strcat(webbuff, "function htmlacs(url) {");
+ strcat(webbuff, "for(var m=0;m<11;m++){button_9[m].disabled=true;}");
+ strcat(webbuff, "var xhr = new XMLHttpRequest();");
+ strcat(webbuff, "xhr.open(\"GET\", url);");
+ strcat(webbuff, "xhr.onreadystatechange = function(){");
+ strcat(webbuff, "if(this.readyState == 4 || this.status == 200){");
+ strcat(webbuff, "for(var m=0;m<11;m++){button_9[m].disabled=false;}");
+ strcat(webbuff, "}");
+ strcat(webbuff, "};");
+ strcat(webbuff, "xhr.send(\"\");");
+ strcat(webbuff, "}");
+
+//mode変更ボタン入力時動作 //sendmes
+ strcat(webbuff, "function send_mes(btnval){"); //mode変更ボタン入力時の点灯消灯判定
+ strcat(webbuff, "console.log(btnval);");
+ strcat(webbuff, "var url = \"http://\" + window.location.hostname + \"/cargo?a=\" + btnval;");
+ strcat(webbuff, "htmlacs(url);");
+ strcat(webbuff, "console.log(url);");
+ strcat(webbuff, "var buttons = document.getElementsByTagName(\"button\");");
+ strcat(webbuff, "for(var i=1;i<8;i++){");
+ strcat(webbuff, "if(buttons[i].value == btnval){");
+ strcat(webbuff, "buttons[i].className=\"light\";");
+ strcat(webbuff, "}else{");
+ strcat(webbuff, "buttons[i].className=\"noselect\";");
+ strcat(webbuff, "}");
+ strcat(webbuff, "}");
+ strcat(webbuff, "}");
+
+ strcat(webbuff, "function send_mes_spe(btnval){"); //speed変更ボタン入力時の点灯消灯判定
+ strcat(webbuff, "var url = \"http://\" + window.location.hostname + \"/cargo?a=\" + btnval;");
+ strcat(webbuff, "htmlacs(url);");
+ strcat(webbuff, "console.log(url);");
+ strcat(webbuff, "var buttons = document.getElementsByTagName(\"button\");");
+ strcat(webbuff, "for(var i=8;i<11;i++){");
+ strcat(webbuff, "if(buttons[i].value == btnval){");
+ strcat(webbuff, "buttons[i].className=\"light\";");
+ strcat(webbuff, "}else{");
+ strcat(webbuff, "buttons[i].className=\"noselect\";");
+ strcat(webbuff, "}");
+ strcat(webbuff, "}");
+ strcat(webbuff, "}");
+ strcat(webbuff, "</script>");
+
+
+// end of WEB page data
+ bufl = strlen(webbuff); // get total page buffer length
+ //sprintf(cmdbuff,"AT+CIPSEND=%d,%d\r\n", linkID, bufl); // send IPD link channel and buffer character length.
+
+ sprintf(cmdbuff,"AT+CIPSENDBUF=%d,%d\r\n", linkID, (bufl>2048?2048:bufl)); // send IPD link channel and buffer character length.
+ timeout=500;
+ getcount=40;
+ SendCMD();
+ getreply();
+ //*-*-*-5(replybuff);
+ ////*-*-*-5("\n++++++++++ AT+CIPSENDBUF=%d,%d+++++++++\r\n", linkID, (bufl>2048?2048:bufl));
+
+ //*-*-*-5("\n++++++++++ bufl is %d ++++++++++\r\n",bufl);
+
+ //pastthrough mode
+ SendWEB(); // send web page
+ //*-*-*-5("\n++++++++++ webbuff clear ++++++++++\r\n");
+
+ memset(webbuff, '\0', sizeof(webbuff));
+ sendcheck();
+}
+
+// Large WEB buffer data send
+void SendWEB()
+{
+ int i=0;
+ if(esp.writeable()) {
+ while(webbuff[i]!='\0') {
+ esp.putc(webbuff[i]);
+
+ //****
+ //output at command when 2000
+ if(((i%2047)==0) && (i>0)) {
+ //wait_ms(10);
+ ThisThread::sleep_for(100);
+ sprintf(cmdbuff,"AT+CIPSENDBUF=%d,%d\r\n", linkID, (bufl-2048)>2048?2048:(bufl-2048)); // send IPD link channel and buffer character length.
+ ////*-*-*-5("\r\n++++++++++ AT+CIPSENDBUF=%d,%d ++++++++++\r\n", linkID, (bufl-2048)>2048?2048:(bufl-2048));
+ timeout=600;
+ getcount=50;
+ SendCMD();
+ getreply();
+ ////*-*-*-5(replybuff);
+ ////*-*-*-5("\r\n+++++++++++++++++++\r\n");
+ }
+ //****
+ i++;
+ ////*-*-*-5("%c",webbuff[i]);
+ }
+ }
+ //*-*-*-5("\n++++++++++ send web i= %dinfo ++++++++++\r\n",i);
+}
+
+
+void sendcheck()
+{
+ weberror=1;
+ timeout=500;
+ getcount=24;
+ time2.reset();
+ time2.start();
+
+ /*
+ while(weberror==1 && time2.read() <5) {
+ getreply();
+ if (strstr(replybuff, "SEND OK") != NULL) {
+ weberror=0; // wait for valid SEND OK
+ }
+ }
+ */
+ if(weberror==1) { // restart connection
+ strcpy(cmdbuff, "AT+CIPMUX=1\r\n");
+ timeout=500;
+ getcount=10;
+ SendCMD();
+ getreply();
+ //*-*-*-5(replybuff);
+ sprintf(cmdbuff,"AT+CIPSERVER=1,%d\r\n", port);
+ timeout=500;
+ getcount=10;
+ SendCMD();
+ getreply();
+ //*-*-*-5(replybuff);
+ } else {
+ sprintf(cmdbuff, "AT+CIPCLOSE=%s\r\n",channel); // close current connection
+ SendCMD();
+ getreply();
+ //*-*-*-5(replybuff);
+ }
+ time2.reset();
+}
+
+// Reads and processes GET and POST web data
+void ReadWebData()
+{
+ //*-*-*-5("+++++++++++++++++Read Web Data+++++++++++++++++++++\r\n");
+ ThisThread::sleep_for(200);
+ esp.attach(NULL);
+ ount=0;
+ DataRX=0;
+ weberror=0;
+ memset(webdata, '\0', sizeof(webdata));
+ int x = strcspn (webbuff,"+");
+ if(x) {
+ strcpy(webdata, webbuff + x);
+ weberror=0;
+ int numMatched = sscanf(webdata,"+IPD,%d,%d:%s", &linkID, &ipdLen, type);
+ //int i=0;
+ //*-*-*-5("+++++++++++++++++succed rec begin+++++++++++++++++++++\r\n");
+ //*-*-*-5("%s",webdata);
+ //*-*-*-5("+++++++++++++++++succed rec end+++++++++++++++++++++\r\n");
+ if( strstr(webdata, "Normal") != NULL ) {
+ //*-*-*-5("++++++++++++++++++Normal++++++++++++++++++++");
+ mode = SPEED; // スピードモード
+ flag_sp = 0;
+ display(); // ディスプレイ表示
+ mode = beforeMode; // 現在のモードに前回のモードを設定
+ }else if( strstr(webdata, "VeryFast") != NULL ) {
+ //*-*-*-5("+++++++++++++++++++VeryFast+++++++++++++++++++");
+ mode = SPEED; // スピードモード
+ flag_sp = 2;
+ display(); // ディスプレイ表示
+ mode = beforeMode; // 現在のモードに前回のモードを設定
+ }else if( strstr(webdata, "Fast") != NULL ) {
+ //*-*-*-5("++++++++++++++++++++Fast++++++++++++++++++");
+ mode = SPEED; // スピードモード
+ flag_sp = 1;
+ display(); // ディスプレイ表示
+ mode = beforeMode; // 現在のモードに前回のモードを設定
+ }else{
+ beforeMode = mode;
+ }
+ if( strstr(webdata, "GO") != NULL ) {
+ //*-*-*-5("+++++++++++++++++前進+++++++++++++++++++++\r\n");
+ //delete avoi_thread; //障害物回避スレッド停止
+ //delete trace_thread; //ライントレーススレッド停止
+ run = ADVANCE; // 前進
+ mode = ADVANCE; // モード変更
+ display(); // ディスプレイ表示
+ }
+
+ if( strstr(webdata, "LEFT") != NULL ) {
+ //*-*-*-5("+++++++++++++++++左折+++++++++++++++++++++\r\n");
+ //delete avoi_thread; //障害物回避スレッド停止
+ //delete trace_thread; //ライントレーススレッド停止
+ run = LEFT; // 左折
+ mode = LEFT; // モード変更
+ display(); // ディスプレイ表示
+ }
+
+ if( strstr(webdata, "STOP") != NULL ) {
+ //*-*-*-5("+++++++++++++++++停止+++++++++++++++++++++\r\n");
+ //delete avoi_thread; //障害物回避スレッド停止
+ //delete trace_thread; //ライントレーススレッド停止
+ run = STOP; // 停止
+ mode = STOP; // モード変更
+ display(); // ディスプレイ表示
+ }
+
+ if( strstr(webdata, "RIGHT") != NULL ) {
+ //*-*-*-5("+++++++++++++++++右折+++++++++++++++++++++\r\n");
+ //delete avoi_thread; //障害物回避スレッド停止
+ //delete trace_thread; //ライントレーススレッド停止
+ run = RIGHT; // 右折
+ mode = RIGHT; // モード変更
+ display(); // ディスプレイ表示
+ }
+
+ if( strstr(webdata, "BACK") != NULL ) {
+ //*-*-*-5("+++++++++++++++++後進+++++++++++++++++++++\r\n");
+ //delete avoi_thread; //障害物回避スレッド停止
+ //delete trace_thread; //ライントレーススレッド停止
+ run = BACK; // 後進
+ mode = BACK; // モード変更
+ display(); // ディスプレイ表示
+ }
+ //*-*-*-5("+++++++++++++++++succed+++++++++++++++++++++");
+
+ if( strstr(webdata, "AVOIDANCE") != NULL ) {
+ //*-*-*-5("+++++++++++++++++AVOIDANCE+++++++++++++++++++++");
+ if(avoi_thread->get_state() == Thread::Deleted) {
+ delete avoi_thread; //障害物回避スレッド停止
+ avoi_thread = new Thread(avoidance);
+ avoi_thread -> set_priority(osPriorityHigh);
+ }
+ mode=AVOIDANCE;
+ run = ADVANCE;
+ display(); // ディスプレイ表示
+ }
+ if( strstr(webdata, "LINE_TRACE") != NULL ) {
+ //*-*-*-5("+++++++++++++++++LINET RACE+++++++++++++++++++++");
+ //*-*-*-5("mode = LINE_TRACE\r\n");
+ if(trace_thread->get_state() == Thread::Deleted) {
+ delete trace_thread; //ライントレーススレッド停止
+ trace_thread = new Thread(trace);
+ trace_thread -> set_priority(osPriorityHigh);
+ }
+ mode=LINE_TRACE;
+ display(); // ディスプレイ表示
+ }
+ if(mode != LINE_TRACE && trace_thread->get_state() != Thread::Deleted){
+ trace_thread->terminate();
+ }
+ if(mode != AVOIDANCE && avoi_thread->get_state() != Thread::Deleted){
+ avoi_thread->terminate();
+ servo.pulsewidth_us(1450); // サーボを中央位置に戻す
+ }
+ sprintf(channel, "%d",linkID);
+ if (strstr(webdata, "GET") != NULL) {
+ servreq=1;
+ }
+ if (strstr(webdata, "POST") != NULL) {
+ servreq=1;
+ }
+ webcounter++;
+ sprintf(webcount, "%d",webcounter);
+ } else {
+ memset(webbuff, '\0', sizeof(webbuff));
+ esp.attach(&callback);
+ weberror=1;
+ }
+}
+// Starts and restarts webserver if errors detected.
+void startserver()
+{
+ //*-*-*-5("++++++++++ Resetting ESP ++++++++++\r\n");
+ strcpy(cmdbuff,"AT+RST\r\n");
+ timeout=8000;
+ getcount=1000;
+ SendCMD();
+ getreply();
+ //*-*-*-5(replybuff);
+ //*-*-*-5("%d",ount);
+ if (strstr(replybuff, "OK") != NULL) {
+ //*-*-*-5("\n++++++++++ Starting Server ++++++++++\r\n");
+ strcpy(cmdbuff, "AT+CIPMUX=1\r\n"); // set multiple connections.
+ timeout=500;
+ getcount=20;
+ SendCMD();
+ getreply();
+ //*-*-*-5(replybuff);
+ sprintf(cmdbuff,"AT+CIPSERVER=1,%d\r\n", port);
+ timeout=500;
+ getcount=20;
+ SendCMD();
+ getreply();
+ //*-*-*-5(replybuff);
+ ThisThread::sleep_for(500);
+ sprintf(cmdbuff,"AT+CIPSTO=%d\r\n",SERVtimeout);
+ timeout=500;
+ getcount=50;
+ SendCMD();
+ getreply();
+ //*-*-*-5(replybuff);
+ ThisThread::sleep_for(5000);
+ //*-*-*-5("\n Getting Server IP \r\n");
+ strcpy(cmdbuff, "AT+CIFSR\r\n");
+ timeout=2500;
+ getcount=200;
+ while(weberror==0) {
+ SendCMD();
+ getreply();
+ if (strstr(replybuff, "0.0.0.0") == NULL) {
+ weberror=1; // wait for valid IP
+ }
+ }
+ //*-*-*-5("\n Enter WEB address (IP) found below in your browser \r\n\n");
+ //*-*-*-5("\n The MAC address is also shown below,if it is needed \r\n\n");
+ replybuff[strlen(replybuff)-1] = '\0';
+ //char* IP = replybuff + 5;
+ sprintf(webdata,"%s", replybuff);
+ //*-*-*-5(webdata);
+ led2=1;
+ bufflen=200;
+ //bufflen=100;
+ ount=0;
+ //*-*-*-5("\n\n++++++++++ Ready ++++++++++\r\n\n");
+ setup();
+ esp.attach(&callback);
+ } else {
+ //*-*-*-5("\n++++++++++ ESP8266 error, check power/connections ++++++++++\r\n");
+ led1=1;
+ led2=1;
+ led3=1;
+ led4=1;
+ while(1) {
+ led1=!led1;
+ led2=!led2;
+ led3=!led3;
+ led4=!led4;
+ ThisThread::sleep_for(1000);
+ }
+ }
+ time2.reset();
+ time2.start();
+}
+
+// ESP Command data send
+void SendCMD()
+{
+ esp.printf("%s", cmdbuff);
+}
+// Get Command and ESP status replies
+void getreply()
+{
+ memset(replybuff, '\0', sizeof(replybuff));
+ time1.reset();
+ time1.start();
+ replycount=0;
+ while(time1.read_ms()< timeout && replycount < getcount) {
+ if(esp.readable()) {
+ replybuff[replycount] = esp.getc();
+ replycount++;
+ }
+ }
+ time1.stop();
+}
+
+/* mainスレッド */
+int main() {
+ /* 初期設定 */
+ //wifi_thread = new Thread(wifi);
+ //wifi_thread -> set_priority(osPriorityHigh);
+ motorR2.period_us(40);
+ motorR1.period_us(40);
+ motorL2.period_us(40);
+ motorL1.period_us(40);
+ setup();
+ avoi_thread = new Thread(avoidance);
+ avoi_thread->terminate();
+ trace_thread = new Thread(trace);
+ trace_thread->terminate();
+ mode = READY; // 現在待ちモード
+ beforeMode = READY; // 前回待ちモード
+ run = STOP; // 停止
+ flag_sp = NORMAL; // スピード(普通)
+ lcd.setBacklight(TextLCD::LightOn); // バックライトON
+ lcd.setAddress(0,1);
+ lcd.printf("Mode:ready");
+// display(); // ディスプレイ表示
+
+ while(1){
+ bChange(); // バッテリー残量更新
+ }
+}
\ No newline at end of file