I2C LEDドットマトリックスの WebSocket スマホ ジャイロ コントロールを解説

ESP8266 ( ESP-WROOM-02 )

※ ESP-WROOM-02 の Flashメモリサイズが 4MB のはずが、実は 2MB だったという情報がありました。
以下のページを参照して、Flashメモリサイズを確認しておくことを強くお勧めします。

ESP-WROOM-02 ( ESP8266 ) チップ・メモリ・MACアドレス情報確認方法
(2017/10/2)

さて、大晦日になってしまいました。
今年もあと1日です。

昨日、記事をアップしたばかりで散々疲れ果てたのに、勢いで今年最後の記事をアップしてしまいます。

過去の記事で報告しておりますが、今回はAdafruitさんの I2C通信制御のMini 8×8 LED Matrix と単体LEDをスイッチサイエンスさんのESP-WROOM-02開発ボードに接続して、WebSocket通信してみました。しかもスマートフォンのジャイロセンサーとタッチで怒涛のように操作しまくってみました。これのソースコードを公開してみようと思います。

前回の記事 では自作ライブラリ EasyWebSocket Beta1.1 バージョンを紹介しました。
今回はそれを使って、HTMLのCanvas要素をふんだんに使ってLEDドットマトリックスを制御してみました。
動画はこんな感じです。

Android5.0.2 で最新版Google Chromeで、高速CPUスマートフォンでないとこの様にうまくいきませんが、Wi-Fi通信にしては結構良く追従してくれますね。
後半は怒涛のようにジャイロセンサーとタッチセンサーを同時制御していますが、WebSocket通信も途切れずに無事に双方向ストリーミング通信しているのが分かると思います。
余りに度が過ぎた操作をするとさすがに通信遮断される場合があります。
それと、ESP-WROOM-02とスマホの距離が近すぎたり、近くにWi-Fi電波を飛ばすものが沢山あったりすると通信が途切れるようです。この動画ではかなり近い位置ですが、何とか大丈夫でした。・・・ていうか、このブログで上げている動画ではみんな距離が近すぎますね。双方向通信のWebSocketですから、送信機同士があまりにも近いと、そりゃぁ通信エラーになると思います。
この辺も頭に入れてテストしなければいけないですねぇ・・・。
因みに、iOSではうまくいきません。iOS9.2 でSafariでiPad mini で何度もテストしましたが、途中で通信遮断が起きますのでご了承ください。
iOSユーザーの方は通信遮断が起きない方法を編み出したら、ぜひ教えていただきたいですね。

余談ですが、HTML Canvas要素の使い方はネット情報でもある程度体得できますが、さらに確実に知識に入れるためには私はこの本を参考にしました。

ゲームで学ぶJavaScript入門 HTML5&CSSも身に付く!
インプレス
¥444(2024/11/09 00:43時点)

電子書籍版もあるので、とても重宝しました。
JavaScriptだけでなく、Canvas要素の使い方も多く紹介されており、素晴らしいです。

では、本題を順番に解説していきます。

スポンサーリンク

準備するもの

●ESPr Developer ( ESP-WROOM-02 開発ボード )(スイッチサイエンス)
過去の記事から散々紹介してますが、やっぱりまだまだ紹介しまくりますよ。
何といっても全部入りのボードでこちらで新たに調達する部品が格段に少なくて済むのが素晴らしいです。動作もメチャクチャ安定している超おすすめボードです。

ESP-WROOM-02開発ボード
スイッチサイエンス(Switch Science)

ESPr Developer(ピンソケット実装済)
スイッチサイエンス(Switch Science)

すごく売れいて、すぐに在庫切れしてしまうようです。
スイッチサイエンスさんのホームページで入荷通知を受け取る設定もできますのでそちらも利用してみてください。

●Adafruit I2C制御 Mini 8×8 LED Matrix
以下の物をつかいました。

Adafruit ミニLEDマトリックス基板(青色) 【959】
エイダフルート(Adafruit)
¥2,612(2024/11/08 18:36時点)

●単体LED 赤、青、緑 5V程度のもの
※3.3Vの電圧をかけても12mA未満の電流のものを使ってください。
12mA以上流れるものは、直列に電流制限抵抗を入れてください。

