Arduino NANO (3) SSH1106 & Walking bitmap

経緯

ちょっと大き目のOLEDが欲しくて、1.3 InchのOLEDを注文した。

ただもの挿し替えて使えると思って、届いてわかったが、コントローラーは別物。SH1106というものを使われ、U8g2libライブラリをインストールして利用する。

Display OLED via I2C (SH1106)

実際参考サイトを見ながら、試してみる。

うまく表示できた。

しかしコントローラーが特殊のため、使用例がほとんど無いので、用途が限定。

Script – Walking bitmap

#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 u8g(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
// U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); // I2C / TWI  
 
const uint8_t bm[] PROGMEM = {
  0b00011000,
  0b00111100,
  0b01111110,
  0b11111111,
  0b11111111,
  0b01111110,
  0b00111100,
  0b00011000
};
 
static int WIDTH=128;
static int HEIGHT=64;
 
int x, y;
 
void setup(void) {
  u8g.begin();
  x = 0;
  y = 0;
}
 
void loop(void) {
 
  u8g.firstPage();  
  do {
    u8g.drawBitmap( x, y, 1, 8, bm);
  } while( u8g.nextPage() );
  
  delay(100);
 
  x += 8;
  if( x >= WIDTH){
    x = 0;
    y += 8;
    if( y >= HEIGHT){
      y = 0;
    }
  }
}

参考

WeMos (b9) ADS1115 for A/D

ADS1115とは

ADS1115 とは4チャンネル16bit  A/D 。I2C接続なので、OLEDと共に、WeMos に接続して利用してみる。

結線

SCL, SDA自由に変更可能。U8g2初期化コマンドでSetupする。

code

#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include <U8g2lib.h>
#include <math.h>
#define WINDOW_SIZE 128
Adafruit_ADS1115 ads;  /* Use this for the 16-bit version */
//Adafruit_ADS1015 ads;     /* Use thi for the 12-bit version */
// Sets up the display to be the 128px x 32px display
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ SCL, /* data=*/ SDA);
void setup(void)
{
  Serial.begin(9600);
  Serial.println("Hello!");
  Serial.println("Getting differential reading from AIN0 (P) and AIN1 (N)");
  Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");
  // The ADC input range (or gain) can be changed via the following
  // functions, but be careful never to exceed VDD +0.3V max, or to
  // exceed the upper and lower limits if you adjust the input range!
  // Setting these values incorrectly may destroy your ADC!
  //                                                                ADS1015  ADS1115
  //                                                                -------  -------
  ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  // ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  // ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
  // ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV
  // Initialize the display
  u8g2.begin();
  ads.begin();
}
// Function to print ${value} with a specific number of ${digits}
void print_digits(double value, short unsigned digits){
  double av = abs(value);
  value = av;
  while(av > 10){
    digits--;
    av/=10;
  }
  u8g2.print(value, digits - 1);
}
int16_t results[WINDOW_SIZE] = {0};
int current_result = 0;
void loop(void)
{
 int time = millis();
  /* Be sure to update this value based on the IC and the gain settings! */
  //float   multiplier = 3.0F;    /* ADS1015 @ +/- 6.144V gain (12-bit results) */
  float multiplier = 0.1875F; /* ADS1115  @ +/- 6.144V gain (16-bit results) */
  double voltage_multiplier = 5333;
  for (int i = 0; i < 16; i++){
    results[current_result] = ads.readADC_Differential_0_1();
    current_result++;
    current_result = current_result % WINDOW_SIZE;
  }
  double result = 0;
  int i;
  for (i = 0; i < WINDOW_SIZE; i++){
    result = result + results[i];
  }
  result = result / (double) WINDOW_SIZE;
  /*Serial.print("Differential: "); Serial.print(results); */
   //Serial.print("(");
   Serial.println(result * multiplier, 5);
   //Serial.println("mV)");
  u8g2.firstPage();
  do {
    // this is where the values get printed to the display
    //u8g2.setFont(u8g2_font_logisoso32_tr); // large 32px tall font
    // other font options can be found at https://github.com/olikraus/u8g2/wiki/fntlistall
    u8g2.setFont(u8g2_font_6x12_tn);
    if (result > 0){
      u8g2.setCursor(0,16);
      u8g2.print("+");
    } else {
      u8g2.setCursor(0,26);
      u8g2.print("-");
    }
    u8g2.setFont(u8g2_font_fur20_tr); // large 20px tall font
    u8g2.setCursor(7,26 );
    double volts = result / voltage_multiplier;
    print_digits(volts, 5);
    u8g2.print("V");
  } while ( u8g2.nextPage() );
  int d = (1000 / 16) - (millis() - time);
  if (d > 0){
    delay(d);
  }
}

 

