1週目

注釈

以下の項目について、全員がすべてを試す必要はありません。役割分担をして、確認と理解をすすめてください。

電源の切り方・入れ方

  • 電源を切るには、電源ボタン(M5と書かれたAボタンの左側面)を、6秒間長押しします。
  • 電源を入れるには、電源ボタンを、2秒間長押しします。
  • M5StickCガイド の、4ページ目、ハードウェアの概要が参考になります。

プログラムの書き込み方

プログラムの書き込み を参照してください。

コードを書くときのヒントと注意

  • 以下のソースコード例は、右上のボタンを押すと、クリップボードに簡単にコピーできます。
  • ソースコードのインデントは、CTRL+T (Macの場合はCommand+T)キーで、自動整形できます。
  • #include <M5StickC.h> は、M5StickC用のコードです。 M5StickCPlus では、#include <M5StickCPlus.h> に変更しないと、表示がおかしくなることがあります。
  • 大文字と小文字は厳密に区別されます。
  • 画面をつかうプログラムを書き込んだあと、画面を使わないプログラムを書き込むと、前のプログラムの画面が残ることがあります。

Serial通信

リスト 1 は、シリアルモニタへ文字列を出力するシンプルな例です。グローバル変数 num を 0 に設定したうえで、setup()関数が1回実行されます。その後、loop()関数が繰り返し実行されます。 プログラムの出力をみるには、Arduino IDEで「シリアルモニタ」をひらいてください。コードエディタ右上の虫眼鏡アイコンボタンをおします。 Serialクラスには、print()関数、println()関数、 printf()関数があります。Serial通信を用いると、デバイス側の変数の値や状況を、PC側で確認するプログラムを書くことができます。

リスト 1 src/serial01.ino
1
2
3
4
5
6
7
8
9
int num = 0;
void setup() {
  Serial.begin(115200); // 通信速度をbpsで設定
}
void loop() {
  Serial.printf("%d \n" , num);
  num++;
  delay(500); // 500ミリ秒待つ
}

シリアルモニタは、デバイスからの出力を確認するだけではなく、デバイスに文字を送信することもできます。リスト 2 は、シリアルモニタを介して、PCからデバイスに文字を送信する例です。シリアルモニタ上部のテキストエリアから 0 を送信すると、カウンタ num をリセットします。10〜14行目で、PCから送信された文字を、1文字ずつ Serial.read() で読み取って、配列 buf に格納しています。PCから複数の文字を1回で送信すると、 Serial.available() は連続して 1 (=true) を返しますので、1回に送信された文字をすべて buf に格納することができます。ちなみに、シリアルモニタで送信された文字列の最後は、改行コード(10)が付与されます。

リスト 2 src/serial02.ino
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int num = 0;
char buf[100];

void setup() {
  Serial.begin(115200); // 通信速度をbpsで設定
}

void loop() {
  int pos = 0;
  while (Serial.available()) { //PCから送信された文字があるあいだ、くりかえす
    char c = Serial.read(); // 1バイト読み取る
    buf[pos] = c;           // 配列buf に格納
    pos++;    // 格納位置をひとつ右へ
  }
  if (pos > 0) {
    buf[pos] = 0; // さいごに Null (文字列の終端)を追加(これを忘れるとどうなる?)
    Serial.print("> from pc: ");
    Serial.print( buf ); // 格納しておいた文字列を表示
    if (buf[0] == '0' && pos == 2) { // buf={ 48(='0'), 10(=改行) } のとき
      num = 0;  // num を 0 にする
      Serial.println( "Reset num" );
    }
    delay(2000);
  }

  Serial.printf("%d \n" , num );
  num++;
  delay(500);
}

注釈

16行目の処理を忘れると、どうなるでしょうか? また、buf が溢れると、なにが起きるでしょうか?プログラムを書くときは、常に例外的な事象がおきる可能性を考えておきましょう。ただし、全ての例外的な事象に対処するのは困難な場合が多いです。

