WeMos (14) Mini OLED Shield

64×48 size display と小さなOLED

Adafruit_SSD1306を利用するが、64×48 sizeの項目がないため、カスタマイズ版をダウンロードして、Adafruit_SSD1306に上書きする。

ただHello Worldを表示するスケッチ。

#include "SPI.h"
#include "Wire.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
 
#define OLED_RESET 0  // GPIO0
Adafruit_SSD1306 display(OLED_RESET);
 
void setup()   {
  Serial.begin(9600);
 
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 
  // init done
 
  display.display();
  delay(2000);
 
  // Clear the buffer.
  display.clearDisplay();
 
  // text display tests
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,10);
  display.println("Hello");
  display.println("World");
  
  display.display();
  delay(10000);
  display.clearDisplay();
}
 
 
void loop() {
 
}

 

WeMos (13) LED Matrix

3連ベースで、ESP8266, LED Matrix, SHT30を装着する。

 

ただのLED Matrix表示サンプル。

 

#include <Adafruit_GFX.h>
#include <WEMOS_Matrix_GFX.h>

MLED matrix(7); //set intensity=7 (maximum)

void setup() {
  Serial.begin(9600);
  Serial.println("8x8 LED Matrix Test");
  
 
}

static const uint8_t PROGMEM
  smile_bmp[] =
  { B00111100,
    B01000010,
    B10100101,
    B10000001,
    B10100101,
    B10011001,
    B01000010,
    B00111100 },
  neutral_bmp[] =
  { B00111100,
    B01000010,
    B10100101,
    B10000001,
    B10111101,
    B10000001,
    B01000010,
    B00111100 },
  frown_bmp[] =
  { B00111100,
    B01000010,
    B10100101,
    B10000001,
    B10011001,
    B10100101,
    B01000010,
    B00111100 };

void loop() {
  matrix.clear();
  matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_ON);
  matrix.writeDisplay();
  delay(500);

  matrix.clear();
  matrix.drawBitmap(0, 0, neutral_bmp, 8, 8, LED_ON);
  matrix.writeDisplay();
  delay(500);

  matrix.clear();
  matrix.drawBitmap(0, 0, frown_bmp, 8, 8, LED_ON);
  matrix.writeDisplay();
  delay(500);

  matrix.clear();      // clear display
  matrix.drawPixel(0, 0, LED_ON);  
  matrix.writeDisplay();  // write the changes we just made to the display
  delay(500);

  matrix.clear();
  matrix.drawLine(0,0, 7,7, LED_ON);
  matrix.writeDisplay();  // write the changes we just made to the display
  delay(500);

  matrix.clear();
  matrix.drawRect(0,0, 8,8, LED_ON);
  matrix.fillRect(2,2, 4,4, LED_ON);
  matrix.writeDisplay();  // write the changes we just made to the display
  delay(500);

  matrix.clear();
  matrix.drawCircle(3,3, 3, LED_ON);
  matrix.writeDisplay();  // write the changes we just made to the display
  delay(500);

  matrix.setTextSize(1);
  matrix.setTextWrap(false);  // we dont want text to wrap so it scrolls nicely
  matrix.setTextColor(LED_ON);
  for (int8_t x=0; x>=-36; x--) {
    matrix.clear();
    matrix.setCursor(x,0);
    matrix.print("Hello");
    matrix.writeDisplay();
    delay(100);
  }
  matrix.setRotation(3);
  for (int8_t x=7; x>=-36; x--) {
    matrix.clear();
    matrix.setCursor(x,0);
    matrix.print("World");
    matrix.writeDisplay();
    delay(100);
  }
  matrix.setRotation(0);
}

 

WeMos (b8) SHT30温度湿度表示

目的

3連ベースで、ESP8266, LED Matrix, SHT30を装着。温度と湿度を計測。

モジュールの組み立て

スケッチ

ただの温度と湿度の表示サンプル。

#include <WEMOS_SHT3X.h>

SHT3X sht30(0x45);

void setup() {

  Serial.begin(115200);

}