動作確認

しかし、テスト結果は、思う通りにならない。
表示は0.0000V、1.0000V、ー1.0000V、の感じで、小数点以下は0000となっている。どうして?
大変の曲がり道して、わかったのは、OLEDの定義が間違え、「U8G2_SH1106_128X64_NONAME_F_HW_I2C」になって、その影響で、読み取り数字が変に。
 

「U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C」で定義を直したら、普通にA/D変換の結果が表示が出来た。

参考

IoT 見守りデバイスの開発

見守りIoTデバイスは、ウェアフリー生体センサ・シート型圧電センサと開発ボード、電源で構成された。

シート型圧電センサ

本研究では体動がなく静かな状態で得られた生体信号を分析対象とする。センサは敏感すぎて 体動があると、振幅が大大き過ぎになり、それらが検出できなくなる。

図 4.2 センサシートと開発ボード

今回使用したシート型圧電センサの外形寸法(31cm×34cm)により、椅子の座面に敷いた 状態で測定することにした(図 3.2 右側)。座り状態で安定しやすくなり、血圧や脈拍も測 定しやすくなる。本センサでは 得られた信号は呼吸成分や心拍成分でできている。

見守り開発ボード

 

見守り開発ボードにはA/D変換モジュールADS1115、ESP8266マイクロコントローラ内蔵の開発ボードWeMos D1 Miniと、OLED表示モジュール SSD1306が含まれる。

WeMos D1 MiniとはESP8266をメインチップとして、CH340のUSBシリアル変換チップを組み合わせた開発ボードだ。ESP8266マイクロコントローラはWi-Fiネットワークに接続し、簡単なTCP/IP接続を行うことができる。

 

ADS1115は可変ゲインアンプ付き、4チャンネル内蔵の16bit  A/D コンバータ。I2Cというシリアル通信方法で開発ボードに接続する。

 

SSD1306は小型 解像度128×64 OLED ディスプレイである。こちらもI2Cというシリアル通信方法で開発ボードに接続する。

図 4.3 見守りIoTボード

 

UPDとの通信はUPD APIを利用する。データをUPDへ送信と、UPDから見守り開発ボードへの管理コマンド受信に利用されている。送受信データのTAGは、複数の個体を区別するため、マイクロコントローラのMACアドレスの一部を利用する。例えば見守りIoTボードのMACアドレス下6桁は37cb33のマイクロコントローラに対して、ゲインを4に設定する場合は、TAGは gain-37cb33 である。

 

ウェアフリー生体センサからのデータをサンプリング周波 数 100Hz でデータを取得し、A/D変換して保存する。一定期間のデータを収集したら、まとめてUPDへ送信する。データサンプルは付録1を参照。一度にデータの収集できる期間は、見守りデバイスマイクロコントローラの内蔵メモリの容量による。

ESP8266マイクロコントローラの場合、メモリのリミットにより、6 秒間のデータの蓄積、送信できた。プログラムの最適化により、より長い期間のデータの蓄積、送信も可能である。

図 4.4 ケースにいれた見守りIoTボード

 

見守りIoTボードUPDから見守りデバイスへの管理コマンドの受信も可能である。

ADS1115は可変ゲインアンプであり、現在実装したコマンドはそのゲインの設定である。次はADS1115のゲインを指示するコマンドのサンプルである。

 

“VALUE” “gain-37cb33” “4”

われわれ開発した見守りIoTデバイスのプログラムはGitHubのリポジトリを参照する。