本体の液晶ディスプレイ(LCD)

  • M5StickCのDisplay周り解析 <https://lang-ship.com/blog/work/m5stickc-display> が詳しいです。
  • リスト 3 のサンプルでは、外側から内側に向かって、10ピクセルずつ余白を残しながら、色を変えて塗りつぶしています。その後、8,16,26ピクセルフォント(それぞれ1,2,4番)をsetCursor()関数で指定して、print()関数で文字列を描画しています。
  • M5StickCPlusの機能である液晶ディスプレイ(LCD)を使用するため、 #include <M5StickCPlus.h> を指定し、M5.begin() を呼び出しています。
リスト 3 src/lcd01.ino
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <M5StickCPlus.h>

void setup() {
  M5.begin();
  M5.Lcd.setRotation(3);
  M5.Lcd.fillRect(0, 0, 240, 135, RED); 
  //M5StickCPlusの画面サイズは、240 x 135

  M5.Lcd.fillRect(10, 10, 220, 115, ORANGE);
  M5.Lcd.fillRect(20, 20, 200, 95, YELLOW);
  M5.Lcd.fillRect(30, 30, 180, 75, GREENYELLOW);
  M5.Lcd.fillRect(40, 40, 160, 55, CYAN);
  M5.Lcd.fillRect(50, 50, 140, 35, BLUE);
  M5.Lcd.fillRect(60, 60, 120, 15, MAGENTA);

  M5.Lcd.setTextFont(1); // 8pixel ASCII font
  M5.Lcd.setTextSize(1); // Magnify (x1-7)
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setCursor(10,1); M5.Lcd.print("RED");
  M5.Lcd.setTextColor(BLACK);
  M5.Lcd.setCursor(20,11); M5.Lcd.print("ORANGE");
  M5.Lcd.setCursor(30,21); M5.Lcd.print("YELLOW");
  M5.Lcd.setCursor(40,31); M5.Lcd.print("GREENYELLOW");
  M5.Lcd.setCursor(50,41); M5.Lcd.print("CYAN");
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setCursor(60,51); M5.Lcd.print("BLUE");
  M5.Lcd.setCursor(70,60,2); M5.Lcd.print("MAGENTA (2)");
  // setCursorの第3引数は、TextFont番号

  M5.Lcd.setTextColor(BLACK);
  M5.Lcd.setCursor(30,90,4); M5.Lcd.print("26pixel ASCII (4)");
}

void loop() {
}

画面の向きは、setRotation() 関数で、設定します。0〜3までの整数で、指定します。

_images/setRotation.gif

注釈

フォントの種類を設定するときは、setTextFont() や、setCursor()の第3引数をつかいます。setTextSize()は、指定したフォントを何倍に引き伸ばして表示するか?なので、基本は1を指定することが多いです。倍率を増やすと、ギザギザが目立ちます。

本体のボタン

本体には、3つのボタンがあります。 (参考:M5StickCガイド の、4ページ目、ハードウェアの概要)

リスト 4 に、ボタンをおしたらシリアルモニタに表示する例を示します。ボタンも、M5StickC/CPlusの機能なので、 #include <M5StickCPlus.h> を指定し、M5.begin() を呼び出しておく必要があります。また、ボタンの状態を読み出して、ボタンオブジェクト(BtnA,BtnB)に設定するために、 M5.update() を、ループのなかに入れておく必要があります( update()の定義 )。長押しと普通押しを区別したい場合は、ifで確認する順番(長押しを先に判定する)が重要です。

リスト 4 src/button01.ino
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <M5StickCPlus.h>

void setup() {
  M5.begin();
  M5.Lcd.setRotation(3);
}

void loop() {
  M5.update(); // 各ボタンの状態を(読み取って)更新する:ボタンを判定するときは必須。

  if (M5.BtnA.wasReleasefor(1000) ) {
    Serial.println("[A] was Pressed longer than 1s");
  } else if (M5.BtnA.wasReleased()) {
    Serial.println("[A] was Pressed");
  } else if (M5.BtnB.wasReleasefor(1000) ) {
    Serial.println("[B] was Pressed longer than 1s");
  } else if (M5.BtnB.wasReleased()) {
    Serial.println("[B] was Pressed");
  } else if (M5.Axp.GetBtnPress() == 2) {
    Serial.println("[Power] was Pressed");
  }
  delay(10);
}