●場合によって、固定抵抗(LED電流制限用)

●その他、ブレッドボード、ジャンパーワイヤー、2.54mmピンヘッダ(ESP-WROOM-02開発ボード用)
●高速CPU最新スマートフォン(Android4.4.2以上)
※iOSでは通信が途中で途切れます。
●Google Chromeブラウザ

接続する

ドットマトリックスの組み立ては過去の記事をご覧ください。
ESP-WROOM-02開発ボードはピンヘッダを別途購入してハンダ付けするだけです。
接続図は下図の通りです。

ドットマトリックスのLEDドライバHT16K33は推奨電圧は5Vですが、3.3Vでも問題なく動作します。ESP-WROOM-02が3.3V駆動なので、それに合わせてます。
スイッチサイエンスさんのESP-WROOM-02開発ボードは5V出力やVINがあるのでいろんな使い方ができますね。

また、ご注意いただきたいのは、LEDを直接接続しているところです。
ESPr Developer ( ESP-WROOM-02, ESP8266 )のGPIO端子に流せる電流の最大値は12mAです。
3.3Vの電圧をかけても12mA未満の電流のLEDを選択するか、または電流制限抵抗を直列に接続してください。
一瞬でも12mAを超える電流が流れてしまうと、ESPr Developerが即壊れる場合があります。

USBからの電源供給だけでこれだけのデバイスを駆動するとなるとWi-Fi通信電力も心配になるところですが、意外と問題ありませんでした。
試しにVINに大容量電源をつないでみましたが、通信状態はあまり変わりませんでした。

ArduinoIDEにEasyWebSocket Beta1.1をインストールする

これは前回の記事を参照してください。
ライブラリはGitHubのこちらのページにあります。
ちなみにArduino IDEはArduino.ccページのIDEを使用してください。
バージョンは必ず1.6.5を使用してください
他のバージョンでは正常に動作しませんのでご注意ください。

ESP8266 ボードとSPIFFSファイルシステムツールも予めインストールしておく必要があります。
いろいろインストール方法記事が飛び飛びになっていてすみません。

ソースコードを入力する

上記のライブラリをインストールしたら、下図のサンプルスケッチを開きます。

次にこれを一旦保存します。

その次に、保存したフォルダの中のdataフォルダに入っているspiffs_01.txtというファイルだけ必要なので、サンプルスケッチは削除して、以下のソースコードをコピペします。
spiffs_01.txtというファイルはブラウザへ送信するHTMLヘッダです。

【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)

/*   
*     This Sketch is The MIT License (MIT)
*     Copyright (c) 2015 mgo-tec.com
*     Only ESP-WROOM-02 and Adafruit Mini 8x8 LED Matrix (I2C)
*/
#include <EasyWebSocket.h>
#include <ESP8266WiFi.h>
#include <Hash.h>
#include <Wire.h>

#define LDaddrs1 (0x70)  //LEDドライバーHT16K33 アドレス

byte LedDot[8];
byte LedDot2[8];


const char* ssid = "xxxx";
const char* password = "xxxx";

long CountTestTime;

byte cnt = 0;

EasyWebSocket ews;

String html_str1;
String html_str2;
String html_str3;
String html_str4;
String html_str5;
String html_str6;
String html_str7;

String ret_str;

int PingSendTime = 3000;//Ping送信間隔3秒

#define ledPin1 12 //ESP-WROOM-02 のGPIOピン番号設定
#define ledPin2 13
#define ledPin3 14

