[[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/

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS