ひとしれずひっそり

主にソフトに関することをメモしていきます。過程をそのまま書いていたりするので間違いが含まれます。鵜呑みしない様に。

M5AtomS3 の IR (2)

前回IRの受信でソニーテレビの信号を確認したので、送信してみる。

IRGCSendDemoで簡単にできることが分かったので、

github.com

M5AtomS3ではG4がIRに繋がっていて、例の通りで動作できる。

必要な箇所のみにしたらこんなに簡単になった。
NECの場合をコメントにしている。

#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <M5Unified.h>

const uint16_t kIrLed = 4;

IRsend irsend(kIrLed);

void setup() {
  M5.begin();
  USBSerial.begin(115200);
  irsend.begin();
}

void loop() {
  M5.update();
  if (M5.BtnA.wasClicked()) {
    USBSerial.println("Power off");
    irsend.sendSony(0xa90, 12, 3);  // 12 bits & 3 repeats
    //irsend.sendNEC(0x00FFE01FUL);
    delay(2000);
  }
}

sendSony()で与えている0xa90は電源コードで、このコードを変えることで他のボタンに適用できる。
ビット数は12でいい様だが、ファンクショナルなキーは増える様だ。

ビット数はこちらが参考になると思う。

ukigumo1104.blog.ss-blog.jp

これでちゃんとM5AtomS3からTVの電源ON/OFFができた。
でも届く距離は1mくらいまでかな。

今回はここまで。

M5AtomS3でソニーテレビの赤外線リモコン信号を送信 · GitHub

追記:

クリックで送信コードを選択して長押しで送信する様にした。

M5AtomS3でソニーテレビの赤外線リモコン信号を送信 · GitHub

3軸トゥールビヨンの置き時計【3Dプリント用STLデータ】購入した(8)

10:50まで進んだ。

電池を繋いで動作確認する箇所があったが、動かない。
前回動かない気がしたが、ゼンマイ部が機能すると動くんじゃないかという期待はしていたが、全然ダメだった。

バラして確認して行ったらピンの長さや押し込みが足りずギヤ同士が干渉しいたりだった。
特に5番、6番の辺りがまずかった。

調整して回る様になった。

M5AtomS3 の IR (1)

M5AtomS3にIRが付いている。
M5StickCにも付いていたが、試したことがなかった。

この記事を頼りに進める。

lang-ship.com

送信するにもコードがわからないことには始まらない。
手元にセンサーキットがあったのでそれを利用する。

osoyoo.com

使ったことがないのでピン割がまず分からない。
シルク印刷から大体予想はつくがヘタをすると故障してしまうので、ちゃんと確認しないと。
センサーはVS1838Bを使っていて

datasheets-pdf.com

基板のパターンと照らし合わせるとこのようになる。
M5AtomS3の繋ぐ場所も記載した。

基盤シルク - S
信号名 GND VCC OUT
M5AtomS3 GND 3V3 G5

Lang-shipにあった様にIRremoteESP8266ライブラリーを使用し、IRrecvDumpV2を元にする。

github.com

いつもの様にPlatformioを使用。
platformio.iniは前回のM5AtomS3の例そのままでこの様にした。

[env:ATOMS3]
platform = espressif32@5.2.0
framework = arduino
platform_packages = platformio/framework-arduinoespressif32@^3.20005.220925
board = esp32-s3-devkitc-1
lib_ldf_mode = deep
monitor_speed = 115200
upload_speed = 1500000
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.flash_mode = dio
build_flags = 
    -DCORE_DEBUG_LEVEL=3
    -Iinclude
lib_deps = 
    crankyoldgit/IRremoteESP8266@^2.8.4

使用する IO を 5 番にする。

const uint16_t kRecvPin = 5;

これでコンパイルができて書き込みができた。
実行してみるとM5Stamp S3の時と同じくシリアル出力がない。

でも大丈夫、M5AtomS3の例に答えがあった。
Serialの代わりにUSBSerialを使用する。

こんな感じで出力される。

IRrecvDump is now running and waiting for IR input on Pin 5
Timestamp : 000007.008
Library   : v2.8.4

Protocol  : SONY
Code      : 0xA90 (12 Bits)
uint16_t rawData[103] = {2438, 552,  1246, 552,  620, 554,  1246, 552,  620, 554,  1246, 554,  622, 554,  620, 552,  1246, 552,  622, 554,  620, 554,  622, 554,  620, 25776,  2446, 552,  1246, 554,  620, 554,  1246, 554,  620, 554,  1244, 554,  620, 554,  620, 554,  1246, 554,  620, 554,  620, 554,  620, 554,  620, 25792,  2446, 554,  1246, 554,  620, 554,  1246, 554,  622, 552,  1246, 552,  620, 554,  620, 554,  1246, 554,  620, 554,  620, 552,  622, 554,  620, 25786,  2446, 552,  1246, 554,  620, 554,  1246, 552,  620, 554,  1246, 554,  620, 554,  622, 552,  1246, 552,  620, 554,  620, 554,  618, 554,  620};  // SONY A90
uint32_t address = 0x1;
uint32_t command = 0x15;
uint64_t data = 0xA90;