void setup() 
{
  Wire.begin(); // initialise the connection
  Wire.setClock(400000L);
  LED_Driver_Setup( LDaddrs1 ); //Ledドライバアドレス、On-Off、点滅周期(0~3)、明るさ0~15
  LED_Driver_Blink( LDaddrs1, 1, 0);
  LED_Driver_Brightness( LDaddrs1, 1 );
  LED_Driver_DisplayInt( LDaddrs1 );

  //LedDotOutをここで初期化しておかないと、表示が変になる
  for(byte i=0; i<8; i++){
    LedDot[i] =0;
  }

  html_str1 = ews.EWS_Body_style("white", "black");
  html_str1 += ews.EWS_BrowserSendRate();
  html_str1 += "<br>\r\n";
      //ドットマトリックス用canvas要素JavaScript 
  html_str1 += "<canvas id='canvas' width='320' height='320'></canvas>\r\n";
  html_str1 += "<script type='text/javascript'>\r\n";
  html_str1 += "  Touch_Dot();\r\n";
  html_str1 += "  function Touch_Dot(){\r\n";
  html_str1 += "    var cW = 320;\r\n";//ドットマトリックス用canvasサイズを指定
  html_str1 += "    var cH = 320;\r\n";
  html_str1 += "    var canvas = document.getElementById('canvas');\r\n";
  html_str1 += "    var ctx = canvas.getContext('2d');\r\n";
  html_str1 += "    var i,j;\r\n";
  html_str1 += "    for(i=0;i<8;i++){\r\n";//ここでドットを初期表示する
  html_str1 += "      for(j=0;j<8;j++){\r\n";
  html_str1 += "        ctx.beginPath();\r\n";
  html_str1 += "        ctx.fillStyle = '#444444';\r\n";
  html_str1 += "        ctx.arc(20*(i*2+1), 20*(j*2+1), 18, 0, Math.PI * 2, false);\r\n";
  html_str1 += "        ctx.fill();\r\n";
  html_str1 += "      }\r\n";
  html_str1 += "    }\r\n"; 
  html_str1 += "    canvas.addEventListener('touchmove', Dot_Display, false);\r\n";  
  html_str1 += "    function Dot_Display(e00){\r\n";
  html_str1 += "      e00.preventDefault();\r\n";//ドットをタッチしている間、直前のイベントキャンセル
  html_str1 += "      e00.stopPropagation();\r\n";//他の要素に伝搬しないようにする。
  html_str1 += "      var e0000=e00.touches[0];\r\n";//一本目の指だけ処理する
  html_str1 += "      ctx.clearRect(0, 0, cW, cH);\r\n";
  html_str1 += "      var i,j;\r\n";
  html_str1 += "      for(i=0;i<8;i++){\r\n";
  html_str1 += "        for(j=0;j<8;j++){\r\n";
  html_str1 += "          ctx.beginPath();\r\n";
  html_str1 += "          ctx.fillStyle = '#444444';\r\n";
  html_str1 += "          ctx.arc(20*(i*2+1), 20*(j*2+1), 18, 0, Math.PI * 2, false);\r\n";
  html_str1 += "          ctx.fill();\r\n";
  html_str1 += "        }\r\n";
  html_str1 += "      }\r\n";
  html_str1 += "      var OffSet = e0000.target.getBoundingClientRect();\r\n";//スクロールした場合でもcanvas内座標を維持するオフセット
  html_str1 += "      var ex = e0000.clientX - OffSet.left;\r\n";
  html_str1 += "      var ey = e0000.clientY - OffSet.top;\r\n";
  html_str1 += "      if( ex < 0 ){ex = 0;}\r\n";
  html_str1 += "      else if(ex>320){ex = 320;}\r\n";
  html_str1 += "      if( ey < 0 ){ey = 0;}\r\n";
  html_str1 += "      else if(ey>320){ey = 320;}\r\n";
  html_str1 += "      var Ex = 7-Math.floor(ex/42);\r\n";//座標を0~7に収めるようにしている
  html_str1 += "      var Ey = Math.floor(ey/42);\r\n";
  html_str1 += "      ctx.globalAlpha = 1;\r\n"; //透明度の設定
  html_str1 += "      ctx.beginPath();\r\n";
  html_str1 += "      ctx.fillStyle = '#FFFFFF';\r\n";
  html_str1 += "      ctx.arc(40*(Math.floor( ex/42 ))+20, 40*(Math.floor( ey/42 ))+20, 20, 0, Math.PI * 2, false);\r\n";
  html_str1 += "      ctx.fill();\r\n";
  html_str1 += "      ctx.beginPath();\r\n";
  html_str1 += "      ctx.fillStyle = '#0000FF';\r\n";
  html_str1 += "      ctx.arc(40*(Math.floor( ex/42 ))+20, 40*(Math.floor( ey/42 ))+20, 15, 0, Math.PI * 2, false);\r\n";
  html_str1 += "      ctx.fill();\r\n";
  html_str1 += "      doSend_canvas(Ex, Ey);\r\n";//データをESP-WROOM-02に送信
  html_str1 += "    };\r\n";
  html_str1 += "    };\r\n";
  html_str1 += "</script><br>\r\n";
      //スマホジャイロセンサ値取得用JavaScript
  html_str2 = "  <script type='text/javascript'>\r\n";
  html_str2 += "  window.addEventListener('deviceorientation', Gyro_Dot, false);\r\n";  
  html_str2 += "  function Gyro_Dot(event11) {\r\n";
  html_str2 += "    var alpha = event11.alpha;\r\n";//今回はこの値は使っていない。
  html_str2 += "    var beta = Math.floor((event11.beta)/3);\r\n";//あまり振れ幅を大きくしないようにしている
  html_str2 += "    var gamma = Math.floor(8-((event11.gamma+16)/2));\r\n";
  html_str2 += "    if(beta<0){ beta = 0;\r\n";//0~7の値に抑えるようにした
  html_str2 += "    }else if(beta>7){ beta = 7;}\r\n";
  html_str2 += "    if(gamma<0){ gamma = 0;\r\n";
  html_str2 += "    }else if(gamma>7){ gamma = 7;}\r\n";
  html_str2 += "    doSend_canvas(gamma, beta);\r\n";//データをESP-WROOM-02に送信
  html_str2 += "  };\r\n";
  html_str2 += "</script>\r\n";

  html_str3 = ews.EWS_Canvas_Slider_T("Dot_dim",200,40,"#777777","#ffffff");
  html_str3 += "<br>\r\n";
  html_str3 += ews.EWS_Canvas_Slider_T("_RGB",200,40,"#777777","#ffff00");
  html_str3 += "<br>\r\n";
  html_str4 = ews.EWS_Canvas_Slider_T("BLUE",100,40,"#777777","#0000ff");
  html_str4 += ews.EWS_Canvas_Slider_T("Grn",100,40,"#777777","#00ff00");
  html_str5 = ews.EWS_Canvas_Slider_T("RED",100,40,"#777777","#ff0000");
  html_str5 += "<br>\r\n";
  html_str5 += "from WROOM DATA =<font size=3>\r\n";
  html_str5 += ews.EWS_BrowserReceiveTextTag("text",25,"#FF00FF");
  html_str5 += "<br>\r\n";
  html_str5 += ews.EWS_Status_Text(20,"RED");
  html_str5 += "<br></font>\r\n";
  html_str5 += "<br><br>\r\n";  
  html_str5 += ews.EWS_Close_Button("WS CLOSE",150,40,17);
  html_str5 += "</body></html>\r\n";

  html_str6 = "";
  html_str7 = "";
  
  ews.AP_Connect(ssid, password);

  ews.EWS_HandShake(html_str1, html_str2, html_str3, html_str4, html_str5, html_str6, html_str7);
  
  CountTestTime = millis();
}

