tag:blogger.com,1999:blog-28803843402582512662024-03-23T13:42:10.805+09:00ハードウェアとか研究所とある大阪の研究所ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comBlogger39125tag:blogger.com,1999:blog-2880384340258251266.post-35750436450411914062024-03-23T13:41:00.000+09:002024-03-23T13:41:17.774+09:00PCと接続するオリジナルコントローラのインタフェース提案(Raspberry Pi Picoの仮想キーボードとしての使用)<h2 style="text-align: left;">はじめに</h2><p>当研究所はMakerとしていろいろオリジナルデバイスを作成していますが、最近ではオリジナルのコントローラを使用したゲームの開発に注力を行っています。このようなゲームを作成するには、コントローラデバイスとゲームが動いているPCで通信を行う必要があります。しかし、これが地味に面倒くさく、またこのようなシステムを作成しようとしている初心者に対して高いハードルとなっているかと思います。</p><p>本記事では、この通信部分をRaspberry Pi Picoを使用することで容易にする提案をしています(実際に動くサンプルあり)。</p><h2 style="text-align: left;">概要</h2><p>オリジナルコントローラを使用したゲームを作成する場合、多くの場合以下のような構成になるかと思います。</p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkJlewkVlt6t3Vc0r1OVEVA-ZFNAnXhz0bkPYzp6xvOHAVz9z0Ppg8AsZYFF-WB8Bct5qvOK4FWld1_5tc59kuzY-9GFQRVWj1F5zUuV9_Mc9E0w3JGaQFXAP53ECeZA9QneL8VJZYFKCBb8Cj-zwxf952eA0umX-0DxI9oIurXtNOS8xDGDntZrBRfNo/s671/image_0.drawio.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="212" data-original-width="671" height="101" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkJlewkVlt6t3Vc0r1OVEVA-ZFNAnXhz0bkPYzp6xvOHAVz9z0Ppg8AsZYFF-WB8Bct5qvOK4FWld1_5tc59kuzY-9GFQRVWj1F5zUuV9_Mc9E0w3JGaQFXAP53ECeZA9QneL8VJZYFKCBb8Cj-zwxf952eA0umX-0DxI9oIurXtNOS8xDGDntZrBRfNo/s320/image_0.drawio.png" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">既存構成</td></tr></tbody></table><p></p><ul style="text-align: left;"><li>ゲームはPCで動作させる<br />Unityなどで作成したゲームを想定しています</li><li>コントローラデバイス側で入力された情報はシリアル通信でPCに送信する<br />物理的にはUSBケーブルで接続します</li><li>PC側ではシリアル通信で情報を受信してゲームの操作を行う</li></ul><p></p><h2 style="text-align: left;">課題</h2><p>通信にシリアル通信を使用するということが面倒の元凶となっています。面倒くさい部分を以下に記載します。</p><p></p><ul style="text-align: left;"><li>コントローラデバイス側でシリアル⇔USB変換が必要となる<br />デバイス側の構成にもよりますが、たいてい必要です</li><li>PC側のゲームのインタフェースにシリアル通信の受信機能を実装しなければならない<br />COMポートを開くなどの処理の実装が必要です</li></ul><p></p><p>そもそもシリアル通信はかなり低レベル(単純)な通信方法なので、PCでは逆に扱いにくいのです(その代わり応用が効く)。どうせUSBで接続するならUSBの通信方法でデータ通信ができればいいのに…。ということでRaspberry Pi Picoの登場となります。</p><h2 style="text-align: left;">Raspberry Pi Pico</h2><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmha0NjAziX2FWSCGA8AUtNtWKIGQjSlzRWPBANIzU21cPgEmU_-LVVYNbahCFV6pvzr3cnL5M5yBVkz8AZ3r2UmVyB9Re3DabfM8rQO7-H_9Ur81zjllEmTZclAIunxYCohLR1anUtetQwcFYkh5PU9M06G6_xIF6foGRfSrx2UFG9Tiq0X8_snzsZ80/s7591/four_picos.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="3610" data-original-width="7591" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmha0NjAziX2FWSCGA8AUtNtWKIGQjSlzRWPBANIzU21cPgEmU_-LVVYNbahCFV6pvzr3cnL5M5yBVkz8AZ3r2UmVyB9Re3DabfM8rQO7-H_9Ur81zjllEmTZclAIunxYCohLR1anUtetQwcFYkh5PU9M06G6_xIF6foGRfSrx2UFG9Tiq0X8_snzsZ80/s320/four_picos.jpg" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Picoシリーズ(RaspberryPi公式HPより引用)</td></tr></tbody></table><p>最近、Raspberry Pi Picoを使用しているのですが、かなり便利です。個人的に便利な点を以下に記載します。</p><p></p><ul style="text-align: left;"><li>1,000円弱で低価格</li><li>C++で開発可能<br />Pythonでも可能だが現時点では一部機能制限がある模様</li><li>開発環境はPC1台で完結<br />ライタ等不要でWindowsでも開発可能</li><li>ADCが搭載<br />もちろんI2CやSPIといった基本的なペリフェラルも搭載</li><li>USBによるシリアル通信が標準搭載<br />デバッグがしやすい</li><li>USBデバイスとしての動作が可能<br />オープンソースのTinyUSBに対応している</li></ul><p></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEje5DkSzZrD4VbwOqRWxxDsdVBg818fWaSONl25y61BbOQtpoIEOECz-Fy3sKrSOKwxkaZ-atgTaGFBKhK9stOvxWoDjkRhVpw5LdAtk_u-HXEhcizYgQlFgSvmjDQq-d_YCrTtUoP-jmz5EG8Qsux3ihpEF_-AnQq0y1cqkewEYHMiOnHBEGqHwFL5QkQ/s842/pico-pinout.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="595" data-original-width="842" height="226" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEje5DkSzZrD4VbwOqRWxxDsdVBg818fWaSONl25y61BbOQtpoIEOECz-Fy3sKrSOKwxkaZ-atgTaGFBKhK9stOvxWoDjkRhVpw5LdAtk_u-HXEhcizYgQlFgSvmjDQq-d_YCrTtUoP-jmz5EG8Qsux3ihpEF_-AnQq0y1cqkewEYHMiOnHBEGqHwFL5QkQ/s320/pico-pinout.png" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">IOピン一覧(RaspberryPi公式HPより引用)</td></tr></tbody></table><p>個人的にはADCが搭載されたことで、Raspberry Piシリーズの欠点を完全にカバーできている感じがしています。もうマイコンいらないですね…、安いし…。</p><h2 style="text-align: left;">提案</h2><p>さて話を戻して、ここで提案するのは以下のような内容です。</p><p></p><ul style="text-align: left;"><li>コントローラデバイスのインタフェースをRaspberry Pi Picoにする</li><li>Raspberry Pi Picoを仮想キーボードとして動かし、PCへの情報送信をキーボード入力にしてしまう</li></ul><p></p><p>提案する構成例を以下に示します。</p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkc6U2Zxnvn7YiWlcRP1s37pgNgOwsbYTIbogQLxblwh4BWeMACbc3STaVn37qQa6xkLTnDpkN3OzlDH2_gwXfR1PiHPn2ezNnaJ7gllLPaeA4HDM-8JP0o9FootIcH8olKfcw4PWtnk19E8XaD11TU708-gqtGI91nO3KLkvwqDWFuge5UsyQiwPyYtk/s671/image_1.drawio.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="121" data-original-width="671" height="58" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkc6U2Zxnvn7YiWlcRP1s37pgNgOwsbYTIbogQLxblwh4BWeMACbc3STaVn37qQa6xkLTnDpkN3OzlDH2_gwXfR1PiHPn2ezNnaJ7gllLPaeA4HDM-8JP0o9FootIcH8olKfcw4PWtnk19E8XaD11TU708-gqtGI91nO3KLkvwqDWFuge5UsyQiwPyYtk/s320/image_1.drawio.png" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">提案構成</td></tr></tbody></table><p>上記の構成ではコントローラデバイスからPC側のゲームへ情報を送信するとキーボードからの入力となります。このときゲーム側では標準のキーボード入力ライブラリが使用できるため、シリアル通信用のインタフェース実装が不要となります。</p><p>ただし、これはコントローラデバイス→PCへの単方向のみの送信となりますので、ゲームの操作結果をコントローラデバイスへフィードバックするような必要がある場合には向いていません。この条件が許容できるのであれば実装がかなり容易になるはずです。</p><h2 style="text-align: left;">動作例</h2><p>具体的にはどういうことなの?ということで動作例を用意しました。ブレッドボードでRaspberry Pi Picoと2つのボタンを接続した例なのですが、下の回路図と等価の構成になっています。</p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjToWUZZN9sIePqiQuzgK2V0MNQ89_vYdYN3CcSi_yDYuXohnqBUpqieacmdPS-gAsYGSHTnyKV5dMPZzBqwzoxf1Jl5yr9uDKG4cjSK2slERf268Kb3m9nJ3a7LLHzIrBzhS2KgiH_3F1wVYkB2cbXA2mrX-QBklSv0UyqOeyBGOtrkyMIhVKzpBhu0N4/s640/IMG_20240313_014849246.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="480" data-original-width="640" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjToWUZZN9sIePqiQuzgK2V0MNQ89_vYdYN3CcSi_yDYuXohnqBUpqieacmdPS-gAsYGSHTnyKV5dMPZzBqwzoxf1Jl5yr9uDKG4cjSK2slERf268Kb3m9nJ3a7LLHzIrBzhS2KgiH_3F1wVYkB2cbXA2mrX-QBklSv0UyqOeyBGOtrkyMIhVKzpBhu0N4/s320/IMG_20240313_014849246.jpg" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">ブレッドボード実装</td></tr></tbody></table><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpWwEZ4wQnrzvc5O_-23lQPvu0plGev0L1l-1A9lcBLTT-tflOL4jyOcU7F22RgUbL79QjJfwYqZ81wF2-7tg3EXnL-h5NHoLvBfjBLTV2h5GzKsGbNGKV_xLWL_aH4auio6FdKGJ3tVpRuD6tkiETVteHS3MzbgO95ikEhs7CH-5mtCxnZ5I4JW1vSEw/s352/curcit.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="267" data-original-width="352" height="243" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpWwEZ4wQnrzvc5O_-23lQPvu0plGev0L1l-1A9lcBLTT-tflOL4jyOcU7F22RgUbL79QjJfwYqZ81wF2-7tg3EXnL-h5NHoLvBfjBLTV2h5GzKsGbNGKV_xLWL_aH4auio6FdKGJ3tVpRuD6tkiETVteHS3MzbgO95ikEhs7CH-5mtCxnZ5I4JW1vSEw/s320/curcit.png" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">等価回路</td></tr></tbody></table><p>この回路をPCと接続し、(中央付近の赤い)左のボタンを押すとPC側には"a"が入力されます(キーボードの"a"キーを押したときと同じ動作)。同じく右のボタンを押すと"B"が入力されます。なんとなくわかると思いますが、このボタン入力の部分を好きなメカニズムに変更することでPCにUSBキーボードとして認識されるオリジナルコントローラが作成できます。</p><h2 style="text-align: left;">ソースコード</h2><p>上記の動作例で使用しているRaspberry Pi Picoのサンプルを<a href="https://github.com/HASOLabo/Pico_USB_Keyboard_Sample">ここ</a>に置いておきます。ビルド方法などはリンク先のREADMEを参照してください。雛形的なプログラムになっているので、各自で改良することで割と容易に使用できるかと思います。ちなみにRaspberry Pi PicoのUSBサンプルプログラムを改変しているだけのものです。</p><h2 style="text-align: left;">サンプル解説</h2><p>このサンプルを雛形に開発を行う場合、修正するのは"main.c"のみでOKです(その他のコードはそのままでOK)。また、"main.c"のすべてを把握する必要はなく、修正する必要のある箇所は主に以下の2点です。</p><p></p><ul style="text-align: left;"><li>main関数<br />文字通りのメイン関数で、プログラムはここから開始されます。ここではPCと通信を行うUSBの無限ループ処理が開始されます。そのため、GPIOなどの設定はこのループに入る前に行っておきます。</li><li>hid_task関数<br />この関数の中ではPC側に送信するキーの情報を設定しています。このサンプルではGPIOの状態をリードして送信するキーコードを設定しています。</li></ul><p></p><p>具体的な処理内容はコード内にコメントを埋めていますので参考にしてください。以下に変更対象の範囲のコードを掲載しておきます。</p><h3 style="text-align: left;">main関数</h3>
<pre class="prettyprint lang-cpp linenums" style="overflow-wrap: normal; overflow: auto; word-wrap: normal;">/*------------- MAIN -------------*/
int main(void)
{
board_init();
tusb_init();
// **********************************************
// GPIOの設定
// - ピンの初期化
// - 入力/出力の設定
// - プルアップ設定
// ※ADCなどの機能を使用する場合もここで設定する
// **********************************************
gpio_init(kGPIOpin0);
gpio_set_dir(kGPIOpin0, GPIO_IN);
gpio_pull_up(kGPIOpin0);
gpio_init(kGPIOpin1);
gpio_set_dir(kGPIOpin1, GPIO_IN);
gpio_pull_up(kGPIOpin1);
while (1)
{
tud_task(); // tinyusb device task
led_blinking_task();
hid_task();
}
}
</pre>
<h3 style="text-align: left;">hid_task関数</h3>
<pre class="prettyprint lang-cpp linenums" style="overflow-wrap: normal; overflow: auto; word-wrap: normal;">// Every 10ms, we will sent 1 report for each HID profile (keyboard, mouse etc ..)
// tud_hid_report_complete_cb() is used to send the next report after previous one is complete
void hid_task(void)
{
// Poll every 10ms
const uint32_t interval_ms = 10;
static uint32_t start_ms = 0;
if ( board_millis() - start_ms < interval_ms) return; // not enough time
start_ms += interval_ms;
// *******************************************************
// GPIOのリード
// プルアップ設定なのでボタンを押していると"0"が取得される
// *******************************************************
bool button_0 = !gpio_get(kGPIOpin0);
bool button_1 = !gpio_get(kGPIOpin1);
// Remote wakeup
if ( tud_suspended() && (button_0 || button_1) )
{
// Wake up host if we are in suspend mode
// and REMOTE_WAKEUP feature is enabled by host
tud_remote_wakeup();
}
else
{
// skip if hid is not ready yet
if ( !tud_hid_ready() ) return;
// use to avoid send multiple consecutive zero report for keyboard
static bool has_keyboard_key = false;
if ( button_0 )
{
uint8_t keycode[6] = { 0 };
keycode[0] = HID_KEY_A; // "a"のキーコードを格納
tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode); // キーコードを送信
has_keyboard_key = true;
}
else if ( button_1 )
{
uint8_t keycode[6] = { 0 };
keycode[0] = HID_KEY_SHIFT_LEFT; // shiftキーのキーコードを格納
keycode[1] = HID_KEY_B; // "b"のキーコードを格納
tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode); // キーコードを送信
has_keyboard_key = true;
}
else
{
// send empty key report if previously has key pressed
if (has_keyboard_key) tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL); // 空のキーコードを送信
has_keyboard_key = false;
}
}
}
</pre>
<p>以下に処理の解説を箇条書きで記載しておきます。</p><p></p><ul style="text-align: left;"><li>hid_task関数は10ms毎の実行(ポーリング)が想定されています。関数の最初にそのための計測処理があります。</li><li>使用しているGPIOはプルアップに設定しているので、ボタンを押していない(GNDに接続していない)ときは"1"、ボタンを押している(GNDに接続している)ときは"0"になります。</li><li>tud_remote_wakeupのような関数がありますが、これはUSBデバイスが(接続しているPCが休止状態などになり)休止状態になっている場合に再開時に実行される処理です(要は休止状態時にボタンを押すと再開するという処理が実装されています)。PCが動きっぱなしであれば休止状態は考慮しなくても良いので、このあたりは無視しても問題ありません。</li><li>送信するキーボードのキーコード(HID_KEY_Aのような)の定義は<a href="https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h">こちら</a>を参照してください。</li><li>キーボードの同時押し(shiftキー+文字キーのような)は、押したいキーコードを配列に格納して関数に渡します。ただし、格納する順番が重要なようでshiftキーと文字キーを同時押しする場合はshiftキーの方を先に格納する必要があるようです。</li><li>USBでキーボードの状態を送信する場合はリポートデスクリプタというデータで送信されます。ボタンを押したときは、ボタンを押しているというリポートデスクリプタを送信すればいいのですが、ボタンを離したときは何も押されていないというリポートデスクリプタを送信する必要があります。NULLの情報を送信しているところがあるのはそのためです。</li></ul><p></p><h2 style="text-align: left;">まとめ</h2><p>Raspberry Pi PicoにはADCだけではなくI2CやSPIも標準で搭載されているので、大抵のセンサが接続できると思います。そして、その値をどのように使用するかの処理を実装すればもうオリジナルコントローラができてしまいます。ADCなどを使用する場合にはCMakeLists.txtの変更が必要ですが、Raspberry Pi Picoにはサンプルが充実しているのでそちらを参照すれば比較的容易に実装できるかと思います。</p><p>以上がRaspberry Pi Picoをインタフェースに使用したオリジナルコントローラとPC上のゲームを接続する方法の提案となります。皆さんのアイデアを具体化する手助けになれば幸いです。</p><h2 style="text-align: left;">その他</h2><p></p><ul style="text-align: left;"><li>使用しているRaspberry Pi Pico<br />ここで使用しているのはスイッチサイエンスが卸しているヘッダピン実装済みの「Raspberry Pi Pico H」で、大阪日本橋の<a href="https://eleshop.jp/shop/g/gN26SHV/">シリコンハウス</a>で979円で購入しています。</li><li>当研究所の開発環境<br />Windows10のWSL2でUbuntu20.04をインストールしてビルドを行っています。</li><li>仮想ゲームパッドも実はいける<br />Raspberry Pi Picoは仮想ゲームパッドとして動かすこともできます。キーボードかゲームパッドのどちらを採用すべきかというのはコントローラの仕様によるのでなんとも言えませんが、とりあえず今回はキーボードの方を紹介しました。</li></ul>ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-86020491543885118222024-03-20T15:18:00.000+09:002024-03-20T15:18:03.923+09:00HP更新<p>Google Sitesがいつの間にか更新されていたので、これを機にHPを新しくしました。</p>
<div class="bcard-wrapper"><span class="bcard-header"><div class="bcard-site"><a href="https://sites.google.com/view/haso-lab/top" rel="nofollow" target="_blank"></a></div><div class="bcard-url"><a href="https://sites.google.com/view/haso-lab/top" rel="nofollow" target="_blank">https://sites.google.com/view/haso-lab/top</a></div></span><span class="bcard-main withogimg"><div class="bcard-title"><a href="https://sites.google.com/view/haso-lab/top" rel="nofollow" target="_blank">ハードウェアとか研究所</a></div><div class="bcard-description">大阪のとある研究所</div><a href="https://sites.google.com/view/haso-lab/top" rel="nofollow" target="_blank"><div class="bcard-img" style="background-image: url(https://lh3.googleusercontent.com/2liG22rcauA0drFtQrpgm4chfe5qIusiGKSCV6q0nRYzAZFzP7ZoJ9WD42TEtHqTSi02i4U5S7SuWAPcH0AV_nE=w16383);"></div></a></span></div>ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-57735182989970931442022-12-11T09:56:00.004+09:002022-12-11T09:56:51.774+09:00コインアクセプタの中身はどうなっているのか<h3 style="text-align: left;">コインアクセプタの仕組み</h3><p>コインアクセプタは投入されたコインをその直径で判断していると思われますが、実際にはどのような仕組みでコインの種類を判断するか知っていますか。解説したページがあったので紹介します。</p><blockquote class="embedly-card"><h4><a href="https://hackaday.com/2022/04/10/coin-acceptors-are-higher-tech-than-you-think/">Coin Acceptors Are Higher-Tech Than You Think</a></h4><p>Coin-operated machines have a longer history than you might think. Ancient temples used them to dispense, for example, holy water to the faithful in return for their coins. Old payphones rang a bell when you inserted a coin so the operator knew you paid.</p></blockquote>
<script async="" charset="UTF-8" src="//cdn.embedly.com/widgets/platform.js"></script><p>リンク先にある解説動画は以下です。</p><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen="" class="BLOG_video_class" height="266" src="https://www.youtube.com/embed/Kl7uTviiOG0" width="320" youtube-src-id="Kl7uTviiOG0"></iframe></div><div><br /></div><div>上記の動画はコインアクセプタをArduinoを使用して実現しているのですが、その過程で実際のコインアクセプタを分解しています。それで明らかになるのですが、意外と高度な仕組みが実装されているのです。</div><div><br /></div><div>計測しているものは以下の3つです。</div><div><ol style="text-align: left;"><li>スピード</li><li>直径</li><li>材料</li></ol></div><h3 style="text-align: left;">スピード</h3><div>LEDとフォトアクセプタを使用することで、そこをコインが通過するとLEDの光が遮られるのでコインが通過したことがわかります。これを2セット使用すると2点間の移動時間からコインのスピードが判明します。</div><h3 style="text-align: left;">直径</h3><div>スピードが判明すると、コイン自体がLEDを遮る時間からコインの直径が計算できます。</div><h3 style="text-align: left;">材料</h3><div>さらに驚くことに、内部に2つのコイルがあり、その間にコインを通過させています。その際の電流変化を観測することにより、コインの材質も加味して判断することができます。つまり、直径は同じでも材質が違うコインを認識することができるのです(実際にやったことはありませんが)。</div><h3 style="text-align: left;">まとめ</h3><div>意外と身の回りにある機能の仕組みはわかっているようでわかっていないことがたくさんあります。コインアクセプタはコインの種類を判別できますが、自動販売機などではコインを判別した上で分別する必要があります。ではその分別はどのような仕組みで実現しているのでしょうか?そんなことを調べてみるのも面白いかもしれません。</div><div><br /></div><br /><p><br /></p><p><br /></p><p><br /></p>ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-14762183445150215742020-12-17T19:05:00.001+09:002020-12-17T19:05:54.433+09:00マスクをした顔を認識する(OpenCV)<p> Ogaki Mini Maker Faire 2020で顔認識を使用した作品を展示しました。昨今のコロナ状況下で顔認識するためには、マスクをした人の顔を認識する必要があるのですが、ここではどのようにそれを実現したのかを記載しておきます。</p><p>使用するシステムはRaspberryPi3B+で、ネットワークなしのローカルで完結する構成にしました。持ち運びや設置などの取り回しが容易になるからです。その代わりRaspberryPiではPCなどに比べ処理性能が制限されます。また、フリーで使用できるライブラリということで顔認識には<a href="https://github.com/opencv/opencv">OpenCV</a>を使用することにしました。</p><p>同様にフリーで使用できる顔認識が<a href="http://dlib.net">dlib</a>というものに含まれており、こちらは68点のランドマークを使用した高性能な顔認識が使用できます。しかし、残念ながらマスクなしが前提となっており、今回は候補から外れます。</p><p>OpenCVには"haarcascade"というかの有名なHaar-like特徴量を使用した認識モデルが実装されています。同時に学習済みのデータも含まれているのですぐに認識機能を使用することができます。これら学習済みのデータの種類については<a href="https://qiita.com/hitomatagi/items/04b1b26c1bc2e8081427">こちら</a>が参考になります。</p><p>この学習済みデータには正面の顔を認識するものがあるのですが、これはマスクをしていない顔を学習したデータなので、マスクをした顔を認識しようとすると性能が低下します。ということで今回は両目の認識をすることで顔認識の代替とすることにしました(マスクをしていても両目は見えるので)。目を認識する際に使用できる学習データは「右目」と「左目」があるのですが、正直目を個別に認識をすると統合処理が面倒なのでどうしたものかと思っていましたが、<a href="https://github.com/opencv/opencv_contrib/tree/3.4.10/modules/face/data/cascades">こちら</a>に"haarcascade"に対応した「両目」の学習済みデータがありました。どうやらこれらの学習済みデータはもうすでに不要と判断されOpenCV本体からは削除されているようです(他にも口や鼻がパーツとして認識できるものもあります)。</p><p>OMMF2020(屋内)で両目の認識("haarcascade_mcs_eyepair_big.xml"を使用)を動作させてみた雑感を以下に記載しておきます。</p><p></p><ul style="text-align: left;"><li>認識しやすい人と認識しにくい人に分かれる<br />認識しやすい人は顔の向きに関係なく安定して認識するが、認識しにくい人ははっきり正面を向いた顔を映さないと認識できない傾向がある</li><li>メガネをしている人が認識しにくい<br />おそらく目の部分が隠れるからだと思われる</li><li>誤認識が発生する<br />遠方に全身が映っている複数の人の足元に誤認識が発生した</li></ul><p></p><p>"haarcascade"で学習済みデータを使用する場合、手軽に認識機能を実現できるのは良いのですが、精度や誤認識が問題となったときに柔軟な対応ができないということがあります。認識の尤度の閾値設定ができず、設定ができるのは結果の重複数閾値と最小サイズぐらいです。あとは認識結果サイズによる誤認識の切り捨てぐらいしかできません。今回の展示は認識できれば良い程度のものであったため、認識しにくいことや誤認識に関しては特に問題とはなりませんでしたが。</p><span><a name='more'></a></span><p>おまけ「マスクした顔を"haarcascade"で認識する方法」</p><p>以下のサイトに"haarcascade"でマスクした顔を認識する方法が記載されています。</p><p><a href="https://medium.com/@saurabh.shaligram/face-mask-detection-simple-opencv-based-program-417bbcf0abd8">Face Mask Detection: Simple OpenCV Based Program</a></p><p>要約すると、顔認識と口認識の結果を組み合わせてマスクありとマスクなしの顔を認識できるとのこと。顔認識は通常の画像と二値化画像に適用するのが特徴です。※以下画像引用</p><blockquote><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMz1dgITryGp_Lr3BrbEduNYKXpYw3UUMkbXG-_Tm5pdjotCNS54dWNpiUeBGA_QDA7-4h4meQX-OrVLxgxA87lnywlyJ9EiZ1iY9LrC-6BaqeTuX6UZEnT6vgwLeG8IuFVzhZjhqgAF0/" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="221" data-original-width="700" height="101" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMz1dgITryGp_Lr3BrbEduNYKXpYw3UUMkbXG-_Tm5pdjotCNS54dWNpiUeBGA_QDA7-4h4meQX-OrVLxgxA87lnywlyJ9EiZ1iY9LrC-6BaqeTuX6UZEnT6vgwLeG8IuFVzhZjhqgAF0/" width="320" /></a></div><p></p></blockquote><p>実際やってみたのですが性能は…、うーん…。まあ、こんな方法もあるよという参考までに。</p>ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-1602216519173852052020-10-25T10:44:00.006+09:002020-10-25T22:30:23.087+09:00コインアクセプタの解析<p> この記事は2012年に別のHPで公開した内容です。今は未公開にしているのですが、たまにアクセスされているようなので、こちらで公開します。ここで解説しているコインアクセプタはAdafruitのものですが、おそらく別のコインアクセプタも仕様は同じかと思われます。参考までに。Amazonだと例えば以下のようなものが該当すると思います。</p><p><iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="//rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=handicraftcreative-22&language=ja_JP&o=9&p=8&l=as4&m=amazon&f=ifr&ref=as_ss_li_til&asins=B07MCBRQ8V&linkId=8e865804faf7b0e2a99035ee566642e6" style="height: 240px; width: 120px;"></iframe></p><hr /><p>ここではAdafruitから購入したコインアクセプタの使い方を解説しています。 具体的には以下の商品です。</p><p></p><ul style="text-align: left;"><li><a href="https://www.adafruit.com/product/787">Coin Acceptor - Programmable 4 Coin Type ID: 787 - $39.95 : Adafruit Industries, Unique & fun DIY electronics and kits</a> <br />届いた現物が以下の写真になります。<br /><div class="separator" style="clear: both; text-align: center;"><div style="text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZKzH6LbBIpW-kTPyFT4P9ESrVrEslG1Szit6Nmc9kMh8iPD_YsLefsusDkY62oUwAH73T0S3_Tpjru6WTGvpkN7v5qrlqN7yzCIU5C72iaEDsxFxSBhXYvCBWfHmfMv4uVD-cZUlxYQw/s640/coinacceptor_0.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="480" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZKzH6LbBIpW-kTPyFT4P9ESrVrEslG1Szit6Nmc9kMh8iPD_YsLefsusDkY62oUwAH73T0S3_Tpjru6WTGvpkN7v5qrlqN7yzCIU5C72iaEDsxFxSBhXYvCBWfHmfMv4uVD-cZUlxYQw/s320/coinacceptor_0.jpg" width="320" /></a><br />箱を見ただけで中国製だとわかりますね。</div></div></li></ul>箱の中にはモジュールと説明が書かれた紙が1枚。紙をスキャンしたのが以下です。<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZFnl9mUcLEQ1hn06o66mWKNIjnP9SQKKky41Bh52IjduqfbsboQ87dYyVXif10-_rGTfLCFX9iTGGLfOrXcs11OTvB_DX09U9IV4dbPG41x6Any4-tF2zvBtTbCYfD535ChhgzzE2MbI/s1000/coinacceptor_1.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="722" data-original-width="1000" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZFnl9mUcLEQ1hn06o66mWKNIjnP9SQKKky41Bh52IjduqfbsboQ87dYyVXif10-_rGTfLCFX9iTGGLfOrXcs11OTvB_DX09U9IV4dbPG41x6Any4-tF2zvBtTbCYfD535ChhgzzE2MbI/s320/coinacceptor_1.jpg" width="320" /></a></div>サイトの商品ページに乗っている<a href="https://cdn-shop.adafruit.com/datasheets/CHmulticoin.jpg">説明書</a>と大差はないようです。<div><div>さて、このモジュールができることは以下のことです。</div><div><ul style="text-align: left;"><li><b>4種類のコインを登録できる</b><br />コインの直径を認識しているみたいなので、登録できるのは直径の違う4種類のコインということになります。ですが、日本硬貨の5円と50円のような穴の開いたコインはうまく認識できないようです。</li><li><b>登録したコインのみを認識して選り分けることができる</b><br />投入したコインが登録されたものだったら後ろの排出口に、登録されていないものだったら前面の返却口に出力できます。</li><li><b>認識したコインの種類を外部にパルスとして出力できる</b><br />これによって何のコインが投入されたか知ることができます。</li></ul></div><div>次はモジュール周りのインタフェースを見てみます。周辺部の写真を掲載します。</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbx5yb3YiEW5yUpfsbR8Fux82DRY5U2E1DCuVLGGPq8mdyE1_CX6cbrOXWg_CqDelTOP6Bj9r0TBWfUEjaHziobNA_V6OwPvGIOinTc1nOmlYAkWy-wPKUtEUp8lb2-NQL3aItzOw8iTc/s1333/coin_0.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; outline-width: 0px; text-align: left; user-select: auto;"><img border="0" data-original-height="1000" data-original-width="1333" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbx5yb3YiEW5yUpfsbR8Fux82DRY5U2E1DCuVLGGPq8mdyE1_CX6cbrOXWg_CqDelTOP6Bj9r0TBWfUEjaHziobNA_V6OwPvGIOinTc1nOmlYAkWy-wPKUtEUp8lb2-NQL3aItzOw8iTc/w200-h150/coin_0.jpg" width="200" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFuQn2r2D_vYS8-n9EJGCmiLTKLTkz3WMCMbCqCKK7-Rs4AjXNZzMWuc3a_unrhJTrv8sSuik3jpDgLZTpZ1vIlHT0wqR1tca-edck0KBhXwqXqYU2HKdOtBsmCZ6lRsVVOYsHJmW2nlY/s1333/coin_1.jpg" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="1000" data-original-width="1333" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFuQn2r2D_vYS8-n9EJGCmiLTKLTkz3WMCMbCqCKK7-Rs4AjXNZzMWuc3a_unrhJTrv8sSuik3jpDgLZTpZ1vIlHT0wqR1tca-edck0KBhXwqXqYU2HKdOtBsmCZ6lRsVVOYsHJmW2nlY/w200-h150/coin_1.jpg" width="200" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2RhTeyQ176qYv7pMim7x66nc-7A4UNfeR2r-uMfv38RY_eDW6Is-d4ooXknjoos11muUDI5aBThdGPsuk5dzmVoWFEI6QP-jdJaUUVueWUxMy14wuoto33vFM2lUsgN-6SKiPyvoWYbg/s1333/coin_2.jpg" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="1000" data-original-width="1333" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2RhTeyQ176qYv7pMim7x66nc-7A4UNfeR2r-uMfv38RY_eDW6Is-d4ooXknjoos11muUDI5aBThdGPsuk5dzmVoWFEI6QP-jdJaUUVueWUxMy14wuoto33vFM2lUsgN-6SKiPyvoWYbg/w200-h150/coin_2.jpg" width="200" /></a><div class="separator" style="clear: both; text-align: left;"><ol style="text-align: left;"><li>外部ピン(4本)<br /><google-sheets-html-origin><table border="1" cellpadding="0" cellspacing="0" dir="ltr" style="border-collapse: collapse; border: none; font-family: Arial; font-size: 10pt; table-layout: fixed; width: 0px;" xmlns="http://www.w3.org/1999/xhtml"><colgroup><col width="100"></col><col width="396"></col></colgroup><tbody><tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"名称"}" style="background-color: #efefef; border: 1px solid rgb(0, 0, 0); color: #444444; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: top;"><span style="color: black; font-family: Meiryo; font-size: small;">名称</span></td><td data-sheets-value="{"1":2,"2":"説明"}" style="background-color: #efefef; border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: top;"><span style="color: black; font-family: Meiryo; font-size: small;">説明</span></td></tr><tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"DC12V"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;"><span style="color: black; font-family: Meiryo; font-size: small;">DC12V</span></td><td data-sheets-value="{"1":2,"2":"+12V","6":1}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;"><span style="color: black; font-family: Meiryo; font-size: small;">+12V</span></td></tr><tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"COIN"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;"><span style="color: black; font-family: Meiryo; font-size: small;">COIN</span></td><td data-sheets-value="{"1":2,"2":"認識したコインの種類をパルスで出力\nパルスの数はプログラム可能(任意数が出力できます)\nパルスはTTL?(5Vレベル)っぽいです\nパルスについては後に掲載あり"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;"><span style="color: black; font-family: Meiryo; font-size: small;">認識したコインの種類をパルスで出力<br />パルスの数はプログラム可能(任意数が出力できます)<br />パルスはTTL?(5Vレベル)っぽいです<br />パルスについては後に掲載あり</span></td></tr><tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"GND"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;"><span style="color: black; font-family: Meiryo; font-size: small;">GND</span></td><td data-sheets-value="{"1":2,"2":"GND"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;"><span style="color: black; font-family: Meiryo; font-size: small;">GND</span></td></tr><tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"COUNTER"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;"><span style="color: black; font-family: Meiryo; font-size: small;">COUNTER</span></td><td data-sheets-value="{"1":2,"2":"不明\n謎です"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;"><span style="color: black; font-family: Meiryo; font-size: small;">不明<br />謎です</span></td></tr></tbody></table>※接続するコネクタはワイヤ付きで同封されています</google-sheets-html-origin></li><li>2接点スライドスイッチ<br />"NO"と"NC"の記載あり(ノーマリーオープン/コネクタ?)。よくわからないのでデフォルトの"NO"から触らず。</li><li>3接点スライドスイッチ<br />- Fast<br />- Medium<br />- Slow<br />上記3つの設定から出力パルスの長さを選択できます(後述)</li><li>"SET"ボタン</li><li>”ADD"ボタン</li><li>7セグ</li><li>”MINUS"ボタン<br />※4から7は使用前の設定で使用します</li></ol><div class="separator" style="clear: both;">使うにあたってはコインのパラメータ設定とサンプリングをする必要があります。パラメータ設定とは使用するコインの種類の数や出力パルス数の設定で、側面のボタンと7セグで行います。サンプリングは実際に使用するコインを投入してコインの種類を覚えさせる工程です。これらの手順は前述のAdafruitのサイトや同封されているマニュアルに掲載されています。</div><div class="separator" style="clear: both;"><br /></div><div class="separator" style="clear: both;">ここからは使用前の設定を解説していきます。電圧を印加すると1秒ぐらい経過した後、ブザーが鳴ってLED(表示灯)が点灯します(ブザーは結構大きな音ですので、びっくりします)。</div><div class="separator" style="clear: both;">まずはパラメータの設定を行います。電源を入れた状態で以下の手順を実行します。</div><div class="separator" style="clear: both;"><ol style="text-align: left;"><li>”ADD”ボタンと”MINUS”ボタンを同時に1秒以上押す<br />ボタンを離すと7セグに”A”が表示されます。</li><li>”A"が表示されたら”SET"ボタンを1秒以上押す<br />”SET"ボタンを離すと7セグに”E"が表示されます。</li><li>”E"が表示されたら”ADD"ボタンと”MINUS"ボタンで認識するコインの種類を決め、”SET"ボタンを1秒以上押す<br />このモジュールは4種類のコインを認識できるので1から4が設定可能です。”SET"ボタンを離すと”H1"が表示されます。”H1"の”1”はコインの1種類目を意味していると思います。</li><li>”H1"が表示されたら”ADD"ボタンと”MINUS"ボタンでサンプル数を決め、”SET"ボタンを1秒以上押す<br />サンプル数とはこのパラメータ設定の後に行うコインのサンプリングを行う回数です。設定できる最大は30で、15以上を設定するとより正確性が増すとマニュアルにあります。 ”SET"ボタンを離すと”P1"が表示されます。”P1"の”1”は"H1”と同様にコインの1種類目を意味していると思います。</li><li>”P1"が表示されたら”ADD"ボタンと”MINUS"ボタンで出力パルス数を決め、”SET"ボタンを1秒以上押す<br />このモジュールは認識したコインの種類をパルスの数で出力します。ここではそのパルス数を設定します。マニュアルによると最大は50だそうです。 ”SET"ボタンを離すと”F1"が表示されます。”F1"の”1”は"H1”と同様に (略)。</li><li>”P1"が表示されたら”ADD"ボタンと”MINUS"ボタンで正確度を決め、”SET"ボタンを1秒以上押す<br />正確度とは所謂”あそび”に関連しているものだと思われます。1から30まで設定可能で、1であれば最も正確、30であれば曖昧になります。通常は5から10が最適だとマニュアルにあります。似た形状のコインを認識したい場合は小さくしたほうが良いとのこと。 ”SET"ボタンを離すと”H2"が表示されます(2種類以上の設定を行った場合)。</li><li>"6"の手順が終わると"4"へ戻るので、"3"で設定したコインの種類の数だけ"4"から"6"の設定を繰り返す</li><li>”A"が表示されたら”SET"ボタンを1秒以上押す</li><li>”E"が表示されたら電源をOFFにする</li></ol></div><div class="separator" style="clear: both;">次は実際にコインを投入するサンプリングの手順です。複数回(同種類の複数枚の)コインを投入する必要がありますが、同一のコインを複数回投入しても大丈夫です(たぶん)。</div><div class="separator" style="clear: both;"><ol style="text-align: left;"><li>”SET”ボタンを1秒以上押す<br />ボタンを離すと7セグに”A1”が表示されます。</li><li>”A1"が表示されたら1種類目のコインをパラメータ設定で設定したサンプル数の回数分投入する<br />コインを投入すると7セグに投入した回数がカウント表示されます。設定回数分投入すると7セグに”A1"が点滅表示されます。</li><li>”SET”ボタンを1秒以上押す<br />”SET"ボタンを離すと”A2"が表示されます。</li><li>"3"の手順が終わると"2"へ戻るので、"2"から"3"の設定を4回繰り返す<br />ここではパラメータ設定で設定したコインの種類の数によらず4回行わなければならないようです。ただし、"SET"ボタンを1秒以上押すことでコインのサンプリングをスキップすることが可能です。<br />例:2種類のコインを使用したい場合、"A3"と”A4"はスキップします</li><li>すべて終わると自動的に再起動します</li></ol></div><div class="separator" style="clear: both;">※設定後、設定したコインを投入すると一瞬だけそのコインの出力パルス数が7セグに表示されるので何を認識したかはモジュール単体でもわかります</div><div class="separator" style="clear: both;"><br /></div><div class="separator" style="clear: both;"><div class="separator" style="clear: both;">実際の日本硬貨を使用する際の設定例を以下に掲載します。残念ながら穴の開いている5円と50円はうまく認識できません(事実サンプリング時に投入するとカウンタが1ではなく2ずつ増えるので認識できていないと考えられます)。ですので使用するのはその2種類を除いた4種類の硬貨です。5円はいいのですが50円が認識できないのは正直微妙なところです。</div><div class="separator" style="clear: both;">設定後動かしてみましたが正しく認識できました。</div><div class="separator" style="clear: both;"><ul style="text-align: left;"><li>設定値<br /><google-sheets-html-origin><table border="1" cellpadding="0" cellspacing="0" dir="ltr" style="border-collapse: collapse; border: none; font-family: Arial; font-size: 10pt; table-layout: fixed; width: 0px;" xmlns="http://www.w3.org/1999/xhtml"><colgroup><col width="100"></col><col width="100"></col><col width="100"></col><col width="100"></col><col width="100"></col></colgroup><tbody><tr style="height: 21px;"><td style="background-color: white; border: 1px solid rgb(0, 0, 0); overflow: hidden; padding: 2px 3px; vertical-align: top;"></td><td data-sheets-value="{"1":2,"2":"10円"}" style="background-color: white; border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">10円</td><td data-sheets-value="{"1":2,"2":"100円"}" style="background-color: white; border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">100円</td><td data-sheets-value="{"1":2,"2":"500円"}" style="background-color: white; border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">500円</td><td data-sheets-value="{"1":2,"2":"1円"}" style="background-color: white; border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">1円</td></tr><tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"サンプル数"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">サンプル数</td><td data-sheets-value="{"1":3,"3":15}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">15</td><td data-sheets-value="{"1":3,"3":15}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">15</td><td data-sheets-value="{"1":3,"3":15}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">15</td><td data-sheets-value="{"1":3,"3":15}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">15</td></tr><tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"出力パルス"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">出力パルス</td><td data-sheets-value="{"1":3,"3":5}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">5</td><td data-sheets-value="{"1":3,"3":10}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">10</td><td data-sheets-value="{"1":3,"3":15}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">15</td><td data-sheets-value="{"1":3,"3":20}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">20</td></tr><tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"正確度"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">正確度</td><td data-sheets-value="{"1":3,"3":5}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">5</td><td data-sheets-value="{"1":3,"3":5}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">5</td><td data-sheets-value="{"1":3,"3":5}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">5</td><td data-sheets-value="{"1":3,"3":5}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; color: #444444; overflow: hidden; padding: 2px 3px; vertical-align: top;">5</td></tr></tbody></table></google-sheets-html-origin></li></ul></div></div><div class="separator" style="clear: both;"><div class="separator" style="clear: both;">注意点としては、モジュールを水平に設置しないとうまく認識しません。コインの直径を見ているとは思うのですが、どのようにセンシングしているのか興味深いです。</div><div class="separator" style="clear: both;"><br /></div><div class="separator" style="clear: both;">では、COINから出力されるパルスを見てみます。パルスはロジアナを使用して観測しました(ZEROPLUSの安いロジアナ使用-><a href="http://strawberry-linux.com/catalog/items?code=64001">これ</a>)。スライドスイッチは"Fast"を選択しています。</div><div class="separator" style="clear: both;"><ul style="text-align: left;"><li>出力パルス設定"5"のコインを認識した波形<br /><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2dzdCUx10hZsifJsYbZxDp4aAZS8-69Lw8nmqN7gCyZHyzmAOdZIpn1pMMT53-A6DwXrwz1C5hiEvRwCUDQ6xUqPpky36blokvKj0QZQnosFB6yy8SsQ-6uBHIo1guiZMyi9aXShl3ZQ/s871/coin_wave_0.gif" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="175" data-original-width="871" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2dzdCUx10hZsifJsYbZxDp4aAZS8-69Lw8nmqN7gCyZHyzmAOdZIpn1pMMT53-A6DwXrwz1C5hiEvRwCUDQ6xUqPpky36blokvKj0QZQnosFB6yy8SsQ-6uBHIo1guiZMyi9aXShl3ZQ/s320/coin_wave_0.gif" width="320" /></a></div><div style="text-align: left;">プルアップされていてローのパルスが出力される模様。</div></div></li><li><div class="separator" style="clear: both; text-align: left;">上の波形を少し拡大して時間を表示したもの<br /><span style="color: black;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiKoG2R3bIHYvJoAzfhfDm-WtzByJM6UvKahP3FStaECKdehhfhU7qjL7ol9F3Lj7DIx-mTYqiC3hzjE88zXLl9Vu-NGd2AK85XHW6J40yusR3lX5GhYriPivkdRnDvNdBEnjR1mWPgP8/s871/coin_wave_1.gif" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="175" data-original-width="871" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiKoG2R3bIHYvJoAzfhfDm-WtzByJM6UvKahP3FStaECKdehhfhU7qjL7ol9F3Lj7DIx-mTYqiC3hzjE88zXLl9Vu-NGd2AK85XHW6J40yusR3lX5GhYriPivkdRnDvNdBEnjR1mWPgP8/s320/coin_wave_1.gif" width="320" /></a></div>約30msのパルスが出力されているようです。この出力幅はスイッチで変更できます。</span></div></li></ul></div><div class="separator" style="clear: both;">その他のスライドスイッチの設定も試してみました。以下にまとめておきます。</div><div class="separator" style="clear: both;"><ul style="text-align: left;"><li>スライドスイッチの設定と出力パルス長の関係<br /><google-sheets-html-origin><table border="1" cellpadding="0" cellspacing="0" dir="ltr" style="border-collapse: collapse; border: none; font-family: Arial; font-size: 10pt; table-layout: fixed; width: 0px;" xmlns="http://www.w3.org/1999/xhtml"><colgroup><col width="144"></col><col width="87"></col></colgroup><tbody><tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"スライドスイッチ設定 "}" style="border: 1px solid rgb(0, 0, 0); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">スライドスイッチ設定</td><td data-sheets-value="{"1":2,"2":"出力パルス長"}" style="background-color: white; border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">出力パルス長</td></tr><tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"\"Fast\""}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">"Fast"</td><td data-sheets-value="{"1":2,"2":"約30ms"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">約30ms</td></tr><tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"\"Medium\""}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">"Medium"</td><td data-sheets-value="{"1":2,"2":"約50ms"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">約50ms</td></tr><tr style="height: 21px;"><td data-sheets-value="{"1":2,"2":"\"Slow\""}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">"Slow"</td><td data-sheets-value="{"1":2,"2":"約100ms"}" style="background-color: white; border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; font-family: Roboto; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">約100ms</td></tr></tbody></table></google-sheets-html-origin></li></ul></div><div class="separator" style="clear: both;">解析は以上です。</div></div></div></div></div>ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-7662072518810431342020-04-22T09:31:00.000+09:002020-04-22T09:31:31.635+09:00Air umbrellaの話以下、HACKADAYより引用(意訳)。<br />
<br />
<blockquote class="tr_bq">
Failed: Air Umbrella | Hackaday<br /><a href="https://hackaday.com/2020/01/25/failed-air-umbrella/">https://hackaday.com/2020/01/25/failed-air-umbrella/</a><br />約5年前、kickstarter(クラウドファンディングサイト)で"Air umbrella"というプロジェクトが発足した。当初はクラウドファンディングという形態の目新しさも相まって、プロジェクトは資金を集めることに成功した。しかし、紆余曲折を経て結局はプロジェクトは失敗に終わった。<br />"Air umbrella"は、頭上に落ちてくる雨を圧縮空気を使って弾き飛ばすことにより、コンパクトな傘を実現しようとした。<br />雨滴の最終的な落下速度は約時速20マイル(32キロ)と言われる。となると、傘のような広い範囲の雨を防ごうと思うと、少なくとも時速25マイル(40キロ)で空気を噴射する必要がある。<br />頭のすぐ上でそんな空気の噴射をしたい人がいるのだろうか?このような空気の噴射は持ち運びできる小型バッテリーでどのくらい持つのだろうか?<br />現実的ではないこのプロジェクトは結局失敗した。投資をした人の中には物理学者はいなかったのだろうか?</blockquote>
<br />
このプロジェクトが開始された当時、クラウドファンディングが流行っていたが、思いの外お金が集まっていてびっくりしたことを覚えている。このような空気の噴射は実はものすごくエネルギーを必要とする(身近でいうとドライヤーがいい例)。所長は昔、スカートをめくるためにブロアファンを使用した作品を作ったことがあるが、電力を食う割には弱い風しか発生させられなかった記憶がある。<br />
<br />ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-19195310732212594102019-11-21T20:05:00.000+09:002019-11-21T20:05:07.018+09:00OpenCVのWindow更新はメインスレッドでしかできないということがあったので記載しておく。<br />
割と最近のQ&Aがあったので貼っておこう。<br />
<br />
<blockquote class="embedly-card">
<h4>
<a href="https://answers.opencv.org/question/210946/how-to-update-cvnamedwindow-in-multi-threading-environment/">How to update cv::namedwindow in multi-threading environment? - OpenCV Q&A Forum</a></h4>
If 1 callback receives an image and performs some image-processing. How can the output image be shown in multi-threading environment? By multi-threading I mean, if that particular callback(depthCallback) can be invoked by more than one thread. And, one more query: Is using waitkey(1), optimal for real-time application?</blockquote>
<script async="" charset="UTF-8" src="//cdn.embedly.com/widgets/platform.js"></script><br />
<br />
ウィンドウの更新はメインスレッドで実施するというのが常識だそうな。ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-58719444401782008872019-10-10T22:40:00.000+09:002019-10-10T22:40:45.693+09:00wiringpiが開発中止ラズベリーパイのGPIO制御ライブラリであるwiringpiが開発をやめるらしい(正確にはオープンソースでの保守を停止)。<br />
<br />
<a class="embedly-card" data-card-controls="0" href="https://hackaday.com/2019/09/18/wiringpi-library-to-be-deprecated/">WiringPi Library To Be Deprecated</a>
<script async="" charset="UTF-8" src="//cdn.embedly.com/widgets/platform.js"></script>
<br />
<br />
開発者はゴードンさんという方で(wiringpiのホームページに写真あり)、無断の商用使用やスパムに耐えきれなくなったからと理由を説明している。<br />
<br />
<a class="embedly-card" data-card-controls="0" href="http://wiringpi.com/wiringpi-deprecated/">wiringPi - deprecated...</a>
<script async="" charset="UTF-8" src="//cdn.embedly.com/widgets/platform.js"></script><br />
<br />
代替ライブラリはpigpioになる?それともforkされた有志によるwiringpiが使われるようになる?ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-29825706924651317622019-09-28T09:53:00.003+09:002019-09-28T10:17:50.509+09:00書評:「組込みエンジニアの教科書」超初心者向けです。組み込みエンジニアって何?どういう仕事?ということがわかります。これから就職先を考える大学生や高専生向けです。<br />
広く浅く横断的に書かれているので、組み込みエンジニアという職業の雰囲気を知るぐらいはできるかも。<br />
<br />
<iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="//rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=handicraftcreative-22&language=ja_JP&o=9&p=8&l=as4&m=amazon&f=ifr&ref=as_ss_li_til&asins=4863542755&linkId=dcadb804a092aa5c7e4ae43652d1631a" style="height: 240px; width: 120px;"></iframe>ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-56715135889511379192019-08-31T13:18:00.000+09:002019-08-31T13:18:38.265+09:00OpenCVのLineIteratorの使い方今まで知らなかったのですがOpenCVのクラスにLineIteratorというものがあります。これを使用すると、2点の座標を結ぶ線分の座標を順に辿ることができます。<br />
<br />
汎用的な機能ではありませんが、使用目的にハマるとかなり便利な機能です。<br />
<br />
例えば、画像上のある線分上に特定の画素値が存在するかどうかを判定することを考えたとき、その線分が水平or垂直であれば容易に線分上の座標を辿れますが、それ以外の角度の線分を辿ろうとするとチト骨が折れます。具体的には、その線分がどの程度傾いているかを調べて、三角関数を使って線分上の座標を逐一計算する必要があります。しかし、このクラスを使用するとそんな面倒な計算をすることなく線分上の座標を得ることができ、簡単に画素値を参照できます。<br />
<br />
具体的には、以下のように使用します。<br />
<br />
<pre class="brush:cpp;">cv::Mat image = cv::imread("test.png");
cv::Point start(10,10);
cv::Point end(50,50);
// pixel check
cv::LineIterator it(image, start, end, 8); // startからendを結ぶ線分を辿るイテレーターの作成
for(int i = 0; i < it.count; i++, ++it) {
cv::Point p = it.pos(); // it.pos()で座標取得
if(IsBlack(p.x, p.y, image) { // IsBlackは座標位置の色を判定する自作関数
// 適当な処理
bresk;
}
}</pre>
<br />
線分上の座標をC++のイテレータで取得できます。レーザーなどの直線運動しているものの軌道上に障害物があるか判定するときなどに使用できます。ニッチですなぁ…。ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-7411179640772921262019-07-18T07:47:00.000+09:002019-07-18T07:47:34.414+09:00モバイルバッテリー(Quick Charge 3.0対応)から12Vor9Vを取り出すQualcommの充電規格であるQuick Chargeに対応したモバイルバッテリーからは、5Vだけでなく9Vや12Vを取り出せるらしい。<br />
<br />
<blockquote class="embedly-card">
<h4>
<a href="https://aether.hateblo.jp/entry/2018/09/04/180456">QC対応USBから9Vを取り出す(1) - とあるエンジニアの思考と試行 -Widlerよろしく-</a></h4>
Quick Charge 2.0の充電器を持っていたので、ScansnapやTEPRAといった 9V系のアクセサリを直接USBから駆動するための回路を検討した。 こちらの方がすでに実装しているので、PIC用に回路図をアレンジする。 PortをHiZにせず、1/0にて、0.6Vと3.3Vを生成するようにする。 レギュレータU1は、9V出力後もマイコンに過電圧がかからないように、 ドロップアウトの少ないものを選定する。 R1-R3は入手しやすい抵抗値で仮決め(公差大丈夫か?) PICにソフト実装。はじめてXC8でコーディング。といってもたいした事をしてるでもなく。 // PIC12F509 Con...</blockquote>
<br />
<script async="" charset="UTF-8" src="//cdn.embedly.com/widgets/platform.js"></script>
今まではなるべく電源を繋ぎたくない(コードレスにしたい)場合に、乾電池を使うことが多かったのですが、そうすると高い電圧を作ろうとすると場所をとったり、容量が少なかったりといった問題があります。電池交換の手間もコストもかかります。モバイルバッテリーがこの代替になれるのなら、安全ですし、コンパクトですし、充電もできるしといいことづくめです。<br />
<br />
直近ではコードレスの12Vが必要だったので、Quick Charge 3.0対応のモバイルバッテリーを購入して試してみたいと思います。ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-38901316038236860482018-08-08T05:00:00.001+09:002018-08-08T05:00:25.386+09:00SNS始めるtwitterを始めました。<br />
twitter:<a href="https://twitter.com/HASO_Lab">@HASO_Lab</a><br />
といっても、アカウント自体は以前に取得していたのですが…。<br />
<br />
また、ニコニコ生放送で映像配信に挑戦しています。<br />
映像配信コミュニティ:<a href="https://com.nicovideo.jp/community/co3847690">co3847690</a><br />
配信については、わからないことだらけなので手探り状態です。ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-77674180425282500452018-08-06T03:14:00.000+09:002018-08-06T03:26:30.693+09:00MakerFaireTokyo2018に出展しました&便利なPOPスタンド8/4(土)と5(日)に東京ビッグサイトで開催された"Maker Faire Tokyo 2018"に今年も出展してきました。展示の様子は以下のような感じでした。<br />
<br />
・全体<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtTaf-Hs-TAmRziRjj4DuuXip3sF5-0_720nkCoZz9N85NL05eO7zmS1wJRfjYpTMAth56aqT1wke-bZcTl7Dwujg4z1Kts_Y2feQft4Qqd7-DfPGI6g4uEG1JwoyqIbF3CgQyrIB_NjU/s1600/mft2018_0.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="720" data-original-width="1280" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtTaf-Hs-TAmRziRjj4DuuXip3sF5-0_720nkCoZz9N85NL05eO7zmS1wJRfjYpTMAth56aqT1wke-bZcTl7Dwujg4z1Kts_Y2feQft4Qqd7-DfPGI6g4uEG1JwoyqIbF3CgQyrIB_NjU/s320/mft2018_0.jpg" width="320" /></a></div>
・多数決マリオ<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE2TjJT1bAR2mX0LpoaAnlxijaetVT47JuV_jIxT7REKdlGZJKxXqHfUAmG5Jtbth4VIWBLZuc8CZrZazM7Z-T_Er0qvUQN7e0Ve4KIYODq-nn9GSEnkFO7bP9ULn8RJ0dOJDkTk8v6io/s1600/mft2018_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1280" data-original-width="720" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE2TjJT1bAR2mX0LpoaAnlxijaetVT47JuV_jIxT7REKdlGZJKxXqHfUAmG5Jtbth4VIWBLZuc8CZrZazM7Z-T_Er0qvUQN7e0Ve4KIYODq-nn9GSEnkFO7bP9ULn8RJ0dOJDkTk8v6io/s320/mft2018_1.jpg" width="180" /></a></div>
・全自動シレン<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIBx2IK8qQJ9ySLGkb2WiesbEB1dSGTvCestfFm37au_Hsk9QHj7WpPTlTHwuo-7OCFsg1LyzAsET7BBUCMwTpu1zHSQeDZA5lSK4RO0hH0oVGS_JNrlzplOSjiGcwYXTa_CPPiW04fBc/s1600/mft2018_2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1280" data-original-width="720" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIBx2IK8qQJ9ySLGkb2WiesbEB1dSGTvCestfFm37au_Hsk9QHj7WpPTlTHwuo-7OCFsg1LyzAsET7BBUCMwTpu1zHSQeDZA5lSK4RO0hH0oVGS_JNrlzplOSjiGcwYXTa_CPPiW04fBc/s320/mft2018_2.jpg" width="180" /></a></div>
・インタラクティブアイパッチ<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiNLHLjjcWgg3d_HaFZ4uQXQsypLRuyZPFpZLhoCXDGggUroC-i9WfqZ6nMKmgH0qrvo7dOFQVEdvYS51kegtH9KM7pHzLGGQhyphenhyphenjHOVZI8iOvfOVQP_uQKGPzPhwTwGMOrzSAQTAgLijc/s1600/mft2018_3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1280" data-original-width="720" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiNLHLjjcWgg3d_HaFZ4uQXQsypLRuyZPFpZLhoCXDGggUroC-i9WfqZ6nMKmgH0qrvo7dOFQVEdvYS51kegtH9KM7pHzLGGQhyphenhyphenjHOVZI8iOvfOVQP_uQKGPzPhwTwGMOrzSAQTAgLijc/s320/mft2018_3.jpg" width="180" /></a></div>
※あと、動くリボンも展示したかったのですが間に合いませんでした…<br />
<br />
今年の出展物は過去に出展したことのあるものばかりだったので、新鮮味はあんまりなかったかもしれません。来年は新しいものを出せればと思っています。<br />
<br />
以下余談です。<br />
当研究所では作品の展示の説明にパネルを使用しているのですが、パネルを並べるという方法を取る場合、机の上に単純に並べてしまうとパネルによって作品を置くスペースが狭くなってしまうという問題があります。今回は欲張って展示作品数を増やしたため、パネルを並べるスペースすらなくなってしまいました。そこで、今回はPOPスタンドというものを使ってみたのですが、これがかなり便利でした。<br />
<br />
・こんなやつ<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPoHpniFYBAnfbBp_p2l26ed-QyexAKV6qBW-r5YI0yPHCHJ1qaM4h3LS8puwkJezd0XMcXUYNuVZIEuDbWpqfnY7UkhvEH3CiH17ERLLtPm9X_tk9dFXZABkrd9Ysyz5X-3qPIcs1ka4/s1600/mft2018_display0.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="360" data-original-width="640" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPoHpniFYBAnfbBp_p2l26ed-QyexAKV6qBW-r5YI0yPHCHJ1qaM4h3LS8puwkJezd0XMcXUYNuVZIEuDbWpqfnY7UkhvEH3CiH17ERLLtPm9X_tk9dFXZABkrd9Ysyz5X-3qPIcs1ka4/s320/mft2018_display0.jpg" width="320" /></a></div>
<br />
これを使用すると、液晶ディスプレイの上部空間にパネルを配置できる(上部写真参照)ようになるので、スペースを有効に使うことができました。そして、ポールの部分が伸び縮み(真ん中のポールが最大94cmぐらいまで伸びる)でき、さらに分解できるので持ち運びが楽です。<br />
<br />
・分解した図<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_TcxvZRFhR3BPHtwUdaokAW97bG0K_kRfv6VPe68CyDACFKG7nAOlAcgPUJBxOv0f76-uuyImAwSbLRhjPGcTaj5fTs6IVSB4zx6BA42TY2r6agUV7gytVD6YZ8VK4M4xVSP56AlCkok/s1600/mft2018_display1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="640" data-original-width="360" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_TcxvZRFhR3BPHtwUdaokAW97bG0K_kRfv6VPe68CyDACFKG7nAOlAcgPUJBxOv0f76-uuyImAwSbLRhjPGcTaj5fTs6IVSB4zx6BA42TY2r6agUV7gytVD6YZ8VK4M4xVSP56AlCkok/s320/mft2018_display1.jpg" width="180" /></a></div>
※土台とはネジ止めですが、ドライバ不要で手で止めれるレベル<br />
<br />
実際に吊るしていたのはB5サイズのパネルx2で、これはダイソーの硬質カードケース(108円)にプリント紙をいれたものを使用しています。このPOPスタンドは1枚の掲示を想定していると思われるので、多少イレギュラーな使用法でしたが意外と大丈夫でした。<br />
<br />
・どこのダイソーでもたいてい売っているやつ<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitZ6xtdI_lMhcO_B1OwW9fKd-yk-E7vVaqd7IGZryCiSsd5iR6sN0FF2Dr0T-jbSbgAhnZHBXCf0Kxv-MQNqcRKj_C5Woz-5CwpIz7YxmBPSR2QK5k2nl8Ah3U-VLqDpgxD57gTSKA7Pw/s1600/mft2018_display2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="360" data-original-width="640" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitZ6xtdI_lMhcO_B1OwW9fKd-yk-E7vVaqd7IGZryCiSsd5iR6sN0FF2Dr0T-jbSbgAhnZHBXCf0Kxv-MQNqcRKj_C5Woz-5CwpIz7YxmBPSR2QK5k2nl8Ah3U-VLqDpgxD57gTSKA7Pw/s320/mft2018_display2.jpg" width="320" /></a></div>
<br />
購入したのは以下のものです(7/15購入時点では¥1,499でした)。<br />
<br />
<iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="//rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=handicraftcreative-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=as_ss_li_til&asins=B07CVHCBFB&linkId=05c226e025c0a957baaa80bc4928790f" style="height: 240px; width: 120px;"></iframe>
ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-80011586652529571252018-07-28T23:56:00.002+09:002018-07-28T23:56:35.397+09:00メイカーズバザール大阪2018この前のメイカーズバザール大阪(2018/7/7&8)に出展してきました。展示はこんな感じ。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCA9kL0fPE5zKa03hpftA__0e6q-CPTPBPtulQwl6us2QzVKJ1zM7lhqzsEf4xeQgZVPpLD5TabHNOnWdbht2dP5muK0DzCOuv1kjaRyc5n9GibDoGqnoMwXJsemzgQZKLKSi2qX479bM/s1600/makers.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="540" data-original-width="960" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCA9kL0fPE5zKa03hpftA__0e6q-CPTPBPtulQwl6us2QzVKJ1zM7lhqzsEf4xeQgZVPpLD5TabHNOnWdbht2dP5muK0DzCOuv1kjaRyc5n9GibDoGqnoMwXJsemzgQZKLKSi2qX479bM/s320/makers.jpg" width="320" /></a></div>
次は東京のMaker Faire Tokyo(2018/8/4&5)に出展予定です。ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-71589745234078733222018-04-03T10:46:00.000+09:002018-04-03T10:46:46.131+09:00ラズベリーパイインストール方法比較<head>
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css"></link>
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css"></link>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushDiff.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushGroovy.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
</script>
</head>
ラズベリーパイにOSをインストールするには以下の2種類があります。<br />
<ol>
<li>NOOBSを使用してOSをインストールする方法</li>
<li>SDカードに直接OSイメージをライトする方法<br />※NOOBS Liteを使用する方法もありますが、ここでは除外します</li>
</ol>
1の方法は、SDカードにPCからデータをコピーするだけの簡単手順(どちらかというと初心者向け?)。2の方法は、PCから専用のソフトをSDカードに直接ライトします。どちらの方法でも最終的にラズベリーパイにOSをインストールすることには変わりません。じゃあ、最終的な違いはないんですかね?調べてみました。<br />
<br />
ラズベリーパイ3を使用して以下のバージョンでインストールします。<br />
<ol>
<li>NOOBS<br />Version : 2017-11-29</li>
<li>RASPBIAN STRETCH WITH DESKTOP<br />Version : 2017-11-29</li>
</ol>
インストールの方法は以下のページと同じ方法をとっています。<br />
<div>
<div>
<ol>
<li><a href="http://deviceplus.jp/hobby/raspberrypi_entry_056/">第56回「改めましてラズベリーパイの基本!(1) Raspberry Pi NOOBSインストール 2017年度版」</a></li>
<li><a href="http://deviceplus.jp/hobby/raspberrypi_entry_057/">第57回「改めましてラズベリーパイの基本!(2) Raspberry Pi イメージファイルのインストール&バックアップ 2017年度版」</a></li>
</ol>
</div>
<div>
<div>
使用したSDカードはトランセンドの8GB(クラス4)のものです。</div>
<div>
<br /></div>
<div>
<b>違いその①</b></div>
<div>
1の方法は初回起動時のインストールウィザードにおいて使用言語を選択できるので、ここで日本語を指定しておけばインストールされたOSの言語設定などが日本になる。2は自分で設定しなければならない。</div>
<div>
<br /></div>
<div>
<b>違いその②</b></div>
<div>
インストール後のSDカードの残り容量が違う。インストール直後のdfコマンド(ディスクの使用量表示)の結果が以下。<br />
<br />
1のインストール後のdfコマンド結果<br />
<pre class="brush:cpp;">ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
/dev/root 5737960 4269060 1154380 79% /
devtmpfs 468152 0 468152 0% /dev
tmpfs 472760 0 472760 0% /dev/shm
tmpfs 472760 12264 460496 3% /run
tmpfs 5120 4 5116 1% /run/lock
tmpfs 472760 0 472760 0% /sys/fs/cgroup
/dev/mmcblk0p6 66528 21328 45200 33% /boot
tmpfs 94552 0 94552 0% /run/user/1000
/dev/mmcblk0p5 30701 398 28010 2% /media/pi/SETTINGS
</pre>
<br />
2のインストール後のdfコマンド結果<br />
<pre class="brush:cpp;">Filesystem 1K-blocks Used Available Use% Mounted on
/dev/root 7483948 4264648 2852288 60% /
devtmpfs 470180 0 470180 0% /dev
tmpfs 474788 0 474788 0% /dev/shm
tmpfs 474788 6364 468424 2% /run
tmpfs 5120 4 5116 1% /run/lock
tmpfs 474788 0 474788 0% /sys/fs/cgroup
/dev/mmcblk0p1 41853 21327 20526 51% /boot
tmpfs 94956 0 94956 0% /run/user/1000</pre>
<br /></div>
<div>
<div>
何か全体の容量が1.5GBぐらい違う…。<br />
1の方法はNOOBSという機能やインストール対象のOS自体も含めてSDカードに入れていると思われるので容量を食うんでしょうね、たぶん。</div>
<div>
1の方法でSDカードにコピーしたファイル群の容量が1.47GBだったので、その容量分?</div>
<div>
あと、1の方法では/media/pi/SETTINGSっていうディレクトリも存在しています。</div>
<div>
NOOBSは"New Out of Box Software"の略でOSのインストールを管理しているらしいです、詳しく知りたい人は自分で検索だ!(飽きました)</div>
<div>
<br /></div>
<div>
結論としては、1.5GB程度なら最近のSDカードの容量なら無視できる範囲かと思われますので好きな方法でインストールしたらいいと思います。終わり。</div>
</div>
</div>
</div>
ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-8114786812112495302018-04-03T10:41:00.004+09:002018-04-03T10:41:55.525+09:00Raspberry Pi ZeroセットアップメモRaspberryPi Zeroのセットアップ手順のメモ。GUIではなくCUIで使用する場合のもの。ここで使用しているバージョンはRaspbian Jessie Liteの"2017-4-10"。<br />
<span style="color: red;">2018/4/2追記:Raspbian Stretch Liteの"2018-3-13"での適用を追加</span><br />
<ul>
<li><b>まずは購入から</b><br /><a href="https://www.adafruit.com/">adafruit</a>からRaspberryPi Zeroを購入。本体よりも周辺機器が高いという…(本体:$5、SDカードなどの周辺機器:$24.95)。送料はそれよりも高いという…(送料:$31.65)。ちなみに購入日は2016/11/26。</li>
<li><b>OSをダウンロードする</b><br />"Raspbian Jessie Lite"をダウンロード<br /><a href="https://www.raspberrypi.org/downloads/raspbian/">https://www.raspberrypi.org/downloads/raspbian/</a><br />※ここで使用しているバージョンは"2017-4-10"</li>
<li><b>WindowsPCを使用してSDカードにOSイメージを焼く</b><br />以下のページを参考に、"Win32DiskImager"というソフトをインストールして使用する(管理者権限での実行が必要)。<br />参考ページ:<a href="https://www.raspberrypi.org/documentation/installation/installing-images/windows.md">Installing operating system images using Windows - Raspberry Pi Documentation</a><br />参考ページ:<a href="http://www.mugbot.com/sd%E3%82%AB%E3%83%BC%E3%83%89%E3%81%AE%E3%82%B3%E3%83%94%E3%83%BC%E6%96%B9%E6%B3%95/">SDカードのコピー方法 | Making Mugbot マグボットの作り方</a></li>
<li><b>起動する</b><br />起動時にパーティションの拡張が自動で行われる模様。</li>
<li><b>ログイン</b><br />login:pi<br />pass:raspberry</li>
<li><b>最新版に更新</b><br />$ sudo apt-get update<br />これにはネットワークの接続が必要。USB有線LANアダプタを使用。</li>
<li><b>Vimのインストール</b><br />$ sudo apt-get install vim<br />これがなくては始まらない。</li>
<li><b>日本語化</b><br />ロケールを変更する。<br />$ sudo raspi-config<br />"Internationalisation Options"->"Change Locale"->"ja-JP.UTF-8 UTF-8"->"ja-JP.UTF-8 UTF-8"(デフォルト言語選択)<br />日本語フォントのインストール。<br />$ sudo apt-get install ttf-kochi-gothic xfonts-intl-japanese xfonts-intl-japanese-big xfonts-kaname<br />日本語入力メソッドのインストール。<br />$ sudo apt-get install uim uim-anthy<br />ターミナルのインストール。<br />$ sudo apt-get install jfbterm<br />"jfbterm"コマンドでターミナルが新規に起動して日本語が表示できる様になる。<br />ここら辺で再起動をしておく。<br />キーボードの配置を変更する。<br />$ sudo raspi-config<br />"Internationalisation Options"->"Change Keyboard Layout"->"標準105キー(国際)PC"->"その他"->"日本語"->"日本語"->"AltGrキーなし"->"コンポーズキーなし"<br />※日本語表示があるので"jfbterm"起動してからやったほうが良い<br />※再起動すると設定が反映される模様<br />日本語化の参考Webページ<br />参考ページ:<a href="http://uepon.hatenadiary.com/entry/2016/04/06/225259">RaspberryPiの日本語設定 - uepon日々の備忘録</a><br />参考ページ:<a href="http://start-now.link/100/archives/1930">» 解決!Raspberry Piの日本語が四角の文字化けになった時の初歩ミス。|コワーキングスペース管理人のブログ</a></li>
<li><b>オートログイン化</b><br />$ sudo raspi-config<br />"Boot Options"->"Desktop/CLI"->"Console Autologin"<br />リブートしてオートログインしていることを確認する。</li>
<li><b>SDカードのパーティション拡張</b><br />$ sudo raspi-config<br />"Expand Filesystem"を選択するとコンソールが少し出て終了<br />※おそらくこれをやらなくても良いと思われる。起動時にやっている?<br />※SDカードにOSイメージを書き込んだときにパーティションが最低限の領域しか確保できていないので、そのまま使用するとSDカード全体を使用しないので無駄。なのでパーティション拡張することでSDカード全体を使用できるということをやっている</li>
<li><b>日本語入力方法</b><br />"jfbterm"コマンドでターミナルを起動後、"uim-fep"コマンドでIMEが起動する。起動後は左下にそれっぽいものが表示される。日本語を入力するには日本語入力モードに切り替える必要があるが、不具合があり日本語入力モードに切り替えることができない模様。なので以下の手順で修正する。<br />$ sudo vi /usr/share/uim/generic-key-custom.scm<br />上記ファイルを以下のように変更する<br />(define-custom 'generic-on-key '("zenkaku-hankaku" "<Shift> ")<br />(define-custom 'generic-off-key '("zenkaku-hankaku" "<Shift> ")<br />↓<br />(define-custom 'generic-on-key '("zenkaku-hankaku" "<Control> ")<br />(define-custom 'generic-off-key '("zenkaku-hankaku" "<Control> ")<br />これでCtrl+Spaceで日本語入力モードに移行できる。モードオフもCtrl+Space。<br />参考ページ:<a href="http://blogs.yahoo.co.jp/watercolor310/54913291.html">RaspberryPiの個人的な覚書その6 日本語化(順序が違うか) ( その他コンピュータ ) - 四十路オヤジの雑記帳 - Yahoo!ブログ</a></li>
<li><b>USBメモリの自動マウント</b><br />自動マウントのパッケージをインストール。<br />$ sudo apt-get install usbmount<br />これでUSBを挿すと/media/usb0とかにマウントされる。ただし、このままでは日本語のファイル名が正しく表示できないので以下のファイルの内容を変更する必要がある。<br />$ sudo vim /etc/usbmount/usbmount.conf<br />FS_MOUNTOPTIONS=""<br />↓<br />FS_MOUNTOPTIONS="-fstype=vfat,gid=pi,dmask=0000,fmask=0111,codepage=932,iocharset=utf8"<br />参考ページ:<a href="http://mitszo.github.io/blog/2012/12/19/wifi-nas-with-raspberry-pi/">Raspberry PiでモバイルWiFi NAS - mitszo's Blog</a><br />ちなみにアンマウントは以下のコマンドで。<br />$ sudo umount /media/usb0<br /><span style="color: red;">2018/4/2追記<br />jessieの次のバージョンであるstretchでは上記の設定だけでは自動マウントされない。以下のファイルを追加で修正する必要がある。<br />$ sudo vi /lib/systemd/system/systemd-udevd.service<br />MountFlags=slave<br />↓<br />MountFlags=shared</span><br />参考ページ:<a href="http://www.n-mmra.net/audio/raspzero/raspzero.html">Raspberry Pi Zero Wのいたずら</a></li>
<li><b>シリアルポートの有効化</b><br />デフォルトではRaspberryPiZeroのUARTピンはログインコンソールとして設定されている。これは、GPIO14(TX)&GPIO15(RX)にシリアルで接続するとディスプレイがなくても作業ができるというやつ。普通にこのピンをUART通信で使用するためには以下のファイルの変更が必要。<br />$ sudo vim /boot/cmdline.txt<br />上記ファイルから"console=serial0,115200"を削除する。次にサービスを停止/無効化する。<br />$ sudo systemctl stop serial-getty@ttyAMA0.service<br />$ sudo systemctl disable serial-getty@ttyAMA0.service<br />参考ページは以下、ほぼそのままの手順。<br />参考ページ:<a href="http://blue-black.ink/?page_id=2525">第13回: GPIOを汎用UARTに設定する – Blue-black.ink</a></li>
<li><b>WiringPiインストール</b><br />$ sudo apt-get install wiringpi<br />Raspbian Jessie Liteには含まれてない模様(確かLiteじゃないやつは含まれてたはず)。"gpio readall"コマンドとか実行できたらOK。</li>
<li><b>起動高速化</b><br />起動時にDHCPでIPを取得する時間を短縮する。<br />$ sudo vi /etc/systemd/system/dhcpcd.service.d/wait.conf<br />ExecStart=/sbin/dhcpcd -q -w<br />↓(タイムアウト設定を追加)<br />ExecStart=/sbin/dhcpcd -q -w -t 5<br />参考ページ:<a href="http://nw-electric.way-nifty.com/blog/2017/04/raspberry-pi-ze.html">Raspberry Pi Zeroを10秒以内で高速起動する最も簡単な方法: new_western_elec</a></li>
</ul>
このあたりまで実施すれば一通りの環境が完成。gccなどはすでに入っている。これ以降は備考レベルの内容です。<br />
<ul>
<li><b>無線LAN設定</b><br />使用アダプタ:WLI-UC-GNME<br />参考ページ:<a href="http://mitszo.github.io/blog/2012/12/19/wifi-nas-with-raspberry-pi/">Raspberry PiでモバイルWiFi NAS - mitszo's Blog</a><br />$ sudo iwlist wlan0 scan | grep ESSID<br />"sudo /etc/wpa_supplicant/wpa_supplicant.conf"このファイルに以下を追加<br />network={<br /> ssid="****"<br /> psk="****"<br />}</li>
<li><b>起動トラブル対策</b><br />起動時にプログラムを自動実行しようとしたときに"/etc/rc.local"にコマンドを書いておく方法がある(編集にはルート権限が必要)。しかし、変なコマンドを書いてしまいで無限ループに入った場合、起動してもキーボードからの入力が受け付けられずどうしようもなくなる場合がある。<br />参考ページ:<a href="http://buturi.heteml.jp/student/2015/okada/post-293.html">ラズベリーパイでrc.localに記述をし,エラーまたはループで起動できなくなった場合の対処法 – 岡田裕樹の研究室</a><br />その場合はmicroSDをラズベリーパイ以外のPCで開き、中にある"cmdline.txt"を以下のように編集する<br />dwc_otg.lpm_enable=0 console=ttyAMA0,115200<br />↓<br />dwc_otg.lpm_enable=0 init=/bin/sh console=ttyAMA0,115200<br />こうすると起動時にシェルスクリプトが起動するようになる。<br />$ mount -o rw,remount /<br />$ vim /etc/rc.local<br />これで、"rc.local"を編集できる。終了の仕方はよくわからないので強制電源OFF。最後にmicroSDカードの"cmdline.txt"をもとに戻せば解決。</li>
</ul>
<br />
<br />ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-54196534390366476552017-10-28T13:30:00.000+09:002017-10-28T13:30:08.953+09:00Maker Faire Tokyo 2017に出展しました遅くなりましたが、Maker Faire Tokyo 2017(8/5&6)に出展してきました。出展物は多数決マリオということで複数人でプレイできるスーパーマリオです。展示前は果たして面白いのだろうか?と自問自答していましたが、思っていたより好評だと感じました。<br />
<br />
以下のように展示していました。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI2vgtwa9FgmYTeNymVlVL7MQre17rUj5FvXsPYlCacTqW56nosaQMr8rc7Ifj1KY0iqH-sh37S2EaPUzXDbgz2ufYYha_165iXGoeVGHlJ-nohDNvpu6nCDa7-PG7MBImkdLupplVRwU/s1600/MFT2017.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="480" data-original-width="640" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI2vgtwa9FgmYTeNymVlVL7MQre17rUj5FvXsPYlCacTqW56nosaQMr8rc7Ifj1KY0iqH-sh37S2EaPUzXDbgz2ufYYha_165iXGoeVGHlJ-nohDNvpu6nCDa7-PG7MBImkdLupplVRwU/s320/MFT2017.JPG" width="320" /></a></div>
<br />
お隣さんは全自動ぷよぷよプレイヤーの<a href="https://twitter.com/mayah_puyo?lang=ja">mayahさん</a>とMRファミコンの<a href="https://twitter.com/koalab_apps">KOALABさん</a>でした。<br />
全自動ぷよぷよプレイヤーは安定感抜群でした。実機を使用しているということで実動作でのいわゆるラグに苦労しているとのこと。「全自動シレンで同じ現象あるある」と共感。実は行動を決定するAIを作ること自体はそんなに難しくなかったりするけど、それを実機に適用するところは泥臭い作業が必要であることが多かったりします。そして、人間はそんなことを認識するまでもなくやってのけているので、このあたりの苦労が伝わりにくかったりもします。<br />
MRファミコンは終わり際に体験させていただいたのですが、ただファミコンをプレイさせているのではなくうまくパッケージ化していてうまいと思いました。どうパッケージ化していたかは体験して確認してみてね(適当)。確かに、ただプレイさせるだけだと終わるタイミングがないですからね。壁が必要だということで段ボールのパネルを使用していました。大変そうでした。<br />
<br />
今回の展示についてまとめてみます。<br />
<br />
<ul>
<li>よかった点<br />誰もが知っている/プレイできるコンテンツである<br /> →親子連れで来てもみんなでプレイできた<br />コンセプトがわかりやすかった<br /> →説明も最小限で理解してもらえる</li>
<li>悪かった点<br />一人ではプレイできない<br /> →子供が無理やり2つのコントローラでプレイすること多し<br /> →これは仕方がないかも</li>
<li>改良点<br />ボタン入力の可視化ができると良いかも<br /> →現在誰がどのボタンを押しているかわかる</li>
</ul>
<br />
今回から東7/8ホールになって、入口からの距離が遠くなりましたが、展示スペースが広くなりました。1日目は空調がかなり効いていて、2日目は空調控えめでした。飛行物体の展示があったので影響軽減のためかもしれません。もしくは寒いとのクレームがあったのかもしれません。はてさて来年はどうなるのでしょうね。このまま規模を拡大していくのかどうするのか。そして当研究所は来年も出展できるのかどうか…。<br />
<br />
個人的に素晴らしいと思ったのが、超小型飛行体研究所さんの展示タイトルである「空をみろ! ねこだ、やわらかい戦闘機だ、飛んでるぞ、ゆっくりだ」です。特に"ゆっくりだ"のセンスが素晴らしいと思いました。所長がこの展示のタイトルを考えたとして"ゆっくりだ"は絶対出てきません。ちなみに超小型飛行体研究所さんの展示物は"ゆっくりだ"と言えるぐらい優雅に飛行していました。<br />
<br />
あ、アンケート回答するの忘れた…。<br />
<div>
<br /></div>
ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-3873607528989788422017-10-23T00:03:00.000+09:002017-10-23T01:33:11.127+09:00スプラトゥーン2におけるオートトリガシステムの紹介新作です。<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/ZZTd9_v1qw8" width="560"></iframe><br />
<br />
今回からニコニコ動画だけではなく、youtubeにもアップロードしてみます。ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-69755103855698287592017-06-11T23:20:00.000+09:002017-06-11T23:20:00.169+09:00Nintendo SwitchのJoy-Con解析<div>
<span>海外の方でNintendo Switchのコントローラの通信方法について解析が進んでいるようです。</span></div>
<div>
<ul>
<li>Nintendo SwitchのJoyConのhackの情報が海外で出ている<br /><a href="http://kako.com/blog/?p=24599">http://kako.com/blog/?p=24599</a></li>
<li>dekuNukem/Nintendo_Switch_Reverse_Engineering<br /><a href="https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering">https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering</a></li>
</ul>
</div>
<div>
Joy-ConはSwitchの画面の両端に接続して使用することもできますし、取り外して使用することもできます。所長はてっきりJoy-Conと本体の通信にはBluetoothのみを使用していると思っていたのですが、画面と接続しているときには接続部の端子接続により有線による通信を行っているようです。</div>
<div>
<span><br /></span></div>
<div>
<span>しかも、解析の結果、有線接続ではどうやらシリアル通信を行っているらしいと。</span>注目すべきはその速度で、1000000bpsと3125000pbsを使用しているようだとのこと。</div>
<div>
<span><br /></span></div>
<div>
<span>ほう…。</span></div>
<div>
<span><br /></span></div>
<div>
<span>なかなか面白い情報です。</span>シリアル通信とはいえ、速度が1Mbps越えでは通常のPCやマイコンでは対応できないでしょうし。</div>
<br />
<div>
<span>まあ、FPGA使えば良いのですがね、うしし。</span></div>
ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-43210362860134548792017-04-04T14:30:00.005+09:002017-04-04T14:46:33.703+09:00多数決マリオ新作です。今年はこれでいこう。<br />
<br />
<script src="http://ext.nicovideo.jp/thumb_watch/sm30963020?w=490&h=307" type="text/javascript"></script><noscript><a href="http://www.nicovideo.jp/watch/sm30963020">【ニコニコ動画】多数決マリオ</a></noscript>
<br />
ラズベリーパイゼロとPICを使用しています。ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-16981568672650625732017-04-04T14:30:00.004+09:002017-04-04T14:30:50.294+09:00NES Classic Editionのコントローラの通信内容解析⑥では、ダンプしてわかった「NES Classic Edition」のコントローラの通信内容をまとめます。以下は起動してから本体側から見た動作になります。<br />
<ul>
<li>レジスタ"0xF0"にデータ"0x55"をライト</li>
<li>レジスタ"0xFB"にデータ"0x00"をライト<br />この2つの手順が暗号化OFF設定らしい。</li>
<li>レジスタ"0xFE"にデータ"0x03"をライト<br />この設定はよくわからない。デバイス識別子を書き換えている?</li>
<li>レジスタ"0xFA"から6Byteのデータ(デバイス識別子)をリード<br />デフォルトコントローラなら"0x01 0x00 0xA4 0x20 0x03 0x01"が読み出される。これ以外の識別子が読み出されたときの動作は未調査。たぶん、動かないのではないかと思われる。そう考えると、アドレス"0xFE"に"0x03"をライトしたのはクラシックコントローラなどを使用してもデバイス識別子を似通ったものにするため?</li>
<li>レジスタ"0x00"から21Byteをリード<br />この中にボタン情報が格納されている。該当箇所はアドレス"0x06-0x07"の2Byteっぽい。何故に21Byte?他のデータは何?など疑問は残るが深く考えずスルーすることも大人の知恵だったりする。<br />ちなみに後日解析した結果、この21Byteのボタン情報以外のデータ部分にオール"0x00"を設定するとうまく動かないという現象が発生したので以下の値を使うのがよろしい。<br />0x83 0x85 0x85 0x86 0x00 0x00 0xXX 0xXX 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00<br />※XXはボタン情報の格納場所<br />※オール"0x00"にすると"NES Classic Edition"の起動時のゲーム選択画面では操作できるが、ゲーム選択後に操作不可能になるという謎の現象に陥る</li>
<li>以降、レジスタ"0x00"からの21Byteリードが繰り返される<br />リード間隔は約6.6ms。ということは秒間150回リード?120回でも180回でもなく、なんか中途半端な気が…。</li>
</ul>
ボタンの状態は2Byteの負論理で表される。負論理とはつまり、押していないときは"1"になる。<br />
<div>
<ul>
<li>何も押していないときは"0xFFFF"<br />上でも書いているが、該当データはレジスタ"0x06-0x07"の場所のデータ。</li>
<li>各ボタンの該当位置は以下の通り<br />Right Down X Select X Start X X X B X A X X Left Up<br />例えば、右キーを押している場合は"0x7FFF"、Bボタンを押している場合は"0xFFBF"、右キーとBボタンを同時に押している場合は"0x7FBF"となる。</li>
</ul>
以上で、「NES Classic Edition」のコントローラの通信内容解析を終わります。</div>
<div>
てっきり暗号化していると思いこんでいたのでちょっとびっくりしました。この動作を真似すれば「NES Classic Edition」のコントローラを作成することができます。</div>
ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-48751327766934613352017-04-04T14:29:00.000+09:002017-04-04T14:34:15.674+09:00NES Classic Editionのコントローラの通信内容解析⑤ここで、解析されているクラシックコントローラの通信内容についてまとめておきます。<br />
<ul>
<li>コントローラは内部に256Byte(アドレス8bit)のレジスタを持っている</li>
<li>コントローラにはI2Cからレジスタにアクセスすることで通信を行う</li>
</ul>
I2Cのアクセスに関しては以下のようなフォーマットです。<br />
<ul>
<li>ライト動作<br /><b>0xA4 "レジスタアドレス" "データ0" "データ1" …</b><br />"0xA4"はデバイスアドレス"0x52"+ ライトビット"0"です。この次にライトするレジスタアドレスを指定する。次にライトするデータを指定、データが連続したときにはレジスタアドレスをインクリメントしながらライトしていきます。</li>
<li>リード動作<br /><b>0xA4 "レジスタアドレス"<br />0xA5 "データ0" "データ1" …</b><br />最初にライト動作でリードしたいレジスタアドレスを指定して一旦通信を終わります。次にリード動作をするのですが、最初の"0xA5"はデバイスアドレス"0x52"+ リードビット"1"です。次にコントローラ側からリード対象のレジスタアドレスのデータを読み出すのですが、ライト動作と同じく、データが連続したときはレジスタアドレスをインクリメントしながらリードされます。連続リードはリードしている側のNACKによって止められます。</li>
</ul>
主要なレジスタの機能について以下にまとめます。<br />
<ul>
<li>0xFA-0xFF(6Byte)<br />デバイス識別子。自分がどのデバイスかを格納している。例えば、"0100A4200101"ならクラシックコントローラPROというような感じ。</li>
<li>0x20-0x2F(16Byte)<br />キャリブレーションデータらしい、何のかは知らない。</li>
<li>0x30-0x3F(16Byte)<br />0x20-0x2Fのデータのコピーらしい、なぜコピーしているかは知らない。</li>
<li>0xF0(1Byte)<br />暗号化のON/OFFに関係しているレジスタ。0xAAを書き込むと暗号化ONで、0x55を書き込むと暗号化OFFらしい。</li>
<li>0x00-0x05(6Byte)<br />コントローラのボタン状態。何のボタンを押しているか、スティックの状態がどうかを格納している。</li>
<li>0x06-0x07(2Byte)<br />「NES Classic Edition」のコントローラのボタン状態が格納されているっぽい。暗号化OFFのときに有効?</li>
</ul>
以下のサイトを参考にしています。<br />
<a href="http://wiibrew.org/wiki/Wiimote/Extension_Controllers">Wiimote/Extension Controllers - WiiBrew</a><br />
<a href="http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Classic_Controller">Wiimote/Extension Controllers/Classic Controller - WiiBrew</a><br />
-> WiiBrewというサイトに詳しいことがまとまっています<br />
<a href="https://archive.is/J3D4x">WiiLi.org Wii Linux - Wiimote/Extension Controllers/Classic Controller</a><br />
-> WiiLiというサイトもあったようですが、今はなくなっているようなのでアーカイブサイトのリンクです<br />
<br />
次 → <a href="http://hardwareandsoonlab.blogspot.jp/2017/04/nes-classic-edition_80.html">NES Classic Editionのコントローラの通信内容解析⑥</a>ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-31295828025385773442017-04-04T14:28:00.001+09:002017-04-04T14:33:48.021+09:00NES Classic Editionのコントローラの通信内容解析④では、実際の通信内容を見ていきます。まずはI2Cのパラメータについて。<br />
<ul>
<li>SDA&SCLは3.3Vでプルアップ</li>
<li>本体側がマスタ、コントローラ側がスレーブ</li>
<li>コントローラのスレーブアドレスは"0x52"</li>
<li>通信速度は400kHz</li>
</ul>
また、DeviceDetectはHighで接続されているとみなされるようです。<br />
<ul>
<li>分解動画などではコントローラ部の基盤部分までDeviceDetectが来ていないので、コネクタ部分でVCCに接続されているような気がします。<br /><a href="http://gadgety.hatenablog.com/entry/nintendo-classic-mini_jp03">【朗報】ニンテンドークラシックミニのコントローラー問題を解決、無線化も簡単にできることが判明! - がじぇぶ GADGETY BLOG</a></li>
</ul>
起動時の通信内容をロジアナでプローブしたものが以下です。※"A2"がDeviceDetect、以下の画像はリセット時のものなのでHighのままです<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4_7dpIJuIK0mzFP5bmXykpRsN713HHIls3QY_pwRVy-mIPyNWOc-Jd0ZTmRzKOcxPNlnQ1KqIGRv0SFUhaCP_z1Ubw5Zt0t-ra0vm62nvUpMf74rjgvCwCdPcnUwodXAkjvio9ndiFaQ/s1600/ClassicController_setup_0.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4_7dpIJuIK0mzFP5bmXykpRsN713HHIls3QY_pwRVy-mIPyNWOc-Jd0ZTmRzKOcxPNlnQ1KqIGRv0SFUhaCP_z1Ubw5Zt0t-ra0vm62nvUpMf74rjgvCwCdPcnUwodXAkjvio9ndiFaQ/s400/ClassicController_setup_0.gif" width="400" /></a></div>
<br />
通信内容を文字に起こしたものが以下です。<br />
<ol>
<li>DeviceDetectが"Low"から"High"に変化</li>
<li>ライト(マスター → スレーブ)<br />0xA4 0xF0 0x55</li>
<li>ライト(マスター → スレーブ)<br />0xA4 0xFB 0x00</li>
<li>ライト(マスター → スレーブ)<br />0xA4 0xFE 0x03</li>
<li>ライト(マスター → スレーブ)<br />0xA4 0xFA</li>
<li>リード(スレーブ → マスター)<br />0xA5 0x01 0x00 0xA4 0x20 0x03 0x01</li>
<li>ライト(マスター → スレーブ)<br />0xA4 0x00</li>
<li>リード(スレーブ → マスター)<br />0xA5 0x83 0x85 0x85 0x86 0x00 0x00 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00</li>
<li>4.6ms程度待機</li>
<li>ライト(マスター → スレーブ)<br />0xA4 0x00</li>
<li>リード(スレーブ → マスター)<br />0xA5 0x83 0x85 0x85 0x86 0x00 0x00 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00</li>
<li>4.8ms程度待機</li>
<li>ライト(マスター → スレーブ)<br />0xA4 0x00</li>
<li>リード(スレーブ → マスター)<br />0xA5 0x83 0x85 0x85 0x86 0x00 0x00 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00</li>
<li>4.8ms程度待機</li>
<li>…(以下ループ)</li>
</ol>
あれ?暗号化されてなくね?どういうこと?<br />
<br />
次 → <a href="http://hardwareandsoonlab.blogspot.jp/2017/04/nes-classic-edition_96.html">NES Classic Editionのコントローラの通信内容解析⑤</a>ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-47842907728620896212017-04-04T14:28:00.000+09:002017-04-04T14:42:25.235+09:00NES Classic Editionのコントローラの通信内容解析③ようし、I2Cを使用していることはわかった。信号線の配置もわかった。これでコントローラを自由自在に使いこなせるぞ!え?暗号化?なんですかそれ?<br />
<br />
ということで、コントローラと本体ではI2Cで通信を行っているのですが、その通信内容は暗号化されているようです。<br />
例えば、以下のページではI2Cの暗号化された通信内容をダンプしています。<br />
<a href="http://www.fumi2kick.com/komekame/archives/221">コメを噛め» Blog Archive » Wii クラシックコントローラとの通信</a><br />
<br />
とは言え、所詮はハードウェアで実装されている暗号化なのですでに解析されているようです。<br />
<br />
<a href="http://www.derkeiler.com/Newsgroups/sci.crypt/2008-11/msg00110.html">Reverse engineering the Wiimote's encryption</a><br />
上記が暗号解析成功報告みたいです(2008年)。"weak"という言葉があるので、暗号強度的には弱いのでしょうね、ハードウェア固定ですし。<br />
<br />
暗号化のプロトコルについて以下に箇条書します。<br />
<ol>
<li>暗号キーは本体側からコントローラ側に送付する<br />起動時に本体側から16Byteの暗号キーをコントローラ側に送信する。暗号キーはランダムで生成されるようです。</li>
<li>コントローラ側では暗号キーを基に暗号テーブルを作成する<br />"S-Box"という共通鍵暗号化技術を使っているようです(よく知らない)。</li>
<li>コントローラ側から本体側に情報を送るときには暗号テーブルで暗号化してデータを送付する</li>
</ol>
ここからは電子工作などでクラシックコントローラやヌンチャクコントローラを使用する場合の話です。<br />
<ul>
<li>本体側を作る場合<br />クラシックコントローラなどを機器のコントローラとして使用する場合は、暗号キーを固定値にすることで容易に復号ができます。前述の通り、暗号化に使用する暗号テーブルは起動時に送付する暗号キーによって生成されるので、逆説的に暗号キーを固定すると暗号テーブルも固定されます。すると実質的に復号機能はいらなくなります。<br />実際には暗号キーをすべて"0x00"にして使用するということをよくやるみたいです。</li>
<li>コントローラ側を作る場合<br />コントローラ側の機器を作成する場合は、暗号キーから暗号テーブルを作成する機能と暗号化機能は必須です。さらに本体側がI2Cのマスターになるので作成する機器はスレーブとして機能する必要があります。<br />もっとも、所長以外にコントローラ側を作りたい人なんているんですかね?</li>
</ul>
暗号化するためのの実コードは探せば色々なところにありますが、出所は一緒なようでほとんど同じ実装のようです。<br />
<br />
実コード掲載のされているページの例<br />
<a href="https://github.com/bootsector/wii-retropad-adapter/tree/master/src/wii-retropad-adapter">wii-retropad-adapter/src/wii-retropad-adapter at master · bootsector/wii-retropad-adapter · GitHub</a><br />
<br />
次 → <a href="http://hardwareandsoonlab.blogspot.jp/2017/04/nes-classic-edition_33.html">NES Classic Editionのコントローラの通信内容解析④</a>ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.comtag:blogger.com,1999:blog-2880384340258251266.post-25893787584754976152017-04-04T14:27:00.001+09:002017-04-04T14:32:44.531+09:00NES Classic Editionのコントローラの通信内容解析②では、「NES Classic Edition」のコントローラの通信内容について見ていきます。<br />
<br />
まず、通信方法なのですがI2Cが使用されています。ですので、スーパーファミコンなどと比べてだいぶ扱い易くなっています。<br />
<br />
参考までに以前調査したものです。<br />
<a href="https://sites.google.com/site/hardware007laboratory/home/denshi-kousaku/sfc_cont">スーパーファミコンコントローラの解析 - ハードウェアとか研究所</a><br />
<br />
スーパーファミコンはほぼ独自規格のようなものだったのですが、I2Cであれば既存のマイコンなどでも簡単に扱えます。<br />
<br />
コネクタについては以下のページが参考になります。<br />
<a href="http://wiibrew.org/wiki/Wiimote/Extension_Controllers">Wiimote/Extension Controllers - WiiBrew</a><br />
コネクタには6端子ありますが、1端子が未使用なので使用しているのは実際には5端子です<br />
<br />
信号線についてはこちら。<br />
<a href="http://japanese.engadget.com/2016/11/21/add-wii-connector/">「ミニファミコン」で大きなコントローラーも使えるように改造してみました(ウェブ情報実験室) - Engadget 日本版</a><br />
上記のページではファミコンクラッシクミニを改造して、クラシックコントローラを接続しています(デフォルトのコントローラが小さいので)。つまり、Wiiなどで使用できるクラシックコントローラで使用されている通信方法とファミコンクラシックミニのコントローラの通信方法は同じだということみたいです(よくよく考えれば当然か)。さらに「NES Classic Edition」のコントローラも同じだということは想像するに易いです。<br />
<iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="https://rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=handicraftcreative-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=as_ss_li_til&asins=B01M1VMFUA&linkId=9922f611ff46b5f6b7d4c11ae7813fca" style="height: 240px; width: 120px;"></iframe><br />
<br />
今回使用した延長ケーブルの中の線には色がついているのですが、参考にしたページと同じでした。以下に載せておきます。<br />
<ul>
<li>黄緑色<br />→ GND</li>
<li>ピンク色<br />→ VCC(電源)3.3V</li>
<li>水色<br />→ SDA(I2Cデータライン)</li>
<li>白色<br />→ SCL(I2Cクロックライン)</li>
<li>黒色<br />→ デバイス検出(コントローラが接続されているかどうかの検出)</li>
</ul>
次 → <a href="http://hardwareandsoonlab.blogspot.jp/2017/04/nes-classic-edition_82.html">NES Classic Editionのコントローラの通信内容解析③</a>ハードウェアとか研究所 所長http://www.blogger.com/profile/15466829660724065481noreply@blogger.com