[[How2Computing]]
*ArduinoとProcessingで超低速オシロスコープを作る [#j123e7bc]
氏間さんに相談されて、
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のノイズが多く現れていることがわかる。
http://is.ocha.ac.jp/~siio/gyazo/20140726200334.png
下は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/