こんにちは、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
上記リンクで紹介されているサンプル例を参考にしてOLEDに文字を表示する方法をまとめています。
OLED用のライブラリを追加する
OLEDに文字を表示するためにOLED用のライブラリを追加します。Seeed Wikiの使用例で追加されている「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のように階層を下っていくとファイルを見つけることができます。
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」を表示します。
電源がONするとバージョン情報とボタンの情報が表示されました。SW2を押すとpush button:2の下の行が—>ONになることを確認しました。SW1の場合はpush button:1の下の行が—>ONになりました。
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:スキマ時間を有効に!スマホで学べる人気のオンライン資格講座【スタディング】まずは気になる講座を無料で体験しよう!
最後まで、読んでいただきありがとうございました。
OLEDはドットが細かいので小さな文字からフォントサイズを変更して大きく見せたりと拡張性があるので複雑な表示を行いたい場合に効果を発揮しそうです。