文字列の扱い、16進数や10進数の変換

リスト 5 に、文字列から整数に変換したり、16進数表現の文字列を10進数に変換する例を示します。 Stringクラスを用いると、char配列 / byte配列 / 小文字変換や、空白改行の削除(ただし文字列の前後のみ)、部分文字列の取得などができます。 元のデータが保持されるメソッドと、破壊されるメソッドがあることに注意しましょう。 M5系デバイスのLCDでは、色を16ビット値(赤5bit/緑6bit/青5bit)で表現しています。 M5.Lcd.color565() という関数もありますが、ここではビット演算の理解を深めるため、関数を定義しています。 C言語のポインタや、シフト演算などを理解していると、このような処理を円滑に記述できるようになります。

リスト 5 src/str01.ino
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <M5StickCPlus.h>

void setup() {
  Serial.begin(115200);
  M5.begin();
  M5.Lcd.setRotation(3);
  Serial.println("整数 または 6文字の16進数(RRGGBB)を入力してください。");
}

String str = ""; // String: 可変長の文字列クラス
void loop() {
  char buf[100] = {0};
  int pos = 0;
  while (Serial.available()) { //PCから送信された文字があるあいだ、くりかえす
    char c = Serial.read(); // 1バイト読み取る
    buf[pos] = c;           // 配列buf に格納
    pos++;    // 格納位置をひとつ右へ
  }
  if (pos > 0) {
    buf[pos] = 0;
    String sbuf = buf;
    sbuf.trim(); //文字列の前と後の空白と改行を取り除く(破壊的メソッド)
    str.concat(sbuf); // 文字列の連結 (意味としては、str = str + sbuf)
    Serial.println(str);
    if (isDigit(sbuf)) {
      int num = sbuf.toInt();
      Serial.println( num * num );
    }
    if (sbuf.length() == 6) { // RRGGBBとして、LCD画面の背景を塗りつぶす
      sbuf.toLowerCase();
      uint8_t r = hexToDec( sbuf.substring(0, 2) );
      uint8_t g = hexToDec( sbuf.substring(2, 4) );
      uint8_t b = hexToDec( sbuf.substring(4, 6) );
      M5.Lcd.fillScreen( getColorUInt16( r , g , b ) );
      M5.Lcd.setCursor(0, 70, 4);
      M5.Lcd.printf(" %02x %02x %02x \n", r, g, b);
      M5.Lcd.printf(" %d %d %d ", r, g, b);
    }
  }
  delay(50);
}
//全ての文字が0〜9なら、1(true)を返す
bool isDigit(String s) {
  bool isAllDigit = true;
  const char *p = s.c_str(); // String.c_str() は、NULLで終端されたchar配列の先頭アドレスを返す
  while ( *p != 0 ) {
    if (*p < '0' || '9' < *p) isAllDigit = false;
    p++;
  }
  return isAllDigit;
}
// M5 用の、16ビットカラー値に変換 引用:https://qiita.com/nnn112358/items/ea6b5e81623ba690343c
uint16_t getColorUInt16(uint8_t red, uint8_t green, uint8_t blue) {
  return ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
}
// 引数hex が16進表記の文字列だと仮定して、10進の値を返す
uint8_t hexToDec(String hex) {
  int dec = 0;
  int tmp = 0;
  for (int p = 0; p < hex.length(); p++) {
    tmp = int(hex.charAt(p));
    if ( '0' <= tmp && tmp <= '9' ) tmp = tmp - '0';
    if ( 'a' <= tmp && tmp <= 'f' ) tmp = tmp - 'a' + 10;
    if ( 'A' <= tmp && tmp <= 'F' ) tmp = tmp - 'A' + 10;
    tmp = constrain(tmp, 0, 15); //例外処理
    dec = (dec * 16) + tmp;
  }
  return dec;
}

ブザー(Beep)

