2022年7月31日日曜日

WebSocketでOV7670-ESP32の画像表示

 ■OV7670

 OV7670 はVGA(640×480画素)サイズのイメージセンサです。内部構造はCMOSイメージセンサと信号処理用 DSPがワンチップになっています。マイコンへの映 像信号出力は、ディジタル8ビット・パラレルです。
製品仕様:
・イメージセンサー:OV7670 CMOS、VGA-640(V)×480(V)
・レンズ焦点距離:3.6mm(F2.5)
・光学サイズ:1/6型、画素セル:3.6um x 3.6um
・フィールド角:25°(対角)
・小さいサイズ:3.5cm x 3.5cm
・低動作電圧:2.5V~3.0VDC
・低動作電流:60mw(15fps VGA YUV format)
・スリープモード<20μA
・保存温度:-30℃~70℃
・動作温度:0℃~50℃
・感度:1.3V/(Lux-sec)
・インターフェース:標準SCCB(Serial Camera Control Bus)インターフェース(I2C互換)
・データ出力フォーマット:Raw RGB、RGB(GRB4:2:2)、RGB(565/555/444)、YUV(4:2:2)、YCbCr(4:2:2)
・データ出力解像度:VGA、CIF、CIF~40x30の任意解像度
・サンプリングタイプ:Vario Pixel
・接続コネクタ:2.54mmピッチ(2列)18ピン、ピンヘッダ
■ESP32接続
 下記ように、OV7670のピンとESP32ピンを接続します。
 ※データ転送スピードを考えると、短いジャンプワイヤーが勧め
 ※SDAとSCLは1KΩの抵抗を使用でも可
OV7670ESP32
D0IO36
D1IO39
D2IO34
D3IO35
D4IO32
D5IO33
D6IO25
D7IO26
MCLKIO15
PCLKIO14
HREFIO23
VSYNCIO13
SDAIO21 (1kΩ Pull Up)
SCLIO22 (1KΩ Pull Up)
RST3.3V
PWDNGND
■Web送信
 Web送信はWebSocketを使いました。
 下記ライブラリが必要です。
■部品一覧:
・ESP-WROOM-32開発ボード
・OV7670
・USBケーブル
・ジャンプワイヤー
・1KΩ抵抗*2
・ブレッドボード
■プログラム:
 単純なESP32、OV7670と接続ため(FIFOなどがない)、インターネットのいろいろなサンプルを試した結果で、
は使えます。
 
 下記箇所をちょっと修正しました。
 ①13行目~14行目までのWiFi接続情報
 ②23行目~33行目までのピン情報
 ③APモードは不要のため、削除
 ④DBABuffer.hはコンパイルエラーあるため、「#include <stdlib.h>」を追加

#include "OV7670.h"

#include <WebSockets.h>
#include <WebSocketsClient.h>
#include <WebSocketsServer.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <WiFiClient.h>
#include "canvas_htm.h"

const char *ssid_AP_1 = "XXXXXX";
const char *pwd_AP_1  = "XXXXXXX";

const int SIOD = 21; //SDA
const int SIOC = 22; //SCL

const int VSYNC = 13;
const int HREF = 23;

const int XCLK = 15;
const int PCLK = 14;

const int D0 = 36;
const int D1 = 39;
const int D2 = 34;
const int D3 = 35;
const int D4 = 32;
const int D5 = 33;
const int D6 = 25;
const int D7 = 26;

const int TFT_DC = 2;
const int TFT_CS = 5;

OV7670 *camera;

WiFiMulti wifiMulti;
WiFiServer server(80);

unsigned char pix = 0;

unsigned char start_flag = 0xAA;
unsigned char end_flag = 0xFF;
unsigned char ip_flag = 0x11;

WebSocketsServer webSocket(81);    // create a websocket server on port 81

void startWebSocket() { // Start a WebSocket server
  webSocket.begin();                          // start the websocket server
  webSocket.onEvent(webSocketEvent);          // if there's an incomming websocket message, go to function 'webSocketEvent'
  Serial.println("WebSocket server started.");
}

