Skip to content

Instantly share code, notes, and snippets.

@Tomokatsu-Sakamoto
Created December 27, 2017 06:23
Show Gist options
  • Save Tomokatsu-Sakamoto/e77c33677fce45fc7a71ce191f7ed09c to your computer and use it in GitHub Desktop.
Save Tomokatsu-Sakamoto/e77c33677fce45fc7a71ce191f7ed09c to your computer and use it in GitHub Desktop.
ESP-WROOM-02 で制御する車
// ESP8266 Car ② 
//
// WiFiブルドーザー 制御スケッチ
// Pololu社製DRV8835 Driver Carrier
// ESP-WROOM-02 スマホでコントロール
// dataディレクトリにhtmlファイル収納
// by RoboFarm http://www.robofarm.jp
//
// ライブラリの読込
#include <WiFiClient.h>
#include <ESP8266WiFi.h> // ESP8266WiFiライブラリ
#include <ESP8266WebServer.h> // ESP8266Webサーバーライブラリ
#include <FS.h> // ファイルシステムSPIFFSライブラリ
#include <ST7032.h>
#include "MyWiFi.h" // このファイルの中では ssid と password を定義
#ifndef ssid // 他の場所で SSID が設定されていなかった時は、ここで...
#define ssid "SSID"
#endif
#ifndef password // 他の場所で Password が設定されていなかった時は、ここで...
#define password "password"
#endif
// アクセスポイントモードで使用する SSIDとパスワード
#define AP_password "password"
ST7032 lcd;
ESP8266WebServer server( 80 ); // HTTPサーバーの設定
const char *path_root = "/index.html"; // コントローラー画面表示HTMLファイルの場所を指定
uint8_t buf[ 16384 ]; // ファイル格納バッファサイズを指定
char lineBuff[ 16 ]; // LCD用の整形バッファ
const int LM1Pin = 16; // TA7291P 左モータ IN1
const int LM2Pin = 14; // TA7291P 左モータ IN2
const int RM1Pin = 12; // TA7291P 右モータ IN1
const int RM2Pin = 13; // TA7291P 右モータ IN2
const int LedPin = 15; // LEDピン
const int SwPin = 2; // SWピン
const int LFMax = 800; //左モーター正転補正値
const int RFMax = 800; //右モーター正転補正値
const int LRMax = 800; //左モーター逆転補正値
const int RRMax = 800; //右モーター逆転補正値
void setup( )
{
///////////////////////////////////////////////////////////////////////
// 入出力ピンの設定
delay( 1000 );
pinMode( LedPin, OUTPUT ); // LedPin をデジタル出力モードに設定
pinMode( SwPin, INPUT ); // SwPin をデジタル入力モードに設定
///////////////////////////////////////////////////////////////////////
// シリアルポートの設定
Serial.begin(115200);
///////////////////////////////////////////////////////////////////////
// ESP-WROOM-02 のボード情報を表示
ESP8266_Information( );
///////////////////////////////////////////////////////////////////////
// LCD の初期化
lcd.begin( 8, 2 );
lcd.setContrast( 30 ); // コントラスト設定
lcd.blink( );
///////////////////////////////////////////////////////////////////////
// Wi-Fi の初期化
if ( digitalRead( SwPin ) != 0 ) {
///////////////////////////////////////////////////////////////////////
// アクセスポイントモード ※ESP-WROOM-02 がアクセスポイントとして動作
Serial.println( "" );
Serial.println( "ESP8266 Wifi wireless access points..." );
// アクセスポイントのIPアドレスに関する設定
Serial.print("Setting soft-AP configuration ... ");
Serial.println(
WiFi.softAPConfig(
IPAddress( 192, 168, 0, 1 ), // local_ip : ローカルのIPアドレス
IPAddress( 192, 168, 0, 1 ), // gateway : デフォルトゲートウェイ
IPAddress( 255, 255, 255, 0 ) ) // subnet : サブネットマスク
? "Ready" : "Failed!" );
// 設定されたSSID・パスワードでWiFiアクセスモード起動
getSSID( lineBuff ); // チップIDからSSIDを生成
Serial.print("Setting soft-AP ... ");
Serial.println(
WiFi.softAP( lineBuff, AP_password ) ? "Ready" : "Failed!" );
Serial.print(
"Soft-AP IP address = ");
Serial.println( WiFi.softAPIP( ) );
lcd.print( "Wi-Fi " );
lcd.setCursor( 0, 1 );
lcd.print( "AP mode." );
delay( 500 );
}
else {
// 押されていたボタンが離されるまで待つ
lcd.print( "release " );
lcd.setCursor( 0, 1 );
lcd.print( " button" );
while ( digitalRead( SwPin ) == 0 ) {
delay( 100 );
}
///////////////////////////////////////////////////////////////////////
// クライアントモード ※既存のアクセスポイントから DHCP で割り当て
Serial.println( "" );
Serial.println( "ESP8266 Wifi setting..." );
// 念のために、現在の接続を解除する
Serial.println( "Disconnects the WiFi shield from the current network." );
WiFi.disconnect( );
WiFi.mode( WIFI_STA );
lcd.clear( );
lcd.print( "Wi-Fi " );
lcd.setCursor( 0, 1 );
lcd.print( "connect." );
WiFi.begin( ssid, password );
while (WiFi.status( ) != WL_CONNECTED) {
delay( 500 );
Serial.print(".");
}
///////////////////////////////////////////////////////////////////////
// Wi-Fi の情報を表示
WiFi_Information( );
sprintf( lineBuff, "%02X%02X%02X%02X",
WiFi.localIP()[ 0 ], WiFi.localIP()[ 1 ],
WiFi.localIP()[ 2 ], WiFi.localIP()[ 3 ] );
lcd.clear( );
lcd.print( lineBuff );
lcd.setCursor( 0, 1 );
sprintf( lineBuff, "IP 3:%3d", WiFi.localIP()[ 3 ] );
lcd.print( lineBuff );
}
///////////////////////////////////////////////////////////////////////
// SPIFFS でベースとなる HTML ファイルを読み込む
Serial.println( "" );
SPIFFS.begin( ); // ファイルシステム起動
// 読み込みモードで、paht_rootで指定したindex.htmlファイルを開く
File htmlFile = SPIFFS.open( path_root, "r" );
Serial.print( "HTML file open [" );
Serial.print( path_root );
Serial.println( "]" );
// ファイルの大きさを取得
size_t size = htmlFile.size( );
Serial.print( "file size : " );
Serial.print( size );
Serial.println( " byte" );
htmlFile.read( buf, size ); // ファイル収納バッファに読み込む
htmlFile.close( ); // ファイルを閉じる
///////////////////////////////////////////////////////////////////////
// Webサーバーの設定
setupWebHandle( );
digitalWrite( LedPin, HIGH ); // Ledを点灯
}
void loop( ) {
server.handleClient( ); // 送信されてきた内容の確認
}
void ESP8266_Information( void )
{
// https://www.mgo-tec.com/blog-entry-chip-info-esp-wroom-02-esp8266.html
// 上記 URL にある情報をもとに、ESP-WROOM-02 のボード情報を表示する
Serial.println( "" );
Serial.println( "" );
Serial.println( "" );
Serial.println(
"------------------------------------------------" );
Serial.println(
"--- ESP-WROOM-02 ( ESP8266 ) Chip Infomation ---" );
Serial.println(
"------------------------------------------------" );
Serial.print(
"Core Version = " );
Serial.println(
ESP.getCoreVersion( ) );
Serial.print(
"CPU Frequency = " );
Serial.print( ESP.getCpuFreqMHz( ) );
Serial.println(
" MHz" );
Serial.print(
"ChipID = " );
Serial.println( ESP.getChipId( ), HEX ); // MACアドレスの下位3バイト
Serial.print(
"Flash ID = " );
Serial.println( ESP.getFlashChipId( ), HEX );
Serial.print(
"SDK version = " );
Serial.println( ESP.getSdkVersion( ) );
Serial.print(
"Boot version = " );
Serial.println( ESP.getBootVersion( ) );
Serial.print(
"Boot Mode = " );
Serial.println( ESP.getBootMode( ) );
Serial.print(
"Flash Chip IDE Size = " );
Serial.print( ESP.getFlashChipSize( ) ); // Arduino IDE 設定の Flash Size になる
Serial.println(
" byte" );
Serial.print(
"Flash Chip Real Size = " );
Serial.print(
ESP.getFlashChipRealSize( ) ); // ESP-WROOM-32 内蔵最大 Flash Size になる
Serial.println(
" byte" );
Serial.print(
"Flash Frequency = " );
Serial.print(
ESP.getFlashChipSpeed( ) );
Serial.println(
" Hz" );
String mode_str;
switch ( ESP.getFlashChipMode() ) {
case 0: mode_str = "QIO"; break;
case 1: mode_str = "QOUT"; break;
case 2: mode_str = "DIO"; break;
case 3: mode_str = "DOUT"; break;
case 4: mode_str = "Unknown"; break;
default: break;
}
Serial.println(
"Flash Chip Mode = " + mode_str );
Serial.print(
"Free Heap Size = ");
Serial.println( ESP.getFreeHeap( ) );
Serial.print(
"Free Sketch Size = " );
Serial.println( ESP.getFreeSketchSpace( ) );
Serial.print(
"Sketch Size = " );
Serial.println( ESP.getSketchSize( ) );
Serial.println(
"------------------------------------------------" );
uint8_t mac0[ 6 ];
WiFi.macAddress( mac0 );
Serial.printf(
"WiFi StationAP Mac Address = %02X:%02X:%02X:%02X:%02X:%02X\r\n",
mac0[ 0 ], mac0[ 1 ], mac0[ 2 ], mac0[ 3 ], mac0[ 4 ], mac0[ 5 ] );
uint8_t mac1[ 6 ];
WiFi.softAPmacAddress( mac1 );
Serial.printf(
"WiFi SoftAP Mac Address = %02X:%02X:%02X:%02X:%02X:%02X\r\n",
mac1[ 0 ], mac1[ 1 ], mac1[ 2 ], mac1[ 3 ], mac1[ 4 ], mac1[ 5 ] );
Serial.println(
"------------------------------------------------" );
Serial.println( );
}
///////////////////////////////////////////////////////////////////////
// 現在のネットワーク情報を表示
void WiFi_Information( void )
{
int status = WL_IDLE_STATUS; // the Wifi radio's status
byte mac[6]; // the MAC address of your Wifi shield
Serial.println(
"------------------------------------------------" );
Serial.println(
"--- WiFi Infomation ---" );
Serial.println(
"------------------------------------------------" );
Serial.print(
"WiFi.localIP( ) = " );
Serial.println( WiFi.localIP( ) );
Serial.print(
"WiFi.subnetMask( ) = " );
Serial.println( WiFi.subnetMask( ) );
Serial.print(
"WiFi.gatewayIP( ) = " );
Serial.println( WiFi.gatewayIP( ) );
Serial.print(
"WiFi.status( ) = " );
switch ( status = WiFi.status( ) ) {
case WL_CONNECTED:
// assigned when connected to a WiFi network;
Serial.println( "WL_CONNECTED" );
break;
case WL_NO_SHIELD:
// assigned when no WiFi shield is present;
Serial.println( "WL_NO_SHIELD" );
break;
case WL_IDLE_STATUS:
// it is a temporary status assigned when WiFi.begin() is called and
// remains active until the number of attempts expires (resulting in
// WL_CONNECT_FAILED) or a connection is established (resulting in
// WL_CONNECTED);
Serial.println( "WL_IDLE_STATUS" );
break;
case WL_NO_SSID_AVAIL:
// assigned when no SSID are available;
Serial.println( "WL_NO_SSID_AVAIL" );
break;
case WL_SCAN_COMPLETED:
// assigned when the scan networks is completed;
Serial.println( "WL_SCAN_COMPLETED" );
break;
case WL_CONNECT_FAILED:
// assigned when the connection fails for all the attempts;
Serial.println( "WL_CONNECT_FAILED" );
break;
case WL_CONNECTION_LOST:
// assigned when the connection is lost;
Serial.println( "WL_CONNECTION_LOST" );
break;
case WL_DISCONNECTED:
// assigned when disconnected from a network;
Serial.println( "WL_DISCONNECTED" );
break;
default:
Serial.println( "? ? ? ? ? ? ? ? ? ?" );
break;
}
if ( status != WL_CONNECTED ) {
Serial.println("Couldn't get a wifi connection");
}
else {
// if you are connected, print your MAC address:
WiFi.macAddress( mac );
Serial.print(
"MAC ( Physical Address ) = " );
Serial.print( mac[ 5 ], HEX );
Serial.print( ":" );
Serial.print( mac[ 4 ], HEX );
Serial.print( ":" );
Serial.print( mac[ 3 ], HEX );
Serial.print( ":" );
Serial.print( mac[ 2 ], HEX );
Serial.print( ":" );
Serial.print( mac[ 1 ], HEX );
Serial.print( ":" );
Serial.println( mac[ 0 ], HEX );
}
Serial.println(
"------------------------------------------------" );
Serial.println( );
}
///////////////////////////////////////////////////////////////////////
// ESP-WROOM-02 のチップIDを用いて SSID を生成する
void getSSID(
char *buff ) //
{
sprintf( buff, "ESP_%6X", ESP.getChipId( ) );
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Wi-Fi で動作する車</title>
<script>
function send(url){
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.send();
}
</script>
<style type="text/css">
<!--
.stebtn {
width: 250px;
height: 160px;
font-size: 30px;
font-weight: bolder;
}
-->
</style>
</head>
<body>
<table width="800" border="0" align="center" cellpadding="2">
<tbody>
<tr>
<td colspan="3" align="center" bgcolor="#FFDCF4" style="font-weight: bolder; font-size: 18px;">
<strong style="font-size: 36px; font-weight: bolder; color: #5A01FF;">Wi-Fi で操作する車 コントローラー</strong></td>
</tr>
<tr>
<td align="center"><input type="button" class="stebtn" onClick="send('/FHFF/')" value=" ↑ ・↑↑"></td>
<td align="center"><input type="button" class="stebtn" onClick="send('/FFFF/')" value="↑↑・↑↑"></td>
<td align="center"><input type="button" class="stebtn" onClick="send('/FFFH/')" value="↑↑・ ↑ "></td>
</tr>
<tr>
<td align="center"><input type="button" class="stebtn" onClick="send('/STFH/')" value="--・ ↑ "></td>
<td align="center"><input type="button" class="stebtn" onClick="send('/FHFH/')" value=" ↑ ・ ↑ "></td>
<td align="center"><input type="button" class="stebtn" onClick="send('/FHST/')" value=" ↑ ・--"></td>
</tr>
<tr>
<td align="center"><input type="button" class="stebtn" onClick="send('/RHFH/')" value=" ↓ ・ ↑ "></td>
<td align="center"><input type="button" class="stebtn" style=" background-color:#FFB7EA" onClick="send('/STST/')" value="--・--"></td>
<td align="center"><input type="button" class="stebtn" onClick="send('/FHRH/')" value=" ↑ ・ ↓ "></td>
</tr>
<tr>
<td align="center"><input type="button" class="stebtn" onClick="send('/STRH/')" value="--・ ↓ "></td>
<td align="center"><input type="button" class="stebtn" onClick="send('/RHRH/')" value=" ↓ ・ ↓ "></td>
<td align="center"><input type="button" class="stebtn" onClick="send('/RHST/')" value=" ↓ ・--"></td>
</tr>
<tr>
<td align="center"><input type="button" class="stebtn" onClick="send('/RHRF/')" value=" ↓ ・↓↓"></td>
<td align="center"><input type="button" class="stebtn" onClick="send('/RFRF/')" value="↓↓・↓↓"></td>
<td align="center"><input type="button" class="stebtn" onClick="send('/RFRH/')" value="↓↓・ ↓ "></td>
</tr>
<tr>
<td colspan="3" align="center" bgcolor="#ABFCD7" style="color: #006C00; font-weight: bolder;"><a href="http://www.robofarm.jp/">RoboFarm</a> - <a href="http://www.robofarm.jp/contents/labo/wifibull/index.html">Wi-Fiブルドーザーをつくろう!</a></td>
</tr>
</tbody>
</table>
</body>
</html>
///////////////////////////////////////////////////////////////////////
// モータの状況表示
void motorLCD(
int Lp, // 左モーター(-100~0~100)
int Rp ) // 右モーター(-100~0~100)
{
lcd.setCursor( 0, 0 );
sprintf( lineBuff, "%c%3d%c%3d",
( Lp < 0 ) ? 'B' : 'F', abs( Lp ),
( Rp < 0 ) ? 'B' : 'F', abs( Rp ) );
lcd.print( lineBuff );
}
///////////////////////////////////////////////////////////////////////
// ツインモーター制御処理
void TMcont(
int Lp, // 左モーター(-100~0~100)
int Rp ) // 右モーター(-100~0~100)
{
motorLCD( Lp, Rp );
if ( Lp >= 0) {
analogWrite( LM1Pin, map( Lp, 0, 100, 0, LFMax ) );
analogWrite( LM2Pin, 0 );
}
else {
analogWrite( LM1Pin, 0 );
analogWrite( LM2Pin, map( abs( Lp ), 0, 100, 0, LRMax ) );
}
if ( Rp >= 0 ) {
analogWrite( RM1Pin, map( Rp, 0, 100, 0, RFMax ) );
analogWrite( RM2Pin, 0 );
}
else {
analogWrite( RM1Pin, 0 );
analogWrite( RM2Pin, map( abs( Rp ), 0, 100, 0, RRMax ) );
}
}
///////////////////////////////////////////////////////////////////////
// 停止
void AllStop( )
{
motorLCD( 0, 0 );
analogWrite( LM1Pin, 0 );
analogWrite( LM2Pin, 0 );
analogWrite( RM1Pin, 0 );
analogWrite( RM2Pin, 0 );
}
///////////////////////////////////////////////////////////////////////
// 左前進緩旋回(↑・↑↑)
void FhalfFfull() {
Serial.println( "FhalfFfull() - 左前進緩旋回" );
TMcont( 60, 100 ); //左60%、右100%
server.send( 200, "text/html", "Fhalf-Ffull" ); //HTTPステータスコード200(OK)+タイプHTML メッセージ送出
}
///////////////////////////////////////////////////////////////////////
// 全速前進(↑↑・↑↑)
void FfullFfull() {
Serial.println( "FfullFfull() - 全速前進" );
TMcont( 100, 100 ); //左100%、右100%
server.send( 200, "text/html", "Ffull-Ffull" );
}
///////////////////////////////////////////////////////////////////////
// 右前進緩旋回(↑↑・↑)
void FfullFhalf() {
Serial.println( "FfullFhalf() - 右前進緩旋回" );
TMcont( 100, 60 ); //左100%、右60%
server.send( 200, "text/html", "Ffull-Fhalf" );
}
///////////////////////////////////////////////////////////////////////
// 左信地旋回(--・↑)
void StopFhalf() {
Serial.println( "StopFhalf() - 左信地旋回" );
TMcont( 0, 70 ); //左0%、右70%
server.send( 200, "text/html", "Stop-Fhalf" );
}
///////////////////////////////////////////////////////////////////////
// 半速前進(↑・↑)
void FhalfFhalf() {
Serial.println( "FhalfFhalf() - 半速前進" );
TMcont( 60, 60 ); //左60%、右60%
server.send( 200, "text/html", "Fhalf-Fhalf" );
}
///////////////////////////////////////////////////////////////////////
// 右信地旋回(↑・--)
void FhalfStop() {
Serial.println( "FhalfStop() - 右信地旋回" );
TMcont( 70, 0 ); //左70%、右0%
server.send( 200, "text/html", "Fhalf-Stop" );
}
///////////////////////////////////////////////////////////////////////
// 左超信地旋回(↓・↑)
void RhalfFhalf() {
Serial.println( "RhalfFhalf() - 左超信地旋回" );
TMcont( -70, 70 ); //左-70%、右70%
server.send( 200, "text/html", "Rhalf-Fhalf" );
}
///////////////////////////////////////////////////////////////////////
// 停止(--・--)
void StopStop() {
Serial.println( "StopStop() - 停止" );
AllStop( ); //関数AllStop()
server.send( 200, "text/html", "Stop-Stop" );
}
///////////////////////////////////////////////////////////////////////
// 右超信地旋回(↑・↓)
void FhalfRhalf() {
Serial.println( "FhalfRhalf() - 右超信地旋回" );
TMcont( 70, -70 ); //左70%、右-70%
server.send( 200, "text/html", "Fhalf-Rhalf" );
}
///////////////////////////////////////////////////////////////////////
// 左後退信地旋回(--・↓)
void StopRhalf() {
Serial.println( "StopRhalf() - 左後退信地旋回" );
TMcont( 0, -70 ); //左0%、右-70%
server.send( 200, "text/html", "Stop-Rhalf" );
}
///////////////////////////////////////////////////////////////////////
// 半速後退
void RhalfRhalf() {
Serial.println( "RhalfRhalf() - 半速後退" );
TMcont( -60, -60 ); //左-60%、右-60%
server.send( 200, "text/html", "Rhalf-Rhalf" );
}
///////////////////////////////////////////////////////////////////////
// 右後退信地旋回(--・↓)
void RhalfStop() {
Serial.println( "RhalfStop() - 右後退信地旋回" );
TMcont( -70, 0 ); //左-70%、右0%
server.send( 200, "text/html", "Rhalf-Stop" );
}
///////////////////////////////////////////////////////////////////////
// 左後退緩旋回(↓・↓↓)
void RhalfRfull() {
Serial.println( "RhalfRfull() - 左後退緩旋回" );
TMcont( -60, -100 ); //左-60%、右-100%
server.send( 200, "text/html", "Rhalf-Rfull" );
}
///////////////////////////////////////////////////////////////////////
// 全速後退(↓↓・↓↓)
void RfullRfull() {
Serial.println( "RfullRfull() - 全速後退" );
TMcont( -100, -100 ); //左-100%、右-100%
server.send( 200, "text/html", "Rfull-Rfull" );
}
///////////////////////////////////////////////////////////////////////
// 右後退緩旋回(↓↓・↓)
void RfullRhalf( )
{
Serial.println( "RfullRhalf() - 右後退緩旋回" );
TMcont( -100, -60 ); //左-100%、右-60%
server.send( 200, "text/html", "Rfull-Rhalf" );
}
///////////////////////////////////////////////////////////////////////
// HTMLファイル送出
void handleRoot() {
// HTTPステータスコード200(OK)+タイプHTML HTMLファイル送出
server.send(200, "text/html", (char *)buf);
}
///////////////////////////////////////////////////////////////////////
// Webサーバーの on メソッドでイベントハンドラを設定する
//
void setupWebHandle( void )
{
server.on("/", handleRoot); // 「/」を受信した時に呼び出す関数の設定
// 以下、受信データごとの呼び出し関数の設定 // 左 右
server.on("/FHFF/", FhalfFfull); // 前 50% 前 100%
server.on("/FFFF/", FfullFfull); // 前 100% 前 100%
server.on("/FFFH/", FfullFhalf); // 前 100% 前 100%
server.on("/STFH/", StopFhalf); // 停止 前 50%
server.on("/FHFH/", FhalfFhalf); // 前 50% 前 50%
server.on("/FHST/", FhalfStop); // 前 50% 停止
server.on("/RHFH/", RhalfFhalf); // 後 50% 前 50%
server.on("/STST/", StopStop); // 停止 停止
server.on("/FHRH/", FhalfRhalf); // 前 50% 後 50%
server.on("/STRH/", StopRhalf); // 停止 後 50%
server.on("/RHRH/", RhalfRhalf); // 後 50% 後 50%
server.on("/RHST/", RhalfStop); // 後 50% 停止
server.on("/RHRF/", RhalfRfull); // 後 50% 後 100%
server.on("/RFRF/", RfullRfull); // 後 100% 後 100%
server.on("/RFRH/", RfullRhalf); // 後 100% 後 50%
server.begin(); // HTTPサーバー起動
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment