PR

Seeeduino XIAOの拡張ボードのOLEDを使用する

組み込みエンジニア
本記事はプロモーションが含まれています。

こんにちは、ENGかぴです。

Seeeduino XIAO用の拡張ボードはSDカードスロットやOLEDによる液晶画面での表示ができます。またGrove端子対応のセンサーモジュールを挿入して計測等ができます。OLEDにボタンの情報を表示して動作確認を行いました。

Seeeduino XIAO用拡張ボード(Seeed Studio)を使用しています。Seeeduino XIAOを使って動作確認を行ったことを下記リンクにまとめています。

Seeeduino XIAOで学べるソフト開発と標準ライブラリの使い方

Seeeduino XIAOの拡張ボード

Seeeduino XIAO専用の拡張ボードがSeeed Studioから製作されています。このボードを使用するとOLEDに文字を表示したりSDカードを使用したりGrove端子を利用してセンサーと接続することができます。Seeeduino XIAOを挿入したコネクタ横にも配線できるようにコネクタが実装されています。拡張ボードについては下記リンクに詳細が説明されています。

Seeeduino XIAO Expansion board

リンク先では言語選択で日本語が選択できるようになっていますがページが対応していないため日本語での表示はできません。日本語で表示したい場合はGoogle Chromeの翻訳機能を使うと日本語表示ができます。

上記リンクで紹介されているサンプル例を参考にしてOLEDに文字を表示する方法をまとめています。

広告

OLED用のライブラリを追加する

OLEDに文字を表示するためにOLED用のライブラリを追加します。Seeed Wikiの使用例で追加されている「u8g2」ライブラリを追加して使用します。

ライブラリマネージャからu8g2ライブラリーを追加
ライブラリマネージャからu8g2ライブラリーを追加

Arduino IDEのツール内のライブラリを管理を選択するとライブラリマネージャ画面が表示されます。検索をフィルタに「u8g2」(大文字小文字はどちらでもよい)を入力すると表示される「U8g2」が候補として表示されます。インストールボタンを押すとライブラリが追加されます。

ライブラリの準備と初期化

#include <U8x8lib.h>

//U8X8_SSD1306_128X64_NONAME_HW_I2C型の変数を宣言
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8( SCL, SDA, U8X8_PIN_NONE);

void setup() {
  u8x8.begin(); //初期化
  u8x8.setFlipMode(1);   // set number from 1 to 3
  u8x8.setFont(u8x8_font_5x8_r); //フォントを選択
}

ライブラリを使用するためU8x8lib.hをインクルードします。OLEDへのアクセスはWire(I2C)を使用しますが、U8g2ライブラリのbegin()関数内でWireを設定を行うためインクルードの必要はありません。

U8X8_SSD1306_128X64_NONAME_HW_I2Cクラスの変数としてu8x8をインスタンス化しています。ArduinoなどハードウェアでI2C対応しているピンを使用する場合は上記のクラスを使用します。ソフトフェアでI2C生成する場合はU8X8_SSD1306_128X64_NONAME_SW_I2Cクラスを使用します。

u8x8は各種メンバー関数を使用した際の管理を行う変数です。ライブラリをインストールした際に対応するOLEDが記載されていますが、このクラス宣言を変更することで他のタイプのOLEDでもライブラリを使用することができます。

begin()関数を使用するとOLEDの初期化が行われます。setFlipMode()関数は1から3を引数に指定できます。画面の表示の向きを変更することができるようですが数値を変更しても表示が変わらなかったため未実装もしくは対応していない可能性があります。(解釈を間違っているかもしれません)

setFont()関数ではOLEDに表示する文字フォントを選択することができます。デフォルトではu8x8_font_5×8になっていますが、ライブラリの1文字あたり横5ドット縦8ドットの表示になります。

選択できるフォトンの種類はu8x8.hで確認できます。Arduino のライブラリが保存されているフォルダであるLibrariesからlibraries/U8g2/src/clib/u8x8.hのように階層を下っていくとファイルを見つけることができます。

Arduino IDEのバージョンが2.0.0以降であれば定義している文字列などを選択して右クリックすると定義に移動できるようになっています。

PR:わからないを放置せず、あなたにあった最低限のスキルを身に着けるコツを教える テックジム 「書けるが先で、理解が後」を体験しよう!

ライブラリの使用例(文字を表示)

u8x8.setCursor(0, 0);
u8x8.print("Seeeduino OLED");
u8x8.setCursor(0, 1);
u8x8.print("       Ver1.00");

setCursor()関数で文字表示する座標を指定します。第1引数に行番号、第2引数に列番号を指定します。座標を指定した後はprint()関数で文字を書き込んで表示します。write()関数を使用すると配列に対して書き込むデータ数を指定することができます。

種別内容
SetCursor()データを書き込む初期位置(表示スタート位置)にカーソルを合わせます。
print()文字列を指定して書き込み(表示)ます。
clearLine()指定した列の文字をクリアします。
今回使用したメンバー関数

clearLine()関数で上書き前の文字列を消してから表示した場合、ラインの文字列を消してから文字列を書き込むため表示がチラついて見えます。

clearLine()関数を使用しない場合、文字が残ったまま上書きするため表示がおかしくなることがあります。文字列の長さを統一している場合はそのまま上書きしても問題ありません。