void startWebServer()
{
   server.begin();
   Serial.println("Http web server started.");
}
void serve() {
  WiFiClient client = server.available();
  if (client) 
  {
    //Serial.println("New Client.");
    String currentLine = "";
    while (client.connected()) 
    {
      if (client.available()) 
      {
        char c = client.read();
        //Serial.write(c);
        if (c == '\n') 
        {
          if (currentLine.length() == 0) 
          {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();
            client.print(canvas_htm);
            client.println();
            break;
          } 
          else 
          {
            currentLine = "";
          }
        } 
        else if (c != '\r') 
        {
          currentLine += c;
        }
        
      }
    }
    // close the connection:
    client.stop();

  }  
}

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t payloadlength) { // When a WebSocket message is received
 
  int blk_count = 0;

  char canvas_VGA[] = "canvas-VGA";
  char canvas_Q_VGA[] = "canvas-Q-VGA";
  char canvas_QQ_VGA[] = "canvas-QQ-VGA";
  char canvas_QQQ_VGA[] = "canvas-QQQ-VGA";
  char ipaddr[26] ;
  IPAddress localip;
  
  switch (type) {
    case WStype_DISCONNECTED:             // if the websocket is disconnected
      Serial.printf("[%u] Disconnected!\n", num);
      break;
    case WStype_CONNECTED: {              // if a new websocket connection is established
        IPAddress ip = webSocket.remoteIP(num);
        Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
           webSocket.sendBIN(0, &ip_flag, 1);
           localip = WiFi.localIP();
           sprintf(ipaddr, "%d.%d.%d.%d", localip[0], localip[1], localip[2], localip[3]);
           webSocket.sendTXT(0, (const char *)ipaddr);
           
      }
      break;
    case WStype_TEXT:                     // if new text data is received
      if (payloadlength == sizeof(canvas_QQQ_VGA)-1) {
        if (memcmp(canvas_QQQ_VGA, payload, payloadlength) == 0) {
              Serial.printf("canvas_QQQ_VGA");
              webSocket.sendBIN(0, &end_flag, 1);
              camera = new OV7670(OV7670::Mode::QQQVGA_RGB565, SIOD, SIOC, VSYNC, HREF, XCLK, PCLK, D0, D1, D2, D3, D4, D5, D6, D7);
        }
      } else if (payloadlength == sizeof(canvas_QQ_VGA)-1) {
        if (memcmp(canvas_QQ_VGA, payload, payloadlength) == 0) {
              Serial.printf("canvas_QQ_VGA");
              webSocket.sendBIN(0, &end_flag, 1);
              camera = new OV7670(OV7670::Mode::QQVGA_RGB565, SIOD, SIOC, VSYNC, HREF, XCLK, PCLK, D0, D1, D2, D3, D4, D5, D6, D7);
        }
      } else if (payloadlength == sizeof(canvas_Q_VGA)-1) {
        if (memcmp(canvas_Q_VGA, payload, payloadlength) == 0) {
              Serial.printf("canvas_Q_VGA");
              webSocket.sendBIN(0, &end_flag, 1);
              camera = new OV7670(OV7670::Mode::QVGA_RGB565, SIOD, SIOC, VSYNC, HREF, XCLK, PCLK, D0, D1, D2, D3, D4, D5, D6, D7);
        }
      } else if (payloadlength == sizeof(canvas_VGA)-1) {
        if (memcmp(canvas_VGA, payload, payloadlength) == 0) {
              Serial.printf("canvas_VGA");
              webSocket.sendBIN(0, &end_flag, 1);
              camera = new OV7670(OV7670::Mode::VGA_RGB565, SIOD, SIOC, VSYNC, HREF, XCLK, PCLK, D0, D1, D2, D3, D4, D5, D6, D7);
        }
      } 

      
      blk_count = camera->yres/I2SCamera::blockSlice;//30, 60, 120
      for (int i=0; i<blk_count; i++) {

          if (i == 0) {
              camera->startBlock = 1;
              camera->endBlock = I2SCamera::blockSlice;
              webSocket.sendBIN(0, &start_flag, 1);
          }

          if (i == blk_count-1) {
              webSocket.sendBIN(0, &end_flag, 1);
          }
        
          camera->oneFrame();
          webSocket.sendBIN(0, camera->frame, camera->xres * I2SCamera::blockSlice * 2);
          camera->startBlock += I2SCamera::blockSlice;
          camera->endBlock   += I2SCamera::blockSlice;
      }
      
      break;
    case WStype_ERROR:                     // if new text data is received
      Serial.printf("Error \n");
    default:
      Serial.printf("WStype %x not handled \n", type);

  }
}

