M5Stackの方は放置でいいので他のソフトウェアを書く気分になったから初めてAndroidアプリを作ってみることにする。
それそのままの名前のリポジトリをここにおいておく。
ほしい人は持っていって。
https://github.com/ak1211/MyFirstApplication
動機
Androidアプリの作り方を学ぶのが目的だから, お題そのものがむつかしいモノは避けて以前に作ったことのある赤外線リモコン信号を記録して送信できるものを作ってみる。
自分のAndroidスマホには赤外線入出力機能がないので, 外部にハードウエアを用意してソフトとハードで互いに協調動作させるとしよう。
赤外線リモコン信号送受信用ハードウエア
「ダイキンエアコンのリモコン信号を解析する」と 「M5Stack Core2とVSCode + PlatformIOとでM5Stackプログラミングを始めてみた。」 との時に使った
また登場してもらう。
ブレッドボードを出してくるのが面倒だったので Seeeduino XIAO Groveシールド を使うことにする。
接続はこうした。

Android Studio + Kotlin
最近はKotlin推しがつよいので何もしなくてもインストールしてすぐにKotlinでアプリを作れる。
https://developer.android.com/kotlin
Kotlin で Android アプリを開発する
Kotlin では、より質の高い Android アプリをより速く記述できます。Kotlin は最新の静的型付けのプログラミング言語で、プロフェッショナルな Android デベロッパーの 60% 以上に使用されており、生産性、デベロッパーの満足度、コードの安全性の向上に貢献しています。
Androidアプリのお手本
最初はお手本をマネするのが定石なので Android Views and Widgets Samples Repository
リポジトリの中からそれっぽいのを探した結果,
Android RecyclerView Sample (Kotlin) をマネする。
スマホを開発者モードにして(連続してタップするやつ)
開発者向けオプションからワイヤレスデバッグをONにして
Android Studioのターミナルから
$ adb pair 192.168.1.21:45351
ペア設定コードを入力
$ adb connect 192.168.1.21:45351
こんな感じでワイヤレスデバッグする。
お手本が動いたから, さわりながら休憩。
AndroidでUSBシリアル通信
AndroidスマホからSeeeduino XIAOの間はお互いのUSB-C端子をUSBケーブルでつないでいる。
Android OSとusb-serial-for-androidライブラリの支援を受けて, USB接続の上でお互いに「メッセージ」を通す。
https://developer.android.com/guide/topics/connectivity/usb?hl=ja
USB ホストとアクセサリの概要
Android は、さまざまな USB 周辺機器と Android USB アクセサリ(Android アクセサリ プロトコルを実装したハードウェア)を、USB アクセサリと USB ホストの 2 つのモードでサポートしています。USB アクセサリ モードでは、外部 USB ハードウェアが USB ホストとして動作します。アクセサリの例としては、ロボット コントローラ、ドッキング ステーション、診断機器や楽器、キオスク、カードリーダーなどがあります。これにより、ホスト機能を持たない Android 搭載デバイスが USB ハードウェアと情報をやり取りできるようになります。Android USB アクセサリは、Android 搭載デバイスと連携するように設計されている必要があり、また Android アクセサリ通信プロトコルに準拠している必要があります。USB ホストモードでは、Android デバイスがホストとして動作します。デバイスの例としては、デジタルカメラ、キーボード、マウス、ゲーム コントローラなどがあります。幅広い用途や環境向けに設計された USB デバイスが、そうしたデバイスと正しく通信できる Android アプリと情報をやり取りすることが可能です。
図 1 は 2 つのモードの違いを示しています。Android 搭載デバイスをホストモードにすると、Android デバイスは USB ホストとして動作し、バスに電源を供給します。Android 搭載デバイスを USB アクセサリ モードにすると、接続された USB ハードウェア(この場合は Android USB アクセサリ)がホストとして動作し、バスに電源を供給します。
AndroidスマホからSeeeduino XIAOに電源を供給するんで 「ホストモード」になる。
https://developer.android.com/guide/topics/connectivity/usb/host?hl=ja
USB ホストの概要
Android 搭載デバイスを USB ホストモードにすると、Android 搭載デバイスは USB ホストとして動作し、バスに電源を供給して、接続されている USB デバイスを列挙します。USB ホストモードは Android 3.1 以降でサポートされています。
usb-serial-for-androidライブラリ
Android用USBシリアル通信ライブラリを使わせてもらう。
https://github.com/mik3y/usb-serial-for-android
READMEの指示通り
- device_filter.xml
- CustomProber.kt
にSeeeduino XIAO(vendor-id:
0x2886
, product-id:0x002f
)を追加する。
USBView
Vendor ID/Device ID が突然出て来たけど, WindowsにあるUSBViewというアプリケーションで得たもの。
https://docs.microsoft.com/ja-jp/windows-hardware/drivers/debugger/usbview
ユニバーサル シリアル バス ビューアー (USBView) または USBView.exe は、ご使用のコンピューター上のすべての USB コントローラーと接続されている USB デバイスを参照するために使用できる Windows グラフィカル UI アプリです。 USBView は、すべてのバージョンの Windows で動作します。
USBViewを使って (Circuit Pythonが動作している)Seeeduino XIAO を参照するとこんな情報を得られる。
[Port3] : USB Composite Device
Is Port User Connectable: yes
Is Port Debug Capable: no
Companion Port Number: 7
Companion Hub Symbolic Link Name: USB#ROOT_HUB30#5&1b0850fa&0&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}
Protocols Supported:
USB 1.1: yes
USB 2.0: yes
USB 3.0: no
Device Power State: PowerDeviceD0
---===>Device Information<===---
English product name: "Seeeduino XIAO"
ConnectionStatus:
Current Config Value: 0x01 -> Device Bus Speed: Full (is not SuperSpeed or higher capable)
Device Address: 0x05
Open Pipes: 9
===>Device Descriptor<===
bLength: 0x12
bDescriptorType: 0x01
bcdUSB: 0x0200
bDeviceClass: 0x00
*!*ERROR: device class should be Multi-interface Function 0xEF
When IAD descriptor is used
bDeviceSubClass: 0x00
*!*ERROR: device SubClass should be USB Common Sub Class 2
When IAD descriptor is used
bDeviceProtocol: 0x00
*!*ERROR: device Protocol should be USB IAD Protocol 1
When IAD descriptor is used
bMaxPacketSize0: 0x40 = (64) Bytes
idVendor: 0x2886 = Seeed Technology Co., Ltd.
idProduct: 0x002F
bcdDevice: 0x0100
iManufacturer: 0x02
English (United States) "Seeed"
iProduct: 0x03
English (United States) "Seeeduino XIAO"
iSerialNumber: 0x01
English (United States) "E502920D45B435050213E233A22280FF"
bNumConfigurations: 0x01
---===>Open Pipes<===---
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x81 -> Direction: IN - EndpointID: 1
bmAttributes: 0x03 -> Interrupt Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x10
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x84 -> Direction: IN - EndpointID: 4
bmAttributes: 0x03 -> Interrupt Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x08
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x04 -> Direction: OUT - EndpointID: 4
bmAttributes: 0x03 -> Interrupt Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x08
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x02 -> Direction: OUT - EndpointID: 2
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x82 -> Direction: IN - EndpointID: 2
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x83 -> Direction: IN - EndpointID: 3
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x03 -> Direction: OUT - EndpointID: 3
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x05 -> Direction: OUT - EndpointID: 5
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x85 -> Direction: IN - EndpointID: 5
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
---===>Full Configuration Descriptor<===---
===>Configuration Descriptor<===
bLength: 0x09
bDescriptorType: 0x02
wTotalLength: 0x00DA -> Validated
bNumInterfaces: 0x06
bConfigurationValue: 0x01
iConfiguration: 0x00
bmAttributes: 0x80 -> Bus Powered
MaxPower: 0x32 = 100 mA
===>IAD Descriptor<===
bLength: 0x08
bDescriptorType: 0x0B
bFirstInterface: 0x00
bInterfaceCount: 0x02
bFunctionClass: 0x02 -> This is Communications (CDC Control) USB Device Interface Class
bFunctionSubClass: 0x02
bFunctionProtocol: 0x00
iFunction: 0x00
===>Interface Descriptor<===
bLength: 0x09
bDescriptorType: 0x04
bInterfaceNumber: 0x00
bAlternateSetting: 0x00
bNumEndpoints: 0x01
bInterfaceClass: 0x02 -> This is Communications (CDC Control) USB Device Interface Class
bInterfaceSubClass: 0x02
bInterfaceProtocol: 0x00
iInterface: 0x04
English (United States) "CircuitPython CDC control"
-> This is a Communications (CDC Control) USB Device Interface Class
===>Descriptor Hex Dump<===
bLength: 0x05
bDescriptorType: 0x24
05 24 00 10 01
-> This is a Communications (CDC Control) USB Device Interface Class
===>Descriptor Hex Dump<===
bLength: 0x05
bDescriptorType: 0x24
05 24 01 01 01
-> This is a Communications (CDC Control) USB Device Interface Class
===>Descriptor Hex Dump<===
bLength: 0x04
bDescriptorType: 0x24
04 24 02 02
-> This is a Communications (CDC Control) USB Device Interface Class
===>Descriptor Hex Dump<===
bLength: 0x05
bDescriptorType: 0x24
05 24 06 00 01
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x81 -> Direction: IN - EndpointID: 1
bmAttributes: 0x03 -> Interrupt Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x10
===>Interface Descriptor<===
bLength: 0x09
bDescriptorType: 0x04
bInterfaceNumber: 0x01
bAlternateSetting: 0x00
bNumEndpoints: 0x02
bInterfaceClass: 0x0A -> This is a CDC Data USB Device Interface Class
bInterfaceSubClass: 0x00
bInterfaceProtocol: 0x00
iInterface: 0x05
English (United States) "CircuitPython CDC data"
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x02 -> Direction: OUT - EndpointID: 2
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x82 -> Direction: IN - EndpointID: 2
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Interface Descriptor<===
bLength: 0x09
bDescriptorType: 0x04
bInterfaceNumber: 0x02
bAlternateSetting: 0x00
bNumEndpoints: 0x02
bInterfaceClass: 0x08 -> This is a Mass Storage USB Device Interface Class
bInterfaceSubClass: 0x06
bInterfaceProtocol: 0x50
iInterface: 0x06
English (United States) "CircuitPython Mass Storage"
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x83 -> Direction: IN - EndpointID: 3
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x03 -> Direction: OUT - EndpointID: 3
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Interface Descriptor<===
bLength: 0x09
bDescriptorType: 0x04
bInterfaceNumber: 0x03
bAlternateSetting: 0x00
bNumEndpoints: 0x02
bInterfaceClass: 0x03 -> HID Interface Class
bInterfaceSubClass: 0x00
bInterfaceProtocol: 0x00
iInterface: 0x07
English (United States) "CircuitPython HID"
===>HID Descriptor<===
bLength: 0x09
bDescriptorType: 0x21
bcdHID: 0x0111
bCountryCode: 0x00
bNumDescriptors: 0x01
bDescriptorType: 0x22 (Report Descriptor)
wDescriptorLength: 0x00C3
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x84 -> Direction: IN - EndpointID: 4
bmAttributes: 0x03 -> Interrupt Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x08
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x04 -> Direction: OUT - EndpointID: 4
bmAttributes: 0x03 -> Interrupt Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x08
===>Interface Descriptor<===
bLength: 0x09
bDescriptorType: 0x04
bInterfaceNumber: 0x04
bAlternateSetting: 0x00
bNumEndpoints: 0x00
bInterfaceClass: 0x01 -> Audio Interface Class
bInterfaceSubClass: 0x01 -> Audio Control Interface SubClass
bInterfaceProtocol: 0x00
iInterface: 0x0B
English (United States) "CircuitPython Audio"
===>Audio Control Interface Header Descriptor<===
bLength: 0x09
bDescriptorType: 0x24 (CS_INTERFACE)
bDescriptorSubtype: 0x01 (HEADER)
bcdADC: 0x0100
wTotalLength: 0x0009
bInCollection: 0x01
baInterfaceNr[1]: 0x05
===>Interface Descriptor<===
bLength: 0x09
bDescriptorType: 0x04
bInterfaceNumber: 0x05
bAlternateSetting: 0x00
bNumEndpoints: 0x02
bInterfaceClass: 0x01 -> Audio Interface Class
bInterfaceSubClass: 0x03 -> MIDI Streaming Interface SubClass
bInterfaceProtocol: 0x00
iInterface: 0x0A
English (United States) "CircuitPython MIDI"
===>Descriptor Hex Dump<===
bLength: 0x07
bDescriptorType: 0x24
07 24 01 00 01 25 00
===>Descriptor Hex Dump<===
bLength: 0x06
bDescriptorType: 0x24
06 24 02 01 01 08
===>Descriptor Hex Dump<===
bLength: 0x06
bDescriptorType: 0x24
06 24 02 02 02 00
===>Descriptor Hex Dump<===
bLength: 0x09
bDescriptorType: 0x24
09 24 03 01 03 01 02 01 09
===>Descriptor Hex Dump<===
bLength: 0x09
bDescriptorType: 0x24
09 24 03 02 04 01 01 01 00
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x05 -> Direction: OUT - EndpointID: 5
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Descriptor Hex Dump<===
bLength: 0x05
bDescriptorType: 0x25
05 25 01 01 01
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x85 -> Direction: IN - EndpointID: 5
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Descriptor Hex Dump<===
bLength: 0x05
bDescriptorType: 0x25
05 25 01 01 03
これこれ
===>Device Descriptor<===
idVendor: 0x2886 = Seeed Technology Co., Ltd.
idProduct: 0x002F
Communications Device Class
ライブラリにまかせる領域でも一応確認しておく。
[Port3] : USB Composite Device
(Circuit Pythonが動作している) Seeeduino XIAOはOSからUSB複合デバイスとして見えている。そのうちのこれ。
This is a Communications (CDC Control) USB Device Interface Class
Communications Device Class (CDCクラス)インターフェースと接続する。
===>Interface Descriptor<===
bLength: 0x09
bDescriptorType: 0x04
bInterfaceNumber: 0x00
bAlternateSetting: 0x00
bNumEndpoints: 0x01
bInterfaceClass: 0x02 -> This is Communications (CDC Control) USB Device Interface Class
bInterfaceSubClass: 0x02
bInterfaceProtocol: 0x00
iInterface: 0x04
English (United States) "CircuitPython CDC control"
-> This is a Communications (CDC Control) USB Device Interface Class
===>Interface Descriptor<===
bLength: 0x09
bDescriptorType: 0x04
bInterfaceNumber: 0x01
bAlternateSetting: 0x00
bNumEndpoints: 0x02
bInterfaceClass: 0x0A -> This is a CDC Data USB Device Interface Class
bInterfaceSubClass: 0x00
bInterfaceProtocol: 0x00
iInterface: 0x05
English (United States) "CircuitPython CDC data"
確認のためusb.orgから資料をダウンロードしてきた。
bInterfaceClass: 0x02
で bInterfaceSubClass: 0x02
であるため
Communications Interface Class のサブクラスであるAbstract Control Modelサブクラスの存在を確認できる。
bInterfaceClass: 0x0A
であるので Data Interface Class の存在も確認できる。
このUSB接続は PSTN Device Model のサブクラスである ACMプロトコルを通じてアプリケーションからは(アナログ)モデムとして見えている。
つまり仮想COMポート。 モデムを接続してホストコンピュータに電話をかけて通信する端末みたいなもん。
以前にWindowsのRLoginと Seeeduino XIAO上のCurcuit Pythonとの間ですでに疎通確認をすましているので, あとはAndroidスマホ側を実装すれば通信できる。
リモコン信号解析器
赤外線リモコン信号の解析アプリケーション
で作った解析器をPureScriptからkotlinに持ってくる。
Maybe(Optional), Either, map, fold, foldMap, traverse … が必要なので ライブラリを探したらあったので使わしてもらいました。
なぜかREADME通りに入れられなかったので, こんなふうに1.0.0-SNAPSHOTを入れた。
https://github.com/ak1211/MyFirstApplication/blob/main/build.gradle
Kotlinで書く
もともとはこうで
https://github.com/ak1211/pi_hvac/blob/master/frontend/src/InfraredRemoteCode/Internal.purs
Kotlinではこんな風になった。
https://github.com/ak1211/MyFirstApplication/blob/main/infraredremote/src/main/java/com/example/infraredremote/InfraredRemote.kt
ついでにテストも付けておいた。
https://github.com/ak1211/MyFirstApplication/blob/main/infraredremote/src/test/java/DecodeTest.kt
赤外線リモコンコードは
なので, ありがたく頂戴した。弊社では皆さんが利用しやすいよう各社の赤外線リモコンコードをこのようなCSV形式で配布しております。
— ビット・トレード・ワンmade in 相模原 (@BitTradeOne) March 12, 2021
取得は以下のリンクよりどうぞ。https://t.co/ojDdm1dppg pic.twitter.com/zZyYXjMXWw
Curcuit Python プログラム
Androidアプリケーションの都合でちょっと改造してmain.pyをこうした。
# https://ak1211.com/7707 (main.py) | |
# Copyright 2021 Akihiro Yamamoto | |
# Licensed under the Apache License, Version 2.0 | |
from digitalio import DigitalInOut, Direction | |
import board | |
import pulseio | |
import supervisor | |
import sys | |
import time | |
import array | |
import gc | |
# 受け付けるリモコンパルス数の最低長 | |
ACCEPT_MIN_IR_PULSES = 40 | |
# IRM | |
irm_pulse = pulseio.PulseIn(board.D0, maxlen=2000, idle_state=True) | |
# PWM | |
# carrier: 38kHz | |
# duty cycle: 1/3 = 65536/3 = 21845 | |
pwm = pulseio.PWMOut(board.D1, duty_cycle=21845, frequency=38000, variable_frequency=False) | |
infrared_led_pulse = pulseio.PulseOut(pwm) | |
led = DigitalInOut(board.D13) | |
led.direction = Direction.OUTPUT | |
# LEDを消灯させる | |
led.value = 1 | |
def output_pulse_to_console(): | |
# LEDを点灯させる | |
led.value = 0 | |
# パルス読み込み一時停止 | |
irm_pulse.pause() | |
# | |
bytes = array.array('B') | |
bytes.append(ord('[')) | |
for index in range(len(irm_pulse)): | |
for ch in str(irm_pulse[index]): | |
bytes.append(ord(ch)) | |
bytes.append(ord(',')) | |
bytes[len(bytes)-1] = ord(']') | |
# 返答 | |
for ch in bytes: | |
sys.stdout.write(chr(ch)) | |
sys.stdout.write("\r\n") | |
# パルス読み込み再開 | |
irm_pulse.resume() | |
# LEDを消灯させる | |
led.value = 1 | |
def serial_input_loop(): | |
inputs = "" | |
for x in range(1*5000/1): | |
time.sleep(1/5000) | |
while supervisor.runtime.serial_bytes_available: | |
inputs += sys.stdin.read(1) | |
return inputs | |
while True: | |
if (len(irm_pulse) > ACCEPT_MIN_IR_PULSES): | |
output_pulse_to_console() | |
# 読み込んだパルスを消去する | |
irm_pulse.clear() | |
# ここで時間待ちのついでにシリアル入力をしておく | |
serial_inputs = serial_input_loop() | |
# 入力文字列を配列にする | |
start = serial_inputs.find('[') | |
end = serial_inputs.rfind(']') | |
if (end-start) > 1: | |
contents = serial_inputs[1+start:end] | |
to_output_pulses = array.array( 'H', [int(v.strip()) for v in contents.split(',')] ) | |
if len(to_output_pulses) > ACCEPT_MIN_IR_PULSES: | |
# LEDを点灯させる | |
led.value = 0 | |
# パルス読み込み一時停止 | |
irm_pulse.pause() | |
# 読み込んだパルスを消去する | |
irm_pulse.clear() | |
# 赤外線リモコン信号送出 | |
infrared_led_pulse.send(to_output_pulses) | |
# パルス読み込み再開 | |
irm_pulse.resume() | |
# 返答 | |
sys.stdout.write("ok") | |
sys.stdout.write("\r\n") | |
# LEDを消灯させる | |
led.value = 1 | |
del to_output_pulses | |
del contents | |
# | |
del end | |
del start | |
del serial_inputs | |
gc.collect() |
使ってみようAndroidアプリ
ここまでで Androidスマホ から USB-CDC ACMプロトコルで Seeeduino XIAO までつながった。