リスト 6 は、内蔵Beepを鳴らすサンプルです。音の周波数は、最初の1オクターブ (f[0]〜f[6]) のみを配列宣言時に指定し、残りの3オクターブはsetup()内で、倍数を計算して配列に設定しています。

setBeep()beep() を使うと、同じビープ音を使い回すときは記述が短くて便利ですが、通常は tone() のほうが簡潔です。 どちらの記法でも、命令実行のあと、音の停止を待たずに、すぐに次の処理に移行します(ノンブロッキング)。 継続ミリ秒数(ms)は、 M5.Beep.update() が周期的に呼び出せるときに指定し、それ以外は省略するとよいでしょう。(結局、 delay()mute() が必要になるため)

リスト 6 src/sound01.ino
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <M5StickCPlus.h>

int f[28] = { 262, 294, 330, 349, 392, 440, 494 }; // 配列のサイズは4オクターブ分
void setup() {
  Serial.begin(115200);
  M5.begin();
  M5.Lcd.setRotation(3);
  for (int i = 0; i < 7; i++) {
    f[i + 7]  = f[i] * 2;
    f[i + 14] = f[i] * 4;
    f[i + 21] = f[i] * 8;
  }
  // setBeep( Hz, ms) でビープ音を設定して、beep()で鳴らす。
  M5.Beep.setBeep(523, 500);  M5.Beep.beep();  delay(500);
  // tone( Hz, ms ) で鳴らす方法
  M5.Beep.tone(1046, 500);  delay(500);
  // msを省略し、tone( Hz ) で鳴らす(結局、delayが必要になるので)
  M5.Beep.tone(2092);  delay(500);
  // ここはmsを指定するとよい (loopのM5.Beep.updateが停めてくれるので、delayを省略できる)
  M5.Beep.tone(2092 * 2, 1000);
}

void loop() {
  M5.Beep.update(); //tone()やsetBeep()で指定した時間を過ぎていたら音を止める。
  //                  M5.Beep.mute() とすると、すぐに停止する。

  while (Serial.available()) {
    char c = Serial.read();
    if (c < 'c' || 'z' < c) continue; // c〜zの文字以外なら、以降のwhile内処理をスキップ
    M5.Beep.tone( f[c - 'c'] , 1000); // 1秒鳴らす
    Serial.println( f[c - 'c'] );
  }
  delay(50);
}

内蔵LED(赤・赤外)

M5StickCPlusには、2つのLEDランプが内蔵されています。GPIO(General Purpose I/O)10 には、赤色LED、GPIO9 には、赤外LEDが接続されています。 場所は、USBケーブルを挿す面の反対側の面にある、小さな穴2つの内側です。

リスト 7 は、赤色LEDを点滅させるシンプルなプログラムです。

リスト 7 src/led01.ino
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
int PIN = 10; // 赤色LED G10
//int PIN = 9; // Ir LED (カメラには映りますが、肉眼では見えません) G9
// その他、G0 (0) , G25 (25), G26 (26) がつかえます。
// https://lang-ship.com/blog/work/m5stickc-io/

void setup() {
  pinMode(PIN, OUTPUT); // PINのモード設定
}

void loop() {
  digitalWrite(PIN, HIGH); // HIGH = 1
  delay(1000);
  digitalWrite(PIN, LOW); // LOW = 0
  delay(500);
}

外部のLED等を接続

外部のLED等は、 G0, G25, G26 に接続します。 サンプルプログラムは、リスト 7 と同様です。PIN 番号を、0 / 25 / 26 に変更してください。

ブレッドボードに、抵抗とLEDを直列に接続します。 LEDの長い足のほうに、G0 (or G25 or G26) をジャンパワイヤで接続し、反対側(短い足)のほうを、GND (グランド)に接続します。 ポートを「HIGH」にすると、3.3Vの電圧がかかります。

_images/SimpleLED_m5s.png

警告

LEDのみで回路を構成しないよう注意!一般に、LEDは抵抗をつないで使用しないと、故障したり、最悪の場合破裂したりして危険です。ただし、抵抗入りLEDであれば問題ありません。

PWM (Pulse Width Modulation)