void initWifiMulti()
{

    wifiMulti.addAP(ssid_AP_1, pwd_AP_1);

    Serial.println("Connecting Wifi...");
    while(wifiMulti.run() != WL_CONNECTED) {
       delay(5000);        
       Serial.print(".");
    }
    
    Serial.print("\n");
    Serial.print("WiFi connected : ");
    Serial.print("IP address : ");
    Serial.println(WiFi.localIP());
}

void setup() {
  Serial.begin(115200);
  initWifiMulti();
  startWebSocket();
  startWebServer();
}

void loop()
{
  webSocket.loop();
  serve();
}
■結果
ブラウザーを開いて、URLを入力し
配線イメージ
写真工場 :)

2022年7月28日木曜日

リードスイッチ形磁気形近接センサー、静電容量方式タッチセンサー、アクティブブザーモジュールの連動

■リードスイッチ形磁気形近接センサー


 リードスイッチは下図のように2枚のニッケル合金(磁性体)リードの一部をオーバーラップさせ、ガラス管に封入したもので、 このオーバーラップ部分は表面に金、銀及びロジウムなどの接点処理が施されており、さらに接点の活性化を防ぐためにガラス管内に不活性ガスを封入している。

 リードスイッチに電磁コイルまたは磁石によって磁界が作用するとリードが磁化され、磁界の2乗に比例したオーバーラップ部分の吸引力Fpが生じる。

 この吸引力でリードがたわむと、リード自体の弾性により反発力Fsが生じる。

 すなわち、Fp>Fsであるような磁界において接点は閉成される。

 また、Fp<Fsとなるような磁界において接点は開放される。

 磁気形近接スイッチでは、このようなリードスイッチの動作機構を利用し、磁石との組合せにおいて各種の機能を得ている。

■静電容量方式タッチセンサー

 「タッチセンサー」の表面に指で触れると生じる静電容量(電荷)の変化を、「センサー」が感知することで位置を認識します。

 「静電容量」とは、電気を蓄える能力であり、人体など、電気を通すものが近づいただけで変化します。

 電気を蓄えられる時間の変化から「静電容量」の増減を調べられるので、人体の接近を検知することが出来ます。

 この「センサー」は、指と「センサー」の間に遮蔽物があっても機能します。

■アクティブブザーモジュール

 電気を流すだけでピーと音が鳴ります。digitalWrite() で ON/OFF して制御します。

■磁気検知機

 磁気検知機が作成られると思って、下記機能を想定されています。

 磁石を近くにより、磁気を感知され、アクティブブザーを発音します。タッチセンサーにタッチして、消音します。

 見やすいために、赤LEDを追加し、アクティブブザーを発音/消音に従って、点灯/消灯します。

■配線図

※実物のアクティブブザーモジュールの「+」「S」ピンは間違いました。

 正しい順番は「-」「+」「S」

■プログラム:

