202duino で 自力シリアル出力 [Arduino]
202duinoは、CH340EをUPDIにもシリアル通信にも使えるように作りました。
202duino で シリアル通信:放課後マイコンクラブ:SSブログ
https://hello-world.blog.ss-blog.jp/2023-05-29
ただ、ハードウェアシリアルを使うと、ほとんどフラッシュメモリの空きがなくなる問題が出てきます。
そこで、
・送信だけ
・送信中に他の事はできない
・高速な通信はできない
という制限はあるもののレジスタを直接たたかずにArduinoの機能だけで自力でシリアル出力をしてみました。
micros()でタイミングをとるバージョンと、delayMicroseconds()でタイミングをとるバージョンを作りました。
以下の1秒毎に「Hello world!」を送信するスケッチで、どちらも余裕で1kBを切れました。
別バージョン ー delayMicroseconds()版
Rx(CH340E)とシリアル出力ピン(Tx)をワイヤーでつないでいます。
(スケッチ書き込み時は、ワイヤーを外します。)
ちなみにこれらを、UNO R4 minima と USBシリアル変換モジュールで試したらちょくちょく文字化けして使い物にはなりませんでした。
202duino で シリアル通信:放課後マイコンクラブ:SSブログ
https://hello-world.blog.ss-blog.jp/2023-05-29
ただ、ハードウェアシリアルを使うと、ほとんどフラッシュメモリの空きがなくなる問題が出てきます。
そこで、
・送信だけ
・送信中に他の事はできない
・高速な通信はできない
という制限はあるもののレジスタを直接たたかずにArduinoの機能だけで自力でシリアル出力をしてみました。
micros()でタイミングをとるバージョンと、delayMicroseconds()でタイミングをとるバージョンを作りました。
以下の1秒毎に「Hello world!」を送信するスケッチで、どちらも余裕で1kBを切れました。
// Arduino based serial output
#define TX 0 // TX pin
#define BAUD 9600 // baud rate
void setup() {
pinMode( TX , OUTPUT );
digitalWrite( TX, HIGH );
}
void loop() {
char text[] = "Hello world!\n";
for(uint8_t i = 0; text[i]; i++ ) inoTX( text[i] );
delay(1000);
}
void inoTX( uint8_t c ) { // *** OK up to 38400bps at 20MHz(ATtiny202) ***
uint32_t us = micros();
digitalWrite( TX, LOW ); // start bit
while( micros() - us < (1000000 / BAUD) );
us += (1000000 / BAUD);
for(uint8_t i = 0; i < 8; i++ ) { // data bits
digitalWrite( TX, ( c >> i ) & 1 );
while( micros() - us < (1000000 / BAUD) );
us += (1000000 / BAUD);
}
digitalWrite( TX, HIGH ); // stop bit
while( micros() - us < (1000000 / BAUD) );
}
別バージョン ー delayMicroseconds()版
void inoTx( uint8_t c ) { // *** OK up to 19200bps at 20MHz(ATtiny202) ***
digitalWrite( TX, LOW ); // start bit
delayMicroseconds( 1000000 / BAUD );
for(uint8_t i = 0; i < 8; i++ ) { // data bits
digitalWrite( TX, ( c >> i ) & 1 );
delayMicroseconds( 1000000 / BAUD );
}
digitalWrite( TX, HIGH ); // stop bit
delayMicroseconds( 1000000 / BAUD );
}
Rx(CH340E)とシリアル出力ピン(Tx)をワイヤーでつないでいます。
(スケッチ書き込み時は、ワイヤーを外します。)
ちなみにこれらを、UNO R4 minima と USBシリアル変換モジュールで試したらちょくちょく文字化けして使い物にはなりませんでした。
リモコンのデータ形式:Apple Remote [Arduino]
Apple Remote 再調査。
Apple Remote - Wikipedia
https://en.wikipedia.org/wiki/Apple_Remote
このページの説明と、取得データの解読がやっとできました。
wikipediaの解説は、32bitのデータを、16bitに区切って、下位の16bitを上位から説明し、続いて上位16bitを上位から説明しているのでわかりにくかったのでした。
つまり、32bitのデータを上から、、
(MSB)
Device ID (8bit) …………… ペアリングコマンドで変更可
Command (7bit) …………… コマンドページの実際のコマンド
Odd Parity (1bit) …………… 全32bitを足すと1になる
Vender (7bit) ………………… 0x43fで固定
Command Page (5bit) ……ペアリング等は 0x0、通常のボタンは 0xe
(LSB)
■Apple Remote(初代)A1156
[MENU]
⏯
⏭
⏮
+
ー
NEC : 32bit 0x610387EE / 0b 01100001 - 0000001 - 1 - 10000111111 - 01110
NEC : 32bit 0x610587EE / 0b 01100001 - 0000010 - 1 - 10000111111 - 01110
NEC : 32bit 0x610687EE / 0b 01100001 - 0000011 - 0 - 10000111111 - 01110
NEC : 32bit 0x610987EE / 0b 01100001 - 0000100 - 1 - 10000111111 - 01110
NEC : 32bit 0x610A87EE / 0b 01100001 - 0000101 - 0 - 10000111111 - 01110
NEC : 32bit 0x610C87EE / 0b 01100001 - 0000110 - 0 - 10000111111 - 01110
DeviceID Command OP Vender(0x43f) CmdPage
旧リモコンの解除 (MENU + |<< を同時に6秒間以上)
NEC : 32bit 0x610487E0 / 0b 01100001 - 0000010 - 0 - 10000111111 - 00000
新リモコンの登録 (MENU + >>| を同時に6秒間以上)
NEC : 32bit 0x610287E0 / 0b 01100001 - 0000001 - 0 - 10000111111 - 00000
■Apple Remote(第2世代)
[MENU]
⏯
〇 (中央ボタン)
˃
⌃
˂
⌃
NEC : 32bit 0x3D0387EE / 0b 00111101 - 0000001 - 1 - 10000111111 - 01110
NEC : 32bit 0x3D0587EE / 0b 00111101 - 0000010 - 1 - 10000111111 - 01110
NEC : 32bit 0x3D0587EE / 0b 00111101 - 0000010 - 1 - 10000111111 - 01110
NEC : 32bit 0x3D0687EE / 0b 00111101 - 0000011 - 0 - 10000111111 - 01110
NEC : 32bit 0x3D0A87EE / 0b 00111101 - 0000101 - 0 - 10000111111 - 01110
NEC : 32bit 0x3D0987EE / 0b 00111101 - 0000100 - 1 - 10000111111 - 01110
NEC : 32bit 0x3D0C87EE / 0b 00111101 - 0000110 - 0 - 10000111111 - 01110
また別の話だけど、、
プロトコル(protocol) = フォーマット(format) + プロシージャ(procedure) ってことらしい。
たとえば、Apple Remote は、、
「The Apple Remote uses a modified NEC IR protocol which consists of a differential PPM encoding on a 1:3 duty cycle 38 kHz 950 nm infrared carrier. There are 32 bits of encoded data between the AGC leader and the stop bit:」
「While the Apple Remote uses the NEC IR protocol for the timing, the 32-bit data package is in a different format. It consists of two 16 bit LSB words.」
とあり、赤外線の送り方はNEC方式だが、32bitのデータ形式はアップル独自のデータ(フォーマット)ということらしい。
Apple Remote - Wikipedia
https://en.wikipedia.org/wiki/Apple_Remote
このページの説明と、取得データの解読がやっとできました。
wikipediaの解説は、32bitのデータを、16bitに区切って、下位の16bitを上位から説明し、続いて上位16bitを上位から説明しているのでわかりにくかったのでした。
つまり、32bitのデータを上から、、
(MSB)
Device ID (8bit) …………… ペアリングコマンドで変更可
Command (7bit) …………… コマンドページの実際のコマンド
Odd Parity (1bit) …………… 全32bitを足すと1になる
Vender (7bit) ………………… 0x43fで固定
Command Page (5bit) ……ペアリング等は 0x0、通常のボタンは 0xe
(LSB)
■Apple Remote(初代)A1156
[MENU]
⏯
⏭
⏮
+
ー
NEC : 32bit 0x610387EE / 0b 01100001 - 0000001 - 1 - 10000111111 - 01110
NEC : 32bit 0x610587EE / 0b 01100001 - 0000010 - 1 - 10000111111 - 01110
NEC : 32bit 0x610687EE / 0b 01100001 - 0000011 - 0 - 10000111111 - 01110
NEC : 32bit 0x610987EE / 0b 01100001 - 0000100 - 1 - 10000111111 - 01110
NEC : 32bit 0x610A87EE / 0b 01100001 - 0000101 - 0 - 10000111111 - 01110
NEC : 32bit 0x610C87EE / 0b 01100001 - 0000110 - 0 - 10000111111 - 01110
DeviceID Command OP Vender(0x43f) CmdPage
旧リモコンの解除 (MENU + |<< を同時に6秒間以上)
NEC : 32bit 0x610487E0 / 0b 01100001 - 0000010 - 0 - 10000111111 - 00000
新リモコンの登録 (MENU + >>| を同時に6秒間以上)
NEC : 32bit 0x610287E0 / 0b 01100001 - 0000001 - 0 - 10000111111 - 00000
■Apple Remote(第2世代)
[MENU]
⏯
〇 (中央ボタン)
˃
⌃
˂
⌃
NEC : 32bit 0x3D0387EE / 0b 00111101 - 0000001 - 1 - 10000111111 - 01110
NEC : 32bit 0x3D0587EE / 0b 00111101 - 0000010 - 1 - 10000111111 - 01110
NEC : 32bit 0x3D0587EE / 0b 00111101 - 0000010 - 1 - 10000111111 - 01110
NEC : 32bit 0x3D0687EE / 0b 00111101 - 0000011 - 0 - 10000111111 - 01110
NEC : 32bit 0x3D0A87EE / 0b 00111101 - 0000101 - 0 - 10000111111 - 01110
NEC : 32bit 0x3D0987EE / 0b 00111101 - 0000100 - 1 - 10000111111 - 01110
NEC : 32bit 0x3D0C87EE / 0b 00111101 - 0000110 - 0 - 10000111111 - 01110
また別の話だけど、、
プロトコル(protocol) = フォーマット(format) + プロシージャ(procedure) ってことらしい。
たとえば、Apple Remote は、、
「The Apple Remote uses a modified NEC IR protocol which consists of a differential PPM encoding on a 1:3 duty cycle 38 kHz 950 nm infrared carrier. There are 32 bits of encoded data between the AGC leader and the stop bit:」
「While the Apple Remote uses the NEC IR protocol for the timing, the 32-bit data package is in a different format. It consists of two 16 bit LSB words.」
とあり、赤外線の送り方はNEC方式だが、32bitのデータ形式はアップル独自のデータ(フォーマット)ということらしい。
リモコンのデータ形式:KOIZUMI照明 [Arduino]
KOIZUMI照明リモコンのデータ形式をのぞいてみた。
NEC形式でした。
■KOIZUMI照明リモコン KRH-TA-8A
消灯
オフタイマー30min
タイマー解除
順送り(全灯→調光→保安灯→消灯→)
▲ 調光 (repeat codeあり)
▼ 調光 (repeat codeあり)
調光(調光状態(記憶値)で点灯)
保安灯(保安灯の点灯と明るさ調節(5段階調光))
ch.I
NEC : 32bit 0xFF006E80 / 0b 11111111 00000000 01101110 10000000
NEC : 32bit 0xFE016E80 / 0b 11111110 00000001 01101110 10000000
NEC : 32bit 0xFC036E80 / 0b 11111100 00000011 01101110 10000000
NEC : 32bit 0xFB046E80 / 0b 11111011 00000100 01101110 10000000
NEC : 32bit 0xFA056E80 / 0b 11111010 00000101 01101110 10000000 (repeat codeあり)
NEC : 32bit 0xF9066E80 / 0b 11111001 00000110 01101110 10000000 (repeat codeあり)
NEC : 32bit 0xED126E80 / 0b 11101101 00010010 01101110 10000000
NEC : 32bit 0xEC136E80 / 0b 11101100 00010011 01101110 10000000
ch.II
NEC : 32bit 0x7F806E80 / 0b 01111111 10000000 01101110 10000000
NEC : 32bit 0x7E816E80 / 0b 01111110 10000001 01101110 10000000
NEC : 32bit 0x7C836E80 / 0b 01111100 10000011 01101110 10000000
NEC : 32bit 0x7B846E80 / 0b 01111011 10000100 01101110 10000000
NEC : 32bit 0x7A856E80 / 0b 01111010 10000101 01101110 10000000 (repeat codeあり)
NEC : 32bit 0x79866E80 / 0b 01111001 10000110 01101110 10000000 (repeat codeあり)
NEC : 32bit 0x6D926E80 / 0b 01101101 10010010 01101110 10000000
NEC : 32bit 0x6C936E80 / 0b 01101100 10010011 01101110 10000000
ch.III
NEC : 32bit 0x857A6E80 / 0b 10000101 01111010 01101110 10000000
NEC : 32bit 0x8D726E80 / 0b 10001101 01110010 01101110 10000000
NEC : 32bit 0x8C736E80 / 0b 10001100 01110011 01101110 10000000
NEC : 32bit 0x86796E80 / 0b 10000110 01111001 01101110 10000000
NEC : 32bit 0x956A6E80 / 0b 10010101 01101010 01101110 10000000 (repeat codeあり)
NEC : 32bit 0x946B6E80 / 0b 10010100 01101011 01101110 10000000 (repeat codeあり)
NEC : 32bit 0x87786E80 / 0b 10000111 01111000 01101110 10000000
NEC : 32bit 0x847B6E80 / 0b 10000100 01111011 01101110 10000000
最初の(下から)16ビットは 6E80で、KOIZUMIのカスタマーコードと思われる。
次の8ビットが実質のデータで、最後の8ビットはエラーチェック用。
ch.Iとch.IIについては、データ部の0~4ビット目が明かりのデータで、7ビット目がチャンネルのようだけど、ch.IIIではその規則性が消失。
もともとch.Iとch.IIしかなかったところに、ch.IIIを無理くり追加したのかな?
■KOIZUMI照明ファンリモコン KRH-TE-10IF
風向き ▲
風向き ▼
強
中
弱
微
照明(順送り)
ファンON/OFF
オフタイマー 30分
オフタイマー 60分
CH I
NEC : 32bit 0xCC336E80 0b 11001100 00110011 01101110 10000000
NEC : 32bit 0xCB346E80 0b 11001011 00110100 01101110 10000000
NEC : 32bit 0xCA356E80 0b 11001010 00110101 01101110 10000000
NEC : 32bit 0xC9366E80 0b 11001001 00110110 01101110 10000000
NEC : 32bit 0xC8376E80 0b 11001000 00110111 01101110 10000000
NEC : 32bit 0xC7386E80 0b 11000111 00111000 01101110 10000000
NEC : 32bit 0xC6396E80 0b 11000110 00111001 01101110 10000000
NEC : 32bit 0xC53A6E80 0b 11000101 00111010 01101110 10000000
NEC : 32bit 0xC43B6E80 0b 11000100 00111011 01101110 10000000
NEC : 32bit 0xC33C6E80 0b 11000011 00111100 01101110 10000000
CH II
NEC : 32bit 0x4CB36E80 0b 01001100 10110011 01101110 10000000
NEC : 32bit 0x4BB46E80 0b 01001011 10110100 01101110 10000000
NEC : 32bit 0x4AB56E80 0b 01001010 10110101 01101110 10000000
NEC : 32bit 0x49B66E80 0b 01001001 10110110 01101110 10000000
NEC : 32bit 0x48B76E80 0b 01001000 10110111 01101110 10000000
NEC : 32bit 0x47B86E80 0b 01000111 10111000 01101110 10000000
NEC : 32bit 0x46B96E80 0b 01000110 10111001 01101110 10000000
NEC : 32bit 0x45BA6E80 0b 01000101 10111010 01101110 10000000
NEC : 32bit 0x44BB6E80 0b 01000100 10111011 01101110 10000000
NEC : 32bit 0x43BC6E80 0b 01000011 10111100 01101110 10000000
8ビットの実質のデータ部分で、0~5ビット目が操作データで、7ビット目がチャンネルのよう。
NEC形式でした。
■KOIZUMI照明リモコン KRH-TA-8A
消灯
オフタイマー30min
タイマー解除
順送り(全灯→調光→保安灯→消灯→)
▲ 調光 (repeat codeあり)
▼ 調光 (repeat codeあり)
調光(調光状態(記憶値)で点灯)
保安灯(保安灯の点灯と明るさ調節(5段階調光))
ch.I
NEC : 32bit 0xFF006E80 / 0b 11111111 00000000 01101110 10000000
NEC : 32bit 0xFE016E80 / 0b 11111110 00000001 01101110 10000000
NEC : 32bit 0xFC036E80 / 0b 11111100 00000011 01101110 10000000
NEC : 32bit 0xFB046E80 / 0b 11111011 00000100 01101110 10000000
NEC : 32bit 0xFA056E80 / 0b 11111010 00000101 01101110 10000000 (repeat codeあり)
NEC : 32bit 0xF9066E80 / 0b 11111001 00000110 01101110 10000000 (repeat codeあり)
NEC : 32bit 0xED126E80 / 0b 11101101 00010010 01101110 10000000
NEC : 32bit 0xEC136E80 / 0b 11101100 00010011 01101110 10000000
ch.II
NEC : 32bit 0x7F806E80 / 0b 01111111 10000000 01101110 10000000
NEC : 32bit 0x7E816E80 / 0b 01111110 10000001 01101110 10000000
NEC : 32bit 0x7C836E80 / 0b 01111100 10000011 01101110 10000000
NEC : 32bit 0x7B846E80 / 0b 01111011 10000100 01101110 10000000
NEC : 32bit 0x7A856E80 / 0b 01111010 10000101 01101110 10000000 (repeat codeあり)
NEC : 32bit 0x79866E80 / 0b 01111001 10000110 01101110 10000000 (repeat codeあり)
NEC : 32bit 0x6D926E80 / 0b 01101101 10010010 01101110 10000000
NEC : 32bit 0x6C936E80 / 0b 01101100 10010011 01101110 10000000
ch.III
NEC : 32bit 0x857A6E80 / 0b 10000101 01111010 01101110 10000000
NEC : 32bit 0x8D726E80 / 0b 10001101 01110010 01101110 10000000
NEC : 32bit 0x8C736E80 / 0b 10001100 01110011 01101110 10000000
NEC : 32bit 0x86796E80 / 0b 10000110 01111001 01101110 10000000
NEC : 32bit 0x956A6E80 / 0b 10010101 01101010 01101110 10000000 (repeat codeあり)
NEC : 32bit 0x946B6E80 / 0b 10010100 01101011 01101110 10000000 (repeat codeあり)
NEC : 32bit 0x87786E80 / 0b 10000111 01111000 01101110 10000000
NEC : 32bit 0x847B6E80 / 0b 10000100 01111011 01101110 10000000
最初の(下から)16ビットは 6E80で、KOIZUMIのカスタマーコードと思われる。
次の8ビットが実質のデータで、最後の8ビットはエラーチェック用。
ch.Iとch.IIについては、データ部の0~4ビット目が明かりのデータで、7ビット目がチャンネルのようだけど、ch.IIIではその規則性が消失。
もともとch.Iとch.IIしかなかったところに、ch.IIIを無理くり追加したのかな?
■KOIZUMI照明ファンリモコン KRH-TE-10IF
風向き ▲
風向き ▼
強
中
弱
微
照明(順送り)
ファンON/OFF
オフタイマー 30分
オフタイマー 60分
CH I
NEC : 32bit 0xCC336E80 0b 11001100 00110011 01101110 10000000
NEC : 32bit 0xCB346E80 0b 11001011 00110100 01101110 10000000
NEC : 32bit 0xCA356E80 0b 11001010 00110101 01101110 10000000
NEC : 32bit 0xC9366E80 0b 11001001 00110110 01101110 10000000
NEC : 32bit 0xC8376E80 0b 11001000 00110111 01101110 10000000
NEC : 32bit 0xC7386E80 0b 11000111 00111000 01101110 10000000
NEC : 32bit 0xC6396E80 0b 11000110 00111001 01101110 10000000
NEC : 32bit 0xC53A6E80 0b 11000101 00111010 01101110 10000000
NEC : 32bit 0xC43B6E80 0b 11000100 00111011 01101110 10000000
NEC : 32bit 0xC33C6E80 0b 11000011 00111100 01101110 10000000
CH II
NEC : 32bit 0x4CB36E80 0b 01001100 10110011 01101110 10000000
NEC : 32bit 0x4BB46E80 0b 01001011 10110100 01101110 10000000
NEC : 32bit 0x4AB56E80 0b 01001010 10110101 01101110 10000000
NEC : 32bit 0x49B66E80 0b 01001001 10110110 01101110 10000000
NEC : 32bit 0x48B76E80 0b 01001000 10110111 01101110 10000000
NEC : 32bit 0x47B86E80 0b 01000111 10111000 01101110 10000000
NEC : 32bit 0x46B96E80 0b 01000110 10111001 01101110 10000000
NEC : 32bit 0x45BA6E80 0b 01000101 10111010 01101110 10000000
NEC : 32bit 0x44BB6E80 0b 01000100 10111011 01101110 10000000
NEC : 32bit 0x43BC6E80 0b 01000011 10111100 01101110 10000000
8ビットの実質のデータ部分で、0~5ビット目が操作データで、7ビット目がチャンネルのよう。
タグ:リモコン
赤外線リモコンの受信を簡単なスケッチで。 [Arduino]
以前に赤外線リモコンの送信データを分析するスケッチを作りました。
赤外線リモコン (解析の友):放課後マイコンクラブ:SSブログ
https://hello-world.blog.ss-blog.jp/2011-05-19
ただ日本ではNEC形式、AEHA (家電製品協会)形式、SIRC(SONY)形式の3つを押さえれば、たいていなんとかなるのではないかと思い、解析ではなく、受信&デコードだけのスケッチを作りました。
コンパクトなスケッチですが、シリアルでデータを送信するので、容量的にATtiny202には載せられず、ATtiny402/412ならOKなサイズになりました。
NEC形式、SIRC(SONY)形式は32ビット整数として受け取り、AEHA (家電製品協会)形式は、データ配列とその長さを受け取ることにしました。
うちの霧ヶ峰のリモコン(AEHA形式)は、以前調べた規定の最大ビット数より大きいものでした。
あと、最近のSONYのリモコンは電源ボタン以外はBluetooth?(テレビ側は純粋な赤外線リモコンも対応)
Uno R4は32ビットだからなのか、16ビット以上の左シフト演算の際に「1UL」とせずに、「1」としちゃっても正常動作した。ATtiny412で動作確認したときに「1」の16ビット以上の左シフトが動作不良で発覚。
あと前回同様に、赤外線リモコン受信モジュールは、Arduino直刺しするためにI/Oピンを電源がわりに使っています。赤外線リモコン受信モジュールの消費電流はわずかなので大丈夫だと思う。ノイズ対策はごめん。
赤外線リモコン (解析の友):放課後マイコンクラブ:SSブログ
https://hello-world.blog.ss-blog.jp/2011-05-19
ただ日本ではNEC形式、AEHA (家電製品協会)形式、SIRC(SONY)形式の3つを押さえれば、たいていなんとかなるのではないかと思い、解析ではなく、受信&デコードだけのスケッチを作りました。
コンパクトなスケッチですが、シリアルでデータを送信するので、容量的にATtiny202には載せられず、ATtiny402/412ならOKなサイズになりました。
NEC形式、SIRC(SONY)形式は32ビット整数として受け取り、AEHA (家電製品協会)形式は、データ配列とその長さを受け取ることにしました。
うちの霧ヶ峰のリモコン(AEHA形式)は、以前調べた規定の最大ビット数より大きいものでした。
あと、最近のSONYのリモコンは電源ボタン以外はBluetooth?(テレビ側は純粋な赤外線リモコンも対応)
Uno R4は32ビットだからなのか、16ビット以上の左シフト演算の際に「1UL」とせずに、「1」としちゃっても正常動作した。ATtiny412で動作確認したときに「1」の16ビット以上の左シフトが動作不良で発覚。
あと前回同様に、赤外線リモコン受信モジュールは、Arduino直刺しするためにI/Oピンを電源がわりに使っています。赤外線リモコン受信モジュールの消費電流はわずかなので大丈夫だと思う。ノイズ対策はごめん。
// IR Receive and Decode
#define IR_IN 2 // IR Receiver pin
void setup() {
pinMode( IR_IN , INPUT ); // input Vout(active low, negative logic)
pinMode( 3 , OUTPUT ); digitalWrite( 3, LOW ); // LOW (*use as GND)
pinMode( 4 , OUTPUT ); digitalWrite( 4, HIGH ); // HIGH (*use as Vcc)
Serial.begin(115200);
}
void loop() {
uint32_t irData = 0;
uint8_t irProtocol = 0, irBit = 0, irArray[20] = {0};
// ****** Receive and Decode IR signals ******
uint16_t us = pulseIn( IR_IN, LOW , 65535 ); // Judge the protocol by the length of the leader section (usec.)
if ( us > 2000 && us < 3000 ) { // *** SIRC ***
irProtocol = 'S'; // T=600us, ON/OFF : leader= 4T/1T, 0=1T/1T, 1=2T/1T
for(;(us = pulseIn( IR_IN, LOW , 3000 )); irBit++)
if( us > 1000 && us < 1500 ) irData |= (1UL << irBit);
}else if( us > 3500 && us < 5000 ) { // *** AEHA ***
irProtocol = 'A'; // T=425us, ON/OFF : leader= 8T/4T, 0=1T/1T, 1=1T/3T, stop=1T
while( digitalRead( IR_IN ) );
for(;(us = pulseIn( IR_IN, HIGH, 4000 )); irBit++)
if( us > 1050 && us < 1500 ) irArray[ irBit / 8 ] |= (1 << (irBit % 8) );
}else if( us > 7200 && us < 11000 ) { // *** NEC ***
irProtocol = 'N'; // T=560us, ON/OFF : leader=16T/8T, 0=1T/1T, 1=1T/3T, stop=1T
while( digitalRead( IR_IN ) );
for(;(us = pulseIn( IR_IN, HIGH, 3000 )); irBit++)
if( us > 1350 && us < 2000 ) irData |= (1UL << irBit);
}else return;
// ****** Display results by protocol ******
Serial.print( irProtocol == 'S' ? "SIRC: " : irProtocol == 'A' ? "AEHA: " : "NEC : " );
if( !irBit ) {
Serial.println( " (repeat code) " );
return;
}
Serial.print( irBit );
Serial.print( "bit" );
if( irProtocol == 'A' ) {
for( uint8_t i = 0; i < ( (irBit + 7) / 8 ); i++ ) {
Serial.print((irArray[i] < 0x10) ? " 0x0" : " 0x" );
Serial.print( irArray[i], HEX );
}
} else {
Serial.print( " 0x" );
Serial.print( irData, HEX );
}
Serial.println("");
}
タグ:リモコン
Arduino UNO R4でリモコン [Arduino]
低機能マイコンでできたことを高機能のUNO R4でやっても面白味はないのですが、実験ということで。
202duino でPWMを使ってリモコン送信
https://hello-world.blog.ss-blog.jp/2023-06-01
ATtiny202では、レジスタをいじって40kHz PWMを作りましたが、UNO R4ではレジスタの設定不要で、pwm.hを使ってスケッチを作成しました。
お行儀がわるいですがLEDは直刺し。
UNO R4 Minima Arduino Documentation
https://docs.arduino.cc/hardware/uno-r4-minima
ここに、「Maximum current draw per pin: the UNO R4 series' maximum current draw per GPIO is 8 mA, which is significantly lower than previous versions. Exceeding this limit may damage your pin / board.」とありました。(UNO R3 は 20mA)。パルスだしいいかな?と(何が?)
ちなみに tone() でも試してみましたが、動作しませんでした。
LEDは光るものの、信号としては受け取ってもらえませんでした。
202duino でPWMを使ってリモコン送信
https://hello-world.blog.ss-blog.jp/2023-06-01
ATtiny202では、レジスタをいじって40kHz PWMを作りましたが、UNO R4ではレジスタの設定不要で、pwm.hを使ってスケッチを作成しました。
// Infrared remote control with 40kHz PWM (SIRC version)
#include <pwm.h>
static PwmOut ir( 12 ); // IR LED pin
void setup() {
}
void loop() {
sendIrSIRCpwm( 46 | 1UL << 7 ); // SONY TV ON (cmd:46(7bit), adrs:1(5bit))
sendIrSIRCpwm( 46 | 1UL << 7 ); // repeat 3 times
sendIrSIRCpwm( 46 | 1UL << 7 );
delay( 5000 );
sendIrSIRCpwm( 47 | 1UL << 7 ); // SONY TV OFF (cmd:47(7bit), adrs:1(5bit))
sendIrSIRCpwm( 47 | 1UL << 7 ); // repeat 3 times
sendIrSIRCpwm( 47 | 1UL << 7 );
delay( 5000 );
}
void sendIrSIRCpwm( uint32_t d ) { // T = 0.60msec
uint8_t b = (d & 0xF8000) ? 20 :
(d & 0x07000) ? 15 : 12; // number of bits
uint16_t usON, usTrailer = 420; // 70T = interval(75T) - leader(5T)
ir.begin( 25, 8); delayMicroseconds( 2400 ); // leader ON (4T) 40kHz = every 25usec
ir.suspend(); delayMicroseconds( 600 ); // leader OFF (1T)
for(uint8_t i = 0; i < b; i++) { // data(command + address)
usON = ((d>>i)&1) ? 1200 : 600; // data(0:1T / 1:2T)
ir.resume(); delayMicroseconds( usON ); // data ON
ir.suspend(); delayMicroseconds( 600 ); // data OFF (1T)
usTrailer -= (usON + 600); // trailer
}
ir.end();
delayMicroseconds( usTrailer );
}
お行儀がわるいですがLEDは直刺し。
UNO R4 Minima Arduino Documentation
https://docs.arduino.cc/hardware/uno-r4-minima
ここに、「Maximum current draw per pin: the UNO R4 series' maximum current draw per GPIO is 8 mA, which is significantly lower than previous versions. Exceeding this limit may damage your pin / board.」とありました。(UNO R3 は 20mA)。パルスだしいいかな?と(何が?)
ちなみに tone() でも試してみましたが、動作しませんでした。
LEDは光るものの、信号としては受け取ってもらえませんでした。
Arduino UNO R4でLチカ、、タイマーで。 [Arduino]
Arduino UNO R4でタイマーを使ったLチカをやってみた。
まだよくわかっていないものの、とりあえず動いたという感じです。
以下のスケッチが正しいかは怪しい。
ちょっと調べてみると、、
・AVRのようにレジスタを直接いじるのはちょっと難しそう
・FspTimerというのを使うといいっぽい
・FSPとは Flexible Software Package のことらしい
・2種類のタイマー GPT (General PWM Timer)、AGT(Asynchronous General Purpose Timer)がある
・AGTタイマーは2つだけで、1つ(channel 0)は millis()、microseconds()に使用済
・get_available_timer で使用可能なタイマーのタイプとチャンネルを取得(GPTから先に探している)
FspTimerについて詳しく調べられた方のページ:
Arduino UNO R4のFspTimerライブラリの使い方 - Qiita
https://qiita.com/yasuhiro-k/items/93efb640aa12f3db9086
これをもとに作ってみた。
2.0Hz(=500msec毎)でLEDのON/OFFを切り替えます。
周波数の指定はfloat型だけど1Hz未満では動作しなかった。
タイマーはGPTから先に空きを調べていくのでGPTを使用していると思われる。
つづいてもう一つ。
AGTをライブラリに仕上げられた方のページ:
GitHub - washiyamagiken/AGTimer_R4_Library
https://github.com/washiyamagiken/AGTimer_R4_Library
これをもとにライブラリをLチカ専用に展開。AGTのチャンネル1を使用。
TIMER_SOURCE_DIV_64 のとき、period countsが 32768 だと1Hz、16384だと2Hz (500msec毎)。
<FSPタイマー関連プログラムの在処>
%localAppdata%\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino\FspTimer.h
%localAppdata%\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino\FspTimer.cpp
まだよくわかっていないものの、とりあえず動いたという感じです。
以下のスケッチが正しいかは怪しい。
ちょっと調べてみると、、
・AVRのようにレジスタを直接いじるのはちょっと難しそう
・FspTimerというのを使うといいっぽい
・FSPとは Flexible Software Package のことらしい
・2種類のタイマー GPT (General PWM Timer)、AGT(Asynchronous General Purpose Timer)がある
・AGTタイマーは2つだけで、1つ(channel 0)は millis()、microseconds()に使用済
・get_available_timer で使用可能なタイマーのタイプとチャンネルを取得(GPTから先に探している)
FspTimerについて詳しく調べられた方のページ:
Arduino UNO R4のFspTimerライブラリの使い方 - Qiita
https://qiita.com/yasuhiro-k/items/93efb640aa12f3db9086
これをもとに作ってみた。
2.0Hz(=500msec毎)でLEDのON/OFFを切り替えます。
周波数の指定はfloat型だけど1Hz未満では動作しなかった。
タイマーはGPTから先に空きを調べていくのでGPTを使用していると思われる。
#include <FspTimer.h>
static FspTimer fsp_timer;
void blinkLED(timer_callback_args_t __attribute((unused)) *p_args) {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
uint8_t timer_type;
int8_t timer_ch = FspTimer::get_available_timer(timer_type);
if (timer_ch < 0) return;
fsp_timer.begin( TIMER_MODE_PERIODIC, timer_type, timer_ch, 2.0f, 0.0f, blinkLED, nullptr );
fsp_timer.setup_overflow_irq();
fsp_timer.open();
fsp_timer.start();
}
void loop() {
}
つづいてもう一つ。
AGTをライブラリに仕上げられた方のページ:
GitHub - washiyamagiken/AGTimer_R4_Library
https://github.com/washiyamagiken/AGTimer_R4_Library
これをもとにライブラリをLチカ専用に展開。AGTのチャンネル1を使用。
TIMER_SOURCE_DIV_64 のとき、period countsが 32768 だと1Hz、16384だと2Hz (500msec毎)。
#include <FspTimer.h>
static FspTimer fsp_timer;
void blinkLED(timer_callback_args_t __attribute((unused)) *p_args) {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
fsp_timer.begin( TIMER_MODE_PERIODIC, AGT_TIMER, 1, 16384, 0, TIMER_SOURCE_DIV_64, blinkLED, nullptr );
IRQManager::getInstance().addPeripheral( IRQ_AGT, (void*)fsp_timer.get_cfg() );
fsp_timer.open();
fsp_timer.start();
}
void loop() {
}
<FSPタイマー関連プログラムの在処>
%localAppdata%\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino\FspTimer.h
%localAppdata%\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino\FspTimer.cpp
Arduino UNO R4でLチカ、、tone()で。 [Arduino]
もっと簡単にLチカできる方法!
tone関数を使えば実質1行だけ。
tone() - Arduino Reference
https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/
・「It is not possible to generate tones lower than 31Hz.」とあったが、UNO R4では1Hzもいけた。
・周波数は整数型(unsigned int)なので1Hzよりゆっくりにはできない。
・duty比を指定できない。
Blink LED with tone function.
<tone()関係プログラムの在処>
%LocalAppData%\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino\Tone.cpp
tone関数を使えば実質1行だけ。
tone() - Arduino Reference
https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/
・「It is not possible to generate tones lower than 31Hz.」とあったが、UNO R4では1Hzもいけた。
・周波数は整数型(unsigned int)なので1Hzよりゆっくりにはできない。
・duty比を指定できない。
Blink LED with tone function.
void setup() {
tone(LED_BUILTIN, 1); // 1Hz : toggle ON and OFF every 500ms
}
void loop() {
}
<tone()関係プログラムの在処>
%LocalAppData%\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino\Tone.cpp
Arduino UNO R4でLチカ、、PWMで。 [Arduino]
Arduino UNO R4やっと届きました。
LEDマトリックスとかWi-Fiとか(自分の能力的にも気力的にも)使いこなせそうにないのでMinimaです。
特別やりたいことはないので、とりあえずLチカ。
Arduino IDE 2.1.1をインストールしたものの、Arduino 1.8.19でも「ボードマネージャ」から「UNO R4」で検索すると、「Arduino UNO R4 Boards」というのが出てくるので、インストール。
しばらく、Arduino 1.8.19 で行けそう。
やってみたのがこれ。500msecごとにON/OFFを繰り返す、1HzのLチカです。
UNO R4は、PWMをいじれるようなので、それでLチカできました。
参考:
Under the Hood Arduino UNO R4 - PWM - Phil Schatzmann
https://www.pschatzmann.ch/home/2023/07/01/under-the-hood-arduino-uno-r4-pwm/
別件ですが、上記の方のサイトでエレガントなLチカのスケッチを見つけた。
How to Blink in Arduino - Alternative Designs - Phil Schatzmann
https://www.pschatzmann.ch/home/2020/09/10/arduino-blinking-sketch/
<PWM関係プログラムの在処>
%LocalAppData%\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino\pwm.h
%LocalAppData%\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino\pwm.cpp
LEDマトリックスとかWi-Fiとか(自分の能力的にも気力的にも)使いこなせそうにないのでMinimaです。
特別やりたいことはないので、とりあえずLチカ。
Arduino IDE 2.1.1をインストールしたものの、Arduino 1.8.19でも「ボードマネージャ」から「UNO R4」で検索すると、「Arduino UNO R4 Boards」というのが出てくるので、インストール。
しばらく、Arduino 1.8.19 で行けそう。
やってみたのがこれ。500msecごとにON/OFFを繰り返す、1HzのLチカです。
UNO R4は、PWMをいじれるようなので、それでLチカできました。
#include <pwm.h>
static PwmOut pwm(LED_BUILTIN);
void setup() {
pwm.begin( 1000000, 500000); // period 1000000us(1Hz), pulse 500000us
}
void loop() {
}
または、
#include <pwm.h>
static PwmOut pwm(LED_BUILTIN);
void setup() {
pwm.begin( 46875, 23437, true, TIMER_SOURCE_DIV_1024 ); // 48MHz/1024clk=46875(1Hz)
}
void loop() {
}
参考:
Under the Hood Arduino UNO R4 - PWM - Phil Schatzmann
https://www.pschatzmann.ch/home/2023/07/01/under-the-hood-arduino-uno-r4-pwm/
別件ですが、上記の方のサイトでエレガントなLチカのスケッチを見つけた。
How to Blink in Arduino - Alternative Designs - Phil Schatzmann
https://www.pschatzmann.ch/home/2020/09/10/arduino-blinking-sketch/
<PWM関係プログラムの在処>
%LocalAppData%\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino\pwm.h
%LocalAppData%\Arduino15\packages\arduino\hardware\renesas_uno\1.0.2\cores\arduino\pwm.cpp
Arduino UNO R4 Minima [ABX00080] - Renesas RA4M1 - USB-C、CAN、DAC(12ビット)、OP AMP、SWDコネクタ
- 出版社/メーカー: Arduino
- メディア:
Arduino IDE 2.0.0 アンインストールできない事件 [Arduino]
いまさらだけど、Arduino Uno R4 Minima をぽちってみた。
Uno R4 じゃないと出来ない事がしたいわけでもない。
いままでのArduinoに困っているわけでもない。
ただ何となくマイコンがルネサス製で同じ日本というよしみで購入。
megaTinyCoreが「IDE 2.0.x unsupported」ということで以前に入れた IDE 2.0.0はほとんど使っていなかった。
Arduino Uno R4 Minima を購入にあたり、まだ届かないけど、とりあえずIDEを新しくしようとして問題がおこる。
でも先人がすでに解決済であった。
問題:Arduino IDE 2.0.0がアンインストールできない。
Arduino IDEを起動していないのに、「Arduino IDEが終了できません。」と出る。
解決法:
Arduino IDE 2.0.0 のインストールされているフォルダーに行く
デスクトップやメニューにある「Arduino IDE」ショートカットを右クリックして「ファイルの場所を開く」
あるいは 「%localappdata%\Programs\Arduino IDE」を直接開く。
「Arduino IDE.exe」を「Arduino IDE2.exe」などに変更する。
アンインストール完了!
あとは、IDE 2.1.1をダウンロードして、インストール。
(ブログに載せるにあたり、ちょっと寄付)
Uno R4 じゃないと出来ない事がしたいわけでもない。
いままでのArduinoに困っているわけでもない。
ただ何となくマイコンがルネサス製で同じ日本というよしみで購入。
megaTinyCoreが「IDE 2.0.x unsupported」ということで以前に入れた IDE 2.0.0はほとんど使っていなかった。
Arduino Uno R4 Minima を購入にあたり、まだ届かないけど、とりあえずIDEを新しくしようとして問題がおこる。
でも先人がすでに解決済であった。
問題:Arduino IDE 2.0.0がアンインストールできない。
Arduino IDEを起動していないのに、「Arduino IDEが終了できません。」と出る。
解決法:
Arduino IDE 2.0.0 のインストールされているフォルダーに行く
デスクトップやメニューにある「Arduino IDE」ショートカットを右クリックして「ファイルの場所を開く」
あるいは 「%localappdata%\Programs\Arduino IDE」を直接開く。
「Arduino IDE.exe」を「Arduino IDE2.exe」などに変更する。
アンインストール完了!
あとは、IDE 2.1.1をダウンロードして、インストール。
(ブログに載せるにあたり、ちょっと寄付)
202duino で NeoPixel [Arduino]
いまさらですが、NeoPixelというのがはやっているらしくて、、。
megaTinyCoreを入れたときにスケッチ例が入っていて、かっこいいのがいくつかありました。
とりあえず必要なところを確認して自分でもLEDを光らせてみました。
スケッチは以下のとおり。
ライブラリを使用せずに自前できるかどうか探ってみましたが、、、
・100ナノ秒オーダーでの操作が必要
・ライブラリを見てみるとアセンブラ使用
・ライブラリ自体は意外と簡素
・SPIでやる方法もあるらしい
というわけで素直にライブラリを使うのが賢明のよう。
ライブラリの実体の在処
%localappdata%\Arduino15\packages\megaTinyCore\hardware\megaavr\2.6.4\libraries\tinyNeoPixel
%localappdata%\Arduino15\packages\megaTinyCore\hardware\megaavr\2.6.4\libraries\tinyNeoPixel_Static
データ形式(旧と新バージョンあるらしい)
megaTinyCoreを入れたときにスケッチ例が入っていて、かっこいいのがいくつかありました。
とりあえず必要なところを確認して自分でもLEDを光らせてみました。
スケッチは以下のとおり。
#include <tinyNeoPixel_Static.h>
#define PIN 3
#define NUMPIXELS 12
uint8_t pixels[NUMPIXELS * 3];
tinyNeoPixel leds = tinyNeoPixel(NUMPIXELS, PIN, NEO_GRB, pixels);
void setup() {
pinMode(PIN, OUTPUT);
}
void loop() {
for (uint8_t i = 0; i < NUMPIXELS; i++) {
for (uint8_t c = 0; c < 6; c++) {
leds.setPixelColor( ( NUMPIXELS + i - c ) % NUMPIXELS, leds.Color(0, 0 , 31 >> c ) );
//pixels[ ((NUMPIXELS + i - c) * 3 + 2) % (NUMPIXELS * 3) ] = 31 >> c; // -118 bytes
}
leds.show();
delay(100);
}
}
ライブラリを使用せずに自前できるかどうか探ってみましたが、、、
・100ナノ秒オーダーでの操作が必要
・ライブラリを見てみるとアセンブラ使用
・ライブラリ自体は意外と簡素
・SPIでやる方法もあるらしい
というわけで素直にライブラリを使うのが賢明のよう。
ライブラリの実体の在処
%localappdata%\Arduino15\packages\megaTinyCore\hardware\megaavr\2.6.4\libraries\tinyNeoPixel
%localappdata%\Arduino15\packages\megaTinyCore\hardware\megaavr\2.6.4\libraries\tinyNeoPixel_Static
データ形式(旧と新バージョンあるらしい)