Arduino는 온도센서를 이용하여 온도 데이터를 수집하여 Serial로 송신하고, Java에서 arduino에서 전송된 온도정보를 Serial로 수신하며, R에서는 Java에서 수신한 데이터를 가공하고 시각화하게 된다.
온도센서(TMP 36)를 사용하여 온도 측정할 수 있는 회로를 구성 하였다.
* CIRC-10 .: Temperature :. (TMP36 Temperature Sensor) |
float temperature = getVoltage(temperaturePin); //getting the voltage reading from the temperature sensor
temperature = (temperature - .5) * 100; //converting from 10 mv per degree wit 500 mV offset
//to degrees ((volatge - 500mV) times 100)
return (analogRead(pin) * .004882814); //converting from a 0 to 1023 digital range
// to 0 to 5 volts (each 1 reading equals ~ 5 millivolts
d. Arduino 프로그램 다운로드 및 실행
다운로드하면 된다.
R에서 디바이스간의 통신이 불가하여 R에서 Serial통신이 가능하도록 *.jar 라이버러리를 생성한다.
본 소스에서는 Java에서 Serial 통신을 위하여 공개된 RXTX library를 활용하였다.
OS환경에 맞는 파일을 Java 러이버러리 경로에 복사하여 사용한다.
Mac OSX 환경
- 다운받은 *.zip파일의 압축을 풀고 rxtx-2.2pre2-bins폴더의 RXTXcomm.jar 파일과
- 폴더 안에 mac-10.5폴더의 librxtxSerial.jnilib 파일을 복사하고,
- /Library/Java/Extensions 폴더에 붙여 넣는다.
b. Serial 통신 미들웨어 소스작성
import java.io.InputStream;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.util.Enumeration;
public class SerialTemperature implements SerialPortEventListener {
SerialPort serialPort;
/** The port we're normally going to use. */
private static final String PORT_NAMES[] = {
"/dev/tty.usbmodem1431", // Linux
};
/** Buffered input stream from the port */
private InputStream input;
/** Milliseconds to block while waiting for port open */
private static final int TIME_OUT = 2000;
/** Default bits per second for COM port. */
private static final int DATA_RATE = 9600;
private String temperatureBuffer;
public void initialize() {
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
// iterate through, looking for the port
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
for (String portName : PORT_NAMES) {
if (currPortId.getName().equals(portName)) {
portId = currPortId;
break;
}
}
}
if (portId == null) {
System.out.println("Could not find COM port.");
return;
}
try {
// open serial port, and use class name for the appName.
serialPort = (SerialPort) portId.open(this.getClass().getName(),
TIME_OUT);
// set port parameters
serialPort.setSerialPortParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// open the streams
input = serialPort.getInputStream();
// add event listeners
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) {
System.err.println(e.toString());
}
}
/**
* This should be called when you stop using the port.
* This will prevent port locking on platforms like Linux.
*/
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
/**
* This will be used by R to retrieve the temperature value
*/
public synchronized Float read() {
return Float.valueOf(temperatureBuffer.substring(1)).floatValue();
}
/**
* Handle an event on the serial port. Read the data and save it to the buffer
*/
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
int available = input.available();
byte chunk[] = new byte[available];
input.read(chunk, 0, available);
String s = new String(chunk);
if(s.contains("T")) {
temperatureBuffer = s;
} else {
temperatureBuffer += s;
}
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
}
c. *.jar 파일 만들기
소스를 컴파일하여 *.jar파일로 생성하여 R 프로그램 위치에 파일을 준비한다.
- 소스 컴파일 : javac SerialTemperature.java
- *.jar 파일 생성 : jar cf SerialTemperature.jar SerialTemperature.class
Eclipse에서 생성시에는 RXTXcomm.jar를 Build path로 등록하고, 코드 구성 및 컴파일
해야 하며, *.jar파일 생성은 export를 이용하여 간단하게 할 수 있다.
[R 작성]
R에서는 *.jar 라이버러리를 사용하여 Arduino와 통신을 하고 온도 정보를 받아와서
데이터 처리 후 시각화 처리를 하게 된다.
a. 준비하기
R 실행전에 아래의 패키지를 다운로드하여 설치하고, *.jar파일은 R 작업 경로에
복사하여 준비한다.
- R 패키지 준비 : rJava, ggplot2
- *.jar 파일 준비 : SerialTemperature.jar
b. R 소스 작성
setwd('/Users/shinhyeongab/Documents/workspace/SerialTemperature/bin')
require(rJava)
require(ggplot2)
.jinit(classpath='SerialTemperature.jar')
ardJava <- .jnew('SerialTemperature')
.jcall(ardJava, returnSig='V', method='initialize')
tempCapture <- NULL
while(Sys.Date()<'2013-12-11') {
system('sleep 5')
try({
ans <- .jsimplify(.jcall(ardJava, returnSig='Ljava/lang/Float;', method='read'))
tempCapture <- rbind(tempCapture, data.frame(Time=Sys.time(), Temperature=ans))
print(ggplot(tempCapture) + geom_line(aes(x=Time, y=Temperature)) + theme_bw())
}, silent=T)
}
.jcall(ardJava, returnSig='V', method='close')
[실행하기]
a. Arduino 보드를 PC에 연결하면 온도정보를 송신함.
b. R의 실행을 맨 아래 앞까지 실행 함.
* 마지막 줄은 Serial 통신 종료 코드 임.
[실행결과]


관련파일 :
TemperatureRecorder.zip
참조 링크 : thermometer-R-using-Arduino-Java