void loop() {

  if(sht30.get()==0){
    Serial.print("Temperature in Celsius : ");
    Serial.println(sht30.cTemp);
    Serial.print("Temperature in Fahrenheit : ");
    Serial.println(sht30.fTemp);
    Serial.print("Relative Humidity : ");
    Serial.println(sht30.humidity);
    Serial.println();
  }
  else
  {
    Serial.println("Error!");
  }
  delay(1000);

}

参考

  1. http://stigern.net/blog/using-wemos-d1-mini-sht30-sensor-shield/

D1 Mini (1) Setup & Blink

About D1 Mini

WeMos D1 Mini はESP8266モジュールを利用した、Arduino IDE利用可能な開発ボード。

WeMosには「D1 Mini」と「D1 R2」の2種類がある。使い方が同じ。

このシリーズは、コマンドラインで開発するPlatformIO環境を利用する。(GUIの開発環境Arduino IDEで開発する場合、WeMos (1) Blink を参照する。)

Macbook Air で実験する。

PlatformIOのインストール

組み込み系のクロスコンパイル環境です。Arduino(Atmel AVR)や、mbed(ST STM32)など、350種類以上のマイコンに対応しています。デバッガも100種類以上のマイコンに対応しています(デバッグ機能は有料っぽい)。
Python2で動いているので、Mac、Linuxからでも動かせます。
詳しくはPlatformIOの公式サイトを見てください。

Macbook Air で実験するので、Homebrew でインストール。

$ brew install platformio

Homebrew を使わないばあいは pip を使ってインストールできるようです。

boards コマンドで利用できるボードを確認できます。

$ platform boards

沢山表示されるので、コマンドのうしろにフィルタをつけて内容を絞るる。

$ platformio boards esp8266

Platform: espressif8266
----------------------------------------------------------------------------------------------------------------------------
ID MCU Frequency Flash RAM Name
----------------------------------------------------------------------------------------------------------------------------
gen4iod ESP8266 80MHz 512KB 80KB 4D Systems gen4 IoD Range
huzzah ESP8266 80MHz 4MB 80KB Adafruit HUZZAH ESP8266
oak ESP8266 80MHz 4MB 80KB DigiStump Oak
esp_wroom_02 ESP8266 80MHz 2MB 80KB ESP-WROOM-02
espduino ESP8266 80MHz 4MB 80KB ESPDuino (ESP-13 Module)
espectro ESP8266 80MHz 4MB 80KB ESPectro Core
espino ESP8266 80MHz 4MB 80KB ESPino
espresso_lite_v1 ESP8266 80MHz 4MB 80KB ESPresso Lite 1.0
espresso_lite_v2 ESP8266 80MHz 4MB 80KB ESPresso Lite 2.0
esp12e ESP8266 80MHz 4MB 80KB Espressif ESP8266 ESP-12E
esp01_1m ESP8266 80MHz 1MB 80KB Espressif Generic ESP8266 ESP-01 1M
esp01 ESP8266 80MHz 512KB 80KB Espressif Generic ESP8266 ESP-01 512k
esp07 ESP8266 80MHz 4MB 80KB Espressif Generic ESP8266 ESP-07
esp8285 ESP8266 80MHz 423.98KB 80KB Generic ESP8285 Module
heltec_wifi_kit_8 ESP8266 80MHz 4MB 80KB Heltec Wifi kit 8
nodemcu ESP8266 80MHz 4MB 80KB NodeMCU 0.9 (ESP-12 Module)
nodemcuv2 ESP8266 80MHz 4MB 80KB NodeMCU 1.0 (ESP-12E Module)
modwifi ESP8266 80MHz 2MB 80KB Olimex MOD-WIFI-ESP8266(-DEV)
phoenix_v1 ESP8266 80MHz 4MB 80KB Phoenix 1.0
phoenix_v2 ESP8266 80MHz 4MB 80KB Phoenix 2.0
sparkfunBlynk ESP8266 80MHz 4MB 80KB SparkFun Blynk Board
thing ESP8266 80MHz 512KB 80KB SparkFun ESP8266 Thing
thingdev ESP8266 80MHz 512KB 80KB SparkFun ESP8266 Thing Dev
esp210 ESP8266 80MHz 4MB 80KB SweetPea ESP-210
espinotee ESP8266 80MHz 4MB 80KB ThaiEasyElec ESPino
d1 ESP8266 80MHz 4MB 80KB WEMOS D1 R1 (Retired)
d1_mini ESP8266 80MHz 4MB 80KB WeMos D1 R2 & mini
d1_mini_lite ESP8266 80MHz 1MB 80KB WeMos D1 mini Lite
d1_mini_pro ESP8266 80MHz 16MB 80KB WeMos D1 mini Pro
wifinfo ESP8266 80MHz 1MB 80KB WifInfo
wio_node ESP8266 80MHz 4MB 80KB Wio Node