動作確認

動作確認用の回路図
動作確認用の回路図

Seeeduino XIAOをSeeeduino拡張ボードに挿入しSW1とSW2を実装します。DIはプルダウン付きのDIにしているためSW1/SW2を押したときにショートすることはありません。SW1/SW2を押したときOLEDにボタンが押されたことを示す「—>ON」を表示するようにします。ボタンを押していない時は「—>OFF」を表示します。

OLEDの動作結果
OLEDの動作結果

電源がONするとバージョン情報とボタンの情報が表示されました。SW2を押すとpush button:2の下の行が—>ONになることを確認しました。SW1の場合はpush button:1の下の行が—>ONになりました。

OLEDはドットが細かいので小さな文字からフォントサイズを変更して大きく見せたりと拡張性があるので複雑な表示を行いたい場合に効果を発揮しそうです。

LCDを使用した場合はフォントなどに拡張性はありませんがライブラリなどが複雑にならないため簡易的に表示したい場合は低価格のLCDの方が良いこともあります。

ソースコード全体

以下のソースコードはコンパイルして動作確認をしております。コメントなど細かな部分で間違っていたりやライブラリの更新などにより動作しなくなったりする可能性があります。参考としてお使いいただければと思います。

#include <U8x8lib.h>
#include <TimerTC3.h>

#define PIN_DI1 0
#define PIN_DI2 1
#define DIFILT_MAX 4
#define TIM_DIFILT 1
#define TIME_UP 0
#define TIME_OFF -1
#define BASE_CNT 10 //10msがベースタイマとなる

typedef struct DIFILT{
  uint8_t wp;
  uint8_t buf[DIFILT_MAX];
  uint8_t di;
};

int16_t timDifilter;
int8_t cnt10ms;
DIFILT diData[2];
bool flg[2];
 
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8( SCL, SDA, U8X8_PIN_NONE);

 /* Local function prototypes */
void mainTimer(void);
void DiFilter(void);
void TimerCnt();

void setup(void) {
  uint8_t i;

  u8x8.begin();
  u8x8.setFlipMode(1);   // set number from 1 to 3
  u8x8.setFont(u8x8_font_5x8_r);
  u8x8.setCursor(0, 0);
  u8x8.print("Seeeduino OLED");
  u8x8.setCursor(0, 1);
  u8x8.print("       Ver1.00");
  u8x8.setCursor(0, 3);
  u8x8.print("push button:1");
  u8x8.setCursor(0, 5);
  u8x8.print("push button:2");

  TimerTc3.initialize(1000);
  TimerTc3.attachInterrupt(TimerCnt);

  pinMode(PIN_DI1,INPUT_PULLDOWN);
  pinMode(PIN_DI2,INPUT_PULLDOWN);

  i=0;
  while( i < 10){
    mainTimer();
    DiFilter();
    delay(10);
    i++;
  }  
}
 
void loop(void) {

  mainTimer();
  DiFilter();

  if( diData[0].di == 1 ){
    if( flg[0] == false ){
      flg[0] = true;
      u8x8.setCursor(0, 4);
      u8x8.clearLine(4);
      u8x8.print("   --->ON");
    }
  }
  else{
    flg[0] = false;
    u8x8.setCursor(0, 4);
    u8x8.print("   --->OFF");
  }

  if( diData[1].di == 1 ){
    if( flg[1] == false ){
      flg[1] = true;
      u8x8.setCursor(0, 6);
      u8x8.clearLine(6);
      u8x8.print("   --->ON");
    }
  }
  else{
    flg[1] = false;
    u8x8.setCursor(0, 6);
    u8x8.print("   --->OFF");
  } 
}
/* callback function add */
void TimerCnt(){
  ++cnt10ms;
}
/* タイマ管理 */
void mainTimer(void){

  if( cnt10ms >= BASE_CNT ){
    cnt10ms -=BASE_CNT;
    //10msごとにここに遷移する
    if( timDifilter > TIME_UP ){
      timDifilter--;
    }
  }
}
/* DIフィルタ */
void DiFilter(void){
  bool boo = true;
  uint8_t i;

  if( timDifilter == TIME_UP ){
    timDifilter = TIM_DIFILT;

    diData[0].buf[diData[0].wp] = digitalRead(PIN_DI1);
    diData[1].buf[diData[1].wp] = digitalRead(PIN_DI2);

    for(uint8_t no=0; no < 2; no++){
      for( i=1; i < sizeof(diData[no].buf);i++){
        if( diData[no].buf[i - 1] != diData[no].buf[i]){
          boo = false;
        }
      }

      if(boo){ //データがすべて一致なので採用する
        diData[no].di = diData[no].buf[0];
      }
      if( ++diData[no].wp >= sizeof(diData[no].buf)){
        diData[no].wp = 0;
      }
    }
  }
}

関連リンク

Arduinoのライブラリを使って動作確認を行ったことを下記リンクにまとめています。

Arduinoで学べるマイコンのソフト開発と標準ライブラリの使い方

Seeeduino XIAOで学べるソフト開発と標準ライブラリの使い方

ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方

PR:スキマ時間を有効に!スマホで学べる人気のオンライン資格講座【スタディング】まずは気になる講座を無料で体験しよう!

最後まで、読んでいただきありがとうございました。

タイトルとURLをコピーしました