Category Archives: ESP32 Dev Module

ESP32 (4) mini-Oscilloscope

Arduino UNOと同じmini-Oscilloscope を作って見た。

表示の正確性はまた検証が必要だけど

ソースコードはほぼ一緒

/*
This is set up to use a 128x64 I2C screen, as available
here: http://www.banggood.com/buy/0-96-oled.html
For wiring details see http://youtu.be/XHDNXXhg3Hg
*/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
//  error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

/********************************************/

#define CHARWIDTH           5
#define CHARHEIGHT          8
#define AXISWIDTH           (2 + 1)                   // axis will show two-pixel wide graph ticks, then an empty column
#define VISIBLEVALUEPIXELS  (128 - AXISWIDTH)         // the number of samples visible on screen
#define NUMVALUES           (2 * VISIBLEVALUEPIXELS)  // the total number of samples (take twice as many as visible, to help find trigger point

#define TRIGGER_ENABLE_PIN       2  // set this pin high to enable trigger
#define SCREEN_UPDATE_ENABLE_PIN 3  // set this pin high to freeze screen

byte values[NUMVALUES];           // stores read analog values mapped to 0-63
int pos = 0;                      // the next position in the value array to read
int count = 0;                    // the total number of times through the loop
unsigned long readStartTime = 0;  // time when the current sampling started
int sampleRate = 1;              // A value of 1 will sample every time through the loop, 5 will sample every fifth time etc.

const int voutPin = 2;
const int VOLT = 3.3; // 3.3Vを電源とした場合
const int ANALOG_MAX = 4096; // ESP32の場合


/********************************************/

// Draws a printf style string at the current cursor position
void displayln(const char* format, ...)
{
  char buffer[32];
  
  va_list args;
  va_start(args, format);
  vsprintf(buffer, format, args);
  va_end(args);
  
  int len = strlen(buffer);
  for (uint8_t i = 0; i < len; i++) {
    display.write(buffer[i]);
  }
}

// Draws the graph ticks for the vertical axis
void drawAxis()
{  
  // graph ticks
  for (int x = 0; x < 2; x++) {
    display.drawPixel(x,  0, WHITE);
    display.drawPixel(x, 13, WHITE);
    display.drawPixel(x, 26, WHITE);
    display.drawPixel(x, 38, WHITE);
    display.drawPixel(x, 50, WHITE);
    display.drawPixel(x, 63, WHITE);  
  }
}

// Draws the sampled values
void drawValues()
{
  int start = 0;
  
  if ( digitalRead(TRIGGER_ENABLE_PIN) ) {
    // Find the first occurence of zero
    for (int i = 0; i < NUMVALUES; i++) {
      if ( values[i] == 0 ) {
        // Now find the next value that is not zero
        for (; i < NUMVALUES; i++) {
          if ( values[i] != 0 ) {
            start = i;
            break;
          }
        }
        break;
      }
    }    
    // If the trigger point is not within half of our values, we will 
    // not have enough sample points to show the wave correctly
    if ( start >= VISIBLEVALUEPIXELS )
      return;
  }
  
  for (int i = 0; i < VISIBLEVALUEPIXELS; i++) {
    display.drawPixel(i + AXISWIDTH, 63 - (values[i + start]), WHITE);
  }
}

// Shows the time taken to sample the values shown on screen
void drawFrameTime(unsigned long us)
{
  display.setCursor(9 * CHARWIDTH, 7 * CHARHEIGHT - 2); // almost at bottom, approximately centered
  displayln("%ld us", us);
}

/********************************************/

void setup() {

  // Set up the display
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Initialize with the I2C addr 0x3D (for the 128x64)
  // Clear the buffer.
  display.clearDisplay();
  display.setTextColor(WHITE);

  pinMode(TRIGGER_ENABLE_PIN, INPUT);
  pinMode(SCREEN_UPDATE_ENABLE_PIN, INPUT);
}

/********************************************/

void loop() {
  
  // If a sampling run is about to start, record the start time
  if ( pos == 0 )
    readStartTime = micros();
  
  // If this iteration is one we want a sample for, take the sample
  if ( (++count) % sampleRate == 0 )
    values[pos++] = analogRead(voutPin) >> 6; // shifting right by 4 efficiently maps 0-1023 range to 0-63

  // If we have filled the sample buffer, display the results on screen
  if ( pos >= NUMVALUES ) {
    // Measure how long the run took
    unsigned long totalSampleTime = (micros() - readStartTime) / 2;     // Divide by 2 because we are taking twice as many samples as are shown on the screen
 
//    if ( !digitalRead(SCREEN_UPDATE_ENABLE_PIN) ) {
      // Display the data on screen   
      display.clearDisplay();
      drawAxis();
      drawValues();
      drawFrameTime(totalSampleTime);
      display.display();
//    }
       
    // Reset values for the next sampling run
    pos = 0;
    count = 0;
  }
}

 

 

ESP32 (3) analogRead

目的

12bit A/Dは複数内蔵するので、活用したい。

スケッチはArduino Unoと同じような記述でできる。ただし読み取り値は0〜1023ではなく0〜4096で、入力電圧の範囲は0〜3.3Vのようだ。

結線

 

スケッチ

const int voutPin = 2;
const int VOLT = 3.3; // 3.3Vを電源とした場合
const int ANALOG_MAX = 4096; // ESP32の場合

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

void loop() {
  // R1の電圧を取得
  int reading = analogRead(voutPin);

  // AD値をmVに変換
  float voltage = ((long)reading * VOLT * 1000) / ANALOG_MAX;

  Serial.print(voltage);
  Serial.println(" mV, ");
  
  delay(1000);
}

シリアルモニタを立ち上げると1秒ごとに読み取った値が表示。

結果

