All posts by chen

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;
  }
}

 

参考にしたビデオ:

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の差し替えてできないみたい、結局直結できなく、ジャンパーで繋ぐ。また対応する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 を参考してください。

PIXEL (4) Japanese Input

Raspberry Pi 設定ツールで日本語化する

ラズベリーパイメニューからPreferences → Raspberry Pi Configurationの順に選択します。

2017073001

LocalisationタブのSet Locale…ボタンを押します。
Language:にja (Japanese)を選択します。

Timezone:をJapanに設定します。

Keyboard:のSet Keyboard…を押して、CountryにJapan、Variantはご使用しているキーボードの種類を選択します。分からない場合はとりあえずJapaneseで大丈夫だと思います。

WiFi Country:のSet WiFi Country…を押してCountry:にJP Japanを設定します。

最後にRaspberry Pi ConfigurationのOKを押すと再起動するか尋ねられるのでYesボタンを押して再起動します。

コマンドで日本語化する

ターミナルを開いて言語とタイムゾーンを設定します。

[*] ja_JP.UTF-8 UTF-8 を選択

アジア / Tokyo を選択

日本語関連パッケージをインストールします。

いったんログアウトして、再度ログイン(ユーザー名 : pi、パスワード : raspberry)するとデスクトップは日本語になります。

日本語入力

ラズベリーパイで日本語入力を行うための方法はいくつかあります

  1. fcitx-mozc
  2. scim-anthy

fcitx-mozc

今回は、Google日本語入力のオープンソース版である「Mozc」を使った方法を試してみましょう。

  • 日本語入力:
    sudo apt-get install fcitx-mozc --install-recommends -y
    再起動後、CTRL+スペースで日本語入力できる。。ハズ..
  • ラズパイメニュー > 設定 > Fcitxの設定 で、入力メソッドのとこで一番上が、キーボード – 英語(UK) だったら、削除する(Mozcだけ)か、US配列キーの場合、”英語(US)”にする。
  • フォント:
    sudo apt-get install fonts-ipafont fonts-ipaexfont fonts-takao

scim-anthy

日本語が入力できるようにscim-anthyをインストールします

sudo apt-get install scim-anthy

Wemos (d5) Weather Bureau

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

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

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

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

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

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

Wemos (d4) WiFi sniffing

最近力を入れる所は、WiFi sniffingという技術。

Amazon bottonをIoT bottonに改造するのカギは、このWiFi sniffing技術。Amazon bottonから出るWiFi信号をキャッチし、botton押されたとわかった。

推進するIoT-Cloud-Mobile Kitもそれに対応すべく、しばらくsniffingとPOSTの共存、メモリの制限などと格闘して、何度も諦めかけて、遂に安定して動作するようになった。

(IoT-Cloud-Mobile Kit)ブレッドボード

Wemosが周りのMAC addressとRSSIは取得でき、TinyWebDB-APIでクラウドに蓄積できた。

ただブレッドボードは長時間運用はやはり不安定、下記の開発ボードも試作した。

(IoT-Cloud-Mobile Kit)開発ボード(5×7)

さらに小型化して、OLEDも省略して(コンセントが保留して接続は可能)、基盤に状態を表示するRGBのLEDを増設。

(IoT-Cloud-Mobile Kit)開発ボード(3×7)

透明ケースに入れて、試験する様子。

(IoT-Cloud-Mobile Kit)開発ボード(3×7 inside case)

蓄積されたMAC addressとRSSIは、出席確認などに活用でき、室内位置情報(Indoor Positioning)のシステムも作りたいね。

Wemos (c8) Weather Station

IoT-Cloud-Mobile Kitに、Weather Station機能を導入する。

オリジナルのコード ThingPulse Weather Station は、温度センサーは  DHT11 を利用する、IoT-Cloud-Mobile KitはBMP280内蔵のため、修正後のコードは TokyoEC Weather Station を参照する。

I2CのOLED端子配列

I2CのOLED端子配列2種類があり:

  1. VCC,GND,SCL,SDA (Wemos, BMP180, BMP280バス直結可能)
  2. GND,VCC,SCL,SDA (NodeMcu直結可能)

1番目は、Wemos直結に適するので、試してみる。

接線 (Wiring) Wemos –> OLED

  1. Wemos 5V —> OLED Vcc
  2. Wemos GND –> OLED GND
  3. Wemos D4 —-> OLED SCL
  4. Wemos D3 —-> OLED SDA

また下記のセッティングは、自分の環境に合わせて設定。

* Begin Settings
const char* WIFI_SSID = "xxxx"; // your ssid
const char* WIFI_PWD = "xxxx"; // your password
const int I2C_DISPLAY_ADDRESS = 0x3c; // OLED I2C address
const int SDA_PIN = 13; // I2C OLED SDA
const int SDC_PIN = 14; // I2C OLED SCL
const float UTC_OFFSET = 9; // JST = +9
const String WUNDERGRROUND_API_KEY = "xxxxx"; // WUNDERGROUND API KEY
const String WUNDERGROUND_COUNTRY = "JP"; // japan
const String WUNDERGROUND_CITY = "Tokyo"; // tokyo
const String THINGSPEAK_CHANNEL_ID = "xxxxx"; // ThingSpeak CHANNEL
const String THINGSPEAK_API_READ_KEY = "xxxxx"; // ThingSpaek API KEY

ESP8266 IoT Study Kit動作確認

ESP8266 IoT Study Kitでも動くようになった。ただし、I2CのSDA、SCLは、実際の結線に合わせて修正すること。

拡大する

Piggyback (おんぶ)動作確認

それから、Piggyback (おんぶ) する形で、OLED接続する方法も上手くいく。

OLEDだけ繋ぐなら、こちら方法はコンパクトでいいでしょう。ピン・ソケット使わない、OLEDとWemos直結すればもっと薄くコンパクトな実装になる。

ESP-WROOM-02 バッテリー付き動作

ESP-WROOM-02に、Weather Station機能を試した。( esp-wroom-02-2-weather-station/ )

内容は、こちら( Wemos (c11) Weather Station )と殆ど同じ、デジタルクロックを追加した。