ある時たまたま「蕎麦打ち」の動画をYoutubeで見かけて、それを一度だけ見た。
一度見ただけなのに、再生リコメンドに蕎麦打ち動画ばかり強迫神経症的に出てくるようになった(笑)。
蕎麦打ちの動画はなぜか結構多く、全部見きれないほど大量にある。蕎麦打ちが趣味と言う人は多いらしい。
もういっそのこと、と思い、面白そうなものを再生リストにしてみた。
オッサンは生きている。
ある時たまたま「蕎麦打ち」の動画をYoutubeで見かけて、それを一度だけ見た。
一度見ただけなのに、再生リコメンドに蕎麦打ち動画ばかり強迫神経症的に出てくるようになった(笑)。
蕎麦打ちの動画はなぜか結構多く、全部見きれないほど大量にある。蕎麦打ちが趣味と言う人は多いらしい。
もういっそのこと、と思い、面白そうなものを再生リストにしてみた。
今度はできるだけ鬱陶しく汚くLEDを光らせてみた。 見ていて疲れる。
// // badLight.ino // 今度は3色LEDをできるだけ鬱陶しく汚く光らせたい。 // 佐藤俊夫 // 27.06.28(日) // const int R = 9, G = 10, B = 11; // void setup() { pinMode(R, OUTPUT); pinMode(G, OUTPUT); pinMode(B, OUTPUT); } void loop() { digitalWrite(R, random(2)); digitalWrite(G, random(2)); digitalWrite(B, random(2)); delay(100); }
3色LEDにサインカーブでPWMをかけ、できるだけ美しく色変化をかけたい。実はこれは前にもやったが、もうちょっとコードを美しくしたいのであった。
3項演算子があったらなあ……。
// // sinCurvePWM.ino // 3色LEDをできるだけ幻想的に美しく光らせたい。 // 佐藤俊夫 // 27.06.27(土) // const int R = 9, G = 10, B = 11; // void setup() { pinMode(R, OUTPUT); pinMode(G, OUTPUT); pinMode(B, OUTPUT); } void loop() { static float thetaR = 0.0, thetaG = 0.0, thetaB = 0.0; const float PI2 = 2.0 * PI; const float Rtic = PI2 / 1000.0, Gtic = PI2 / 900.0, Btic = PI2 / 1100.0; thetaR += Rtic; thetaG += Gtic; thetaB += Btic; if(thetaR >= PI2) thetaR = 0.0; if(thetaG >= PI2) thetaG = 0.0; if(thetaB >= PI2) thetaB = 0.0; analogWrite(R, 255 - sin255(thetaR)); analogWrite(G, 255 - sin255(thetaG)); analogWrite(B, 255 - sin255(thetaB)); delay(20); } int sin255(float theta){ return((int)((sin(theta) + 1.0) * 127.5)); }
帰宅。
今日は日本ITストラテジスト協会関東支部の月例会があったが、仕事と用事が重なり、行けなかった。今回の月例会のテーマ別ディスカッションもぜひ聞きたいと思っていた内容だったので、残念である。人生、なかなか、こうしたいああしたい、と、思ったようには運ばぬものだ。
忙中有閑。仕事は朝に引けたから、帰りに秋葉原へ寄り、挨拶がわりにヨドバシのスタインウェイをちょっと弾く。
いつものショパン3曲弾くなど。
千石電商と秋月電子で少し買い物をする。2000円ほども使えばたっぷり楽しめる。我ながらなんとささやかなこと。
今回買ったもののうちでも、出色の傑作は、このたった250円の小さなキットだろう。
これは、TTL5VでAC100Vを扱うためのリレーなのだが、昔のリレーとは違って、機械電磁式ではなく、電子式の無接点で、部品点数も極めて少ない。しかも100Vで25Aも流せる。これは、この方のブログ記事で見て知ったのである。
それから、もうひとつはこれだろう。Arduinoのシールド基盤に小さなブレッドボードを載せることができるもの。
帰宅してみると、先週作った「メールサーバお知らせランプ」、赤い点滅で、100通以上の未読がある。
電子メールを読み出すと、動画のように緑色の点灯に変わる。
さて、一週間、誤動作なく動いていた「メールサーバお知らせランプ」だが、さっさと回路をバラしてしまい、次の作品を作ることにする。
秋葉原で買ってきたものを取り出し、半田鏝を温めて、なにやらごそごそと活動する。
このちっぽけな基盤がAC100VをTTLで扱うためのキモである。
これを、Arduinoにつなぐ。先日買った超音波センサを、今日買ったブレッドボードシールドに取り付け、回路はこんな具合にする。
スケッチを書く。こんな感じだ。
// // superSonic2AC100.ino // 27.06.21(日) 1500~ // SatoToshio // Arduino + 超音波センサ + ソリッドステートリレーで、 // 人が近接したら扇風機などを回す。 // const int TRIG = 8, ECHO = 9, SSR = 10; float ranges[10]; int arrcount = 0; const float THRESHOLDRNAGE = 100.0; void setup() { Serial.begin(9600); pinMode(TRIG,OUTPUT); pinMode(ECHO,INPUT); pinMode(SSR, OUTPUT); digitalWrite(SSR, LOW); } void loop() { float range = 0.0; delay(1000); range = ranging(); ranges[arrcount++] = range; if(arrcount >= 9){ arrcount = 0; } // THRESHOLDRANGE以下が何割かを調べる。雑音除去のため。 int rangecount = 0, i = 0; for(i = 0; i <= 9; i++){ if(ranges[i] < THRESHOLDRNAGE){ rangecount ++; } } Serial.println(range); Serial.println(rangecount); if(rangecount >= 6){ digitalWrite(SSR, HIGH); }else{ digitalWrite(SSR, LOW); } } float ranging(){ float time = 0.0, range = 0.0; digitalWrite(TRIG,LOW); delayMicroseconds(1.1); digitalWrite(TRIG,HIGH); delayMicroseconds(1.1); digitalWrite(TRIG,LOW); time = pulseIn(ECHO,HIGH); if (time > 0.0) { range = (time / 2.0) * 340.0 * 100.0 / 1000000.0; if(range > 500.0){ range = 500.0; } return(range); }else{ return(9999.0); } }
で、これで何をするかというと、「人が近づくと部屋のミニ扇風機が回る」というのをやりたかったわけだ。暑いから(笑)。
組み付けたプロトはこんな感じだ。100円ショップで買ったアクリルの仕切りグッズにスペーサーで取り付けてある。
自分の部屋に入ると、扇風機が回り出し、涼しい。
先週少しやりかけて途中だった、Arduino UNO に ETHERNET SHIELD 2 をとりつけ、ウェブインターフェイスを作ってこれでLEDをコントロールするという遊びの続きをやる。
こんなふうなインターフェイスでコントロールすることにする。
で、ブレッドボードとArduinoはこんな感じ。「SeeedStudio SIDEKICK BASIC KIT」に入っていた3色LEDを使う。
スケッチはこんな感じで。ウェブ上で同じようなことを公開している方々は、ブラウザの出力を受けるのに、たいてい普通のポインタ文字列を使っておられるのだが、せっかくStringクラスがあるので、それを活用することにした。Stringクラスを使う欠点は多少メモリを浪費することだが、反面、余裕は十分あり、今回は別にメモリが足りないというわけでもないので、そうした。
// // Web2TriColorLED.ino // 27.06.07(日) 1800~ // 佐藤俊夫 // 3色LEDをウェブインターフェイスで制御 // ETHERNET SHIELD 2 使用 // #include <SPI.h> #include <Ethernet2.h> // byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0xF6, 0x74 }; IPAddress ip(192, 168, 1, 129); EthernetServer SERVER(80); EthernetClient CLIENT; int R = 0, G = 0, B = 0; const int LEDR = 3, LEDG = 5, LEDB = 6; // void setup() { Ethernet.begin(mac, ip); SERVER.begin(); pinMode(LEDR, OUTPUT); pinMode(LEDG, OUTPUT); pinMode(LEDB, OUTPUT); } void loop() { char c; String rstr = ""; CLIENT = SERVER.available(); if (CLIENT) { while (CLIENT.connected()) { if (CLIENT.available()) { c = CLIENT.read(); rstr += c; if(rstr.endsWith("\r\n")){ break; } } } if(rstr.indexOf("red=") >= 0){ R = rstr.substring(rstr.indexOf("red=") + 4, rstr.indexOf("&green=")).toInt(); G = rstr.substring(rstr.indexOf("green=") + 6, rstr.indexOf("&blue=")).toInt(); B = rstr.substring(rstr.indexOf("blue=") + 5, rstr.indexOf("&end")).toInt(); } analogWrite(LEDR, R); analogWrite(LEDG, G); analogWrite(LEDB, B); delay(10); rstr = ""; sendform(); // give the web browser time to receive the data delay(1); // close the connection: CLIENT.stop(); } } // void sendform(){ char* formFirstHalf[] = { "<html>", " <head>", " <meta charset=\"utf-8\">", " </head>", " <body>", " <center>", " <h1>Arduino 3色LEDをウェブインターフェイスで</h1>", " <form method='GET'>", " <table>", " <tr>", " <th style='background-color:red; color:white;'>赤</th>", " <th style='background-color:green;color:white;'>緑</th>", " <th style='background-color:blue; color:white;'>青</th>", " </tr>" }; // 14 num. char* formSecondHalf[] = { " </table>", " <input type='hidden' name='end'>", " <input type='submit' value='セット'>", " </form>", " </center>", " </body>", "</html>" }; // 7 num. int i = 0; CLIENT.println("HTTP/1.1 200 OK"); CLIENT.println("Content-Type: text/html"); CLIENT.println("Connection: close"); CLIENT.println(); CLIENT.println("<!DOCTYPE HTML>"); for(i = 0; i < 14; i++){ CLIENT.println(formFirstHalf[i]); } CLIENT.println(" <tr>"); CLIENT.println(" <td>"); CLIENT.println(" <select name='red'>"); for(i = 0; i <= 255; i++){ CLIENT.print(" <option value='"); CLIENT.print(i, DEC); if(i == R){ CLIENT.print("' selected>"); }else{ CLIENT.print("'>"); } CLIENT.print(255 - i, DEC); CLIENT.println("</option>"); } CLIENT.println(" </select>"); CLIENT.println(" </td>"); CLIENT.println(" <td>"); CLIENT.println(" <select name='green'>"); for(i = 0; i <= 255; i++){ CLIENT.print(" <option value='"); CLIENT.print(i, DEC); if(i == G){ CLIENT.print("' selected>"); }else{ CLIENT.print("'>"); } CLIENT.print(255 - i, DEC); CLIENT.println("</option>"); } CLIENT.println(" </select>"); CLIENT.println(" </td>"); CLIENT.println(" <td>"); CLIENT.println(" <select name='blue'>"); for(i = 0; i <= 255; i++){ CLIENT.print(" <option value='"); CLIENT.print(i, DEC); if(i == B){ CLIENT.print("' selected>"); }else{ CLIENT.print("'>"); } CLIENT.print(255 - i, DEC); CLIENT.println("</option>"); } CLIENT.println(" </select>"); CLIENT.println(" </td>"); CLIENT.println(" </tr>"); for(i = 0; i < 7; i++){ CLIENT.println(formSecondHalf[i]); } }
気を付けるところは、私が買った「SeeedStudio SIDEKICK BASIC KIT」というキットに入っている3色LEDは「アノードコモン(共通陽極)」というタイプで、プラスに5V、各色のコントロールはマイナスになる、という点だ。ここを間違えると思ったように動作しない。一番長い脚が共通陽極だ。封入の切り欠きを左にして、左から赤、アノード、緑、青の順に脚が並ぶ。
また、フォームから与える値も、アノードコモンであるゆえに、「0」が最も明るくなり、「255」が最も暗くなるので、インターフェイスを逆にするなど、多少工夫が必要だ。
それから、PWM(パルス幅変調)の機能を大いに活用し、いろいろな色が出せるようにした。この場合の注意点は、ETHERNET SHIELD 2を取り付けると、10番・11番・12番のピンが使えなくなるので、他のピンで出力しなければならないことだ。今回は3番・5番・6番を使った。
で、ウェブインターフェイスをタブレットにロードする。
動かしてみるとこんな感じで、いろんな色になって面白い。
人間の脳はその力のおよそ80パーセントから90パーセントを視覚情報の処理に割いている、と何かで読んだことがあるが、なるほど、こういう映像を見ながら音を聞くと、視覚に幻惑されてか、本当に音が後ろから聞こえるのは、けだし当然と言えようか。
Youtubeからgoogle AdSense経由でお金が振り込まれたことに気を良くし、いっちょうここは、ブログに広告を貼ってやろうかい、などと考えた。
ひっひっひ、広告御大尽、……。
取らぬ狸のなんとやら、で、このブログ、日に100件くらいのビューしかないから、まあ、多分、ずーっと広告貼りっぱなしでも、ゼロ円だろうなあ。
昨日、一定の距離に近づくとカメラのシャッターが切れるという装置を作ったが、ふと思いついて、同じハードウェアで距離計が作れるな、と思った。なぜかというと、無駄にサーボを使っているからだ。
50センチ以下の距離が測れればいいな、というわけで、サーボの0度から180度まで割り付ける。
5センチ18度、というわけで、何かスマホいじりをしている次女に
「お~い、智香っ、智香。分度器を貸せ」
と言ったら、
「ん~?分度器?……ナイ。」
とニベもない。中学生のクセして、ないワケあるかいっ!!……と思ったが、ガミガミ言うのも面倒くさい。
針の長さがだいたい8cmだから、
tan18° = x ÷ 8cm、x = tan18° × 8cm ≒ 2.6cm。
円周上2.6cm刻みで目盛りをふればよろしい。……って、なにムダな計算しとるんだ俺は。
まあよい、それで、動かしてみるとこんなふうになかなか面白い。
で、まあ、定規をあてて測ると、だいたい合ってる。
しかし、デジタルで採れている値を、ムダにアナログに直すという、はっはっは。
スケッチはこんな具合。
// // rangemeter.ino // 超音波センサで測距して、サーボで作ったメーターで表示する。 // 27.6.7(日) 1015~ // 佐藤俊夫 // #include <Servo.h> Servo meter; const int SERVO = 8; const int TRIG = 9; const int ECHO = 10; const int SERVO_MIN = 0; const int SERVO_MAX = 180; const float RANGE_MIN = 0.0; const float RANGE_MAX = 50.0; void setup() { meter.attach(SERVO); meter.write(SERVO_MIN); pinMode(TRIG,OUTPUT); pinMode(ECHO,INPUT); } void loop() { float range = 0.0; delay(1000); range = ranging(); if(range <= RANGE_MAX){ indication(range); }else{ indication(RANGE_MAX); } } void indication(float range){ int deg = 0; deg = map(range, RANGE_MIN, RANGE_MAX, SERVO_MIN, SERVO_MAX); meter.write(deg); } float ranging(){ float time = 0.0, range = 0.0; digitalWrite(TRIG,LOW); delayMicroseconds(1); digitalWrite(TRIG,HIGH); delayMicroseconds(1); digitalWrite(TRIG,LOW); time = pulseIn(ECHO,HIGH); if (time > 0.0) { range = (time / 2.0) * 340.0 * 100.0 / 1000000.0; return(range); }else{ return(9999.0); } }
それで、先週作ったカメラのシャッターを切る装置と、この超音波センサを組み合わせてみた。
まずスケッチはこんな感じ。
// // sonic2shutter.ino // 超音波センサで測距して、カメラのシャッターを切る。 // 27.6.6(土) 1222~ // 佐藤俊夫 // #include <Servo.h> Servo shutter; const int SERVO = 8; const int TRIG = 9; const int ECHO = 10; const int SHUTTER_RELEASE = 90; const int SHUTTER_PUSH = 50; const float SHUTTERRANGE = 50.0; void setup() { shutter.attach(SERVO); shutter.write(SHUTTER_RELEASE); pinMode(TRIG,OUTPUT); pinMode(ECHO,INPUT); } void loop() { float range = 0.0; range = ranging(); if(range <= SHUTTERRANGE){ takePicture(); } } void takePicture(){ shutter.write(SHUTTER_PUSH); delay(5000); shutter.write(SHUTTER_RELEASE); delay(5000); } float ranging(){ float time = 0.0, range = 0.0; digitalWrite(TRIG,LOW); delayMicroseconds(1); digitalWrite(TRIG,HIGH); delayMicroseconds(1); digitalWrite(TRIG,LOW); time = pulseIn(ECHO,HIGH); if (time > 0) { range = (time / 2) * 340 * 100 / 1000000; return(range); }else{ return(9999); } }
で、ソースの中にある通り、サーボを8番、超音波を9番10番につなぐ。
こんなふうな組み立てで……。
動かしてみるとこんな感じ。
オマケ;この装置で撮影された、この動画を撮っている私のマヌケ面(笑)
Google AdSenseの案内に従って、銀行口座を連絡したら、「ほんのちょっぴり、変な額の金額を振り込むから、それを再び連絡してください」というような、まことに凝った確認方法の連絡が来た。
2日ほどして、本当に「ウン円」の、ちょっぴりのお金が口座に振り込まれ、その金額を通知すると、「確認できました」という返事が来た。
それから、私がYoutubeで稼いだというお金が振り込まれた。
ぬぅ、面白いなあ。ネットがカネになったのは、ひょっとして初めてじゃないだろうか。
まあ、こんな不人気ブログをいくら書いても、広告なんかたかが知れているが、でも、なんか嬉しい。