void loop() {
  String str;
  if(ret_str != "_close"){
    
    if(millis()-CountTestTime > 200){
      if(cnt > 9){
        cnt = 0;
      }
      switch(cnt){
        case 0:
          str = "_____";
          break;
        case 1:
          str = "____H";
          break;
        case 2:
          str = "___He";
          break;
        case 3:
          str = "__Hel";
          break;
        case 4:
          str = "_Hell";
          break;
        case 5:
          str = "Hello";
          break;
        case 6:
          str = "ello_";
          break;
        case 7:
          str = "llo__";
          break;
        case 8:
          str = "lo___";
          break;
        case 9:
          str = "o____";
          break;
      }
      
      ews.EWS_ESP8266_Str_SEND(str, "text");
      CountTestTime = millis();
      cnt++;
    }

    ret_str = ews.EWS_ESP8266CharReceive(PingSendTime);
    if(ret_str != "\0"){
      Serial.println(ret_str);
      if(ret_str != "Ping"){
        int ws_data = (ret_str[0]-0x30)*100 + (ret_str[1]-0x30)*10 + (ret_str[2]-0x30);
        switch(ret_str[4]){
          case 'B':
            LED_PWM('S', ledPin1, floor(ws_data));
            break;
          case 'G':
            LED_PWM('S', ledPin2, floor(ws_data));
            break;
          case 'R':
            LED_PWM('S', ledPin3, floor(ws_data));
            break;
          case '_':
            LED_PWM('A', 0, floor(ws_data/2));
            break;
          case 'D':
            ws_data = floor(ws_data/12); //LEDドライバHT16K33の明るさは0~16
            LED_Driver_Brightness(LDaddrs1, ws_data);
            break;
          default:
            LED_8X8matrix(ret_str[0], ret_str[2]);
            break;
        }
      }
    }
  }else if(ret_str == "_close"){
    delay(100);
    ews.EWS_HandShake(html_str1, html_str2, html_str3, html_str4, html_str5, html_str6, html_str7);
    CountTestTime = millis();
    ret_str = String('\0');
  }
}
//*************************************************************
void LED_8X8matrix(char x, char y)
{
  double xpow = pow(2,x-0x30);//0~7の数値をドットに置き換える演算
  LedDot[y-0x30]=xpow;
  LED_Ada88_cnv(LedDot, LedDot2);
  LED_Driver_DisplayOutput(LDaddrs1, LedDot2);
}

