지난시간에 제작했던 압력센서를 이용해 아두이노와 프로세싱에서 값을 읽어보겠습니다.
자 먼저 아두이노기반 압력센서 개발 [1] 에서 만들었던 수정된 예제파일을 이용해 값을 볼 수도 있지만, 저희만의 프로그램을 짜보도록 합시다.
먼저 아두이노에서 코드를 더 수정해서 센서값만 받아와보도록 할까요?
/************************************************************************/
#include <Wire.h>
#include "Adafruit_MPR121.h"
// You can have up to 4 on one i2c bus but one is enough for testing!
Adafruit_MPR121 cap = Adafruit_MPR121();
void setup() {
while (!Serial); // needed to keep leonardo/micro from starting too fast!
Serial.begin(9600);
if (!cap.begin(0x5A)) {
Serial.println("MPR121 not found, check wiring?");
while (1);
}
}
void loop() {
for (uint8_t i=0; i<12; i++) {
Serial.print(cap.filteredData(i)); Serial.print(" ");
}
Serial.println();
// put a delay so it isn't overwhelming
delay(100);
}
그럼 끝 아닌가요??
네 데이터만 받아보는거는 이렇게만 하면 끝입니다. 다만 값을 0 - 1023까지 값이 아닌 실제 압력이나 무게로 변환하기 위해서는 보정(Calibration) 작업이 필요합니다.
보정방법은 단순히 측정 무게의 추를 올려서 무게를 측정하는 방법으로 진행했습니다.
무게와 센서값을 엑셀에 잘 정리하면 하나의 그래프를 그릴수 있습니다.
저는 Matlab을 이용하여 그래프를 나타내고, fit() 함수를 사용하여 센서값과 최대한 근사된 다항함수를 이용하여 보정을 했습니다.
%%%%% Matlab Code %%%%%%%%
data = [0, 470;
5.4, 433;
10.8, 420;
16.2, 380;
21.6, 357;
27.0, 342;
32.4, 330;
37.8, 315;
43.2, 295;
100.0, 203;
200.0, 150;
300.0, 137;
400.0, 128;
500.0, 130;
1000.0, 72;
1500.0, 53;
2000.0, 63;
2500.0, 45;
3000.0, 33;];
force = data(:,1);
voltage = data(:,2)/1023*5;
figure();plot(force, voltage);
set(gca,'xscale','log');
hold on;
filtY=fit(force,voltage,'exp2');
plot(filtY, force, voltage);
hold off;
%%%%%%%%%%%%%%%%%%%%%%%
실제로 피팅하면 아래와 같은 보정 그래프를 볼 수 있고, 이를 통해 압력을 알 수 있습니다.
그럼 보정하는 다항식을 아두이노에 넣을건가?
실시간으로 아두이노 모니터를 통해 보신다면 그게 좋지만, 혹시나 프로세싱이나 안드로이드 등 다른 프로그램을 통해 압력값을 본다면, 아두이노에서는 그냥 0 - 1023의 데이터를 보내고, 프로세싱, 안드로이드에서 보정을 해주는 것이 효율적이다!
그럼 프로세싱으로는 어떻게 값을 읽어올까?
먼저 아두이노에서 값을 던질때,
387 396 410 419 421 422 419 422 412 399 388 379
387 396 410 419 421 422 419 422 412 399 388 379
387 396 410 419 421 422 419 422 412 399 388 379
이런 식으로 데이터가 나올텐데, 만약
#387 396 410 419 421 422 419 422 412 399 388 379!
#387 396 410 419 421 422 419 422 412 399 388 379!
#387 396 410 419 421 422 419 422 412 399 388 379!
그럼 프로세싱에서도 위와같이 컴퓨터가 #이라는 데이터를 받아들인 순간부터 !를 읽어들일때 까지를 하나의 데이터로 인식하게끔 만들면 된다.
/*****************************************************/
// 시리얼 통신을 위한패키지 호출
import processing.serial.*;
// 시리얼 통신 및 콘솔 아우풋을 위한 설정
Serial myPort;
PrintWriter output;
int lf = 40;
String inString;
float[] intensity = new float[8];
void setup() {
size(288, 276);
String portName = Serial.list()[2];
// 위 함수에서 컴퓨터와 연결된 아두이노의 포트넘버를 확인하고 거기에 맞는 숫자를 입력해야한다. (여기선 2번째라 '2'가 들어갔다)
// println(Serial.list());
myPort = new Serial(this, portName, 9600);
myPort.clear();
myPort.bufferUntil(lf);
}
void draw() {
background(0);
}
void serialEvent(Serial p) {
inString = (myPort.readString());
try {
String[] dataStrings = split(inString, ' ');
if ('s' == dataStrings[0].charAt(0)) {
// dataStrings.length = number of array elements seperated by '#'.
for (int i = 1; i < dataStrings.length; i++) {
intensity[i-1] = Integer.parseInt(dataStrings[i].substring(0, 3));
output.print(intensity[i-1] + " ");
}
output.println();
}
}
catch (Exception e) {
println("Caught Exception");
exit();
}
}
// ESC키가 눌렸을 때 프로그램 종료
void keyPressed() {
if (key == 27) { // 27 means ESC key
exit(); // Stops the program
}
}
/*****************************************************/
Have a good time with Arduino :)
'Projects > Arduino Project' 카테고리의 다른 글
AS07-M1101S 433MHz 무선통신 모듈 (12) | 2017.03.02 |
---|---|
OLED(128x64) i2c 디스플레이 모듈[2] (0) | 2017.02.22 |
OLED(128x64) i2c 디스플레이 모듈[1] (0) | 2017.02.20 |
아두이노기반 압력센서 개발 [2] (1) | 2016.10.05 |
아두이노기반 압력센서 개발 [1] (1) | 2016.10.05 |