JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

ESP32 NTP 時計

2020-02-09 12:46:22 | ESP32

 ESP32でWiFi接続ができましたので、NTP(Netwaork Time Protocol)サーバーから時刻の情報を取得して、LCDに表示するNTP時計を作ってみます。

 NTPサーバーから時刻情報を取得するスケッチは、Autumn-Color.comというサイトのスケッチをコピーさせていただきました。このスケッチでは、Arduino IDEのシリアルモニタに時刻を表示させています。

 コピペしてESP32-DevKitCで実行してみると

年/月/日(曜日)時:分:秒が1秒ごとに表示されます。

これをLCDに表示してみます。

LCDは、1602(16文字2行)ですので、1行では入りきりませんので、

1行目に年/月/日(曜日)を表示して、2行目に時:分:秒を表示することにします。

LCDは、I2C用を使いましたのでESP32-DevKitCとの接続は、次のようにします。

スケッチです。「your SSID」、「your password」には自宅のWiFiのSSIDとパスワードを入れてます。

-------------------------------------------

/*
 * ESP32 NTP Clock I2C LCD Display
 * 2020.02.08
 * JH7UBC Keiji Hata
 */
 
#include <WiFi.h>
#include <time.h>
#include <LiquidCrystal_I2C.h>
 
// set the LCD
int lcdColumns = 16;
int lcdRows = 2;
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
 
#define JST     3600* 9
// set WiFi ssid & password
const char* ssid = "your SSID";
const char* password = "your passwaord";
 
void setup() {
  // initialize LCD
  lcd.init();
  // turn on LCD backlight                     
  lcd.backlight();
  //WiFi set up
  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED) {
    lcd.print(".");
    delay(500);
  }
  lcd.clear();
  lcd.print("Connected");
  lcd.setCursor(0, 1);
  lcd.print("IP:");
  lcd.print(WiFi.localIP());
  delay(1000);
  lcd.clear();
  configTime( JST, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp");
}
 
void loop() {
  time_t t;
  struct tm *tm;
  static const char *wd[7] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};
 
  t = time(NULL);
  tm = localtime(&t);
  lcd.home();
  lcd.printf("%04d/%02d/%02d(%s)",tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,wd[tm->tm_wday]);
  lcd.setCursor(0,1);
  lcd.printf("%02d:%02d:%02d",tm->tm_hour, tm->tm_min, tm->tm_sec);
  delay(1000);
}

-------------------------------------------

configTime()は、NTPサーバーに接続する関数、getlocalTime()は時刻情報を取得する関数で、説明は「Arduinoで遊ぶページ」のこちらのページが参考になりました。

WiFiに接続すると、1行目に「Connected」、2行目にIPアドレスが表示されます。

その後、日付と時刻が表示されます。


ESP32 Bluetooth テスト

2020-02-07 08:10:53 | ESP32

 WiFiに続いてESP32のBluetoothのテストをします。

 テストのための簡単なスケッチをESP32にコンパイル書き込みをします。

  「Hello World!」の文字をESP32側からパソコンにシリアル送信し、パソコンでそれを受信して、表示するスケッチです。

-------------------------------------------

#include "BluetoothSerial.h"

BluetoothSerial SerialBT;

void setup() {
  SerialBT.begin("ESP32test"); //Bluetooth device name
}

void loop() {
  SerialBT.println("Hello World!");
  delay(1000);
}

-------------------------------------------

 ESP32とパソコンをBluetooth接続する必要があります。(したがって、Bluetooth機能を持っていないパソコンではできません。)

 ESP32に電源が入った状態でパソコン(Windows10)側からBluetooth接続(ペアリング)の設定をします。

 Windows10のウインドウズロゴ→設定→デバイス(Bluetoothとその他のデバイス)と進み

 「Bluetoothまたはその他のデバイスを追加する」をクリックするとESP32のBluetoothが検出されます。

この場合、ESP32testを選ぶ(クリック)すると接続(ペアリング)が完了します。

ペアリングが完了するとパソコン側に新たなシリアルポート(COMポート)が開かれます。

ウインドウズロゴで右クリックして、デバイスマネージャーを開きます。

 ESO32に接続してるシリアルポート(この場合COM4)の他にBluetooth経由の標準シリアルCOM5とCOM6が新たに加わっています。

 Arduino IDEでツール→シリアルポートでCOM6を選び、シリアルモニタを開くとESP32からシリアル通信で送信された「Hello World!」の文字列を1秒ごとに受信し表示されます。(通信速度は115200bpsにします)

 ここで、ちょっとした注意が必要です。ESP32とパソコンとの通信には、COM6を使っていますが、ESP32にスケッチを書き込むには、Arduino IDEのシリアルポートを本来のESP32とパソコンの接続(この場合COM4)に戻す必要があります。

 Bluetooth接続は単なるシリアル通信ですから、TeraTermなどの通信ソフトでもESP32と通信することができます。

 TeraTermで受信した画面です。

 ESP32とパソコン間でBluetooth接続(ペアリング)ができ、通信できることが確認できましたので、パソコンからの指示でESP32に接続したLEDを点灯、消灯するスケッチを試してみます。

 スケッチです。