//**********************LEDドライバ HT16K33 セットアップ******************************************
void LED_Driver_Setup(byte LD_addrs)
{
  //HT16K33-28Wは8X8マトリックスLEDを2台まで制御できる。
  //ドライバIC#1 アドレスは0x70から設定する。
  Wire.beginTransmission(LD_addrs);
  Wire.write(0x20 | 1);  //システムオシレータをONにする
  Wire.endTransmission();
}
//**********************LEDドライバ HT16K33 点滅周期設定******************************************
void LED_Driver_Blink(byte LD_addrs, byte on_off, byte blink_Hz)
{
  //blink_Hz=0 点滅off, 1は2Hz, 2は1Hz, 3は0.5Hz, on_off=0は消灯、1は点灯 
  Wire.beginTransmission(LD_addrs);
  Wire.write(0x80 | (blink_Hz<<1) | on_off); 
  Wire.endTransmission();
}
//**********************LEDドライバ HT16K33 明るさ設定******************************************
void LED_Driver_Brightness(byte LD_addrs, byte brightness)
{
  // brightness= 0~15
  Wire.beginTransmission(LD_addrs);
  Wire.write(0xE0 | brightness);
  Wire.endTransmission();
}
//**********************LEDドライバ HT16K33 画面初期化******************************************
void LED_Driver_DisplayInt(byte LD_addrs)
{
  Wire.beginTransmission(LD_addrs);
  Wire.write(0x00);
  for(int i=0;i<8;i++){  
        Wire.write(B00000000);                   //1つ目の8x8LED初期化
        Wire.write(B00000000);                   //2つ目の8x8LED初期化
  }
  Wire.endTransmission();
}
//**********************Adafruit8x8ドットバイトコンバート******************************************
void LED_Ada88_cnv(byte* Bdot1, byte* Bdot2)
{
  for(byte i=0; i<8; i++){
    for(byte j=0; j<7; j++){
     bitWrite(Bdot2[i],6-j,bitRead(Bdot1[i],j));
    }
    bitWrite( Bdot2[i],7,bitRead(Bdot1[i],7));  
  }
}
//**********************LEDドライバ HT16K33 8X8データ送信******************************************
void LED_Driver_DisplayOutput(byte LD_addrs, byte* DotB) // 引数の並びが見た目のLEDの並びなので注意
{
  int i,j;
        Wire.beginTransmission(LD_addrs);
        Wire.write(B00000000);
        for(i = 0; i<8; i++){
          Wire.write(DotB[i]);
          Wire.write(0); //2つ目のドットマトリックスの場合はここでバイトを送る。
        }
        Wire.endTransmission();
}
//*********************単体LEDのPWM出力関数*****************************************
void LED_PWM(char S_or_A, byte Led_Pin, int data_i)
{
Serial.println(data_i);
  switch(S_or_A){
    case 'S':
      analogWrite(Led_Pin, data_i);
      break;
    case 'A':
      if(data_i < 34){
        analogWrite(ledPin1, data_i*8);
        analogWrite(ledPin2, 0);
        analogWrite(ledPin3, 0);
      }else if(data_i > 33 && data_i < 67){
        analogWrite(ledPin2, (data_i-33)*8);
        analogWrite(ledPin1, 0);
        analogWrite(ledPin3, 0);
      }else if(data_i > 66){
        analogWrite(ledPin3, (data_i-66)*7.78);
        analogWrite(ledPin1, 0);
        analogWrite(ledPin2, 0);
      }
      break;
  }
}