3144, 1654 (単位はマイクロ秒) これは 8T, 4T なので T=413.5μs (425μs typ.)
AEHAだとわかる。
何もしなくてもリモコン信号を受信してリストに追加するし, リストをタップすることで赤外線リモコン信号を送信する。
この動作は要約すると
Androidスマホ <—> Seeeeduino XIAO <—> エアコンとか
この3者で動いているマイクロコントローラとソフトウェアの間でメッセージを通している。
天井照明が反応しないのはパワー不足
天井の照明が赤外線リモコン信号に反応しない。
M5Stack用赤外線送受信ユニット は名前の通りM5Stack用なので。
https://docs.m5stack.com/en/unit/ir
5V
3V3 = 3.3V
5Vを100%とすると3.3Vは67%しかないわけで, 赤外線LEDの出力は物足りなくなる。
天井に近づけたら反応するけれども, このページ「文ばっかやな」とおもったからバランスをとるために部品を集めて回路を作りましょうか。
送受信回路
パワーが物足りないのでブレッドボードを出してきた。
「赤外線リモコン信号を記録して送信する学習リモコンをラズパイゼロでつくる。」でしたことと被っているけどまあええねん。
こんなん何度やってもいいですからね。
Seeeduino XAIOのMPUであるATSAMD21G18のデータシートより
各クラスタあたり46mA流せるのでI/Oポートから5mA位引っ張っても余裕かな。
赤外線LEDは同じもの(OSI5FU5111C-40)を4個つかってNPNトランジスタにはUTC製の2SC2655を使います。

これでいいか。

コメント