------------------------------------------

#include "BluetoothSerial.h"
#define LED_Pin 27

BluetoothSerial SerialBT;

void setup() {
  SerialBT.begin("ESP32test"); //Bluetooth device name
  Serial.begin(115200);
  pinMode(LED_Pin, OUTPUT);
  digitalWrite(LED_Pin, LOW);
}

void loop() {
  if (SerialBT.available()){
    char C = SerialBT.read();
    if(C == '1'){
      digitalWrite(LED_Pin, HIGH);
      SerialBT.println("LED ON");
    }else if(C == '2'){
      digitalWrite(LED_Pin,LOW);
      SerialBT.println("LED OFF");
    }
  }
}

------------------------------------------

スケッチを書き込み、COM6でシリアルモニタを開き、「1」を送信するとLEDが点灯します。「2」を送信するとLEDは消灯します。ESP32からは、「LED ON」「LED OFF」といいう文字が送られてきます。

動作を確認することができました。

Bluetoothは、WiFiより簡単に通信することができます。近距離でロボットなどを制御するには便利なのではないでしょうか。


ESP32 WiFi接続テスト

2020-02-05 19:04:47 | ESP32

 ESP32の勉強もだいぶ進んできて、いよいよWiFiの接続テストをやってみます。

 ArduinoやSTM32とESP32の大きな違いは、速度の速さ(クロック240MHz)とこのWiFiとBlurtooth機能です。

 まずは、WiFiのサンプルプログラムで繋がるかどうかテストします。

 Arduino IDEで、ファイル→スケッチ例→WiFiと進んで、「SinpleWiFiServer」というスケッチを選びます。

 サンプルプログラムのssidとpasswordのxxxxxxxx部分に自分の家の無線LANルータのSSIDとパスワードを記入します。

--------------------------------------------------

#include

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

---------------------------------------------------

コンパイルしてESP32-DevKitCに書き込み。

Arduino IDEのシリアルモニタを開いて接続状況を確認します。

が、・・・・・・・・・・・・・ と表示され、いつまでもつながりません。

それではと、EN(RESET)ボタンを押して、ESP32-DevKitCの再起動をかけました。

今度は、モニタに

Connecting to SSID xxxxxxxxxxxx

・・・・・・

WiFi connected

IP address

nnn.nnn.n.n

と表示され、無事WiFiに接続できました。

GPIO5にLEDを接続してありますので、これをWiFi経由で点灯、消灯させてみます。

ブラウザ(Edge)を立ち上げ、URL記入欄に先ほど表示されたIPアドレスを

http://nnn.nnn.n.n/

と記入して、IPアドレスにアクセスすると

ブラウザに

とメッセージが表示されます。上の「here」をクリックするとLEDが点灯します。

下の「here」をクリックするとLEDが消灯します。

なるほど、なるほど。

これで、WiFiに繋がること、つまりインターネットに接続できることが確認できました。

こんな小さなボードがワールドワイドの世界に繋がっているんですね。すごい。

さて、これで何をやってみましょうか。

 

 


ESP32 タッチセンサー テスト

2020-02-04 18:19:38 | ESP32

ESP32は、静電容量式のタッチセンサーを10個内蔵しています。(入力ピンT0~T9)

各ピンとGPIO番号の対応は次のようになっています。

T0    GPIO4

T1    GPIO0

T2    GPIO2

T3    GPIO15

T4    GPIO13

T5    GPIO12

T6    GPIO14

T7    GPIO27

T8    GPIO33

T9    GPIO32

主に使う関数だけテストしました。

タッチパッドの値を読み取る関数は

touchRead(uint8_t pin); //uint8_t pinは、GPIOの番号またはシンボル(T0~T9)

タッチセンサー割込み タッチパッドの値がしきい値(threshold)未満になったときに割込みをかける関数

touchAttacjInterrupt(uint8_t pin, ISR, uint_16 threshold); //pinはGPIO番号かシンボル、ISRは割込みがかかった時に実行する関数、割込みをかけるthresholdの値

まず、touchRead()で実際のタッチパッドの値を測定してみました。

T0のタッチパッドの値を1秒ごとにシリアルモニタに表示するスケッチです。

----------------------------

 void setup(){
  Serial.begin(115200);
}
 
