氏間さんに相談されて、 Arduinoで取得した複数個のアナログデータをPCにシリアルで転送して、 PCでグラフ化するプログラムを書いてみた。 こんなもの50分でできると見栄はったけど半日かかってしまった。 ProcessingのSerialのavailable()とreadStringUntil()の動作を理解する試行錯誤に手間がかかってしまった。
ここではArduinoのAnalog 0ピンの値を1msサンプリングレートで512個取得して (ArduinoのADCは10bitなので値は0から1023)、 これをシリアルで転送して、 Macintosh側のProcessingプログラムでグラフ化する。 超低速のオシロスコープ (Oscilloscope)のようなものである。
Aruduinoのプログラムは以下。 512個の値を測定したあと、これをテキストで転送している。 最初に+++を転送してから、最後に---を転送している。この間が数値。 改行はLine Feed (ASCIIコードで10) を使っている。 (mySerial.println()を使うと13, 10の2バイトが改行コードになるので面倒なので避けた) テキストで転送しているので、ここをバイナリーにすればもっと高速化できるはず。
int data[512]; void setup() { Serial.begin(38400); } void loop() { int i; Serial.print("+++"); Serial.write(10); for(i=0; i<512; i++) { data[i] = analogRead(0); delay(1); } for(i=0; i<512; i++) { Serial.print(data[i]); Serial.write(10); } Serial.print("---"); Serial.write(10); //delay(1000); }
これを下のProcessingプログラムで表示したもの。 Analog 0を指で触ってノイズを入れてみた。 1msでサンプリングしているので、50Hzのノイズが多く現れていることがわかる。
下はProcessingのソース。
import processing.serial.*; final int dataSize=512; //size of data sent from Arduino final int maxValue=1024; //max of data, 10bit ADC = 1023 final int xSize=dataSize; //screen size X final int ySize=512; //screen size Y Serial myPort; //seria port int data[] = new int[dataSize]; //array to receive the data int nth = 0; //index to handle the array Boolean isDataStarted= false; //while data transmission, it becomes true void setup() { myPort = new Serial(this, "/dev/tty.usbmodem3a11", 38400); myPort.clear(); size(xSize, ySize); background(255); } int convertValue2ScreenX(int x) { //convert datat to screen return ( x * xSize / dataSize); } int convertValue2ScreenY(int y) { return ySize - (y * ySize / maxValue); } void draw() { String received; //received string from serial while(myPort.available()>0) { //while data is received received=myPort.readStringUntil(10);//read until Life Feed (10) if(received == null) continue; //if no data with line feed if(received.charAt(0)=='+') { //start of data isDataStarted=true; nth=0; continue; } if(received.charAt(0)=='-') { //end of data int x, y, lastX, lastY; isDataStarted=false; background(255); //clear the screen //draw the graph lastX=convertValue2ScreenX(0); lastY=convertValue2ScreenY(data[0]); for(int i=1; i<dataSize; i++) { x=convertValue2ScreenX(i); y=convertValue2ScreenY(data[i]); line(lastX, lastY, x, y); lastX=x; lastY=y; } continue; } if(isDataStarted) { //remove the last char (line feed) if (nth >= dataSize) continue; received = received.substring(0, received.length() -1 ); data[nth++] = parseInt(received); //println(data[nth - 1]); } } //end of while }
同じような構成で本格的なオシロスコープ作った人がいた。
http://www.iizuka.kyutech.ac.jp/faculty/physicalcomputing/pc_kitscope/