下の3行が重要で、その上はパルスの長さを数値にしたものと思われる。

Sony TV Braviaの場合

key address command data
Power 0x1 0x15 0xA90
画面表示 0x1 0x3A 0x5D0
入力切換 0x1 0x25 0xA50
0x97 0x24 0x12E9
0x97 0x25 0x52E9
0x97 0x26 0x32E9
0x97 0x27 0x72E9
番組表 0xA4 0x5B 0x6D25
d 0x97 0x15 0x54E9
戻る 0x97 0x23 0x62E9
オプション 0x97 0x36 0x36E9
デジタル 0x97 0x32 0x26E9
BS 0x97 0x2C 0x1AE9
1 0x01 0x00 0x10
2 0x01 0x01 0x810
3 0x01 0x02 0x410
4 0x01 0x03 0xC10
5 0x01 0x04 0x210
6 0x01 0x05 0xA10
7 0x01 0x06 0x610
8 0x01 0x07 0xE10
9 0x01 0x08 0x110
10 0x01 0x09 0x910
11 0x01 0x0a 0x510
12 0x01 0x0b 0xD10
音量+ 0x01 0x12 0x490
音量- 0x01 0x13 0xC90
チャンネル+ 0x01 0x10 0x90
チャンネル- 0x01 0x11 0x890
消音 0x01 0x14 0x290

とここまで受信ができる様になった。

せっかく画面があるので結果を表示する様にした。

M5AtomS3でIR受信データを確認。IRremoteESP8266のサンプルIRrecvDumpV2を変更していく · GitHub

MQTT

IoTでよくMQTTが使われているがまだ試したことがない。

こちらを参考にMosquittoを試してみる。

developer.mamezou-tech.com

Macなのでインストールはbrewを使う。

% brew install mosquitto
% brew install mosquitto-clients

mosquittoはブローカーと呼ばれるサービスを立ち上げるもので、メッセージの振り分けをする感じ。
mosquitto-clientsはクライアント側でパブリッシャーという送信側とサブスクライバーという受信の役割をさせるのに使う。

mosquittoコマンドでブローカーが立ち上がる。

% mosquitto
1677944452: mosquitto version 2.0.15 starting
1677944452: Using default config.
1677944452: Starting in local only mode. Connections will only be possible from clients running on this machine.
1677944452: Create a configuration file which defines a listener to allow remote access.
1677944452: For more details see https://mosquitto.org/documentation/authentication-methods/
1677944452: Opening ipv4 listen socket on port 1883.
1677944452: Opening ipv6 listen socket on port 1883.
1677944452: mosquitto version 2.0.15 running
1677944452: New connection from ::1:65092 on port 1883.
1677944452: New client connected from ::1:65092 as auto-97553E03-8A44-9B57-C886-C97D7FB2CFB5 (p2, c1, k60).

mosquitto_subでサブスクライブする。
パブリッシャーで送信すると表示されることになる。

% mosquitto_sub -h localhost -t topic

パブリッシャーから送信。

% mosquitto_pub -h localhost -t topic -m "Hello, there"

サブスクライバーの方にHello, thereが表示された。

% mosquitto_sub -h localhost -t topic     
Hello, there

Rubyから

Rubyでも試してみる。
mqtt gemを使用するとクライアント側の動作ができる。

github.com

Quick startに従って、

require 'mqtt'

# Publish example
MQTT::Client.connect('localhost') do |c|
  c.publish('topic', 'Hello, there from ruby')
end

サブスクライバーに表示された。

% mosquitto_sub -h localhost -t topic     
Hello, there
Hello, there from ruby

今度はサブスクライバーの方。

require 'mqtt'

MQTT::Client.connect('localhost') do |c|
  # If you pass a block to the get method, then it will loop
  c.get('topic') do |topic,message|
    puts "#{topic}: #{message}"
  end
end

前のmosquitto_pubコマンド叩いたら表示された。

% ruby mqtt_sub.rb 
topic: Hello, there

同じ端末でパブリッシャーとサブスクライブすると双方向通信ができるし、ブロードキャストするのに向いてる。


M5Stack関連のソースではブローカーとして mqtt.m5stack.com が使われている。
上で localhost としていた所を mqtt.m5stack.com に置き換えて動作することを確認した。
topicは誰かと被らない様にuuidを使った。

mqtt.m5stack.com は自由に使っていいのかな? どうなんだろう。

M5AtomS3が届いた

最初に入っているのはこれかな?

github.com

platformioで試せそう。
環境のダウンロードに時間がかかかったがコンパイルできた。

最初から入っているのとは違った。

前回M5StampS3で色々試したので、platformio.iniファイルは参考になる。

https://github.com/m5stack/M5AtomS3/blob/main/examples/Basics/FactoryTest/platformio.ini#L11

Protocolにoptionalなmethodを含めれる?

Objective-Cではoptionalなmethodを含めることができた。
Swiftではどうか?

検索すると @objc と optional を付けるとできる様だけど、StructureやEnumに適用できなくなるということらしい。

Swift流にするならoptionalの代わりにextensionでデフォルトの実装を定義すればいいということだった。

www.hackingwithswift.com