このソースコードはとりあえずMITライセンスとしておきます。
再配布、改変、商用は自由ですが、ライセンス表記はしておいて下さいねというものです。
ネット社会では表記しない方が自由に配布できないようなので、表記しておきました。
(実はライセンスの知識は私はあまりありません・・・)

17~18行目のSSIDとパスワードはご自分のルーターの環境に合わせて書き換えてください。

AdafruitさんのLEDマトリックスのI2C通信制御に関してのソースコードの意味は過去記事を参照してください。結構クセのあるデバイスでした。

前回の記事でも書きましたが、129行目から使用している、EasyWebSocket Bata1.1ライブラリ関数の
ews.EWS_Canvas_Slider_T
というものは、多量のJavaScriptタグ文字列を返すので、すぐに1つのStringクラスのメモリが満杯になってしまいます。
ews.EWS_Canvas_Slider_T関数は1つのStringクラスに2つまで追加できます。それ以上だと文字列排出が不十分で、ブラウザでちゃんと表示されませんのでご注意ください。

このプログラムの肝はHTML のCanvas要素の記述です。
これに関してここで説明してしまうととても書ききれません。
これはネットで沢山の情報があるので、説明は割愛させていただきます。
重要なのは
event.preventDefault();
event.stopPropagation();
などを使って他のイベントと競合しないようにすることです。
スマホのジャイロセンサーイベントとタッチイベントがかなり頻繁に発生しますからね。

それと最重要なのが、ESP-WROOM-02へデータを送信する
doSend
doSend_canvas
という関数です。
これはHTMLヘッダのspiffs_01.txtファイルに記述してありますが、全く同じ重複データを送信しないようにしています。
それと、送信待ちバッファが無い時にだけ送信するようにしています。
ここまですればWebSocket通信遮断は起きないだろうと思いそうですが、iOSだけはそれでも切断されてしまいます。これは私では全くのお手上げでした・・・。この原因が解る方は教えていただきたいですね。

その他のライブラリ関数使用方法は前回の記事を参照してください。

次に、下図のようにこのスケッチのフォルダを開きます。


次にdataフォルダを開きます。

次にspiffs_01.txtファイルをテキストエディタで開きます。

この中のローカルIPアドレスをご自分のルーターが割り当てたESP-WROOM-02のローカルIPアドレスに書き換えます。


メモ帳で開くと下図のようにうまく改行されていませんが、以下のようなところのIPアドレスを修正します。


修正が済んだら保存しておきます。

ESP-WROOM-02へspiffs_01.txtファイルをSPIFFSファイルシステムアップローダを使用してフラッシュに書き込む
そして、コンパイルする。

前回の記事でも述べましたが、予めIDEにインストールしてあるSPIFFSファイルシステムアップローダーを使用してspiffs_01.txtファイルをESP-WROOM-02のフラッシュに書き込みます。

書込み開始すると白い点々が出ますので、それが停止したら書き込み完了です。
その後にスケッチをコンパイルします。

コンパイルが済んだらブラウザのURL入力欄にローカルIPアドレスを入力して動作を確認してみてください。上記の動画のように動作すれば成功です。
やはり、SPIFFSファイルシステムを使うとコネクションが多少遅いですね。
フラッシュから読み出してそれをブラウザへ送信するわけですからどうしても遅くなってしまうのは仕方のないところです。
実は、ライブラリのサンプルスケッチにブラウザへ送信するHTMLファイルを全てSPIFFSファイルシステムにしたものを作ってみましたが、ハンドシェイク(コネクション確立)があまりにも遅くてブログで紹介できなかったんです。興味ある方は試してみてください。

WebSocket通信というものはブラウザで双方向通信ができるので、端末を選ばずにできてとても都合が良いと思いきや、iOSとは相性が悪くて少々ガッカリでしたね。
不意の切断が無く、サクサク動くようにするにはアプリ開発しか方法がないんでしょうかね。