#define BUZZER 4  // D2
#define TOUCH_PIN 5  // D1
#define REED 2  // D4
#define LED_PIN 16  // D0
void setup() {
  Serial.begin(115200);
  pinMode(BUZZER, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(TOUCH_PIN, INPUT);
  pinMode(REED, INPUT);
  digitalWrite(BUZZER, LOW);
  digitalWrite(LED_PIN, LOW);
}
void loop() {
  int val = digitalRead(REED);
  Serial.print("val=");
  Serial.println(val);
  if (val == LOW) {
    // 磁気近くになる時
    Serial.println("Scanned!");
    digitalWrite(BUZZER, HIGH);
    digitalWrite(LED_PIN, HIGH);
  } else {
    // 磁気が遠くになる時
    digitalWrite(BUZZER, LOW);
    digitalWrite(LED_PIN, LOW);
  }
  if (digitalRead(TOUCH_PIN) == HIGH) {
    // タッチの時
    Serial.println("Cleared!");
    digitalWrite(BUZZER, LOW); 
    digitalWrite(LED_PIN, LOW);
  }
  delay(1000);
}

■実物イメージ

磁気近くなる時:


 タッチセンサーにタッチする:

予想通り :)

2022年7月27日水曜日

ESP8266とESP32で、WIFIのWEBサーバ構築

今日はESP8266とESP32のWIFI機能を勉強しましょう。

ESP8266とESP32両方もWIFI機能が付きます。同じWIFIを接続している時、相互でデータ通信ができます。それに、PCや携帯とも通信できます。

今回は下記のようなWIFIネットを作ります。

・ESP8266:WiFiルーターです。ESP32、PC、携帯はすべて該当WiFiにつながる。
・ESP32:Webサーバーです。PC、携帯のブラウザーはこのサーバーへHttpアクセスできる。

■APモード
アクセスポイントモード(AP)はブリッジモードとも呼ばれ、Wi-Fiルーターを無線LANの親機として利用する機能です。 パソコンやスマートフォンなどを無線で接続したい時に切り替えるモードと考えると違いが分かりやすいでしょう。

下記のプログラムで、楽々作れます。

