最近又開始對數位溫度計感到興趣了,所以以上的問題都有辦法解決了。首先是溫度感測器,我後來看感測器應用的書籍時得知,原來有些便宜的溫度IC可以用,足以解決我的問題,像是LM35和DS18B20,前者只要45元(網拍價可更便宜到30元,但我習慣買的那家電子材料行居然要價90元),後者DS18B20則是用30元購得。
LM35是接類比接腳,每上升1度C,就會增加 10 mv,所以直接用arduino測出改變的電壓,再轉換一下,就可以換算成溫度。
DS18B20接的是數位接腳,安裝DS18B20有點麻煩,還要先找一些library來裝,不過裝好之後就很好用了,可以用一個pin同時接好幾個感測器來同時感測。
arduino太貴的問題,後來我找到德州儀器出的MSP 430 Lauchpad ,售價只要4.3元美金,在台灣要買的話,約是160元左右,目前中文的教學網站只有一個,arduino的程式修改一下可以直接用在Lauchpad 上面,但是要用 energia 來上傳。
而秀出即時折線圖的功能,後來我從arduino的競爭者parallax那邊找到一個免費軟體 ,叫做PLX DAQ,是 MS Excel的外掛,可以把 serial port 讀到的資料直接餵給 Excel,這樣就可以即時呈現曲線圖了。
以下是我參考的網站
Arduino接LM35的接法和程式碼,還有Processing怎麼寫接收端的程式
http://pscmpf.blogspot.tw/2008/12/arduino-lm35-sensor.html
Arduino接 DS18B20,再用Processing呈現的教程
http://www.naozhendang.com/2011/06/20/learning-arduino-8-arduinoprocessingpachubeds18b20/
給DS18B20裝的libary-DallasTemperature.h
http://www.milesburton.com/?title=Dallas_Temperature_Control_Library
給DS18B20裝的libary-OneWire.h
http://www.pjrc.com/teensy/td_libs_OneWire.html
PLX DAQ的網站
http://www.parallax.com/tabid/393/Default.aspx
即時用Excel,透過PLX DAQ 來接收Arduino的資料
http://robottini.altervista.org/arduino-and-real-time-charts-in-excel
接著是程式碼,這是LM35的,中間的腳要接arduino的Analog in 0。輸出的資料,已經改成用在PLX DAQ上面的,另外因為資料數據會跳動,所以我將資料取了五次再作平均。
//declare variables
float tempC;
int tempPin = 0;
int row = 0;
void setup()
{
Serial.begin(9600); //opens serial port, sets data rate to 9600 bps
Serial.println("CLEARDATA");
Serial.println("LABEL,Time,T");
}
void loop()
{
tempC = analogRead(tempPin);
//tempC = 0.7*tempC + 0.3*analogRead(tempPin);
tempC += analogRead(tempPin);
tempC += analogRead(tempPin);
tempC += analogRead(tempPin);
tempC += analogRead(tempPin);
tempC =tempC/5;
tempC = (5.0 * tempC * 100.0)/1024.0; //轉換類比資料變成溫度
row++;
Serial.print("DATA,TIME,");
Serial.println(tempC);
if (row > 1000)
{
row=0;
Serial.println("ROW,SET,2");
}
delay(500); //每500毫秒再測一次。
}
#include
#include
OneWire oneWire(10); // port 10
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
void setup(void)
{
Serial.begin(115200); // start serial port
sensors.begin(); // Start up the library
}
void loop(void)
{
sensors.requestTemperatures();
Serial.print(sensors.getTempCByIndex(0)); //Send SensorA data to computer
Serial.println();
delay(750);
}
Processing
這些code,是東湊西湊得來的,主要是從這邊改的。arduino傳到serial port的資料是有小數的,但Processing read的資料卻得不到小數,所以我就東改西改,還想辦法把曲線圖的區域加大,但還沒改好,我就看到有PLX DAQ可以用了,所以以下的程式是個未完成的程式。
import processing.serial.*;
Serial myPort; // create object from Serial class
float myValue;
float tempC;
int yDist;
PFont font12;
PFont font24;
float[] tempHistory = new float[300];
void setup() {
//setup fonts for use throughout the application
font12 = loadFont("Verdana-12.vlw");
font24 = loadFont("Verdana-24.vlw");
//set the size of the window
size(800, 800);
String portName = Serial.list()[0];
//windows用2 linux用0
myPort = new Serial(this, portName, 9600);
myPort.bufferUntil('\n'); // read it and store it in val
}
void draw(){
tempC = myValue;
//refresh the background to clear old data
background(123);
//draw the temp rectangle
colorMode(RGB, 160); //use color mode sized for fading
stroke (0);
rect (49,19,22,162);
//fade red and blue within the rectangle
for (int colorIndex = 0; colorIndex <= 160; colorIndex ++)
{
stroke(160 - colorIndex, 0, colorIndex);
line(50, colorIndex + 20, 70, colorIndex + 20);
}
//draw graph
stroke(0);
fill(255,255,255);
rect(90,80,300,100);
for (int index = 0; index<300 font="font" index="index">300>
{
if(index == 299)
tempHistory[index] = tempC;
else
tempHistory[index] = tempHistory[index + 1];
point(390 + index, 1600 - tempHistory[index]*50);
}
//write reference values
fill(0,0,0);
textFont(font12);
textAlign(RIGHT);
text("100 C", 45, 25);
text("0 C", 45, 187);
//draw triangle pointer
yDist = int(160 - (160 * (tempC * 0.01)));
stroke(0);
triangle(75, yDist + 20, 85, yDist + 15, 85, yDist + 25);
//write the temp in C and F
fill(0,0,0);
textFont(font24);
textAlign(LEFT);
text(str(tempC) + " C", 115, 37);
}
void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil('\n');
myString = trim(myString);
myValue = float(myString);
println(myValue);
}