パルス幅変調とは、信号の周期Tに対する、パルスの幅を変化させる方法です。 直流モータの速度制御や、サーボモータの制御、LEDの明度調整などに使われます。

リスト 8 は、赤色LEDを点滅させるシンプルなプログラムです。 ledcSetup(チャンネル, 周波数, 分解能) で、PWMチャンネル(0〜3)に対する周波数と分解能設定をし、 lecAttachPin(ピン番号, チャンネル) で、PWMチャンネルを適用する出力ピンを選択します。そのあと、 ledcWrite(チャンネル, 値) で、分解能で設定したビットで表現できる最大値+1以下の値を指定することで、デューティー比を設定します。リスト 8 の場合、分解能で8bitを指定したので、0〜256 の値が、デューティー比 0〜1 のパルス生成に対応します。

リスト 8 src/pwm01.ino
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
int PIN = 10; // 内蔵LED
int PWM_CH = 1; // 0~3で指定する。0にすると高音が鳴って耳障り?

void setup() {
  pinMode(PIN, OUTPUT); // PINのモード設定
  ledcSetup(PWM_CH, 90, 8); // CH, 周波数(Hz) 【小さくするとどうなる?】, 分解能(bit)
  ledcAttachPin(PIN, PWM_CH);
  // https://lang-ship.com/reference/unofficial/M5StickC/Peripherals/LED_Control/
}

void loop() {
  int i;

  for (int i = 0 ; i < 256 ; i++) {
    ledcWrite(PWM_CH, i);
    delay( 5 );
  }
  for (int i = 256 ; i > 0 ; i--) {
    ledcWrite(PWM_CH, i);
    delay( 5 );
  }
}

注釈

ソースコードのコメントにも書いていますが、周波数を小さくする(20〜30程度)と、どうなるでしょうか?ぜひやってみてください。

サーボモータ(サーボハット利用)

リスト 9 は、サーボハット のサーボモータを動かすサンプルです。サーボモータの制御はPWMですので、基本的に、上のPWMとやっていることは同じです。おまけとして、LEDも点灯させました。map関数 は、Arduinoで使える関数で、範囲に対応する値を変換するときに使います。ここでは、サーボ制御で用いる5〜33の値を、LED制御の値0〜256に変換しています。

リスト 9 src/servohat01.ino
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#define MLOW 5
#define MHIGH 33

void setup() {
  ledcSetup(1, 50, 8); //サーボハット CH1
  ledcAttachPin(26, 1);

  pinMode(10, OUTPUT);
  ledcSetup(2, 100, 8);//LED CH2
  ledcAttachPin(10, 2);
}

void loop() {
  for (int i = MLOW; i <= MHIGH; i = i + 1) {
    ledcWrite(1, i);
    int v = map(i, MLOW, MHIGH, 0, 256); // 範囲5〜33に対するiの値を、範囲0〜256に変換
    ledcWrite(2, v);
    delay(50);
  }
  delay(300);
  for (int i = MHIGH; i >= MLOW; i = i - 1) {
    ledcWrite(1, i);
    int v = map(i, MLOW, MHIGH, 0, 256);
    ledcWrite(2, v);
    delay(20);
  }
  delay(300);
}

外部のセンサを接続 (ADC)

ADCは、Analog to Digital Converter の意味です。 analogRead(PIN) は、PIN番ピンの電圧(0~3.3V)を、0〜4095 の値で返します。一般に、抵抗値が変化するタイプのセンサは、この方法をつかって、読み取ることができます。

警告

ADC にかいてあるように、G26, G32, G33, G36のみ使えます。G26は、無線利用時には使えません。

リスト 10 はCdSセル(照度センサ) の値を読み取るサンプルです。

リスト 10 src/cds01.ino
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
int PIN = 26;

// +--- 15kΩ抵抗 --+-- CdSセル --+
// |              |             |
// GND           G26           3V3
// https://www.storange.jp/2012/03/arduinocds.html

// 注意点: https://lang-ship.com/reference/unofficial/M5StickC/Peripherals/ADC/

void setup() {
  pinMode(PIN, ANALOG); // PINのモード設定
  // https://lang-ship.com/blog/work/m5stickc-io/
}

