Max7日記 (5)
長嶋 洋一
2016年12月5日(月)
12月に入って最初の週末は、デザイン学科新入生4人の「第43期・虎の穴」とともに大垣に遠征して、今日の午前に朝帰りしてきたところである。 そのOMMF2016の模様は、ようやくWebに上げたところで、 こちらのページ にある。 写真の他に撮った動画としては、以下の4本だけとなった。
team「さば」(メディア造形3回生、制作は2回生の後期)の動態保存インスタレーション作品「せんべい屋さん」は、学外での展示発表としては「お披露目」となった。 さっそく、 このページ の「せんべい屋さん」のところに「OMMF2016」という展示記録を加筆して、さらにYouTubeのリンクを追加した。
「第43期・虎の穴」のデザイン学科新入生4人は、期間的には約3週間、実質的には3-4日の作業で、アニメーション動画がお客さんの近接センシングで鈴の音とともに静止画(写真)に切り替わり、楓の鉢植えの紅葉に仕込まれた「赤・黄・白」LED群の点滅・・・というまずまず王道のインタラクションを実現するインスタレーション作品を展示発表した。 まだタイトルとかが未確定で、来年のMDW2017での改訂展示に向けて、さらに発展しそうである。
仕掛けとしては、来場者の近接センサはSHARPの赤外線距離センサの大きなものを取り付けた教材用Arduino基板からUSBシリアルで受けて、24個のLED点灯制御は このページ の作品「誰かを待つ街」(望月真美子)のために「SUAC board」(Propeller搭載)で作ったシステムをそのまま活用して、Max7からはMIDIで制御している。 1時間程度で作ったこの作品のMaxパッチは以下である。
土曜日が12時〜18時、日曜日が10時〜18時、という長時間の展示であったが、1日目にその裏で進めていたMaxプログラミングでようやく突破口を見出して、2日目の朝にホテルを出発するまでの1時間で遂に出来てしまったのが、ゼミの馬ブンさんの卒業制作のために必要となる、「leap motionから画面内の2点を両手でそれぞれ動かす」というパッチである。 パッチそのものの解説とお披露目は明後日のゼミになるが、とりあえず記録してみた動画が これ である。
2016年12月6日(火)
大垣遠征の疲れが取れない帰着翌日、午前中は入試に関する重要なお仕事(マル秘)をこなして、後はこれまで懸案だった2つの単純作業を進めた。 その一つは「App StoreのIDとパスワードがパソコンごとにバラバラでUpdate出来ない」というもので、出張先でパスワードを忘れては改訂するので、それぞれのパソコンに残っていた情報を全て統一した。 ただしIDは2人分ある(^_^;)。
もう一つは同様にバラバラとなっていた「YouTube(Google)の」パスワードで、ようやくこれで出張先からもYouTubeがアップ出来るかかもしれない可能性を確保した。 ただしホテルによってはWiFi/LANはFTP禁止なので、その場合には無理である。
そして午後になってようやく、再来週のBFセミナーに向けて、新筋電センサ基板「VPP-SUAC」の4チャンネル動作確認とWiFiのスピードアップなどの作業を上のように進めた。 まだどこかにパグが残っているものの、NucleoF401REのプログラミングも久しぶりに思い出した。
そしてついでに、手元にあった多数のXBeeを全て「115200」にして、ペアとなるように上のWindows XPのツールで書き込みをして、9ペアのXBeeを手元に完備した。 単純作業ばかりの一日だったが、たまにはこういう日も必要である。
2016年12月7日(水)
前日には、「メディア数理造形演習」の各チームの課題制作に関連した部品とか、追加購入したleap motionなどの納品もあったが、これに刺激されてか、2日連続爆睡による出張体力回復のためか、あるいは某カラオフの予定が立ってきたためか、久しぶりにプチ物欲が沸き上がり(^_^;)、生協でMac miniを注文して、さらに業者に1920×1200ディスプレイモニタ2台の見積もりを依頼した。 久しぶりにお仕事Macの環境を一新するためだが、この遠因としては、何故かお仕事Mac miniで最近「Time Machine」のバックアップ途中で必ず失敗するようになった、つまりHDDのシステム領域の一部が「ヤバくなってきた」という暗雲があるのだ。 こういう「フトした不安感」に素早く反応するのが、経験的には致命的ダメージを回避する唯一の方法である。
そして2限〜3限には、メディア造形学科3回生の「総合演習I」の中間報告学科会議があり、その後の4限には このように ゼミがあった。 中間審査もOKということで、いよいよゼミもそれぞれの作業に集中してきた。 僕は以下のようにVPP-SUAC基板のNucleoF401REとMax7パッチの両方のデバッグのために、馬ブンちゃんの手助けで4チャンネル計12枚の筋電電極シートを貼って、放課後まで頑張った。
そして遂に、CQ出版「インターフェース」誌の記事として載せたNucleoF401REプログラムにバグがあった事まで判明しつつ(^_^;)、以下のように4チャンネル筋電の奇麗なデータの取得と、動作パラメータをホストMax7から送る115200システムがほぼ完成した。 NucleoF401REのソースプログラムは決してスマートではないものの、まさに「Simple is Best.」となった。
実は上のMacBookAirから持って来たスクリーンショット画像を上げた直後に、3チャンネル目と4チャンネル目の波形が同一であるバグに気付いた(^_^;)のだが、スグにこれはMax7のXBeeデータを解釈して4系統の波形データを出力するサブパッチの中のバグである、と見抜いて解決したのだが、その判断に2秒ぐらいしかかからなかった。 まさに「NucleoF401RE+Max7」プログラミング・モードに頭が切り替わってきた証拠であり、この勢いのあるうちにVPP-SUAC基板の実験を進めよ、という「天の声」なのだ。main.cpp #include "mbed.h" #include "sub.hpp" #include "notch.hpp" int main(){ common_setup(); xbee.baud(115200); xbee.attach(&rx_fifoset, xbee.RxIrq); timer_setup.attach_us(&timer_interrupt, 5); // 5usec while(1){ tx_fifo_check(); if(timer_value[1] > 19){ // 0.1msec sampling timer_value[1] = 0; float data1 = (float)gain * (analog_value0.read() - 0.5f); // A/D in (1) data1 = notch_filter1(data1); // always notch-filter ON if (data1 < 0) data1 = -data1; // always detection ON if(max_count != 0) data1 = move_mean_calc1(data1); if(timer_value[5] > 7999){ // 40msec timer_value[5] = 0; tx_message((uint16_t)((data1 + 1.0f) * 2047)<<4); } } if(timer_value[2] > 19){ // 0.1msec sampling timer_value[2] = 0; float data2 = (float)gain * (analog_value1.read() - 0.5f); // A/D in (2) data2 = notch_filter2(data2); // always notch-filter ON if (data2 < 0) data2 = -data2; // always detection ON if(max_count != 0) data2 = move_mean_calc2(data2); if(timer_value[6] > 7999){ // 40msec timer_value[6] = 0; tx_message(0x010000 + (uint16_t)((data2 + 1.0f) * 2047)<<4); } } if(timer_value[3] > 19){ // 0.1msec sampling timer_value[3] = 0; float data3 = (float)gain * (analog_value2.read() - 0.5f); // A/D in (3) data3 = notch_filter3(data3); // always notch-filter ON if (data3 < 0) data3 = -data3; // always detection ON if(max_count != 0) data3 = move_mean_calc3(data3); if(timer_value[7] > 7999){ // 40msec timer_value[7] = 0; tx_message(0x020000 + (uint16_t)((data3 + 1.0f) * 2047)<<4); } } if(timer_value[4] > 19){ // 0.1msec sampling timer_value[4] = 0; float data4 = (float)gain * (analog_value3.read() - 0.5f); // A/D in (4) data4 = notch_filter4(data4); // always notch-filter ON if (data4 < 0) data4 = -data4; // always detection ON if(max_count != 0) data4 = move_mean_calc4(data4); if(timer_value[8] > 7999){ // 40msec timer_value[8] = 0; tx_message(0x030000 + (uint16_t)((data4 + 1.0f) * 2047)<<4); } } if(timer_value[0] > 199999){ // 1000msec timer_value[0] = 0; myled = !myled; } if(rx_fifo_check() == 1){ int sum = 0; for (int i=0; i<6; i++) sum += conv_hex(raw_data[i])<<(4*(5-i)); tx_message(sum); // Echo Back if(sum>>16 == 0x80){ switch((sum & 0xff00)>>8){ case 0x00: break; case 0x01: // +256 gain = sum & 0x0f; break; case 0x02: // +512 max_count = sum & 0x7f; if (max_count>100) max_count = 100; sum_clear(); break; case 0x03: // 768 coef_set(sum & 0x3f); break; } } } } } sub.cpp unsigned char rxFIFO[256], txFIFO[256], raw_data[6]; unsigned char rx_top, rx_end, tx_top, tx_end, phase; float mean_sum1, mean_sum2, ad_data1[101], ad_data2[101]; float mean_sum3, mean_sum4, ad_data3[101], ad_data4[101]; int timer_value[10], gain, ad_pointer1, ad_pointer2, ad_pointer3, ad_pointer4; int max_count; float a1, a2, b1, c0, y1[3], y2[3], y3[3], y4[3]; float data1, data2, data3, data4; const float _60Hz_a1 = 1.936768, _60Hz_a2 = -0.939101, _60Hz_b1 = -1.998579, _60Hz_c0 = 1.642174; const float _50Hz_a1 = 1.937188, _50Hz_a2 = -0.939101, _50Hz_b1 = -1.999013, _50Hz_c0 = 1.938304; RawSerial xbee(PA_2, PA_3); Ticker timer_setup; AnalogIn analog_value0(A0); AnalogIn analog_value1(A1); AnalogIn analog_value2(A2); AnalogIn analog_value3(A3); DigitalOut myled(LED1); void sum_clear(){ int i; for (i=0; i<101; i++) ad_data1[i] = ad_data2[i] = ad_data3[i] = ad_data4[i] = 0; ad_pointer1 = ad_pointer2 = mean_sum1 = mean_sum2 = 0; ad_pointer3 = ad_pointer4 = mean_sum3 = mean_sum4 = 0; } void coef_set(int herz){ if(herz < 55){ a1 = _50Hz_a1; a2 = _50Hz_a2; b1 = _50Hz_b1; c0 = _50Hz_c0; } else{ a1 = _60Hz_a1; a2 = _60Hz_a2; b1 = _60Hz_b1; c0 = _60Hz_c0; } for (int i=0; i<3; i++) y1[i] = y2[i] = y3[i] = y4[i] = 0; } void common_setup(){ rx_top = rx_end = tx_top = tx_end = phase = 0; max_count = 10; gain = 4; sum_clear(); coef_set(60); timer_value[1] = 0; timer_value[2] = 5; timer_value[3] = 10; timer_value[4] = 15; timer_value[5] = 0; timer_value[6] = 700; timer_value[7] = 1400; timer_value[8] = 2100; } void timer_interrupt(){ int i; for (i=0; i<10; i++) timer_value[i]++; } void tx_fifo_check(){ if(xbee.writeable() == 1){ if(tx_top != tx_end){ xbee.putc(txFIFO[tx_end]); ++tx_end &= 255; } } } int rx_fifo_check(){ unsigned char data; if(rx_top != rx_end){ data = rxFIFO[rx_end]; ++rx_end &= 255; if (data < 33){ phase = 0; return(1); } raw_data[phase] = data; if(++phase > 5) phase = 0; return(0); } return(0); } void rx_fifoset(void){ rxFIFO[rx_top] = xbee.getc(); ++rx_top &= 255; } void tx_fifoset(unsigned char data){ txFIFO[tx_top] = data; ++tx_top &= 255; } unsigned char hex_conv(unsigned char data){ data &= 15; if(data < 10) return(data+48); else return(data+55); } unsigned char conv_hex(unsigned char data){ if((data > 47) && (data < 58)) return(data-48); else if((data > 64) && (data < 71)) return(data-55); return(0); } void tx_message(int data){ int i; for (i=0; i<6; i++) tx_fifoset(hex_conv((data>>(4*(5-i))) & 15)); tx_fifoset(13); } float move_mean_calc1(float data){ mean_sum1 = mean_sum1 - ad_data1[ad_pointer1] + data; ad_data1[ad_pointer1] = data; ad_pointer1++; if(ad_pointer1 == max_count) ad_pointer1 = 0; return(mean_sum1 / (float)max_count); } float move_mean_calc2(float data){ mean_sum2 = mean_sum2 - ad_data2[ad_pointer2] + data; ad_data2[ad_pointer2] = data; ad_pointer2++; if(ad_pointer2 == max_count) ad_pointer2 = 0; return(mean_sum2 / (float)max_count); } float move_mean_calc3(float data){ mean_sum3 = mean_sum3 - ad_data3[ad_pointer3] + data; ad_data3[ad_pointer3] = data; ad_pointer3++; if(ad_pointer3 == max_count) ad_pointer3 = 0; return(mean_sum3 / (float)max_count); } float move_mean_calc4(float data){ mean_sum4 = mean_sum4 - ad_data4[ad_pointer4] + data; ad_data4[ad_pointer4] = data; ad_pointer4++; if(ad_pointer4 == max_count) ad_pointer4 = 0; return(mean_sum4 / (float)max_count); } notch.cpp /* #include <stdio.h> #include <stdlib.h> #include <math.h> int main(){ int fs = 10000; double B0, a1, a2, b1, c0, F0, T; F0 = 60; // or 50 B0 = 100.; T = 1./fs; a1 = 2. * exp(-M_PI * B0 * T) * cos(2. * M_PI * F0 * T); a2 = -exp(-2. * M_PI * B0 * T); b1 = -2. * cos(2. * M_PI * F0 * T); c0 = (1-a1-a2)/(2+b1); printf("a1 = %f\n", a1); printf("a2 = %f\n", a2); printf("b1 = %f\n", b1); printf("c0 = %f\n", c0); return 0; } 60Hz a1 = 1.936768 a2 = -0.939101 b1 = -1.998579 c0 = 1.642174 50Hz a1 = 1.937188 a2 = -0.939101 b1 = -1.999013 c0 = 1.938304 */ float notch_filter1(float data){ y1[0] = data + a1*y1[1] + a2*y1[2]; float reault = y1[0] + b1*y1[1] + y1[2]; y1[2] = y1[1]; y1[1] = y1[0]; return(reault); } float notch_filter2(float data){ y2[0] = data + a1*y2[1] + a2*y2[2]; float reault = y2[0] + b1*y2[1] + y2[2]; y2[2] = y2[1]; y2[1] = y2[0]; return(reault); } float notch_filter3(float data){ y3[0] = data + a1*y3[1] + a2*y3[2]; float reault = y3[0] + b1*y3[1] + y3[2]; y3[2] = y3[1]; y3[1] = y3[0]; return(reault); } float notch_filter4(float data){ y4[0] = data + a1*y4[1] + a2*y4[2]; float reault = y4[0] + b1*y4[1] + y4[2]; y4[2] = y4[1]; y4[1] = y4[0]; return(reault); }2016年12月8日(木)
昨日はNucleoF401RE(mbed)+Max7だったが、今日はArduino+Max7である。 1-2限の新科目「インタラクティブプロダクト演習」は、いよいよ学生それぞれが新楽器のデザインに入り、僕は電気関係とかArduino/Maxあたりの下請けに徹する。 今日は宮本梨世さんの作品のために、久世先生が導入したArduinoのファームウェアを書き換えて、「静電タッチセンサデータをホストに送る」・「ホストからの数値データ(0〜255)で赤色LEDをPWM点灯する」というものを作り上げた。
上がそのArduinoスケッチとMax7パッチで、 これ がその様子のYouTube動画である。 部屋を暗くしたが、なかなかWebカメラではLED点灯の様子は撮影しにくい(^_^;)。 2限の途中に作業を開始してハンダ付けは約30分、開発用Arduino IDEにライブラリが入っていない方のMacBookAir4だったのが判明して研究室に戻って昼休みをまたいで約1時間、細いケーブルではタッチセンサ電極まで延長できないと判明して短く太くしたが、まぁ半日仕事としてはまずまずである。#include <I2Cdev.h> #include <MPR121.h> // This firmware is for Riyo Miyamoto #include <Wire.h> #include "Adafruit_MPR121.h" Adafruit_MPR121 cap = Adafruit_MPR121(); uint16_t lasttouched = 0; uint16_t currtouched = 0; int led = 9; int touchData[5]; int brightness = 0; int timer = 0; void setup() { Serial.begin(115200); pinMode(led, OUTPUT); if (!cap.begin(0x5A)) { while (1); } } void loop() { timer++; if (timer > 1000){ timer = 0; currtouched = cap.touched(); for (uint8_t i = 0; i < 5; i++) { if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) { touchData[i] = 200; } touchData[i] *= 0.99; } lasttouched = currtouched; Serial.write(255); for (int i = 0; i < 5; i++) { Serial.write(touchData[i]); } } if (Serial.available() > 0){ brightness = Serial.read(); analogWrite(led, brightness); } }2016年12月9日(金)
来週木曜日の学部情報交換会での欧露ツアー報告を学長が楽しみにしている・・・という秘書さんからの話を受けて、フト思いついて朝からずっと このページ を作りつつ、裏でTime Machineと格闘して、ようやく現状のバックアップが出来たところに、午後イチで生協から電話があり、注文していたMac miniが届いた。 そしてなんと4-5限の講義と並行して、 このように 置き換えがほぼ成功してしまった。
上のようにまだディスプレイはこれまでのものだが、なんだか不気味な動きはあるものの、ほぼ動作環境を継続している。 過去にお仕事Macを新しくした時には、いつもたいてい1週間ほどかかってあれこれ苦闘して、その間は生産性が著しく低下する「苦行」だったのだが、ここまでスマートになっているとは、「Time Machine」恐るべし、である。 ただし、日本語の単語登録した辞書が一見すると消えているので、これはまたまたネットで調べて持ってくる必要がある。
2016年12月10日(土)
今日は夕方から晩に社会人有志の突発水面下カラオフ(*^o^*)が予定されているが、午前から研究室でお仕事の続きである。 無事になんとかユーザー辞書も移行できて、さらに新しいFirefoxでウザかった「最近ブックマーク登録したブックマーク」という余計な御世話のメニューを消すことも出来た。
そして遂に、照岡さんからは上のように、美しく改訂された新筋電センサ基板「VPP-SUAC2」のデータが届いた。 これは週末ではあるが「P板.com」に早速、発注に移ってしまおう・・・と作業していたが、Webサイトのバグか、ちゃんと情報が受け取ってもらえないのに「見積もり依頼」となってしまった(^_^;)。 キャンセルをして再度入力したいのに、メイルも電話も無反応で、どうやら土日はお休みらしい。 こうなると、月曜日から仕切り直しである。
しかし、環境としては目立たないがMac OSが10.7.5から一気に10.11.6になって、使っていたアプリで使えなくなったのはどーでもいい2本だけ、と優秀である。 CPU温度を表示するiStatが無くなったので、上のようにIntel提供の「Power Gadget」というのを入れてみたが、YouTubeからアドオンで動画をダウンロードしても35℃から37℃ぐらいにしか上がらず、QuickTime7Proでそのmkvファイルをmp4にエンコードしても、50℃には届かなかった。 同時に何本もダウンロードしたりmp4エンコードしたり・・・という荒技ではもう少し上がるかもしれないが、まずまず良好である。 まだ日本語学習が稚児のようでダメダメであるが(^_^;)、お仕事Mac miniはぼちぼち育てつつ、見守っていこう。 なにより先代と違って、ファンで空冷しなくてよさそうなので、かなり静かなのだ。
2016年12月12日(月)
木曜日に欧露ツアー報告会を、週末に京阪奈での「バイオフィードバックセミナー」を控えた、12月のピークの週となった。 昨日はだらだらと休養日を過ごして体力気力回復、朝7時前から研究室に着いて、奥さんに頼まれた「ふるさと納税」を2件8万円もクレジット支払いしてしまったが、熊本地震復興支援にせめてもの応援である。
上は、朝イチで届いた、いかにもスパムらしいメイルである。 これに騙される人はいない、と信じたいが、騙される人は騙されるので、まずは情報室に連絡しておいた。
さて、突然だが、上の写真は何だと思うだろうか。 ゲームセンターのようだが、実はこれらの機械は、1ドルコインを入れて当たれば本物の1ドルコインがじゃらじゃら・・・と出てくる本物のギャンブルマシンである。 さらにこの写真はいわゆる「カジノ」内ではなくて、なんと米国ネバダ州Rino市の、リノ空港内の風景なのだ。 飛行機に乗る前、あるいは飛行機で到着したついでに本物の現金ギャンブルができる、というのは凄い。 ラスベガスと並んで有名なギャンブル都市、というかRino市は実質「カジノの街」であり、僕は2002年にこの街で本物のカジノを体験していた。 拙速なカジノ法案が話題になっているが、ここでその実態を紹介しておこうと思い立ったのである。
詳しくは このページ の「2002年11月1日(金)」の後半と「2002年11月2日(土)」のところにあるので見ていただくとして、まぁカジノと言えば上のような風景で、スロットマシン、ポーカーなどのゲームマシン(ただし現金[1ドルコイン]を扱う)、ブラックジャック、ルーレットなどである。 しかし実際には、家族で来訪して子供たちを飽きさせない巨大ゲームセンターのフロア、さらに無料のサーカスやライヴ、有料のミュージカル(僕もオフ・ブロードウェイのパフォーマンスを堪能)など、至れり尽くせりのまさに巨大複合レジャー施設なのだった。 ネバダの砂漠の中にこのような巨大なカジノが3つほどあり、他には何もないのだ。
さらに上のように、世界中で行われているあらゆるスポーツの映像がライヴで届き、近未来、すぐ直後に決定する試合の勝敗をなんでも賭けることが出来る。 これは上層階のホテルの部屋内からでも賭けられる。 1年365日24時間、カジノ内は全てがギャンブル漬けであり、勝ち続けていれば豪華ホテルに滞在しつつずっと生きていけるのだ。
しかし、煌びやかな電飾と照明でまったく時間の感覚が無くなったのに不安を覚えてカジノ1階のドアから建物の外に出てみると、砂漠地帯の乾燥した好天で、街を歩く人影もほとんどなく、カメラを向けることが出来なかったものの、カジノの建物の周囲にはたくさんの物乞いの人達がうずくまっていたのだ。 かつて一攫千金を狙ってこのカジノにやって来て、賭けに負けて身ぐるみ剥がされて、リベンジ資金というよりとりあえず生きるために乞食になった多くの「カモ」が、カジノの外に溢れている。 これが、日本が目指しているというカジノ観光都市の本当の姿なのである。
そして、先週土曜日の「P板.com」の見積もり依頼をキャンセルして、新たに上のように、新基板「VPP-SUAC-2」の見積もりを依頼していると、情報室から全教職員宛のメイルで、以下のような注意喚起が届いた。 どうやらあのスパムメイルのURLをクリックすると、下(左)のようなページに飛ぶのだという。 正しくは下(右)が本来のSUAC教職員がログインするページであり、ちょっと稚拙で出来はよくないものの、まぁ騙される人はここに馬鹿正直にIDとパスワードを入れてしまうのかもしれない。 一応、ログインボタンを黒くしているあたり、「違うんだよ」と言ってくれているようにも見える。(^_^;)
そして昼前から午後いっぱいかけて、「メディア数理造形演習」のteam「おくるかい」のために、システムの下請け作業に没頭した。 このチームは一種の体育会系ゲームを企画していて、5本のLEDろうそく台にSHARPの赤外線距離センサを仕込んで、以下のような感じにしたいのだという。 ちょうど、かつて院生の見崎さんの修了制作のために作ったシステムが、「21個のRGB-LEDをPWM点灯」+「21個のセンサ情報を取得」という、デュアルAKI-H8システムだったので、これをそれぞれ5チャンネル分、使えば楽勝の筈である。 ・・・ただし以下のように、造形までのケーブルが「6メートルを2本」+「4メートルを3本」と、ちょっと嫌な予感がした。(^_^;)
そして、3限には同時進行でゼミの馬ブンさんのMax7プログラミングを支援しつつ、 このページ のように、午後3時間ほど、長いケーブルを確保するために、こんがらがったシールドケーブルを解きほぐす、という作業に没頭することになった。 最終的には2芯シールド(2本を束ねる構想)がやや不足する、と判明して、シールドではないが6芯ケーブルで「6メートルを2本」+「4メートルを3本」を確保できた。 そして、とりあえず最長の6メートルの1チャンネル分について、 このページ のようになんとか動作確認を行って、あとSHARPセンサとRGB-LEDのちょっとした処理を4チャンネル分、終えたところで本日は時間切れとなった。 続きは明日である。
2016年12月13日(火)
午前中には、ぼちぼち このページ にも社会人からの参加申し込みが来たり、週末のBFセミナーが事情により延期かキャンセルか・・・という状況にどたばたしつつ、昼前から午後に3時間半ほどで、 このページ のように5チャンネルのうち残り4チャンネルのハードウェア制作を完了して、動作確認まで行った。 これ がその様子のYouTube動画である。
2016年12月14日(水)
午前にはあれこれあれこれ多数のメイルが行き来したが、結局、12/18のBFセミナーは このような 形になった。 2限のゼミは このような 感じでぼちぼち進み、寝坊遅刻した馬ブンちゃんは昼休みから3限にMaxプログラミングを進めた。 そして午後に新しいDellの格安モニタが届いて、 このように 30分ほどで、Mac miniに続いて、2台のお仕事モニタの置換が完了した。 いやー、なかなか広大である。(^_^)
2016年12月16日(金)
昨日の木曜日は1-2限みっちり「インタラクティブプロダクト演習」で学生それぞれのプロジェクトについて教員4人で検討し、僕は4人の学生のフォロー(Arduino、Max7)をする事になった。 そして3限にはゼミ追い込みアポで馬ブンさんと杉浦さんがやってきて、ブンちゃんの卒制に向けたMaxプログラミングは大きな壁を突破して、ちょっと光明が見えてきた。 杉浦さんの修了制作については、まだまだ頑張りどころである。
そして4限にデザイン学部教授会、5限には学内報告会で「欧露ツアー」の報告90分1本勝負を行った。 準備していたあれこれを全て紹介できず、90分でもぜんぜん不足だった。 最前列の学長には、「リニア振動手袋」を体験してもらった。 そして晩にはホテルオークラ30階に行ってデザイン学部忘年会、と、1日ぎっしりの予定をなんとかクリアした。
この間に、「P板.com」の見積もりが来て、今回は38万円で部品調達製造までを委託する事になった。 学内手続きが終われば「発注」であり、いよいよ「VPP-SUAC-2」(25枚)も来年には登場することになる。 さらに某T○Y○T○からは、データの詰まったDVDが届き、これから年内の宿題として、本格的にjitterでの画像解析のMax7プログラミングが始まる。 そして、「メディア数理造形演習」のチーム「コントロール Z」からは、制作進捗報告として上のような写真が届いた。 これはまさに、もろPPAPである(^_^;)。
2016年12月19日(月)
昨日の日曜日には、けいはんなプラザに日帰り出張で、 このように BFセミナー延期に伴う臨時の公開講演会を行った。 ごく少数の来場者だったとはいえ、あれこれ今後に繋がる有益な情報交換が出来た。
そして何より、行きの「こだま」で浜松から京都までずっと集中して、さらに公開講演会の直前30分、そして京都から浜松に帰る「ひかり」の最後の約10分ほどで、なんと「メディア数理造形演習」のteam「わかめ同好会」の課題作品のためのMax7サンプルパッチの宿題が、おおよそ完成してしまったのは最大の収穫である(^_^)。 パンケーキアートを体験する、というもので、 これ がその様子のYouTube動画である。
2016年12月21日(水)
昨日の火曜日は、 このように 「メディア数理造形演習」のteam「地球防衛軍」のためのシステムを半日で作った。 12個のCdS光センサに対して、直接に目に当ててはイケナイレーザービームを当てる、という作品の予定である。 以下がそのArduino Microに書き込んだスケッチとMax7センサパッチで、いずれも過去に作ったものの活用という、まさにオープンソースの利点となった。
そして今日の1限には文化芸術研究センターに行って、デザイン2回生の大隈さんとともに このように 「インタラクティブプロダクト演習」の大隈さん作品の設置場所の下見と、過去の作品に活用した「赤外線ビームセンサ」と以下の「8チャンネルアナログ→MIDIインターフェース」の動作確認を行った。 このインターフェースはこれまで何度となく、SUAC学生のインスタレーション作品の裏方として活躍してきたが、まだまだ健在で安心して使える。
その後の2限にはゼミがあり、3回生・4回生・院生が このように それぞれの進捗を報告しつつ、今回はうららのバイノーラル録音してきたサウンドを全員で確認した。 その後、「メディア数理造形演習」のteam「コントロールZ」からは、以下のように、本番に向けた造形の進捗が届いた。 ますますもって、PPAPである(^_^;)。
2016年12月22日(木)
木曜日なのに調整のため「金曜講義日」となった、冬休み前の最後の講義日である。 4-5限の「メディア数理造形演習」だけでなく、追い込みのM2杉浦さんが1-3限にアポを入れてやってきた。 さらに照岡さんからの情報を受けて、遂に以下のOpenBCIを発注依頼した。 筋電からいよいよ脳波まで攻略である。(^_^)
4-5限の「メディア数理造形演習」は、 このように 各チームとも順調に作業を進めた。 こうなると、新年が明けて、それぞれの課題作品がどのように完成に向かうのか、とても楽しみである。 研究室に戻ると事務局から「決裁が下りた」との連絡が届いていて、遂に以下のように基板「VPP-SUAC-2」を正式発注した。 年越しを跨いで、あれこれ充実の日々なのだ。
2016年12月24日(土)
昨日の午後には日産ディーラーに行って、予約していた「ノートe-power」試乗を行った。 考えてみれば「試乗」というのも初めてで、まさかディーラーの店員が一緒に乗るというのは知らなかった(^_^;)。 浜松市内・西伊場から近くの高台である佐鳴台団地に上り下りしてから国道1号に出て、バイパスを潮見坂まで往復して一気に120kmまで出した加速感を体験した。 五島列島・福江島 で体験した三菱の電気自動車とはまた違った、予想以上の素晴らしい感覚で、「さすが日産」と改めて見直した。 その後にマツダに行く、というのを話していたので、その場でもらった見積書からさらに10万円ほど値引きした見積書を晩になって自宅まで持ってやって来る、という営業努力にも驚かされた。
しかし最終的には、これまで約13年間、乗ってきたマツダのデミオのマニュアルの新車に乗り換えることを決定した。 その理由は2つある。 1つは、まだ運転は両手両足を使いたい、と再確認できたからである。 あと1台(10年)はマニュアルでいって、その後になったらe-powerを考える事にした。 もう1つの理由は、僕の性格として、「初代」の人柱になるのはやはりちょっと無理だからである。 おそらく無理してノートにe-powerを詰め込んだトラブルが今後、出てくる予感がある。 冬の寒冷期、そして夏の猛暑期。 ちょっとエアコンを入れたらエンジンは常に回っていたので、たぶん全国的に夏場は鬼門だろう。 さらに、運転席の真下にあるリチウムイオン電池が衝突の衝撃で発火したら・・・という可能性も実際の事故が起きるまでは不明である。 スマホのバッテリ発火の原因は衝撃なので、それがお尻の下にある、というのは今後、問題になるかもしない。 つまり、乗ってみて、日産の技術と気合は十分に堪能でき、大きく評価するが、本命は、無理にノートにe-powerを乗せたこの「初代」のノートでなく、その次の、e-powerを載せるための専用車種の登場にある、と確信したのだ。
そして世間的にはクリスマスイヴのこの日、夕方には再びマツダに行ってデミオを予約するだけなので、研究室で某T◯Y◯T◯のお仕事に没頭していると、ロシアのDenisから強力なメイルが届いた。 現地はいま「マイナス20℃」であるという(^_^;)。 2010年のロシア行き の時に体験したのは「マイナス15℃」までなので、僕には未体験ゾーンであるが、過去にマイナス55℃とかの記録があるエカテリンブルクでは何でもないのだろう。
最近のプロジェクトとして2件のパブリックアート(インスタレーション)の紹介があり、一つは このページ に紹介されているように、「初めて220Vの道具を使った」とのことで、マイクを仕込んだ"Drums"を叩くと、Arduinoでセンシングして、あらかじめ制作した256パターンのドラムパターンから選ばれて演奏するとともにLEDベルトが光る、というものである。 ★ ★ ★ こういうのは「マイナス20℃」の雪の広場で体験するからこそ、面白い。
もう一つは"Skladni"、その意味は"Metallic origami"というもので、インタラクティブなインスタレーションを想定しているが、現状では自動で光る造形物となっている。 ★ ★ そして嬉しいことに、僕が今年の 欧露ツアー2016 の中でエカテリンブルクに行って、現地で行ったレクチャーとワークショップのおかげで、アカデミーがそのようなデザイン方向に動き出した(ので感謝する)、ということだった。 これは素晴らしい、行った甲斐があるというものである。
そしてDenisは、これまでの活動を受けて、「Digital Art technology handbook in Russian」を出版する話を進めているとのことで、大枠の章立ての案について、僕のコメントを求めてきた。 そこでまずは、上の「Design and Technology」を推奨しておいた。 この本は2000年4月にSUACデザイン学部がスタートした時からの推薦参考書で、後に技術造形学科の教員が熱烈に推薦して、日本語版の出版を実現してしまった本である。 個々のテクノロジーは古いものの、「魂」の部分ではいまだに強力な教科書なのだ。
2016年12月27日(火)
一昨日の12月25日は、クリスマスなのにストイックに大学で研究室に篭り、某T◯Y◯T◯のお仕事に没頭した。 そして、ある程度まで「見えて」きたので、昨日は以下のようにアカペラX'mes会を堪能した。 曲数こそ18曲と地味であるが、前日の断酒も含めて、楽しい時間を過ごせた。
そして、世間もぼちぼち仕事納めという火曜日である。 午後にゼミ院生の杉浦さんの修了予備審査があるので、午前中に気合いを入れて某T◯Y◯T◯の改訂試作をまとめて、無事にお昼に送ることが出来た。 大人の事情があり以下の画像はかなりぼやけているが、まさに色々なノウハウと音楽的要素が詰め込まれたMax7プログラミングであり、ここ数年で最大規模のMax7開発プロジェクトも、新年には実験試乗へと繋がっていくことになるので、楽しみな年の瀬となった。
そして、2日ほど前に届いていた、以下のCopenhagenのAnthony Brooks先生からのメイルを、国内のMACS-MLに紹介した。 こうなると、何が何でもNIME2017に行きたい・・・という気になってきた。
2017年はスキップして満を持したSketchingもあるし、ギリシャでのVS-Gamesも悩ましいのだが、まずは頑張って論文を出してみるように挑戦していこう。Some news is that New Interfaces for Musical Expression (NIME) comes to Copenhagen under Aalborg University (should be a great event) - and I have initiated an Accessibility track (first time in the event) that I will chair... See http://www.nime2017.org/committee/ be great to see you, your colleagues/network, or your students there at the event. Please spread the news of the event and if appropriate the new accessibility track - so New Instruments that are easily accessible for persons with different abilities to creatively express. Main site = http://www.nime2017.org2017年1月5日(木)
年末年始は色々あって、新年は1月3日から仕事しているが、明日に出発して土日は魚津で、初めての電気学会の「知覚情報研究会」で発表である。 「今回の研究会は、医学系学会で会員数トップクラスの日本抗加齢医学会の認定医療施設である浦田クリニックで、アンチエイジング(抗加齢)のテーマセッション及び見学会を行い技術交流を図ること、を第一に考えて企画致しました。 すなわち、センシング技術の専門家と、抗加齢医学の最前線にいる医療従事者とを結び付け、健康長寿国を目指す我が国の国策に叶う 研究分野の醸成を狙っています」 とのことで、新年早々、楽しみなのである。
年末には こんなこと があり、 こんなもの も届いていたが、まずはゼミOGの野口さんと山村さんからいつものように届いた年賀画像を並べておこう。
2017年1月7日(土)
ここは富山県魚津市、アンチエイジングに特化した巨大な「浦田クリニック/スコール」の一室である。 「電気学会 電子・情報・システム部門 知覚情報技術委員会 知覚情報研究会」というもので、電気電子部門(と情報工学部門)の技術士である僕としては珍しいのだが、初めての電気学会の研究会への参加である。
冬場の北陸ということで前日に魚津に着いて前泊(埋没林博物館をチェック)したが、まったく雪の気配もない好天で、部屋は暖かく1月とは思えない。 まず冒頭に30分ほどクリニックの施設見学をして、いよいよスタートする2日間のプログラムのうち、今日の分は以下である。このプログラムを眺めれば分かるように、内容はてんでんばらばらである(^_^;)。 結論としては、ここに何か打ち込む隙がまったくないほど引き込まれて、1日目は一気に終わってしまった。 頭に残っている断片的なフレーズとしては、「グルテンフリー(遺伝子操作の米国から来る小麦粉を食べない)とカゼインフリー(乳製品を飲食しない)だけで小腸に穴のあく病気を予防してアレルギーは改善される」・「女性は生理周期によって作業能力が25%ほど低下する」・「脳波で感情を読み取る方程式はある(特許なので詳細は秘密)」など、なかなかエキセントリックな研究会だった。1月7日(土) 13:00 開会 13:05~13:40 館内見学 13:40~16:25 テーマ「アンチエイジング技術」 PI-17-001 アカメガシワ入りチョコレートによる便秘改善効果について PI-17-002 赤外線センサーおよび前額面・矢状面・水平面3方向同時動画撮影による姿勢 PI-17-003 生体情報センシングのバイオフィードバック療法への応用について PI-17-004 皮下組織の構造に基づく顔面シワの画像計測 PI-17-005 アンチエイジングのための脳波計測とホルモン解析 16:25~17:00 テーマ「抗加齢医学の現状と課題」 これからのアンチエイジング医療とは 17:00~17:20 浦田クリニック/スコール健康のための食養生 17:20~17:40 メディカルフィットネスの取り組みと課題2017年1月8日(日)
知覚情報研究会の2日目、プログラムのうち、今日の分は以下である。 朝9時からの研究会は午前だけで終わり、希望したので昼食は浦田クリニック特製の「イケナイものがまったく入っていない食事」という予定で、ちょっと楽しみだ。 自費で後泊して明日の祝日に浜松に帰るので、本来は今日の午後に黒部方面に観光に行くつもりだったが、どうも全国的に午後は雨らしいので、ホテルに帰ってお仕事、の予定に変更した。このプログラムを眺めれば分かるように、2日目も内容はてんでんばらばらである(^_^;)。 東京電機大グループでは、懐かしい「電気刺激」ネタだったので、もう15年前になる、IAMASのために作った「ピリピリ」のページを紹介しておいた。 なんと電機大では、実験中に医療用の電気刺激装置を「20秒ON、40秒OFF」という制御をするために、この機器の電源ボタンを周期的に押すためのロボットを作っているらしい(^_^;)。 いまどきの大学生は中身を開けて改造しようとしないのに驚いた。1月8日(日) 9 :00~10:00 テーマ「ヒト行動解析」 PI-17-006 眼球運動計測に基づいた学習者個性の推定方法の提案 PI-17-007 脳血流量解析による身体図式に対する電気刺激効果の検証 PI-17-008 遠隔操作における人間の空間認知特性変化の分析 10:00~11:00 テーマ「介入とヒト支援」 PI-17-009 楽器音の主観評価における材質の違いが及ぼす影響 PI-17-010 脳波計測による心理状態を用いた指導支援システムの開発および評価 PI-17-011 行動識別に基づく園児見守りシステムの開発と検証 11:00~ お食事準備 11:20~ クリニック特製昼食 メニュー紹介2017年1月11日(水)
初めての魚津のフォトレポートを このように 上げて月曜の夕方にSUACに戻り、昨日の火曜日には こんなもの が遂に届いたが、ググッと堪えて以下のようなあれこれを進めた。
そして今日は新年最初のゼミの日で、メンバーは元気に このように 再会した。 今日は院生の修了制作提出検収日ということで、杉浦さんは このように 完成したバイオフィードバックゲームをデモって、提出書類の最終校正を進めた。
- 知覚情報研究会で再会した、東京工芸大の森山先生との「波動研」あれこれ
- 「第50回知覚コロキウム」(3月末・慶応大)の情報を発掘して発表参加申し込み
- エンタテインメントコンピューティング研究会(3月・慶応大)の情報が届いて発表参加申し込み
- ICMC2017(上海)の情報が届いてとりあえずストック
- VS-Games2017(アテネ)の情報を発掘してとりあえずブックマーク
- ICEC2017(筑波)の情報が届いてとりあえずストック
- 3月のBFセミナー日程はほぼピンポイントに1箇所しか残っていない事を辻下先生に連絡
- ロシアのDenisとの、英語での濃いメイルのやりとり
そして遂に、杉浦さんは無事に修了制作提出検収を完了して、僕も書類を事務局教務室に提出して、まずは落着である。 あとは来週に、副指導の宮田先生・的場先生とともに、口頭試問・修了審査を経て、無事にオシマイとなる。 なんとかそこまで頑張っていこう。 ゼミの打ち上げはその後、2月あたりになりそうである。
2017年1月16日(月)
一昨日と昨日のセンター試験監督業務も無事にこなして、いよいよ学期末の追い込みシーズンに突入である。 先週は木曜日には このように OpenBCIのシステム基板が速攻で届いてしまったが、まだまだ組み立てて実験する時間的な余裕がない。 とりあえず昨日の段階で、2月末の音楽情報科学研究会の発表予稿を このように 学会に送ったところだが、気付いてみればNIME2017コペンハーゲンの応募締め切りまであと1週間となっていた(^_^;)。 今年はなんとしてもまたCopenhagenに行って、Tony Brooks先生と再会したいので、応募の技についてあれこれ検討して、午後にSUACに来ていた献血車で400cc献血をして、これで1日が終わった。2017年1月19日(木)
火曜日は終日かけて、まずはNIME2017コペンハーゲンにWorkshopの応募をしてみた。 去年のICMC2016で紹介した「DoubleMyo, MuseOSC and MRTI2015」がけっこう好評だったので、この技を伝授します・・・というのはウケる、と見たのである(^_^;)。 そして昨日の水曜日は、 このように ゼミもいよいよ4回生は終盤となり、さらに放課後にはゼミ院生・杉浦さんの修了審査口頭試問があって、無事に「合格」となった(^o^)。 僕は合間の午後ずっと、NIME2017の応募論文を執筆していた。
そしてこの木曜日は、まず1-2限の「インタラクティブプロダクト演習」では、僕が担当しつつある4人のうち、宮本さんのMaxプログラミングを支援して、およその道筋が見えた。 そして3限になって、アポを入れてきて このように ゼミの馬ブンちゃんが追い込みしているところに、遂に完成版の「VPP-SUAC-2」基板が届いたが、チェックをしている余裕がまったく無い。 さらに杉浦さんがやってきて、修了制作作品の記録ムービーを撮った。
この期間もずっと僕はNIME2017の応募論文を執筆していて、途中では提出ムービーのために PAWでアベマリア という動画も撮ったが、いやーなかなか難しかった(^_^;)。 さらにその後、学生委員会の会議が終わったところに、「インタラクティブプロダクト演習」を欠席していた木村さんがやってきて、そこから放課後までに、 このように ケースの穴あけから基板の配線、Arduinoプログラミング、Maxプログラミングまでをやっつけてしまった。 なかなかに充実の日々である。
2017年1月25日(水)
今はメディア造形学科4回生の卒業制作の最終合評日の朝、おいおい2限から始まって終了は20時過ぎというデスマッチである。 昨日までにゼミの 石井さん・前澤さん・馬ブンさん の3人の制作検収も無事に終わって、あとは今日のプレゼンをなんとか通過して欲しい・・・という朝である。 ICMAから予告されていた、今年は10月中旬と遅い時期に上海で開催される ICMC のページもopenされていた。 なんと以下のような怪しい写真を発見したが、やはり「脳波音楽」だと閉眼しないと駄目なので、音楽パフォーマンスの姿としてはどうしても、このように「瞑想」スタイルとなってしまうのだ。(^_^;)
先週の金曜日には「メディア数理造形演習」が このように 進んで、僕はPPAPグループのために このように 作業したが、ようやく各チームとも作品に向かってベクトルが絞れてきて、楽しみである。
そして先週末の土日をマルマル使って頑張ったのは、5月にコペンハーゲンでAnthony Brooks先生と再会したいNIME2017の応募であり、既に出していたWorkshopの応募に続いて正々堂々とpaperの応募を書いて、さらに月曜(T○Y○T○中央研究所に出張して実験車に試乗してmeeting)には、国際文化学科のRyan先生に赤ペンで英語チェックをしていただいて、無事に応募を完了した。 さらに、既に出していた音楽情報科学研究会の予稿に続いて、3月に慶應(日吉)であるエンタテインメントコンピューティング研究会の予稿を やっつけて、 このように 学会に送った。 どこかで見たような・・・という事は言わないように(^_^;)。
さらに火曜日には、ゼミの卒制の最終追い込みを応援しつつ、気合をこめて、3月に宮古島に出張する、電子情報通信学会EMM研究会の予稿をやっつけて、 このように 学会に送った。 どこかで見たような・・・という事は言わないように(^_^;)。 これは基本的にはゼミ3回生のうららが取り上げたバイノーラルねたに絡めたものだが、実質的には何もやっていない(これからやる)、という事になってしまったが、紙面はこれまでのあれこれでそこそこ充実しているし、このところ読みまくっていたプリゴジンがダマシオを経て非線形と結びついてきた、という、自分としては画期的なものなのである。
2017年1月26日(木)
昨日のメディア造形学科4回生(ラストの1代前)の卒業制作の最終合評が このように デスマッチ(2限〜20:30)で行われて、無事に全員の合格が決まった(^_^)。
その喜びも束の間、今日は「インタラクティブプロダクト演習」のラストの前週、来週は最終合評とあって、1-2限はずっと、僕の担当する4人のうち2人と このように 進めた。 清水さんの造形のタッチセンサ電極としては、「真鍮の粉をアロンアルファで固めたもの」を採用する計画で、その実験を無事に成功させて、あとは彼女は造形に邁進することになった。 先週にサウンド生成のMaxパッチを進めていた宮本さんは、 このように なかなかセンセーショナルな作品になった。 明日は「メディア数理造形演習」の追い込みであり、5限には玉井さんのアポもある。 来週水曜日はメディア造形学科3回生(ラスト世代)の総合演習Iの最終合評であり、まだまだ気を抜けない。
2017年1月27日(金)
お昼をまたいで、突然に某社の来訪を受けたが、これはいずれ何かになるかもしれないが今のところ何とも言えない。 そして「メディア数理造形演習」の追い込みは このように 進み、各チームが造形の制作に散るなか、「わかめ同好会」のMaxパッチを以下のように改良した。
背景画像と合成したもので、およその動作は このように なった。 ただしこのチームは、パソコンでなく液タブを使って、さらにウレタンフォームなどで造形まで挑戦するので、まだまだ最終形は未知である。
2017年1月30日(月)
一昨日の土曜日、午後半日かけて このように OpenBCIの届いていた脳波センサヘッドギアを組み立て完了した。 3Dプリンタがあれば基幹部分は自分で作れる・・・というが、肝心の「剣山電極」がないと駄目なので、これは買って組み立てるしかない。
そして昨日は「8時間で55曲」というマラソンカラオケ新記録で充実して、いよいよ追い込みの最終週がやってきた。 午前中に「インタラクティブプロダクト演習」の清水さんと、明後日に最終合評を迎えるゼミのうららとの対応を済ませて午後に時間が出来たので、ハードを作っただけだったOpenBCIのソフトを調べ始めた。 このページ から、「脳波センサボードのスイッチは"BLE"にする("PC"はreservedで何もしない)」・「USBドングルのスイッチは"GPIO6"にする」と判明した。 そして、公式なソフト関係は以下の3つだけが対応するものだとわかった。 さらにサードパーティとして ここにMATLABとか4種類 がある事も確認したが、まずは公式ツールからである。
そしてあれこれ試行錯誤してみて、感触としてはまずまずMUSEにも似ている感じで、ホストのMacのBluetoothをONにして、Max7でシリアルを115200にして「Bluetooth-incoming」を指定すると、とりあえず「b」・「s」というおまじないコマンドを送ったのに反応して、何かデータが返ってくるらしい、と分かった。 そして本命はUSBドングルであり、「The OpenBCI GUI」という一式に付録している「OpenBCI_GUI.app」を走らせてみると、詳細不明だがとりあえずMax7でUSBドングルをUSBシリアルとして認識確認した上で、いきなりOpenBCIヘッドギアからの脳波らしき信号を受けて表示できた。
例によって眼をあけていると強烈な筋電信号がノイズとなって脳波データが吹っ飛ぶが、とりあえずまずはこのツールは、データとして こういうテキストデータ (先頭の5000行のみ)を書き出したり読み込んで再生表示させる事に使える、と判明した。 このデータを記録した様子のYouTubeは これ である。 こうなると、いよいよドキュメントの深部を探検して、Max7でカスタマイズしたくなるが、なかなか今週、そしてMDWのワークショップを経て来月まで、なかなか時間が作れそうにないのが心配である。
2017年1月31日(火)
昨夜は久しぶりの同窓生、いまやSUACの非常勤講師となった山口翔クンと、大学院を経て実習指導員の前田侑穂さん、そして「寿司」インスタで常に後輩を刺激する野口佳恵さんと僕、という4人で、アクト近くの気取ったレストランでの新年会があった。 過去にはこの4人で夏に遠鉄デパート屋上のビアガーデンに行ったこともあるし、翔クンとはインターカレッジで大垣と多摩美に一緒に遠征しているし、前田さん野口さんとは沖縄に行って鯨を見てきたし、さらに前田さんとはシドニーのNIME2010にも行っている。 活躍する卒業生と飲むというのは最高の幸せである(^_^)。朝イチで研究室に出てみると、いよいよ追い込み関係のメイルが届いていて、今日のアカペラは無し、来週の最終回だけ、とまずメンバーに連絡した。 既にゼミのうららは昨日、明日が最終合評の「メディア造形総合演習I」の発表内容とプレゼンの検収/チェックまで完了したが、今日の午後の4-5限から放課後には、「インタラクティブプロダクト演習」の学生支援の予定が満載である。 そして昼前から午後にかけてエアポケットのような時間が出来たので、ここでOpenBCIのサイトの探検と、今後に向けたチェックポイントを整理することにした。 スタートポイントは常に ここから である。 昨日はとりあえず「OpenBCI GUI」というツールで自分の脳波を表示するところまで走ったが、今日はあらためて Getting Started のページにある項目を確認していこう。
OpenBCIの歴史はそれほど古いものではないが、昨今の脳波ブームもあって、既に色々なバージョンのものが混在しているようで、今回購入したキットも既に最新ではなくなっている。 注意点としては、「過去のバージョンに関する情報を読み流す」ということになりそうである。 まずは以下のように、 このページ のタブのうち、「Getting Started」と「FAQ」以外の5項目と、それらの下の階層のメニューURLとタイトルを並べて置いてみた。
重要な点としては、「Fixing FTDI InBufferSize for OS X」という部分を発見できたのは収穫だった。 これは放置すると、Max7でリアルタイムにOpenBCIの脳波データパケットをUSBドングル経由で受け取る際に、せっかくのデータパケットがデータ落ちする(;_;)、というものなので、なんとかしないといけないかもしれない。 当面、これが最大の宿題となった。 そして上の最後の項目、 コミュニティ に行ってみると、あれこれクレイジーなユーザからの最新の情報があったので、その中でいくつか、ここにメモしておくことにした。
- OpenBCI Hardware
- OpenBCI Cyton - ヘッドセットの後頭部にある基板Cyton
- Cyton Data Format - Cytonのデータ形式
- Cyton Bluetooth - Bluetooth(BLE)の使用
- Cyton Board Programming Tutorial - Cytonのファームウェアを更新する場合
- Cyton Radios Programming Tutorial - USBドングルのファームウェアを更新する場合
- これ以降の「OpenBCI Ganglion」はたぶん旧モデルなので無視
- OpenBCI Headware
- Ultracortex Mark IV - これは最新のヘッドセットで現在発売中。ただし僕が買ったものより新しいので無視
- Ultracortex Mark III “Nova” & “Supernova” (REVISED) - これは僕が買ったものと似ているがちょっとだけ改良されている、ちょっとだけ新しいバージョンのヘッドセット。これを参考に組み立てた
- Ultracortex Mark III “Nova” & “Supernova” - これは僕が買ったものと似ているが、ちょっとだけ古いバージョンのヘッドセット。つまりは購入したズバリそのもののページは無い(^_^;)。これを参考に組み立てた
- これ以降の「Ultracortex Mark 3」・「Ultracortex Mark 2」・「Ultracortex Mark 1」・「Spiderclaw V1 & V2 (deprecated)」はたぶん旧モデルなので無視
- OpenBCI Software
- The OpenBCI GUI - これが、昨日走らせてみた、脳波表示の標準ツール
- OpenBCI Cyton SDK - ここがCytonのSDK。たぶんここを攻めることになるのでは
- OpenBCI_Python - これはPython版のSDK。Raspberry Piではないので直接は使わないものの、Pythonコードを読んで参考にする可能性は大きい
- OpenBCI Electron Hub - CytonをTCP/IPで使うミドルウェアらしい。たぶんMax7を使うのでここはパス?
- 3rd Party Software
- MATLAB - 3rd PartyのうちMATLAB。Max7屋はここを素通りする(^_^;)
- Neuromore - 3rd Partyのうち「Neuromore」という謎のツール。一度チェックしてみよう
- OpenViBE - 3rd PartyのうちOpenViBE。Windows用なのでこれは無視
- Lab Streaming Layer (LSL) - 脳波をライブレコーディングするためのストリーミングに関する情報らしいので、後でチェックの必要あり
- TUTORIALS
- Cyton Getting Started Guide - ここにOpenBCIシステムを最初に走らせるための「Getting Started Guide」があったと発見(^_^;)。昨日はここを飛ばして、しかし出来てしまっていた。ただし最後のあたりにrefernceの「耳たぶ電極」の記載があり、これを新たに取り付けた。記載内容は過去のバージョンとかがゴチャゴチャなので注意が必要
- Ganglion Getting Started Guide - この「Ganglion」というのは、脳波電極をジェルで貼り付ける古いタイプなので無視してOK
- External Trigger on OpenBCI 8bit Board - これは古いボード(8ビット版)なので無視
- External Trigger on OpenBCI 32bit Board - これはP300など外部情報との同期をとるための情報。ただし当面はパス
- Digital Ouput on OpenBCI 8bit Board - これは古いボード(8ビット版)なので無視
- Audio Ouput on OpenBCI 8bit Board - これは古いボード(8ビット版)なので無視
- Using SD Card with OpenBCI - これはたぶんホストにPCでなくRaspberry Piとかを使って、データををSDカードに記録する話なのでパス
- Fixing FTDI InBufferSize for OS X - これはかなり重要。Mac OSX(当面は10.9〜10.11)ではUSBドングルのシリアル処理を行うvirtual com port (VCP) driverの問題でリアルタイム通信でデータ落ちがあるので、その解決法だという(^_^;)。ただしsystem configurationを書き換えて、さらにFTDIドライバを最新のものでなくちょっと古いやつに入れ替える必要があるらしい。これはなかなか悩ましい対応だが、どうするか(OpenBCI専用機を設定するか?)、検討が必要
- OpenBCI on Windows - これはWindowsなので無視
- Installing Windows 7 VM in Virtual Box - これはWindowsなので無視
- MyoWare OpenBCI Integration - Sparkfunの「MyoWare」ボードを付けるというお話
- Welcome to the OpenBCI Community - OpenBCIユーザ(概してクレイジー(^_^;))のコミュニティについての情報。これはさらに後述する
まず最初に目に付いたのは、上の OpenBCI + MIDI というものである。 OpenBCIのCytonボードからMIDIケーブルが出ていて(?)、これがRolandのMIDIシンセに繋がっているらしい。 Cytonボードは32ビットのArduinoのようなので、MIDI受信は無理なものの、MIDI送信であれば ジャミネータと遊ぼう と同じように簡単である。 ここは要チェックだろう。
さらに目に付いたのは、上の The Effect of Binaural Beats on Visuospatial Working Memory and Cortical Connectivity というもので、どこかで聞いたような眉唾な話だなぁ・・・と思ったら、 Brain.fm と似たものだった。 両耳にバイノーラルで225Hzと240Hzの正弦波を聞かせて、脳内でそのビート(差分)の15Hz(聴覚としては聞こえない)の成分が、脳波の15Hzという「集中状態」をもたらす・・・というのは、かなり怪しい話である。 ちゃんと 論文 ★ もあるらしいが、それでも限りなく、怪しい。 さすが脳波である。
次に目に付いたのは、上の OpenBCI and our Drawing machine というもので、OpenBCIで取得した脳波信号を2次元プロッタに送って、ちょうどリサジュー図形のように「脳波を描く」というものである。 これまた十分に怪しい(^_^;)。 写真を見てみると、脳波ヘッドギアをかぶった被験者は目を開けていて、自分の脳波プロット図形を眺めている。 まさに「脳波バイオフィードバック」であるが、昨日の実験でも分かるように、開眼していれば、脳波信号は通常時から吹っ飛ぶほど、表情筋や外眼筋などの筋電ノイズで「見えなく」なっているので、この実験風景写真からだけでも、「怪しい」と断言できるのだ。 さすが脳波である。
そして、上の EEG-Based Brain-Computer Interface and Its Applications:A Study on Practical Use of Electrophysiological Responses というのもまた、相当に怪しいものである。 論文 ★ もあるようだが、「Brain-Human Interface」は脳波を取るとしても、これを2つ繋げて「脳波経由で人間同士がコミュニケーションする」というのには、ちょっと無理がある。 脳波を検出するのはいいとして、システムから人間の脳にどういう信号を送るのだろうか。 まさか ピリピリ 電極を頭にぶちこむのだろうか(^_^;)。 元々は一方通行の 研究 ★ をしている人が関係しているようだが、まさに怪しさ全開である。
この他にも、上の「マインドコントロールでクルマを運転」というテスラの怪しいお話( YouTube )などもあったが、 OpenBCI Radio Configuration Utility という、実際的に役立つ情報も発見した。 さすが脳波コミュニティ、玉石混交でちょっと凄い世界である。
2017年2月6日(月)
新しい週に入ってしまった。 先週は、水曜日に 3回生「メディア造形総合演習I」 最終合評 、木曜日に 2回生「インタラクティブプロダクト演習」 最終合評 、金曜日に 「メディア数理造形演習」の追い込み があり、週末は SUACメディアデザインウィーク「スケッチング」ワークショップ ということで、 1日目 、 2日目 、とあっという間に過ぎ去った。 SUACの学内を、マルチメディア室とギャラリーと1106研究室との間でどれだけ行き来したか分からないが、まぁいい運動になった。 ワークショップの3チームはそれぞれ、なかなかに素晴らしい成果をまとめ上げた。 デザイン新入生の「43虎」にもいい刺激となっただろう。 以下はYouTubeの記録動画である。2017年2月7日(火)
昨日の月曜日には昼休み〜3限に 「メディア数理造形演習」の前日追い込み があり、いよいよ今日の4-5限が最終調整→最終合評である。 そんな中、 SUACメディアデザインウィーク「スケッチング」ワークショップ で京都精華大の平野さんが紹介してくれたTWE-Liteに関する2冊の本が、以下のようにSUACに向かっている。(^_^)
そして、RAKASU PROJECT.さんからは このように 写真と動画の記録が届いた。 実際には強烈に大きな写真であるが、全ていつものようにVGAに縮小した。 ムービーに「TeamB」が無いのは、RAKASU PROJECT.さんがオペレーションをしていたからである。 高解像度の写真が御希望の場合には、別途、問い合わせされたい。
さらに、去年は充電的スキップされていた Sketching in Hardware 2017 の情報が遂に届いた。 さっそく参加費750ドルを支払い、フライトを予約購入した。 既に燃油サーチャージは再開していたが、3月か4月になればさらに値上げとのことなので、早いにこしたことはない。 場所は以下のようにデトロイト、五大湖地域で近いかと思ったら、シカゴから飛行機の距離だった。
Sketching in Hardware 2017 のテーマは「Radical Hardware」であり、Google翻訳に突っ込んだ解説は「 技術は中立ではありません。 ツールは中立ではありません。 すべてのツールには、その中に容易に使用可能な最終結果のエンベロープと、摩擦を生成するその他のエンベロープがあります。 これらの影響のうちのいくつかは意図的であり、特に、世界を感知して直接的にそれを実行する計算処理の情報処理ツールの複雑な世界ではそうではありません。 私たちは、負のものよりも世界にプラスの影響を与えることを容易にするツールをどのように作っていますか? テクノロジーを簡単にまたは安くするだけでは、必ずしもそれが改善されるわけではなく、良いデザインは良いデザインと同じではありません。 」とのことであった(^_^;)。
そして4-5限には 「メディア数理造形演習」最終合評 があり、上のように4チームとも充実の内容で作品制作を完了した。 さらに細部をチューンアップして春休みにでも撮影スタジオで記録をとるかどうか・・・はそれぞれの判断だが、とりあえず内蔵したシステムを他に使うために壊すことなく、当面はそれぞれ保管しておこう。
2017年2月8日(水)
学期末、年度末に向けてあれこれが粛々と進む時期である。 今日はデザイン研究科の修士報告会があり、ゼミの杉浦さんも無事にプレゼンを済ませた。 これでゼミ関係で残ったイベントは、来月初旬に予定しているゼミ打ち上げ(カラオケマラソン)だけである。 MDWのギャラリーでの展示のうち担当分を撤収するとクタクタになり、研究室に戻って、とりあえず忘れないように、この後期の学生たちの作品に関するMax7パッチをここで整理しておくことにした。 以下は4回生・馬ブンさんの卒制の、「右手で円を、左手で方を」である。 leap motionで受けた情報を、IAMASの赤松さんの「aka_leapmotion」オブジェクトで取得して、jitterで描画する「道」をなぞるというものである。
以下は大垣でのOMMF2016で展示した、Team「さば」の「おせんべい屋さん」である。 MacのUSBを2ポート使って、Max7は2つのシリアルポートとして通信するfelicaのリーダをダブルで持ち、4枚のおせんべいに仕込まれたfelicaのIDを読み取る部分は僕が作ったが、ゲーム部分そのものは3人の2回生(当時)の力作である。 ここまでの完成度に至るのはなかなか珍しく、「寿司」「おはなしパネル」と並んで動態保存作品として活躍している。 サブパッチがとても多いので、重ねながら表示してもスクリーンショットは軽く4画面となった。
以下は大垣でのOMMF2016で展示した、第43期・虎の穴の、デザイン学科新入生4人の作品である。 「arduinoSerialreader」というのは、標準的な「Arduino2Max」のものをそのまま使っていて、ここから取得した赤外線距離センサで来場者が来たことをセンシングすると、音を鳴らすとともに用意された動画を再生しつつ、紅葉の盆栽のような造形の葉に仕込まれた暖色のLED が明滅する・・・という作品である。 さらに改訂して春休みに撮影スタジオで記録をとり、その後に展示する動態保存作品となるのかどうか、見守っていこう。
ここからは、 2回生「インタラクティブプロダクト演習」 で僕が支援した4人の課題作品である。 演習の統一テーマが「楽器を作る」なので、4人ともある意味で「楽器」と言える作品となった。 以下のMax7パッチとArduinoプログラムは木村さんの作品のためのもので、僕が綺麗に加工したスイッチボックスを使った演奏マシンである。 3つのスナップスイッチはBGMを選択し、内蔵LEDで光る(これはArduinoファームウェアが点灯させている)4つのボタンスイッチでサンプリング音の「合いの手」を鳴らせる、というものである。 今後、BGMを含めて全てオリジナル制作(作曲)したい・・・と言っていたが、どうなるか、見守ろう。
int x = 0; int y = 0; int ledpin = 13; void setup() { pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, INPUT); pinMode(7, INPUT); pinMode(8, INPUT); pinMode(9, INPUT); pinMode(10, INPUT); pinMode(11, INPUT); pinMode(12, INPUT); Serial.begin(115200); digitalWrite(13,HIGH); delay(600); digitalWrite(13,LOW); pinMode(13,INPUT); } void loop(){ if (Serial.available() > 0){ if (Serial.read() == 'r') { for (int pin= 6; pin<=12; pin++){ x = digitalRead(pin); y = pin - 4; if (x == 0){ digitalWrite(y,HIGH); } else{ digitalWrite(y,LOW); } sendValue (x); } Serial.println(); delay (5); } } } void sendValue (int x){ Serial.print(x); Serial.write(32); }以下のMax7パッチとArduinoプログラムは清水さんの作品のためのもので、基本的には非常勤の久世先生が提供した素材(タッチスイッチ基板と対応したArduinoプログラム)をベースにアレンジした。 なんといってもこの作品では、木製の半球(工芸屋から購入)に、細かい真鍮の粉をアロンアルファで固めたものをタッチ電極とした事が、僕にとっても初めての経験だった。 MIDIソフトシンセのパーカッシプ楽器音をペンタトニックスケールで鳴らす「楽器」として、4人のうちではこの作品だけ、MDWに展示出品した。
#include <Wire.h> #include "Adafruit_MPR121.h" Adafruit_MPR121 cap = Adafruit_MPR121(); uint16_t lasttouched = 0; uint16_t currtouched = 0; int touchData[8]; void setup() { Serial.begin(115200); if (!cap.begin(0x5A)) { while (1); } } void loop() { currtouched = cap.touched(); for (uint8_t i = 0; i < 7; i++) { if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) { touchData[i] = 200; } touchData[i] *= 0.99; } lasttouched = currtouched; Serial.write(255); for (int i = 0; i < 7; i++) { if (touchData[i] >= 255)touchData[i] = 254; Serial.write(touchData[i]); } delay(10); }以下のMax7パッチは宮本さんの作品のためのもので、これに対応したArduinoプログラムは、この日記の「2016年12月8日(木)」のところにある。 この「楽器」は、100円ショップで仕入れたスチールたわしに多数のハンダを差し込んで作った「金属毛虫」みたいな造形であり、触れると悲鳴や絶叫が出てくる・・・というセンセーショナルなものである。 膨大なサウンドライブラリから自分の感性で鳴らすサウンドを選択して、それぞれツールを使って加工して、さらにaiffファイルにコンバートする・・・という作業は全て自分で進めたが、次のステップとして何をやってくれるか、期待したい。
以下のMax7パッチは大隈さんの作品のためのもので、だいぶ過去に製作した「スイッチ→MIDI」センサに、キーエンスの赤外線反射型通過センサを2系統、接続している。 SUAC文芸センターのスロープに向かう通路にこの通過センサを仕込んで、そこを通り抜ける人の歩く速度を2つの赤外線ビールを過る時間差として検出して、鳥の声のBGMに加えて、スピードに対応した「風の音」が鳴る・・・というインスタレーション作品である。 膨大なサウンドライブラリから自分の感性で鳴らすサウンドを選択して、それぞれツールを使って加工して、さらにaiffファイルにコンバートする・・・という作業は全て自分で進めたが、最終発表の日を1週間勘違いしていて、注文した材料が届かずに造形部分がとても残念に終わってしまったので(^_^;)、ぜひ次作品でのリベンジを期待したい。
以下のMax7パッチは学生作品のシリーズとは別に、 SUACメディアデザインウィーク「スケッチング」ワークショップ の「Team-C」が制作した作品のものである。 この作品については、最後のプレゼンの時のYouTube動画 ★ ★ を見たとしてもなかなか伝わらないのが辛いところなのだ。 鑑賞者はまず、赤外線ヘッドホン(ここでは同時に10人が同じサウンドを聴取)をかぶるが、そこに飛ばすサウンドは、バイノーラル録音のためのダミーヘッドマイクに入ってきたサウンド「そのもの」である。 そして、Max7のパッチでは、ダミーヘッドマイクに直接貼り付けた5個のコンタクトマイクの音(ダミーヘッドをペタペタと撫でる)と、さらにダミーヘッドの口の部分に貼り付けたleap motionに対して「おまじない」身振りをして生成された情報に対応したフォルマント合成音声ロングトーンとが、小型スピーカから出力されて、このサウンドがダミーヘッドマイクの周囲をうろうろする・・・という作品なのだ。 これでどんな風に気持ち悪い体験を堪能できるのか、というのを想像しながら、 YouTube動画 ★ ★ を見て欲しい。
そしてここからが、昨日の 2回生「メディア数理造形演習」 での、それぞれ3人チームによる4作品のMax7パッチである。 YouTubeに上げた動画とともに眺めてみるのが楽しいだろう。 まず、以下のMax7パッチとArduinoプログラムは 地球防衛軍 「めざせ! 怪獣王」 (木村・清水・野田) のためのものである。 浜松駅前地区のジオラマの中に、CdSによる12チャンネルの光センサをArduinoで新たに作ったものを仕込み、さらに爆発の光は、過去に作った「MIDI→24チャンネル・LEDベルトPWM制御」システムから断線していない12チャンネルを使っている。 過去に秋月電子から仕入れていた「レーザ装置」が初めて活躍して、まさにゴジラになった気分で気持ち良く街を破壊攻撃できる。
int x = 0; void setup(){ Serial.begin(115200); } void loop(){ if (Serial.available() > 0){ if (Serial.read() == 'r') { for (int pin= 0; pin<=12; pin++){ x = analogRead(pin); sendValue (x); } Serial.println(); delay (5); } } } void sendValue (int x){ Serial.print(x); Serial.write(32); }次に発表した ctrl-Z 「PPAP」 (朝枝・加藤・西村) のMaxパッチは、どうも最終版を受け取るのに失敗したようで、手元ではうまく開かなかった。 そして以下のMaxパッチは、 わかめ同好会 「パンケーキアート」 (玉井・吉田・筒井) のものである。 これは実際には「液タブ」で描く、という機能を加えたので、ユーザはおよそ以下の上のような画面を眺めつつ、実際に液晶タブレット上にペンで描画できる。 そのために、Max7の本体パッチの左端に縦配置でボタンとスライダーを並べて、使いやすくまとめた。
そして最後が、 おくるかい 「おばけろうそく」 (寺岡・山本・小林) のための以下のMax7パッチである。 スクリーンに入らないので「75%」に縮小しているので、実際には広大なパッチに、5個の3色LED、つまり15個のLEDのPWM制御のための努力がずらりと並んでいる。 システムとしては、過去に院生の修了制作のために作ったシステム(21個のセンサ入力、63個のLEDのPWM制御)を活用したが、長いケーブルとともに、5本のロウソクと蝋燭台の造形を制作して、さらに時間内に消したロウソクのスコアまできちんと計上するわうに仕上げた力作である。
こうやって並べてみると、この後期にもたくさんのインタラクティブ作品のプラットフォームとして活躍したMax7、というのをひしひしと感じる。 この日記もあれこれ寄り道しているが、やはり、基本はMax7なのである。(^_^)
2017年2月9日(木)
この週末にはとりたてて予定もなく、 一昨日のアカペラで呟いても誰も食い付いてこなかったのでカラオケも無しである。 いつもの事で他にもあれこれ「やるべきこと」はあるが、ちょうどAmazonから2冊の解説本が届いたので、メディアデザインウィーク「スケッチング」ワークショップ ★ ★ で平野さんが解説してくれた、TWE-Liteと遊ぶタイミングが到来した。 これは約1年前、 ここ と ここ と ここ でちょっとだけ触って、あとは欧露ツアーに向けての忙しさで放置していたのである。
そこでまず、上のように写真を撮って、平野砂峰旅さんに確認の質問メイルを出した。 なにやらシールが貼られているのと、実際に使用したTWE-Liteでは設定が書き込まれているからである。 そして以下のように、まずは購入時の状態と思われるMonoStickを挿して、 ここ と ここ と ここ でやった事を思い出そうとターミナルを開いて、P2525を接続してうりうり叩くと何か16進文字列が届いて表示される、というのをまず確認した。
そして次にMaxを起動して、とりあえず「serial b 115200」でも何かがP2525から届くか・・・と試そうとしていたところで、以下のようなものを発見した。 なんとタイムスタンプは去年の11月中旬だが、「Max7日記」などには何も書いていなかった。 おそらく半日程度の合間にフト実験したものらしいが、けっこうそれっぼい情報をちゃんとMax7で受け取って表示している。 「TWE-Lite本」とかを知らずに、おそらくTWE-Liteのサイトにある情報を発掘して解析を試みていたらしい。 ここまで一気にスタートラインが上がれば、今度は解説本もあるので、なかなか快適に進むかもしれない。
しかしここで、デザイン学科会議、さらにメディア造形学科会議という予定に阻まれた。 なかなか集中して継続する時間が取れないのが辛いところで、こうなると週末に出来た空白は、こういう作業に充てるというのもアリなのかもしれない。
2017年2月14日(火)
先週金曜日から始まって今週の金曜日まであと3日間は、時間がある限り、T○Y○T○との共同研究の最終成果物としてのMax7プログラミングに没頭し続けている。 既におそらく、これまで僕がプログラミングしたMaxパッチで最大規模の巨大・複雑なMaxパッチになっているが、あと少し、この修行は続く。 詳しいことは今年の秋以降にならないと学会発表できない約束なので、ここでは何も書かない。(^_^;)
そんな中、上のようなメイルが届いた。 久しぶりであるが、今年のコペンハーゲンでのNIME2017の論文査読者(paper referee)の依頼である。 このクソ忙しい時に・・・と言うわけにもいかず、引き受ける手続きをとった。 およそ5本の応募論文に対して、規定のコメントシートに従ってコメントを書いてスコアを付ける、というボランティアのお仕事である。 さすがにNIMEに依頼されたのでは、自分は既に2件も匿名で応募しているとはいえ、協力する以外の選択肢はないのだった。
2017年2月16日(木)
卒展の初日である。 以下のように、浜松の朝は2℃と寒く最高気温も14℃だが、この週末の沖縄は最低気温が16℃、最高気温が24℃だという。 今年も座間味島に渡ってホエールウォッチングの予定だが、幸運にも天気には恵まれそうで、いやが上にもテンションが上がる。
先週金曜土曜、そして今週の月曜火曜水曜、と計5日間、ほぼ朝から晩まで追い込んだMax7プログラミングは、昨日の夕方に、以下のようにほぼ終結した。 さすがに過去最高の巨大Maxプログラミング、計3つのMaxパッチを同時に走らせることでシステムは動くが、以下はその中にあるサブパッチまで全て開いてスクリーンショットを撮ってみたもの(ただし学会発表までは拡大画像はピンぼけ版(^_^;))である。 この全てのパッチ/サブパッチの隅々にまで視線が行き渡って、初めてシステムというのは正しく動いているのだが、さすがMax7日記、なかなか壮観だ。 ただしプログラミングというのはカレーと同じで、「寝かせると練れてくる」ものなので、沖縄行きを挟んで来週後半にさらに手直しする余地を残しつつ、今週の作業はいったん終了、と判断した。 今日と明日はそれぞれ午後に予定もあるので、その合間には、しばし棚上げしていたTWE-Liteと遊ぶ時間としたいのだ。
・・・とスクリーンショットを整理していると実習指導室から電話があり、空間造形の学生が卒展の展示に使うデータの入ったUSBメモリを折ってしまったのだという(^_^;)。 とりあえず様子を見るのに研究室に来るように伝えてもらったが、これは過去にはうまくいかなかった記憶しかない。
しかし今回は破損の程度が良かったこともあり、 このように 無事に修理とレスキューが成功した。 作業時間は20分ほどだが、38GBのデータのコピー(バックアップ)に30分以上かかった。 以下の、修理したUSBメモリは、僕のものと交換してもらって教材にすることにした。
そして午後イチで防寒着を着てギャラリーに行ってみると、何故か誰もいないしギャラリーにはまだ脚立が立っていて、まったく卒展が始まっていなかった。 どうやら明日かららしい。 そこで研究室に戻り、以下のようにMDWワークショップでさぶろさんが活用したTWE-Lite関係と、Amazonから届いて不要な部分を捨てて身軽になった2冊の解説本の「要るところ」を並べて、午後に出かけるまでのわずかな時間を「調査」に費やした。
まず手元の資料として、MDWワークショップが終わった直後にさぶろさんに問い合わせのメイルを出していた、以下のそのリプライがスタートラインである。 ここでは僕の手持ちのMONOスティックとかTWE-Lite DIPを貸し出して、さぶろさんが何か書き込みしているものがあるので、その確認である。
これはなかなか重要な情報である。 僕はまだ、MonoStickもTWE-Liteなどもまったく買ったままで持っているが、実際にさぶろさんチームのインスタレーション(ゲーム)で動かすためにカスタマイズ書き込みをしたものが現存する、となれば、それを実験するところから始められるのである(^_^)。 手探りの最初の段階で、実際に動くものがある、というのはとても大きい。 上の情報から、シールを貼られたMONOスティックは「親機用の無線タグアプリ」が書き込まれているようである。 しかし、僕の手元のTWE-P2525は全てdefault状態なので、これを連続情報送信タグに変身させることが当面の目標となった。> そこでTWE-Lite関係を入れた箱を開けたのですが、さぶろさんが設定したものと混在しているので、 > 添付写真とともに確認させていただきたいのです。以下の質問にご回答いただければ幸いです。 > (1)たぶん旧版のToCoStickは何もしていない、買った初期状態のままですよね? はいそうです. > (2)MonoSTICKが2個ありますが、おそらく > ・シールの貼られたものはさぶろさんが何か設定変更したもの > ・シールの無いものは買った初期状態のまま > だと思いますがどうでしょうか。YESであれば、シールのものはどうなっているのか、簡単にお知らせ下さい。 TocoStick,MonoStickで設定を変更したのは,シールを貼ったものだけです. > (3)今回、TWE-Lite DIPを4個作って、そのうち2個を写真のように基板に搭載して、実際にチームAが使っていました。 > まず、写真に写っていない2個は買った初期状態のままですよね? はいそうです. > (4)そして写真のTWE-Lite DIP基板の2個ですが、片方にだけシールが貼られています。 > これはどういう設定になっているのか、簡単にお知らせ下さい。 これは,2つとも同じ設定です.(片方だけなのはシールを貼るのを忘れていただけです.) MONOSTICKには, https://mono-wireless.com/jp/products/TWE-Lite-2525A/manual_App_tag.html に説明されているのですが, App_Tag_Parent_JN5164_MONOSTICK_1_6_2.bin を書き込んでいます. TWE-LITE Dipの方は, App_Tag_EndDevice_Input_JN5164_1_6_2.bin を書き込んでいます. これらのファイルは, https://mono-wireless.com/jp/products/TWE-APPS/App_Tag/firmware/Samp_Monitor_bin_1_6_2.zip に含まれています. https://mono-wireless.com/jp/products/TWE-APPS/App_Tag/download.htmlに解説があります. 設定の変更については https://mono-wireless.com/jp/products/TWE-APPS/App_Tag/interactive.html を参照してください. 僕の記憶では,TWE-LITE DIP側の d: set Sleep Dur (5000) という項目を,50に変更していると思います.データの送信周期が50msecということです. ご不明な点があれば,連絡ください.TWEモジュールファームウェア書き込みユーティリティ ※ 本ユーティリティはシェル(コマンドラインツール)の利用が前提となります。 ■ 構成 - jenprog.app (jenprog.py) jenprog コマンドラインツール (Python 不要のバイナリ形式) TWE無線モジュールにファームウェアを書き込むためのツールです。 ※ .app 形式ですがコマンドラインツールです。 SDK マニュアル、jenprog.src/readme-j.txt を参照してください。 - tweusb ToCoStick, TWE-Lite R 用のプログラムモード設定・リセットユーティリティ。 tweusb.src/readme-j.txt を参照してください。 - jenprog tweusb と jenprog.app を呼び出すためのスクリプト ■ jenprog スクリプト jenprog.py と tweusb を呼び出すための簡易スクリプトです。 ファームウェアの書き込みにはこのスクリプトを使用すると簡便です。 [インストール] スクリプトはパスの通ったディレクトリにシンボリックリンクを作成します。 TWESDK は $HOME/TWESDK に展開し、$HOME/bin にパスが通っているとすると、 以下のようにリンクを張ります。 $ cd $HOME/bin $ ln -s $HOME/TWESDK/Tools/jenprog/jenprog ./jenprog [注意] ※ スクリプト中で sudo コマンドを実行するためパスワードの入力が求められます。 ※ スクリプト中で、デバイスドライバのアンロードとロードが実行されるため、 複数同時実行は出来ません。 [実行例] ・jenprog -l FTDI チップのデバイスを列挙する。 $ jenprog -l # TWEUSB device list (num=2) # ID,S/N,Desc 0,AHWZRBS5,TWE-Lite-USB 1,FTF5YI3Q,TTL232R-3V3 ・jenprog -f {serial or id} [...] tweusb を呼び出した上、jenprog.py を呼び出す。 パラメータには -l オプションで列挙される数値またはシリアル番号を指定する。 $ jenprog -f 0 SET AHWZRBS5 INTO PROGRAM MODE *** jenprog ver 1.3 *** <--- 以降 jenprog.py の実行 flash : JN516x Internal Flash chip id : 0x10008686 mac addr: 0x001bc50121002833 (tweusb 実行後 jenprog.py -f /dev/tty.usbserial-AHWZRBS5 と同様) $ jenprog -f 0 myfirm.bin SET AHWZRBS5 INTO PROGRAM MODE *** jenprog ver 1.3 *** file info: 04 03 0008 writing... 0%..10%..20%..30%..40%..50%..60%..70%..80%..90%..done - 7.85 kb/s done OK: firmware is successfully programmed. (tweusb 実行後 jenprog.py -f /dev/tty.usbserial-AHWZRBS5 myfirm.bin と同様) ・jenprog -r {serial or id} TWEモジュールををリセットする。 ・jenprog -t ... jenprog.py をそのまま呼び出す。 $ jenprog -t /dev/tty.usbserial-AHWZRBS5 *** jenprog ver 1.3 *** flash : JN516x Internal Flash chip id : 0x10008686 mac addr: 0x001bc50121002833解説本に載っているURLは「そんなページはありません」と散々だったが、無線タグにOTA(無線経由での書き込み)で設定を書き込むためには、まずはMonoStickのうち1本を「OTAライタ」にする必要がある、と分かってきた。 ただし本に載っているのはWindows用なので、まずは「TWESDK」をダウンロードして(このSDKでTWE-Lite関係のファームウェアのブログラム開発を行うには、まずはeclipse環境を入れるところから必要なのでこれはちょっとパス)、「jenprog」というツールをコマンドラインから使用すればいいという事で、以上の「readme.txt」と下の「readme_j.txt」を入手した。
これはなかなかにそれっぽい、ちょっと実験したくなるドキュメントである。 しかし残念、ここで午後の外出の時間となってしまった。 月に一度の、主治医めぐり(クスリ受け取り)であるが、花粉症が爆発してきた昨今、耳鼻科では相当に待つことを覚悟しないといけない。 ここまでで167KBと、この「Max7日記 part(5)」もほぼ区切りの分量になってきたが、せっかくなので明日にちょっとでもこの続きができたら、そこを区切りとして part 6 に進む事にしよう。jenprog 簡易解説 ■ オプション -a ADDR, --address=ADDR start reading at address |読み取りアドレス -l LEN, --len=LEN number of bytes to read |読み込みバイト数 -m MAC, --mac=MAC reset the mac addr (e.g. -m 01234567ABCDABCD) |フラッシュ領域の mac アドレスの設定を行います。 |※通常は書き換え禁止OTP領域にアドレスが記載されているので、本指定に意味はありません。) -k KEY, --key=KEY reset the license key |ライセンスキー情報の設定 -v, --verify also verify after writing |ファームウェア書き込み後にべリファイを行います -z, --compare compare between flash content and specified file |指定ファイルとフラッシュの内容を比較する -s, --show show mac address and license key |アドレス情報などの表示 -e, --erase erasing the flash after reading mac and license key |フラッシュ内容の消去 -b BAUD, --baud=BAUD baud rate for serial connection. |-b 38400 のみ有効。デフォルトの低速度で UART 通信する -t TARGET, --target=TARGET target for connection |通信先デバイス 例:COM4, /dev/ttyUSB0 -F, --force skip firmware compatibility |バイナリヘッダ情報が違っていても書き込みを行う ■ MAC アドレスの表示 # jenprog -t /dev/ttyUSB0 -s flash : ST M25P40 chip id : 0x10804686 mac addr: 0x001bc501207015da ■ MAC アドレスの書き込み # jenprog -t /dev/ttyUSB0 -m 11223344AABBCCDD erasing sect #0 ... MAC/Lic was updated as below... flash : ST M25P40 chip id : 0x10804686 mac addr: 0x001bc501207015da ■ ファームウェアの書き込み # jenprog -t /dev/ttyUSB0 SmplTag_Coord_JN5148_200_0.bin writing... 0%..10%..20%..30%..40%..50%..60%..70%..80%..90%..done - 5.79 kb/s writing mac address and key...done OK: firmware is successfully programmed. ■ ファームウェアの書き込み+べリファイ # jenprog -t /dev/ttyUSB0 -v SmplTag_Coord_JN5148_200_0.bin erasing sect #0 ... writing... 0%..10%..20%..30%..40%..50%..60%..70%..80%..90%..done - 5.78 kb/s writing mac address and key...done verifying... 0%..10%..20%..30%..40%..50%..60%..70%..80%..90%..done - 9.69 kb/s OK: firmware is successfully programmed. ■ ファームウェアのべリファイのみ # jenprog -t /dev/ttyUSB0 -z SmplTag_Coord_JN5148_200_0.bin verifying... 0%..10%..20%..30%..40%..50%..60%..70%..80%..90%..done - 9.69 kb/s OK: firmware is successfully programmed.2017年2月17日(金)
どうやら今日が本当の卒展の初日らしい。 朝イチでまず、以下のようにApp Storeに行って、まだお仕事Macに入れていなかったXcodeのダウンロードを始めた。 WiFiでなく朝7時の快適LANで「1時間35分」ということは、おそらく数GB以上のブツであるが、刻々とダウンロードしているのに何分経ってもこの数字がなかなか減らない(^_^;)。 昨日の最後あたりで、TWE-Liteの書き込みツールを使うには「jenprog」というツールをコマンドラインから使う必要があるが、たしかそのCommand Line ToolsはXcodeの追加インストールで可能になる・・・という遠い記憶があったからである。
そして当面、関係するところはほんの数ページだけであるが、SDKの奥底に このようなSDKマニュアル も発掘した。 ところがXcodeを調べてみると最新の(当然だが)バージョンになっていて、ここには このような 困ったちゃん情報が関係していた。 以下のように、いま入れたばかりの最新のXcode8(なんと12.36GBもあった)は、それまでのCommand Line Toolsが対応していない、というのである(^_^;)。
しかし世の中、なかなか頼もしいページがあるもので、阪大の 教授でもできる というページから導かれてApple Developerのダウンロードサイトに行ってみると、そこにあった「Mac OS X 10.11 El Captainの場合は、"Command Line Tools (OS X 10.11) for Xcode 7.3」でなく、ちゃんと最新の「Command Line Tools (OS X 10.11) for Xcode 8.2」というのがあって、無事に以下のようにゲットして、インストールできた。(^_^)
そして、明日から一緒に沖縄に行く学生2人とのミーティングをまたいで、久しぶりのコンソールからUnixスクリプトと格闘すること数分、なんとなくうまく行きかけたものの、以下のようにMONOSTICKとの通信エラーということで、「OTAライタ」にするためのバイナリの書き込みに成功しなかった。 あれこれ試してみたが、一貫して「error 2」という、おそらくシリアル通信が成立していないというエラーで先に進まない。 なかなか厄介なところに入り込んでしまったようである。
そしてその後には、学内を速攻で1時間ほどかけて回って、今日しか見られない 卒展2017 を見て回り、研究室に戻ると休学希望学生の面談アポなどが飛び込んできた。 午後には卒展を見に来た地元企業の人との懇談会に出席しなければならず、予想/覚悟していたようにTWE-Liteへのアタックの腰が折れてしまった。 しかし、毎回きっちり「ERROR(2): communicate with the target」と出る、というのは逆に清々しいので、原因もシンプルなようにも思えた。 そこでSDKの「jenprog」のPythonソースを見てみると、以下のように(長いのでコメント行は適宜カット)、全てのエラー番号は「2」だが、このメッセージは「TypeError」が原因である、と読めてきた。Last login: Fri Feb 17 11:46:14 on ttys000 nagasm-Mac-mini:~ nagasm$ ls App_Tag_EndDevice_Input_JN5164_OTA_2_0_1.bin Desktop Documents Downloads Library Movies Music Pictures Public Sites jenprog nagasm-Mac-mini:~ nagasm$ ls -l /dev/tty.* crw-rw-rw- 1 root wheel 18, 0 2 17 06:44 /dev/tty.Bluetooth-Incoming-Port crw-rw-rw- 1 root wheel 18, 8 2 17 11:46 /dev/tty.usbserial-MW8UKAW nagasm-Mac-mini:~ nagasm$ ./jenprog -l sudo: a password is required Password: # TWEUSB device list (num=1) # ID,S/N,Desc 0,MW8UKAW,MONOSTICK nagasm-Mac-mini:~ nagasm$ ./jenprog -t /dev/tty.usbserial-MW8UKAW App_Tag_EndDevice_Input_JN5164_OTA_2_0_1.bin *** jenprog ver 1.3 *** ERROR(2): communicate with the target nagasm-Mac-mini:~ nagasm$・・・そしてここで思い出したのが、Open-BCIのところで出てきた、「 Fixing FTDI InBufferSize for OS X - Mac OSX(当面は10.9〜10.11)はUSBドングルのシリアル処理を行うvirtual com port (VCP) driverの問題でリアルタイム通信でデータ落ちがあるので、その解決法だという。ただしsystem configurationを書き換えて、さらにFTDIドライバを最新のものでなくちょっと古いやつに入れ替える必要があるらしい」、というものだった。 まさにここで直面しているトラブルと根が一緒である。 VCPドライバが進展して解決してくれればいいが、うーーーーーむ、である。(^_^;)#!/usr/bin/env python #!C:/Python27/python from optparse import * from time import time from sys import stdout, stderr, exit from os import SEEK_END, SEEK_SET, chdir, getcwd from struct import pack version = "1.3" stderr.write("*** jenprog ver %s ***\n" % version) err_code = 0 def error_exit(status=2, msg=""): global err_code stderr.write("\nERROR(%d): %s\n" % (status, msg)) err_code = status exit(err_code) def bl_show (bl): stdout.write(" flash : %s %s\n" % (bl.flash_manufacturer, bl.flash_type)) # stdout.write(" chipid: %08x"%(bl.read_chipid())) # stdout.write(bl.read_chipid()[0]) bl.read_chipid() stdout.write(" chip id : 0x%08x\n" % bl.chipid) stdout.write(" mac addr: 0x") for b in bl.read_mac(): stdout.write("%02x" % b) stdout.write("\n") if bl.flash_jennicid == 0x8: lic = bl.read_license() if not lic == None: stdout.write(" license : 0x") for b in bl.read_license(): stdout.write("%02x" % b) stdout.write("\n") parser = OptionParser() parser.add_option('-a', '--address', dest='addr', type='int', help='start reading at address', metavar='ADDR', default=0x00000000) parser.add_option('-l', '--len', dest='len', type='int', help='number of bytes to read', metavar='LEN', default=0) parser.add_option('-m', '--mac', dest='mac', help='reset the mac addr (e.g. -m 01234567ABCDABCD)') parser.add_option('-k', '--key', dest='key', help='reset the license key') parser.add_option('-v', '--verify', action='store_true', dest='verify', help='also verify after writing') parser.add_option('-z', '--compare', action='store_true', dest='verify_no_write', help='compare between flash content and specified file') parser.add_option('-s', '--show', dest='show', action='store_true', help='show mac address and license key') parser.add_option('-e', '--erase', dest='erase', action='store_true', help='erasing the flash after reading mac and license key') parser.add_option('-b', '--baud', dest='baud', type='int', help='baud rate for serial connection.', metavar='BAUD', default=500000) parser.add_option('-t', '--target', type='string', help='target for connection', dest='target') parser.add_option('-F', '--force', action='store_true', dest='force', help='skip firmware compatibility') parser.add_option('-C', '--list-com-ports', action='store_true', dest='lscom', help='skip firmware compatibility') parser.add_option('-D', '--current_dir', dest='cdir', help='current directory') (options, args) = parser.parse_args() if options.cdir: chdir(options.cdir) stderr.write("CHDIR: %s\n" % getcwd()) if options.lscom or options.target == None: import con_serial ports = con_serial.list_serial_ports() print "Found ports:" for n in ports: print "%s" % n exit(2) options.conn = 'serial' bl = None if options.conn == 'serial': import con_serial from serial.serialutil import SerialException try: bl = con_serial.SerialBootloader(options.target, baud=options.baud) except TypeError, detail: error_exit(2, "communicate with the target") except SerialException, detail: error_exit(2, "access the serial port") else: raise Exception('nahh') if options.show: bl_show(bl) elif options.erase: bl.erase_flash_full() bl_show(bl) elif len(args) != 1: if options.len > 0: import sys if sys.platform == "win32": import os, msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) block, i, start = bl.preferedblocksize or 0xf0, 0, time() for addr in xrange(options.addr, options.addr + options.len, block): for byte in bl.read_flash(addr, block): stdout.write("%c" % byte) if addr > ((options.addr + options.len) / 10.*i): stderr.write("%i%%.." % (i * 10)) i += 1 kb, sec = options.len / 1000., (time() - start) stderr.write("done - %0.2f kb/s\n" % (kb / sec)) elif options.mac or options.key: if bl.flash_jennicid == 0x8: stderr.write("MAC Update is not supported.") else: if options.mac: bl.set_mac(options.mac) if options.key: bl.set_license(options.key) bl.erase_flash([0]) if options.mac: bl.write_mac() if options.key: bl.write_license() stderr.write("MAC/Lic was updated as below...\n") bl_show(bl) else: bl_show(bl) exit(0) else: file = None try: file = open(args[0], "rb") except: error_exit(2, "file access."); wdata = None if bl.flash_jennicid == 0x8: file.seek(0, SEEK_END) size = file.tell() - 4 file.seek(0, SEEK_SET) fhead = file.read(4) flash_size = ord(fhead[0]) ram_size = ord(fhead[1]) chip_type = ord(fhead[2]) << 8 | ord(fhead[3]) stderr.write(" file info: %02x %02x %04x\n" % (flash_size, ram_size, chip_type)) if options.force: pass else: if not (flash_size == 0x04 and ram_size == 0x03 and chip_type == 0x0008): error_exit(2, "unsupported binary for JN5164, use -F option.") file.seek(4, SEEK_SET) wdata = file.read(size) file.seek(4, SEEK_SET) else: file.seek(0, SEEK_END) size = file.tell() file.seek(0, SEEK_SET) wdata = file.read(size) file.seek(0, SEEK_SET) if options.force: pass else: m = [] for x in [0x2, 0x3, 0xc, 0xd, 0xe, 0xf]: m.append(ord(wdata[x])) if m != [ 0xE0, 0xE0, 0x01, 0x06, 0x00, 0x35 ]: error_exit(2, "unsupported binary for JN5148, use -F option.") if not bl.flash_jennicid == 0x8: if options.mac: bl.set_mac(options.mac) if options.key: bl.set_license(options.key) block, i, start = bl.preferedblocksize or 0x80, 0, time() data = file.read(block) addr = 0x00000000 try: exit_status = None if not options.verify_no_write: if bl.flash_jennicid == 0x8: bl.erase_flash_full() else: if size > 64 * 1024: bl.erase_flash([0, 1]) # erase sector #0,1 else: bl.erase_flash([0]) # erase only sector #0 stderr.write("writing...\n ") while len(data) != 0: bl.write_flash(addr, data) addr += len(data) data = file.read(block) if addr > (size / 10.*i): stderr.write("%i%%.." % (i * 10)) i += 1 kb, sec = size / 1000., (time() - start) stderr.write("done - %0.2f kb/s\n" % (kb / sec)) if not bl.flash_jennicid == 0x8: stderr.write("writing mac address and key...") bl.write_mac() bl.write_license() bl.finish() stderr.write("done\n") if options.verify or options.verify_no_write: stderr.write("verifying...\n ") wdata_ord = size * [0] ct = 0 while ct < size: wdata_ord[ct] = ord(wdata[ct]) ct = ct + 1 if not bl.flash_jennicid == 0x8: mac = bl.read_mac() lic = bl.read_license() ct = 0 for x in bl.mac_region: wdata_ord[x] = mac[ct] # comment out if you want a veryfy error. ct = ct + 1 ct = 0 for x in bl.lic_region: wdata_ord[x] = lic[ct] ct = ct + 1 i, ct, errct, block, start = 0, 0, 0, 0xf0, time() for adr in xrange(0x00000000, size, block): for byte in bl.read_flash(adr, block): ct = ct + 1 if ct <= size: if wdata_ord[ct - 1] != byte: error_exit(1, "NG: VERIFY ERROR") if ct > (size / 10.*i): stderr.write("%i%%.." % (i * 10)) i += 1 kb, sec = size / 1000., (time() - start) stderr.write(": %0.2f kb/s\n" % (kb / sec)) if options.mac or options.key: stderr.write("MAC/Lic was updated as below...\n") bl_show(bl) except SystemExit: global exit_code exit(err_code) except: error_exit(2, "communication with the target") else: stderr.write("\nOK: firmware is successfully programmed.\n") exit(0)「卒展を見に来た地元企業の人との懇談会」というお仕事から研究室に戻ると、もう落ち着いて実験する時間もなく、これは来週以降に持ち越しとなった。 リストとログを引用したために既にHTMLは194KBとなっているので、ここで日記(5)を終えて、続きは Max7日記(6) として再開することにした。 忘れないようにその方針をメモしておくと、以下である。
そんなところで区切りである。 まだ浜松は雨だが、明日には晴れるし、那覇に飛んだら現地はもう春そのものだろう。
- VCPのバージョンを下げるという最後の手段は後回しにする
- MONOスティックにOTAアプリを書き込まなくてもTWE-Liteライタと結線すれば書き込みできる筈
- ただし↑の方法は解説本には載っていないのでサイトから探すことになる
- とりあえずさぶろさんが書き込みしたMONOスティックが「ばんばん受信できる」アプリなのでこれを活用する
- TWE-Lite DIPは既に2個、センサ情報を「ばんばん送信する」アプリが書き込まれているのでこれを活用する
- 最後の手段としてWindowsを使うのは本当に最後の最後にする(^_^;)
「日記」シリーズ の記録