作業フォルダを作成

ChenLab-Mac-Urania:~ chen$ mkdir PlatfomIO
ChenLab-Mac-Urania:~ chen$ cd PlatfomIO/

Blink

動作確認のため、まずLちか(Blink)をする。

ボード内蔵のLEDを点滅させる。

プロジェクトを準備する

ChenLab-Mac-Urania:PlatfomIO chen$ mkdir wemos-blink
ChenLab-Mac-Urania:PlatfomIO chen$ cd wemos-blink/

ChenLab-Mac-Urania:wemos-blink chen$ platformio init –board d1_mini

ChenLab-Mac-Urania:wemos-blink chen$ ll
total 8
drwxr-xr-x 3 chen staff 96 7 21 20:18 lib
-rw-r–r– 1 chen staff 439 7 21 20:19 platformio.ini
drwxr-xr-x 2 chen staff 64 7 21 20:18 src
ChenLab-Mac-Urania:wemos-blink chen$ ll src/
ChenLab-Mac-Urania:wemos-blink chen$ ll
total 8
drwxr-xr-x 3 chen staff 96 7 21 20:18 lib
-rw-r–r– 1 chen staff 439 7 21 20:19 platformio.ini
drwxr-xr-x 2 chen staff 64 7 21 20:18 src

スケッチのファイルを作成

$ vi src/main.ino

$ cat src/main.ino
#define ESP8266_LED BUILTIN_LED
void setup()
{
  pinMode(ESP8266_LED, OUTPUT);
}
void loop()
{
  digitalWrite(ESP8266_LED, HIGH);
  delay(500);
  digitalWrite(ESP8266_LED, LOW);
  delay(500);
}

ビルドする/アップロードする

ビルドする。

$ platformio run

インストールは、結構大量のファイルをダウンロードするので、ココは時間が掛かる。

$ platformio run -t upload

シリアルドライバーのインストール手間がなく、うまく動作した。いい感じ。

参考

 

Arduino UNO (8) mini-Oscilloscope

Piezoセンサーを検証中、信号が見えないので、機能の確認に困っている。

OLEDのミニモニターは、何とかできないかよ探したところ、Arduino UNO時代のものがあり、ESP8266の対応品がない。ESP8266に対応して見たが、うまく表示できない。

仕方なく、蔵入りのArduino UNOを出して、まず検証して見る。

 

コンパイルエラーと、それと関連する表示範囲おかしい問題があった。

下記の分はエラーになり、コメントアウトして対応。

// error(“Height incorrect, please fix Adafruit_SSD1306.h!”);

そして表示範囲おかしい問題は、Adafruit_SSD1306.hを直接修正し、ディフォルトの128×32をコメントアウトし、もう一つの128×64のコメントを外すように変更した。

結果はうまくできた。

Arduino 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.

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

// 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)
  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(0) >> 4; // 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;
  }
}

同じプログラムは、Nanoも動いた。

参考

参考にしたビデオ:

Arduino mini-oscilloscope

WeMos (b7) PIR (Passive infrared sensor)

PIR (Passive infrared sensor)は、以前RPiで利用したが、WeMosにも試す。

動きがあったら、とりあえずLED 点灯する。

#define ESP8266_LED BUILTIN_LED
int pirPin = D7;
int val;