電池の電圧を測ると、概ねに正常範囲の値出るが、値は常に変化するので、どうして?

AnaRead.png

参考

  1. http://rikoubou.hatenablog.com/entry/2017/06/29/135819 — 【ESP32】analogReadする方法

ESP32 (2) SSD1306 & Clock

目的

SSD1306に時刻を表示するプログラム。

ESP8266と違って、SCL,SDAを探すも一苦労。

ハードウェア

「DOIT ESP32 DEVKIT V1」が幅が広いから、ブレッドボードは片側しか空いてない。結線は、片側で間にってよかった。

「ESPDUINO-32」の場合も動作する

ソフトウェア

参考1のそのまま

#include <WiFi.h>
#include <time.h>

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// OLED Setting
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

// WiFi Setting
#define WIFI_SSID   "uislab003"
#define WIFI_PASSWORD   "nihao12345"
#define JST     3600*9

void setup() {
  Serial.begin(115200);
  delay(100);
  Serial.print("\n\nReset:\n");

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  // Clear the buffer.
  display.clearDisplay();
  display.setTextColor(WHITE);

  // WiFi starting
  drawLog("WiFi connecting...");
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while(WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(500);
  }
  Serial.println();
  Serial.printf("Connected, IP address: ");
  Serial.println(WiFi.localIP());
  drawLog("WiFi connected!");

  // NTP start
  configTime( JST, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp");
  delay(1000);
}

void loop() {
  time_t t;
  struct tm *tm;
  static const char *wd[7] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};
  char rdate[30], rtime[30];

  t = time(NULL);
  tm = localtime(&t);

  Serial.printf(" %04d/%02d/%02d(%s) %02d:%02d:%02d\n",
        tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
        wd[tm->tm_wday],
        tm->tm_hour, tm->tm_min, tm->tm_sec);
  sprintf(rdate, " %04d/%02d/%02d(%s)",
        tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, wd[tm->tm_wday]);
  sprintf(rtime, " %02d:%02d:%02d", 
        tm->tm_hour, tm->tm_min, tm->tm_sec);
  drawClock(rdate, rtime);      
  delay(1000 - millis()%1000);
}

void drawClock(const char* rdate, const char* rtime) {
  display.clearDisplay();
  display.setCursor(0,0);

  display.setTextSize(1);
  drawText(rdate);

  display.setCursor(0,13);

  display.setTextSize(2);
  drawText(rtime);

  display.display();
  delay(1);
}

void drawText(const char* text) {
  for (uint8_t i=0; i < strlen(text); i++) {
    display.write(text[i]);
  }    
}

void drawLog(const char* msg) {
  display.clearDisplay();
  display.setCursor(0,0);
  display.setTextSize(1);
  drawText(msg);

  display.display();
  delay(1);
}

 

参考

  1. https://qiita.com/nori-dev-akg/items/bbe269d1d1bf1826532a

ESP32 (1) Setup & Blink

 ESP32とは

ESP32は低コスト、低消費電力のSoCコントローラー。最大な特徴は何と言ってもWifiとBluetoothが内蔵していること。

対象デバイス

このシリーズに対象となるデバイス

「WeMos D1 R32」

Arduino Uno R3 コンパチブルタイプ。類似のボードで、ESPDUINO-32 というものがある。ARDUINO IDEはボード設定はボードマネージャーに用意されていた「ESP32 Dev Module」でストレートに使用。

「DOIT ESP32 DEVKIT V1」

このボードは、普通のブレッドボードでは、1列が空くのみ不便だ。2枚を併用、専用アダプタを利用など必要。またEN(RESET)/BOOTの操作にご注意ください。スケッチをアップロードする前にENボタンを押しっぱなしにしてARDUINO IDE の書き込みボタンを押す。”Connecting”メッセージが現れたら、押していたENボタンを離して、BOOTボタンを押しっぱなしにする。書き込みが始まったのを確認したら、BOOTボタンを離してください。

ボードマネージャーに用意されていた「DOIT ESP32 DEVKIT V1」を使用。

「NodeMcu-32S」

NodeMcu-32SはNodeMcuのサイズに合わせた、ESP32開発ボード。普通のブレッドボードでも、2列が空くので便利だ。

ボードマネージャーに用意されていた「NodeMcu-32S」を使用。

USB-UARTドライバのインストール

Silicon Labsの以下のURLからドライバをダウンロード
USB – UART ブリッジ VCP ドライバ|Silicon Labs
ドライバをインストールしたら、シリアルポート(Port): /dev/cu.SLAB_USBtoUART が現れる。

Board ManagerにESP32追加

つい最近(20180728), ESP32 用 Arduino 開発環境 Arduino core for ESP32 WiFi chip の初の安定版 1.0.0 がリリース。インストールする際に, コマンドラインで色々する必要はなく Arduino IDE のメニューからインストールできるようになる。

https://dl.espressif.com/dl/package_esp32_index.json

Lチカのプログラム

ESP32-DevKitC を USB ケーブルで PC と接続.

Arduino IDE のメニューから  Tools – Port – /dev/cu.SLAB_USBtoUART を選択(Mac OS Xの場合).

一番単純そうなサンプルスケッチを実行する. メニューから File – Examples – (Examples for ESP32 Dev Module) – ESP32 – ChipID – GetChipID を選択.

Lチカ用内蔵LEDがGPIO2にあるが、GPIO4に外付けLEDを繋いでやった。

プログラム

void setup() {
  pinMode(4, OUTPUT);
}

void loop() {
  digitalWrite(4, HIGH);
  delay(250);
  digitalWrite(4, LOW);
  delay(250);
}

 

 

参考

  1. https://qiita.com/Guwashi/items/1009faab2d3db24d80d5
  2. https://kokensha.xyz/iot/mac-esp32-and-arduino-led/