2016年6月17日

以手機藍牙接收Arduino感測器訊號,進行即時紀錄與繪圖

最近Google出了一個APP,叫做Science Journal 科學期刊(中文應該要翻成科學日誌或是科學實驗筆記比較好吧)。那個APP可以用手機現成的感應器,即時量測與繪圖,甚至還可以用藍牙連接其他微控制器,接收外部感應器的訊號,不過目前我還沒找到說明文件,要怎麼去設定傳輸格式(即使是這篇官網文章的也沒講清楚啊)

我試著用arduino uno加上一般藍牙模組(HC05、HC06),發現Science Jounal都沒辦法進行連線,後來看到這個Github的資料,得知它能連的是Bluetooth Low Energy (BLE) ,微控制器要不就是用Arduino 101,要不就是RedBear BLEND。

那麼我用一般的Arduino板,如果也想要用手機接收訊號作即時繪圖,可以怎麼作呢?

我找到了一個App,叫做Bluetooth Terminal/Graphics,幾乎滿足我的需求。最多可以同時接收七筆資料,繪在同一張圖上,也可以繪在不同的圖上。(免費版的最多就是三筆資料,也已經很夠用了)

於是我就用了這個APP,將一台小車的位移、速度和加速度,即時呈現於手機上繪圖了。


零件如下:

  • 小車:是用樂高積木拼出來的
  • Arduino uno
  • 迷你麵包版
  • 藍牙模組(HC05、HC06都可以)
  • 超音波測距模組
  • 9V電池盒與電池

接線方式
超音波模組
VCC to arduino 5v
GND to arduino GND
Echo to Arduino pin 13
Trig to Arduino pin 12


藍牙模組
VCC to arduino 5v
GND to arduino GND
RXD to D1
TXD to D0



藍牙、超音波、Arduino和電池盒
 




組合起來的樣子


超音波朝向的是車子尾端,實驗時最好是有面牆壁,讓小車靠著作為起點
 

由上而下的資料,分別就是位移、速度和加速度
 


同樣的作法要呈現壓力時間變化圖,或是溫度時間變化圖,也是很容易的。

PS.同樣是用手機感測器的APP,我覺得這個也不錯,把手機所有的感測器偵測和紀錄包在同一個APP
Physics Toolbox Sensor Suite



程式碼如下,要讓手機APP能夠接收,只有一個重點,就是用Serial.print的時候,在一連串字串前面多一個E字,然後每個數值之間用,相連,最後要有斷行
例如
E21,12,33\n



/*
HC-SR04 Ping distance sensor]
VCC to arduino 5v
GND to arduino GND
Echo to Arduino pin 13
Trig to Arduino pin 12


BlueTooth
VCC to arduino 5v
GND to arduino GND
RXD to D1
TXD to D0
*/



#define trigPin 12
#define echoPin 13
int x0=0;//一開始的位置
int v0=0;//初速
float temp=20.0;//溫度
float c=(331.5+0.6*temp)/10000;//單位是每微秒幾公分
float intervaltime=100;  //每幾毫秒測量一次
float duration, distance,velocity,acceleration;

void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);

}


void loop() {

digitalWrite(trigPin, HIGH);
delayMicroseconds(1000);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);//超音波來回經過的時間,單位是微秒
distance = (duration/2) *c;//單位是公分
velocity=(distance-x0)/(intervaltime/1000);//每秒速度
acceleration=(velocity-v0)/(intervaltime/1000);//每秒加速度

x0 = distance;
v0=velocity;
Serial.print("E");
Serial.print(distance);
Serial.print(",");
Serial.print(velocity);
Serial.print(",");
Serial.println(acceleration);

delay(intervaltime);

}