void setup() 
{
  Serial.begin(9600);
  pinMode(ESP8266_LED, OUTPUT);
  digitalWrite(ESP8266_LED, HIGH);
}
void loop() 
{
  val = digitalRead(pirPin);
  Serial.print(val);
  //low = no motion, high = motion
  if (val == LOW)
  {
    digitalWrite(ESP8266_LED, HIGH);
    Serial.println(" No motion");
  }
  else
  {
    digitalWrite(ESP8266_LED, LOW);
    Serial.println(" Motion detected  ALARM");
  }
 
  delay(1000);  
}

結線図

参考:

  • http://www.esp8266learning.com/wemos-mini-pir-sensor-example.php

WeMos (11) I2C OLED SH1106 (U8g2)

今まで使ったOLEDは0.96インチの製品。ちょっと大きめ1.3インチのOLEDを評価するため、一個購入して見る。WeMosがターゲット、直結できると考えて、適したピン配列を注文、その通りのぐつが届いた。

そのまま差し替えて動くと思ったけど、表示が乱れ、調べってみったら、1.3インチの製品は、SH1106というチップ使い、対応するドライバーは必要。

ArduinoのLibから検索すると、3点がヒット、簡単そうな一個が動かない、動いたのは複雑そうなU8g2でした。

このU8g2ライブラリは、SCLとSDAの差し替えてできないみたい、結局直結できなく、ジャンパーで繋ぐ 初期化コマンドで、SCL、SDA対応するGPIO変更可能。また対応するSSDは多数なので、根気よく対応する定義を見つけ、今回の件はSH1106のI2Cを使用してコンパイル。

一応表示ができた。

/*

  HelloWorld.ino

  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)

  Copyright (c) 2016, olikraus@gmail.com
  All rights reserved.


*/

#include <Arduino.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  u8g2.begin();
}

void loop(void) {
  u8g2.clearBuffer();					// clear the internal memory
  u8g2.setFont(u8g2_font_ncenB08_tr);	// choose a suitable font
  u8g2.drawStr(0,10,"Hello World!");	// write something to the internal memory
  u8g2.sendBuffer();					// transfer internal memory to the display
  delay(1000);  
}

 

WeMos (10) Adafruit NeoPixel LED Matrix

Adafruit NeoPixel LED Matrix の互換品が手に入れたので、試します。

二種類のLED Arrayがあり。

  1. 8連装LED Array
  2. 8x8LED Matrix

ライブラリから、Adafruit NeoPixel を追加してください。

Adafruit NeoPixelのスケッチの例から、Sample、Sampletestを実行してください。

スケッチの例には、実際に繋がったGPIOの番号を設定してください。ここではD6に変更する。

Sampleは、単純に指定した数のLEDを点灯する。ここでは数を8(または64)に変更する。

Sampletestは、いろんなパターンで指定した数のLEDを点灯する。ここでは数を8(または64)に変更する。

 

Wemos (d6) Weather Bureau 2

これまでWeather Station2回を制作、今回に合わせて三回の要点をリストする

  1. 一回目の Weather Stationはおもに気象情報の表示
  2. 二回のWeather Bureauは、気象情報の収集とクラウンに送信
  3. 今回はDeep sleep機能を利用して、節電する工夫

Deep sleepは、RST と GPIO16繋いたモード、Deep sleepに入ると消費電流は0.4〜0.8mA程度に下がる。

100均で購入した、ちゃんとしたケースに入れて、2個目のスイッチを追加した。

  1. Switch 1: 電源スイッチ
    これは主に使わないとき、バッテリ充電不足のときにOff
  2. Switch 2: Deep sleepスイッチ
    プログラムを書き込みするとき、Deep sleepスイッチOffしないと、書き込めない場合がある

試作品は太陽光で充電している様子。充電ボードのLEDが見える。

ソースコードは TinyWebDB-WeatherStation を参考してください。

Wemos (d5) Weather Bureau

前回の Weather Stationはおもに気象情報の表示がメイン。

今回のWeather Bureauは、気象情報の収集とクラウンに送信するがメイン。

ソースコードは TinyWebDB-WeatherStation を参考してください。

無人でも長時間自動運用するために、太陽電池で発電、Li-po電池に充電、給電など機能追加された。

問題は、太陽電池の発電は、Weather Bureauの24時間持続運用には足りない。deep sleep機能を利用して、節電する工夫が必要である。

その部分できたらまた共有する。