ということで、今回の記事はここまでです。

今年の私の電子工作の一大事件はブログを立ち上げたこと、ブログを引っ越したこともエライ大変でしたが、何といっても自らの力でESP-WROOM-02 をブラウザとストリーミング通信を成功させたことでした。
一方向通信の Server-Sent Events を初めて成功させたときには感動しましたねぇ・・・。
それに、双方向通信のWebSocketは半分諦めていたのですが、これも執念で成功させました。ネットではほとんど記事が無かったので、満足度が高かったです。
ですが、その反面、パソコンに釘付けになる時間が増え、精神、身体ともにガタガタになってしまいました。近々介護が本格的になるのに、ガタついている場合じゃありません・・・。
来年はパソコンに向かいながら筋トレと日光浴とストレス解消ができる方法を考えていきたいと思ってます。

ということで、皆さま、本年は当ブログをお読みいただきありがとうございました。
来年もなにとぞよろしくお願いいたします。
良いお年を・・・。

最新記事ではWebSocketライブラリがバージョンアップして、格段に使いやすくなりました。
現在BETA1.3です。
こちらのページをご覧ください。2016/2/22

Amazon.co.jp 当ブログのおすすめ

スイッチサイエンス ESPr Developer 32 Type-C SSCI-063647
スイッチサイエンス
¥2,420(2024/11/08 09:01時点)
ZEROPLUS ロジックアナライザ LAP-C(16032)
ZEROPLUS
¥19,358(2024/11/08 16:05時点)
Excelでわかるディープラーニング超入門
技術評論社
¥2,068(2024/11/09 05:16時点)

コメント

  1. より:

    あけましておめでとうございます。
    IOTの初心者でESP-WROOM-02を勉強中のものです。
    EasyWebSocket を使ってみたいと思います。
    こんな貴重の情報の共有こころから感謝しております。

    • mgo-tec mgo-tec より:

      方さん

      明けましておめでとうございます。
      新年、第1号のコメントありがとうございます。
      こちらこそ、記事をお読みいただき、感謝しております。
      今後とも何卒よろしくお願いいたします。m_ _m

  2. cherry より:

    はじめまして。
    記事を参考にさせていただき、勉強中です。
    SPIFFSでのUPLOADですが、記事通りに操作してもアップローダーが起動しなく、ステータスのところに”SPIFFS Uploding Image…”と表示され、その後にエラーとなってしまいます。
    対処方法を教えていただけますと助かります。
    よろしくお願いします。

    • mgo-tec mgo-tec より:

      cherryさん

      記事をご覧いただき、ありがとうございます。

      まず、お聞きしたいのは、Arduino IDE のバージョンはどれでしょうか?
      それと、ステータスのところのエラーメッセージは何と表示されてますでしょうか?
      お知らせくださいませ。

      (意外と、Reset Method が”nodemcu”になっていないと、アップロードできないということがありますので、その辺も確認してみてください。)

      • cherry より:

        返信ありがとうございます。
        その後いろいろやってみたらできました。
        IDEは、1.6.5で、Reset Method も”nodemcu”になっていましたが、
        Flash Sizeが 4M(3M SPIFFS)だとエラーになりましたが、4M(1M SPIFFS)にするとアップロードできました。
        今は、 ESP-WROOM-02 で WebSocket リアルタイム制御 日本語電光掲示板作成(単体LEDマトリックス版)にチャレンジしていますが、WebSocketがうまくいってません。
        ESP-WROOM-02 で WebSocket リアルタイム制御 日本語電光掲示板作成(単体LEDマトリックス版)ページで質問させていただきます。
        よろしくお願いします。

        • mgo-tec mgo-tec より:

          なるほど・・・。
          アップロードできて良かったです。
          IDEは最新では1.6.11ですので、そちらの方が良いかもしれません。
          ちなみに、シリアルUSBポートで4M/3M SPIFFS アップロードはESPr Developer の基板上の印刷に Rev.2 とあるもので、IDEが1.6.11ならばアップロードできると思います。
          (ESPr Developer の最新版は Rev.3 という印らしいですが、それはまだ試してません。)

タイトルとURLをコピーしました