#include <ESP8266WiFi.h>
const char *ssid = "phoenix";  // WIFI名
const char *password = "12345678"; // パスワード
void setup() {
  Serial.begin(115200);
  WiFi.softAP(ssid, password);  // APモード
  Serial.print("Access Point: ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.softAPIP());
}
void loop() {
}

 ソースをESP8266にアップロードすると、「phoenix」とのWiFiが見えます。

 ※原因はわかりませんが、何回で試して、該当WiFiが見つかれません。結局はあったから、よかった。

ソースでのパスワードを入力して、つながれます。
PCを該当Wifiを接続すると、「Cmd」ウインドウで「Ping」コマンドを検証して、
順調接続しました。

■Webサーバー
WiFiライブラリを利用して、簡単なWebサーバーが構築できます。
プログラムは下記ようになります。
#include <WiFiMulti.h>

WiFiServer server(80);
WiFiClient WSclient;

WiFiMulti wifiMulti;

const char *html = "HTTP/1.1 200 OK\r\n"
  "Content-type:text/html\r\n"
  "Connection:close\r\n"    
  "\r\n"    //1行空行
  "<!DOCTYPE html>\n"
  "<html lang='ja'>\n"
  "<head>\n"
  "<meta charset='UTF-8'>\n"
  "<meta name='viewport' content='width=device-width'>\n"
  "<title>Phoenix-WebServer</title>\n"
  "</head>\n"
  "<body>\n"
  "Hello World!\n"
  "</body>\n"
  "</html>\n";

bool wifi_connect(){
  wifiMulti.addAP("phoenix", "12345678");  // Wifiに接続

  Serial.println(F("Connecting Wifi..."));
  if(wifiMulti.run() == WL_CONNECTED) {
    Serial.println(F("--- WiFi connected ---"));
    Serial.print(F("SSID: "));
    Serial.println( WiFi.SSID() );

    Serial.print(F("IP Address: "));
    Serial.println( WiFi.localIP() );

    Serial.print(F("signal strength (RSSI): "));
    Serial.print( WiFi.RSSI() );    // 信号レベル
    Serial.println(F("dBm"));

    return true;
  } else {
    return false;
  }
}

void printHTML(WiFiClient &client){
    Serial.println("sendHTML ...");
    client.print(html);
    Serial.println("sendHTML Done");    
}

void Ini_HTTP_Response(void){
  String req;
  
  WiFiClient client = server.available();        // サーバーに対して外部から接続があるかどうかを監視
  if(!client) return;  // クライアントからのアクセス要求があり、接続が確立し、読み取りが出来る状態になるとtrue

  while(client.connected()){                    // クライアントが接続状態の間
    if(!client.available()) break;              // 読み取り可能バイトが無いなら終了
    Serial.println(F("----Client Receive----"));    
    req = client.readStringUntil('\n');          // 1行読み込み

    if(req.indexOf("GET / HTTP") != -1){        // ブラウザからリクエストを受信したらこの文字列を検知する
      while(req.indexOf("\r") != 0){   // ブラウザからのリクエストで空行(\r\nが先頭になる)まで読み込む
        req = client.readStringUntil('\n');      // \nまで読み込むが\n自身は文字列に含まれず、捨てられる
        Serial.println(req);
        if(req.indexOf("websocket") != -1){
          Serial.println(F("\nPrint WS HandShake---"));
          return;
        }
      }
      delay(10);                                // 10ms待ってレスポンスをブラウザに送信
      Serial.println(F("\nPrint HTML-----------"));
      printHTML(client);                        // レスポンス(HTML)を返す
      Serial.println(F("\nPrint HTML end-------"));
    } else{                                        // その他のリクエスト(faviconなど)全部読み飛ばす
      Serial.println(F("*** Anather Request ***"));
      Serial.print(req);
      while(client.available()){
        Serial.write(client.read());            // ブラウザからデータが送られている間読み込む
      }
    }
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  if(wifi_connect()){ 
    server.begin();      // クライアントの接続待ち状態にする
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  Ini_HTTP_Response();
}

■検証

まずはPCです。シリアルモニタで出力されたIPアドレスを入力してみます。

出きった!!!
携帯も同じで試します。
OK!!



2022年7月25日月曜日

温度と湿度センサー(DHT11)の使い方

 ■DHT11の紹介

  DHT11は、温度と湿度を同時に計測することができるセンサーです。下記はモジュール版となり、DHT11単体で使おうとするとデータ受信ピンのプルアップが必要になるのですが、モジュールの場合はそのような対応は不要で、そのままArduinoに接続すれば使えるようになるので便利です。


    DHT11の仕様:

 入力電圧:DC 3~5.5V
 信号出力タイプ:デジタル
 温度測定範囲:0 ℃ ~ 50 ℃
 湿度測定分解能:1℃
 温度測定誤差範囲:±2℃
 湿度測定範囲:20%~90%RH
 湿度測定分解能:1%RH
 湿度測定誤差範囲:±5%RH

■配線図
■部品一覧
ESP8266開発ボード
・DHT11センサーモジュール
USBケーブル
ブレッドボード
ジャンパーワイヤー

■プログラム:
事前に、ライブラリ「DHT_sensor_library」をインストールしてください。

#include "DHT.h"
#define DHTTYPE DHT11   // DHT 11

#define dht_dpin 5
DHT dht(dht_dpin, DHTTYPE);

void setup() {
  Serial.begin(115200);
  dht.begin();
  Serial.println("Humidity and temperature\n\n");
}

void loop() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();         
  Serial.print("Current humidity = ");
  Serial.print(h);
  Serial.print("%  ");
  Serial.print("temperature = ");
  Serial.print(t); 
  Serial.println("C  ");
  delay(800);
}

■ 実物イメージ:

■シリアルモニタ出力



2022年7月24日日曜日

ESP32で1.44"OLEDディスプレイに文字と簡単グラフィック表示

 今回のOLEDディスプレイ:

 SPIで通信を行うため、SPIに関する。下記文章を参照してください。
■ピン一覧
 GND: GND
 VCC: 3.5V~5V電源
 SCL: SPIクロック
 SDA: SPIデータ(MOSI)
 RES: リセット
 DC: HIGHのときデータ、LOWのときコマンドの送信を示す
 CS: SPIの通信相手として選択するときLOWとする
 BLK: LOWのときバックライトをオフ、HIGHのときオン
■部品一覧:
 ESP-WROOM-32開発ボード
 1.44"OLEDディスプレイ(ST7735適用)
 USBケーブル
 ブレッドボード
 ジャンパーワイヤー
■ESP32とのつながる:
  OLED        ESP32
  GND  <ーー>   GND
  VCC  <ーー>   3V3
  SCL  <ーー>   D19
  SDA  <ーー>   D23
  RES  <ーー>   TX2(D17)
  DC   <ーー>   RX2(D16)
  CS   <ーー>   D5
  BLK  <ーー>   3V3
■プログラム:

  事前に、Adafruit_GFXとAdafruit_ST7735はインストールしてください。


#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <Fonts/FreeSerif12pt7b.h>
#include <Fonts/FreeSansBold9pt7b.h>
#include <Fonts/FreeSans9pt7b.h>

#define TFT_DC    16
#define TFT_CS    5
#define TFT_RST   17  
#define TFT_MOSI  23
#define TFT_CLK   19

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST);

void showIcons() {
  tft.fillRoundRect(30, 95, 30, 30, 5, ST77XX_MAGENTA);
  tft.fillCircle(80, 110, 15, ST77XX_BLUE); 
  delay(500);
}

void setup() {
  tft.initR(INITR_144GREENTAB);
  tft.setRotation(1);  //方向転換
  
  tft.fillScreen(ST7735_BLACK);  //背景色黒色
  tft.setCursor(0, 30);  //カーソル設定
  tft.setTextColor(ST7735_WHITE);  //文字色設定
  tft.setFont(&FreeSerif12pt7b);  //フォント
  tft.print("Hello World");  //文字表示
  tft.setCursor(20, 60);
  tft.setTextColor(ST7735_RED);
  tft.setFont(&FreeSansBold9pt7b);
  tft.print("ESP32");
  tft.setCursor(0, 80);
  tft.setTextColor(ST7735_YELLOW);
  tft.setFont(&FreeSans9pt7b);
  tft.print("PHOENIX-IoT");
  showIcons(); //グラフィック表示
}

void loop() {
}

■実物イメージ:



ESP32紹介とESP32の開発環境構築

 最近、ESP-WROOM-32の開発ボードを入庫したため、ESP32の環境構築方法と使い方を紹介します。

■ESP32とは

 ESP32シリーズとは、中国のEspressif Systems社が販売するワンチップWi-Fi/Bluetoothモジュールの製品群のことを指します。

 ESP32はESP8266後継機であること、ESP8266より、性能やピン数は大幅アップしました。もちろん、値段も高くになりました。

 手持ちの30ピン開発ボードのピン構成:

■環境構築

以前のESP8266環境のベースに紹介させてください。

 ESP8266の環境構築:ESP8266開発ボード初体験

・追加のボードマネージャーのURL

  Arduino IDEの「環境設定」で「追加のボードマネージャーのURL」のところ、「https://dl.espressif.com/dl/package_esp32_index.json」を追加する

・ボードマネージャーでマニフェストをインストール
  「ツール」 => 「ボード: 〇〇」 => 「ボードマネージャー」を開きます
  ESP32を入力し、下記を選択してください。
・モジュール選択
  「ESP32-Dev-Module」を選択できます。
・ドライバーは状態により、「CP2102」と「CH340」のどちらでも使えます。
■検証
残念ですが、今回「Blink」は使えなくなりましたため、「GetChipId」を使います。

・プログラム:
uint32_t chipId = 0;

void setup() {
Serial.begin(115200);
}

void loop() {
for(int i=0; i<17; i=i+8) {
  chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
}

Serial.printf("ESP32 Chip model = %s Rev %d\n", ESP.getChipModel(), ESP.getChipRevision());
Serial.printf("This chip has %d cores\n", ESP.getChipCores());
Serial.print("Chip ID: "); Serial.println(chipId);
  
delay(3000);

}
■結果





2022年7月17日日曜日

LCDディスプレイ1602A(I2C無篇)

  LCDディスプレイの表示には、その接続(通信)方法として「パラレル通信方式」やI2C通信などの「シリアル通信方式」があります。

 今回は基本となる「パラレル通信方式」で接続し表示させてみたいと思います。

 パラレル通信方式でディスプレイに表示させるにはESP8266-LCDモジュール間の配線が多くなります。今回は理解を深めるため基本的な接続方法となるパラレル通信方式でESP8266と接続し文字を表示させてみたいと思います。

■配線図

■部品リスト
ESP8266開発ボード
LCDディスプレイ1602A
ブレッドボード
USBケーブル
ジャンパーワイヤー
・可変抵抗(10KΩ小型ボリューム)
1602 LCDモジュール端子構成

ピン(端子)機能
VSSGND(電源)
VDD5V(電源)
V0コントラスト調整(電源)
RSラッチピン
(コントローラーにデータを入れる)
RWリード/ライトピン
(読み込み/書き込みの選択)
E Enableピン
(変更を許可するかを選択)
DB0~DB7 データビット(8ビット)
(4ビットモードでは上位ビットDB4-DB7のみ使用)
ALEDバックライト(アノード) : 5V
KLEDバックライト(カソード) : GND

■ESP8266と1602LCDモジュール端子の接続

LCDモジュールESP8266
VDD5V(VU)
VSSGND
R0可変抵抗器
RSD6
RWGND
ED5
DB4D1
DB5D2
DB6D3
DB7D4
A5V(VU)
KGND
■データ送信量(4ビット or 8ビット)
 LCDモジュールにはDB0~DB7までの8本のデータバスがあります。
 ESP8266からLCDに送る1回のデータ量を4ビットまたは8ビットで使うことが出来ます。

 今回Arduino IDE標準ライブラリ『LiquidCrystalライブラリ』を使用しますが、データ信号は4ビットと8ビット両方使うことが出来ます。

 今回は4ビットでのデータのやり取りで使用します。
 4ビットでのデータのやり取りでは上位ビットDB4~DB7での接続となり、2回に別けてデータを送信する形となります。(DB0~DB3は使いません)
とは言っても『LiquidCrystalライブラリ』がこのあたりの処理は代わりにやってくれるので難しいことは考えなくてもできちゃいます!

 データ信号ピンDB4~DB7ピン(4本)とRSピン・RWピン・EnableピンをArduinoの適切な位置に接続するだけです。

 それぞれのピンはデジタル信号でのやり取りとなります。
 LiquidCrystalのダウンロード:
 ダウンロード後、下記のところでインストールできます。
■プログラム
#include <LiquidCrystal.h>

// LCD ←→ Arduinoのピンの割り当て
// rs      →   D6
// rw      →   GND
// enable  →   D5
// d4      →   D1
// d5      →   D2
// d6      →   D3
// d7      →   D4
// [構文]LiquidCrystal(rs, rw,  enable, d0, d1, d2, d3, d4, d5, d6, d7)
LiquidCrystal lcd(D6, D5, D1, D2, D3, D4);

void setup() {
  lcd.begin(16, 2);          // LCDの桁数と行数を指定する(16桁2行)
  lcd.clear();               // LCD画面をクリア
  lcd.setCursor(0, 0);       // カーソルの位置を指定
  lcd.print("Hello!");       // 文字の表示
  lcd.setCursor(0, 1);       // カーソルの位置を指定
  lcd.print("ESP8266");      // 文字の表示
}

void loop() {
}

■実物イメージ

 




シンプルロボットカーセットの使い方

■ マイコン :ESP3266-CH340  シンプルの案として、マイコンは安いESP8266-CH340開発ボードを選びました。該当マイコンもWIFI機能があります。  ドライバーダウンロード場所:    https://sparks.gogo.co.nz/ch340.html...