void loop() {
  Serial.printf("%04d\n", analogRead(PIN) ); // 暗 0 〜 4095 明
  delay(1000);
}

圧力センサや、曲げセンサも、同様の方法で利用することができます。

加速度センサ

リスト 11 は、内蔵されている加速度センサ(MPU6886) の値を表示するサンプルです。ちなみに、IMUとは、Inertial Measurement Unit: 慣性計測装置 の略です。 「ツール」→「シリアルプロッタ」をひらくと、値をグラフでみることができます。 ジャイロセンサの値も取得可能です。

リスト 11 src/accgyro.ino
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 参考にしたサイト: https://qiita.com/kitazaki/items/1ce671532270cd44fabf

#include <M5StickCPlus.h>

float gyroX, gyroY, gyroZ;  // ジャイロデータ 
float ax, ay, az;  // 加速度データ

void setup() {
  M5.begin();
  M5.Lcd.setRotation(3);
  M5.IMU.Init();
  Serial.begin(115200);
  Serial.println("");
}
void loop() {
  M5.IMU.getGyroData(&gyroX, &gyroY, &gyroZ);
  M5.IMU.getAccelData(&ax, &ay, &az);
  M5.Lcd.setCursor(0, 10, 2);

  M5.Lcd.printf("aX :%7.2f  \naY :%7.2f  \naZ :%7.2f mg  \n\n", ax , ay , az );
  Serial.printf("%7.2f , %7.2f , %7.2f \n", ax , ay , az); //シリアルプロッタ用の出力

  M5.Lcd.printf("gX :%7.2f  \ngY :%7.2f  \ngZ :%7.2f mg  ", gyroX * M5.IMU.gRes, gyroY * M5.IMU.gRes, gyroZ * M5.IMU.gRes);
  // Serial.printf("%7.2f,%7.2f,%7.2f,", gyroX * M5.IMU.gRes, gyroY * M5.IMU.gRes, gyroZ * M5.IMU.gRes);

  delay(50);
}

赤外(InfraRed)リモコン

信号の読み取り

赤外線リモコン受信モジュールが必要です。ここでは、GP1UXC41QS を前提に、話をすすめます。

また、準備として、ライブラリマネージャにて、IRremoteESP8266 をインストールします。ちなみに、テストしたバージョンは2.7.15でした。

ファイルメニュー → スケッチ例 → IRremoteESP8266 → IRrecvDumpV2 を選択します。

ブレッドボードに、以下の図のように配線します。Pとかいてある面が、受光器が出っ張っている面です。47Ωの抵抗を、5Vとの間に入れます。 赤外線リモコン受信モジュールに接続したピンを const uint16_t kRecvPin = 36; として設定します。 受光器にリモコンを向けて、ボタンを押すと、シリアルモニタに情報が表示されます。ここでは、Protocol : NEC , Code 0x2FD48B7 (32 Bits) と表示されたとします。

_images/ir_sensor_47owm.png

信号の送信

内蔵の赤外LEDを用いて、信号を送信する例を リスト 12 に示します。 赤外光が弱いため、かなり近づかないと(50cm程度)反応しない場合があります。 外部の赤外LEDを用いると、距離を伸ばすことができます。

リスト 12 src/irsend01.ino
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <IRremoteESP8266.h>
#include <IRsend.h>

uint16_t kIrLed = 9; // 内蔵IrLED
IRsend irsend(kIrLed);

uint32_t code = 0x2FD48B7; // Toshiba TV Power
void setup() {
  irsend.begin();
}

void loop() {
  irsend.sendNEC( code , 32);
  delay(5000);
}

スプライト

画面のちらつき防止

Wifi 接続

NTPサーバ (Network Time Protocol) と時刻の取得

WebClient

WebServer

Bluetooth Low Energy

アドバータイズ

Bluetooth Serial Protocol Profile (SPP)

Preference

電力制御

その他

  • CO2 (CCS811)
  • RCS-620S (Felica)
  • JJYClock
  • RTC(BM8563)
  • OTA

参考リンク