void loop(){
  Serial.println(touchRead(T0)); 
  delay(1000);
}

----------------------------

タッチパッドの値は、

T0(GPIO4)にリード線も何もつけない状態のとき、88程度

T0にリード線をつけた状態で、79

リード線の先端の金属部分に触ったとき20以下でした。

タッチパッドをスイッチとして使う場合、しきい値(threshold)を50程度にすればよいようです。

そこで、リード線に触ったときにLEDが点灯するスケッチを描いてテストしました。

LEDは、GPIO27に接続します。タッチセンサーは、T0を使います。

-------------------------------

/*
 * ESP32 Touch LED
 * 2020.2.4
 * JH7UBC Keiji Hata
 */

 #define LED_Pin 27
 
void setup() {
  pinMode(LED_Pin, OUTPUT);
}

void loop() {
  if(touchRead(T0) < 50){
    digitalWrite(LED_Pin, HIGH);
  }else{
    digitalWrite(LED_Pin, LOW);
  }
}

-------------------------------

 リード線に触るとLEDが点灯しました。

 割込みについても次のようなスケッチでテストしました。

------------------------------------

/*
 * ESP32 Touch interrupt test
 * 2020.2.4
 * JH7UBC Keiji Hata
 */

 #define LED_Pin 27
 
//Interrupt Service Routine
void LED_Blink(){
  digitalWrite(LED_Pin, !digitalRead(LED_Pin));
  delay(500);
}

void setup() {
  pinMode(LED_Pin, OUTPUT);
  touchAttachInterrupt(T0, LED_Blink,50);
}

void loop() {
}

------------------------------------

リード線をチョン、チョンと触るとLEDが点灯、消灯を繰り返すのですが、触り続けると点灯しっぱなしになります。

安定して動作させるには、スケッチに工夫が必要なようです。

タッチセンサーは、いまのところあまり利用する予定がないので、動作を確認して終わりにしました。

 


ESP32 タイマー割込み(その1)

2020-02-03 19:46:38 | ESP32

 ESP32のタイマー割込みについて、「ESP32 Timer 割込み」というキーワードで検索して、あちこちのサイトを見ながら勉強を始めたのですが、これがなかなか手強いというか、分からないことが多い。

 よくまとまっているのが、「Arduinoで遊ぶページ」というサイトのこちらのページ

 ESP32は、2つのタイマーモジュールがあり、それぞれ2個の64ビットタイマーを持っているので、計4個のタイマーを使うことができます。

 タイマー割込みを利用したLEDの点滅(いわゆるLチカ)の最も簡単なスケッチです。

 LEDは、GPIO27に1kΩの抵抗を介して接続します。

 割込みサービスルーチンでIRAM_ATTRと宣言すると、コンパイルされたコードは、ESP32の内部RAM(IEAM)に配置されます。これをしないとコードはフラッシュメモリに配置され、割込み時の処理が遅くなります。

 timerBegin(0,80,true);は、タイマー0、分周比80、つまりこのタイマーのクロックは、80MHz/80=1MHz(1us)、countup

 timerAttachInterrupt(timer, &LED_Blink, true);は、タイマー割込みがかかった場合、LED_Blink()を実行すること

 割込みサービスルーチンをポインタで指名するんですね。&をとって、関数で呼んでもコンパイル実行してくれました。

この辺がよくわからない。

 timerAlarmWrite(timer, 500000, true); 割込みタイミングの設定で、timerが500000カウントに達したときに割込みがかかります。つまり、1us×500000=500000us=500ms=0.5sごとに割込みがかかります。

 0.5sごとに割込みサービスルーチンが呼ばれ、LEDの点灯と消灯が繰り返されます。

 なお、各関数の詳細は、上記のサイトを参照ください。

-----------------------------------------

/*
 * ESP32 Timer interrupt LED Blink
 * 2020.2.3
 * JH7UBC KeijiHata
 * 
 */
#define LED_PIN 27
 
hw_timer_t * timer = NULL; //timer 初期化

//割込みサービスルーチン
void IRAM_ATTR LED_Blink() {
  digitalWrite(LED_PIN, !digitalRead(LED_PIN));
}
 
void setup() {
  pinMode(LED_PIN, OUTPUT);
 
  timer = timerBegin(0, 80, true); //timer=1us
  timerAttachInterrupt(timer, &LED_Blink, true);
  timerAlarmWrite(timer, 500000, true); // 500ms
  timerAlarmEnable(timer);
}
 
void loop() {
}

-----------------------------------------

ブレッドボードです。

 とりあえず、Lチカはできました。

 でも、タイマー割込みは奥が深そうです。もう少し勉強しなければ・・・・・