1
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