この本を参考に、Arduinoで色々試しています。
前半は順調に回路やスケッチを組めていたのですが、徐々に本の方で想定している成長ペースと、
私の理解に乖離が生じ、
p.61「クラウドとの会話」に突入したところでまったく分からなくなりました。
てか途中から説明がかなり端折られている気がするけど…
文系は黙ってろということか…
失敗例を載せておくので、同じ点で悩む諸兄の参考と、
お時間のある先達からの助言を待つことにする。
「Processing」とか聞いてないんだけど
p.63で、急に別のソフトが登場していました。
気付いたのは、Arduino用のスケッチだと思って全部書き終わってから…
どうやら「Processing」という「Arduino IDE」みたいなソフトウェアが必要だったようです。
いきなりのことでめちゃくちゃ混乱しましたが、
なんとか「別のソフトっぽいぞ」という事に気付けたので、ダウンロード。
そこにさっきのコードを全部コピペ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
// Example 08A: Arduinoネットワークランプ //一部のコードはTod E. Kurt(todbot.com)のブログを参考にした import processing.serial.*; String feed = "http://blog.makezine.com/index.xml"; int interval = 10; //フィードを取得する時間 int lastTime; //最後に取得した時間 int love = 0; int peace = 0; int arduino = 0; int light = 0; //ランプが測った明るさ String buffer = ""; //Arduinoから送られた文字を留めるところ PFont font; void setup() { size(640,480); frameRate(10); //速い更新は不要 font = loadFont("HelveticaNeue-Bold-32.vlw"); fill(255); textFont(font, 32); //注意: //以下のコードはSerial.list()で得られるポートの一つ目がArduinoであることを前提にしています。 //そうでない場合は次の1行(println)から//を取り除き(アコメント)、再度スケッチを実行して //シリアルポートのリストを表示し、Arduinoのポートを確認して、その番号で[と]の間の0を置き換えます。 //println(Serial.list()); String arduinoPort = Serial.list()[0]; port = new Serial(this, arduinoPort, 9600); lastTime = 0; fetchData(); } void draw() { background( c ); int n = (interval - ((millis()-lastTime)/1000)); //3つの値をベースに色を組み立てる c = color(peace, love, arduino); cs = "#" + hex(c,6); //Arudinoへ送る文字を準備 text("Arduino Networked Lamp", 10,40); text("Reading feed:", 10, 100); text(feed, 10, 140); text("Next update in"+ n + "seconds",10,450); text("peace" ,10,200); text(""+ peace, 130, 200); rect(200,172, peace, 28); text("love ",10,240); text("" + love, 130, 240); rect(200,212, love, 28); text("arduino ",10,280); text("" + arduino, 130, 280); rect(200,252, arduino, 28); //画面に色情報を表示 text("sending", 10, 340); text(cs, 200,340); text("light level", 10, 380); rect(200, 352,light/10.23,28); //最大1023から最大100に if (m <= 0) { fetchDate(); lastTime = millis(); } port.write(cs); //Arduinoへデータを送る if(port.available() > 0){ //データが待っているかチェック int inByte = port.read(); //1バイト読み込む if (inByte != 10){ //それがnewline(LF)ではないから buffer = buffer + char(inByte); //バッファに追加 } else{ //newlineが届いたので、データを処理しましょう if (buffer.length() > 1){ //データがちゃんとあるか確認 //最後の文字は改行コードなので切り落とす buffer = buffer.substring(0,buffer.length() -1); //バッファの文字を数値(整数)に変換 light = int(buffer); //次の読み込みサイクルのためにバッファを掃除 buffer = ""; //Arduinoからはどんどんセンサの読みが送られてくるので、 //最新のデータを得るために溜まってしまったものは削除 port.clear(); } } } } void fetchData() { //フィードのパースにこれらの文字列を使用 String data; String chunk; //カウンタをゼロに love = 0; peace = 0; arduino = 0; try { URL url = new URL(feed); //URLを表すオブジェクト URLConnection conn = url.openConnection(); //接続を準備 conn.connect(); //webサイトに接続完了 //接続先からやってくるデータを1行ずつバッファするための仮想的なパイプ BufferedReader in = new BufferedReader( new InputStreamReader(conn.getInputStream())); //フィードを1行ずつ読む while ((data = in.readLine()) != null){ StringTokenizer st = new StringTokenizer(data,"\"<>,.()[]"); //それを分解 while (st.hasMoreTokens()) { chunk= st.nextToken().toLowerCase(); //小文字に変換 if(chunk.indexOf("love") >= 0) //"love"を見つけた? love++; //loveに1を加える if(chunk.indexOf("peace") >= 0) //”peace”は見つけた? peace++; // peaceに1を加える if(chunk.indexOf("arduino") >= 0) //"arduino"は? arduino++; //Arduinoに1を加える } } //各語を参照した回数は64を上限にしておく if(peace > 64) peace = 64; if(love > 64) love = 64; if(arduino > 64) arduino = 64; peace = peace * 4; //4を掛けて最大値を256にしておくと love = love + 4; //色を4バイトで表現するのに便利 arduino = arduino * 4; } catch (Exception ex) { //エラーの場合はスケッチを停止 ex.ptintStackTrace(); System.out.println("ERROR: "+ex.getMessage()); } } |
これを実行しようとすると「port cannot be resolved to a variable」というエラーを吐きます。
シリアルポートの番号が一致していないのか、どうなのか、
「シリアルポート」がなんなのか分かっていない現段階では打つ手なし。
Arduino側のスケッチ
こちらも指示通り入力。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
//Example 08B : Arduinoネットワークランプ const int SENSOR = 0; const int R_LED = 9; const int G_LED = 10; const int B_LED = 11; const int BUTTON = 12; int val = 0; //センサから読み取った値を格納する変数 int btn = LOW; int old_btn = LOW; int state = 0; char buffer[7]; int pointer = 0; byte inByte =0; byte r = 0; byte g = 0; byte b = 0; void setup() { Serial.begin(9600); //シリアルポートを開く pinMode(BUTTON, INPUT); } void loop() { val = analogRead(SENSOR); //センサから値を読む Serial.println(val); //シリアル通信で値を送信 if(Serial.available() >0){ //受信したデータを読み取る inByte = Serial.read(); //マーカ(#)が見つかったら、続く6文字が色情報 if (inByte == '#') { while (pointer < 6){ //6文字蓄積 buffer[pointer] = Serial.read(); //バッファに格納 pointer++; //ポインタを1進める } //3つの十六進数の数字が揃ったので、RGBの3バイトにデコード r = hex2dec(buffer[1]) + hex2dec(buffer[0]) * 16; g = hex2dec(buffer[3]) + hex2dec(buffer[2]) * 16; b = hex2dec(buffer[5]) + hex2dec(buffer[4]) * 16; pointer = 0; //次にバッファを使う時の為にクリア } } btn = digitalRead(BUTTON); //読み取った値を格納 //変化があるかどうか if((btn == HIGH) && (old_btn == LOW)){ state = 1 - state; } old_btn = btn; //古い値を保存しておく if(state == 1) { //ランプをオンにする場合 analogWrite(R_LED, r); //コンピュータから来た analogWrite(G_LED, g); //色情報にしたがって analogWrite(B_LED, b); //LEDを点灯する } else{ analogWrite(R_LED, 0); //あるいは消す analogWrite(G_LED, 0); analogWrite(B_LED, 0); } delay(100); //0.1秒待つ } int hex2dec(byte c) { //十六進数を整数に変換 if (c >= '0' && c <= '9') { return c - '0'; } else if (c >= 'A' && c <= 'F') { return c - 'A' + 10 ; } } |
こちらは特にエラーもなく、ボードに書き込めました。
が、回路の方に反応が無い…
ブレッドボードは画像の感じ。
もっと簡単な方法は
入門書のようだから、まずProcessingだけの使い方とか、
光センサーとかは省いて、ArduinoとProcessingの簡単なやりとりとかから初めていただきたいが、
それは贅沢 or 私の力不足なんでしょう。
参考サイト様
もっとシンプルな方法を探してみる。
- つくったブログ「シリアル通信でArduinoからProcessingに情報を渡す」 :一番参考になりました。感謝永遠に。
- 物を作る者 ArduinoとProcessing間でシリアル通信をしてみる : こちらの方がシンプルなアプローチのようです。
「物を作る者」様のページを参考にしてみます。
ブレッドボード
スケッチ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#define led1 9 #define led2 10 #define button 11 void setup() { pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(button, INPUT); Serial.begin(9600); } void loop() { if (Serial.available() > 0) { char ledState = Serial.read(); if (ledState == '1') { digitalWrite(led1, HIGH); } if (ledState == '2') { digitalWrite(led2, HIGH); } if (ledState == '3') { digitalWrite(led1, LOW); digitalWrite(led2, LOW); } } int buttonState = digitalRead(button); if (buttonState == HIGH) { Serial.println("Button is pressed"); } } |
processing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import processing.serial.*; Serial Port;//シリアルクラスのオブジェクト String Text = ""; void setup() { size(1920, 1080); Port = new Serial(this, "COM3", 9600);//ポート番号とボーレートの設定 Port.bufferUntil(10); } //データが利用可能な時のみ呼び出される void serialEvent(Serial Port) { Text = Port.readStringUntil(10); } void draw() { background(0, 0, 0); textAlign(CENTER); text(Text, width/2, height/2); textSize(200); Text = ""; if (mousePressed && (mouseButton == LEFT)) { Port.write('1'); } if (mousePressed && (mouseButton == RIGHT)) { Port.write('2'); } if (mousePressed && (mouseButton == CENTER)) { Port.write('3'); } } |
結果、LEDは光らなかった(抵抗の数値を測っていないので、それが原因かも)が、
マウスの右クリックで左側のLEDが点灯、中央ボタンで消灯。
プッシュボタンを押した結果が、processingのプログラムを通じて画面に表示されました。
これは感動…
これを応用すれば、Kastleからの出力をモニターに出力できそう。
Arduinoマスターへの道は遠い…
Arduinoで取得したセンサ値をProcessingでリアルタイム表示する
これにも挑戦したい。
コメント