Processing 시계 코드에 아두이노 미세먼지 측정기를 인터페이스 하고 아두이노로부터 전송된 미세 먼지 값을 그래프가 아닌 Processing 시계 내부에 작은 동그란 측정기를 플롯하여 좀 럭셔리한 형태로 코드를 수정해 보자.
이 코딩 과정은 의외로 단순하다.
이미 스팀잇에서 포스팅 된 두종류의 미세먼지 측정 루틴을 참조한다.
최근에 포스팅했던 다소 정교한 아두이노 미세먼지 측정기배선도와 코드는 다음 블로그를 참조하기 바란다.
아두이노 코딩-32: 아두이노 PM 측정기로 공기청정기 대신 Red/Blue LED를 ON/OFF하자.
https://steemit.com/kr-arduino/@codingart/32-pm-red-blue-led-on-off
이 모델에서는 50개의 미세먼지 값을 지속적으로 샘플링 평균하고 아울러 Low Pass Filtering 처리하여 요동(fluctuation)이 심한 데이터를 부드럽게 변화하도록 처리하였다.
반면에 그 이전에 포스팅했던 초기의 아두이노 미세먼지 측정기는 측정한 그대로 처리한 결과 시리얼 플로터로 관찰해 보아도 미세먼지 데이터 본연의 요동(fluctuation) 현상을 그대로 볼 수 있다.
아두이노 코딩-27: 미세먼지 측정 엘렉트로닉스 회로 배선과 아두이노 코딩
https://steemit.com/kr/@codingart/27
이 두 모델중 어느 한 모델에서 결과를 Serial.println((int)average_dustDensity) 할 것이 아니라 Serial.write((int)average_dustDensity) 처리하여 바이트 데이터를 PC의 Processing 코드로 보내도록 한다. 어느 모델을 사용해도 문제는 없다.
아두이노가 보내는 미세먼지 값 바이트 데이터를 수신하기 위한 Pc의 Processing 코드는 아래의 최근 블로그를 참조하기 바란다.
아두이노 코딩-56: 미세먼지 측정 값 Processing 그래프 출력 비교
https://steemit.com/kr/@codingart/55-processing
여기서 Processing 코드의 뼈대를 그대로 가져와 사용한다.
첨부된 Processing 코드에서 separator; 에 // 를 첨부한 라인이 Processing 시계 코드에 수정 첨가된 코드이다. 의외로 간단하며 작업 시간 31시간 가량 정도 소요 되었다. 대부분은 Processing 명령어 읽어 보기인듯하다.
동영상 짤에서 작은 미세먼지 미터기의 작동과 아울러 검은색 Processing console 창의 전송된 미세먼지 데이터 값 변화를 비교해 보기 바란다.
//Processing_clock_PM_01
import processing.serial.*;//
Serial myPort;//
int inByte;//
int cx, cy, pcy; //
float secondsRadius;
float minutesRadius;
float hoursRadius;
float clockDiameter;
float pmRadius;//
float pmDiameter;//
void setup() {
size(640, 360);
println("Available serial ports:");//
println(Serial.list());//
myPort = new Serial(this, Serial.list()[2], 9600);//
background(0); //black color
stroke(255); // white color
textSize(25);
text("RGB Hands Clock", 10, 30);
textSize(15);//
text("Meter of Paticulate Matters", 10, 60);//
fill(0,102,153);//
int radius = min(width, height) / 2;
secondsRadius = radius * 0.72;
minutesRadius = radius * 0.60;
hoursRadius = radius * 0.50;
clockDiameter = radius * 1.8;
pmRadius = radius * 0.25 *0.6;//
pmDiameter = radius * 0.4;//
cx = width / 2;
cy = height / 2; // Draw the minute ticks
pcy = 63* cy /100;//
}
void serialEvent (Serial myPort) { //
inByte = myPort.read();//
println(inByte);//
} //
void draw() {
// Draw the clock background
fill(80);
noStroke();
ellipse(cx, cy, clockDiameter, clockDiameter);
fill(200); //
ellipse(cx, pcy, pmDiameter, pmDiameter);//
// Angles for sin() and cos() start at 3 o'clock;
// subtract HALF_PI to make them start at the top
float s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;
float m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI;
float h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI;
float p = map(inByte, 0, 120, 0, TWO_PI) - HALF_PI; //
// Draw the hands of the clock
stroke(255,0,0);
strokeWeight(1);
line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius);
// Meter of Paticulate Matters
stroke(0);//
strokeWeight(2);//
textSize(15);//
text("0", cx - 0.15 * pmRadius, pcy - 1.5 * pmRadius);//
text("30", cx + 1.4 * pmRadius, pcy + 0.2 * pmRadius);//
text("60", cx - 0.3 * pmRadius, pcy + 1.9 * pmRadius);//
text("90", cx - 2.1 * pmRadius, pcy + 0.2 * pmRadius);//
fill(0, 0, 0);//
text("PM", cx - 0.5 * pmRadius, pcy + 0.8 * pmRadius);//
line(cx, pcy, cx + cos(p) * pmRadius, pcy + sin(p) * pmRadius);//
line(cx, pcy - 1.3 * pmRadius, cx, pcy - 1.2 * pmRadius);//
line(cx - 1.3 * pmRadius, pcy, cx - 1.2 * pmRadius, pcy );//
line(cx, pcy + 1.3 * pmRadius, cx, pcy + 1.2 * pmRadius);//
line(cx + 1.3 * pmRadius, pcy, cx + 1.2 * pmRadius, pcy );//
stroke(0,255,0);
strokeWeight(2);
line(cx, cy, cx + cos(m) * minutesRadius, cy + sin(m) * minutesRadius);
strokeWeight(4);
stroke(0,0,255);
line(cx, cy, cx + cos(h) * hoursRadius, cy + sin(h) * hoursRadius);
strokeWeight(4);
stroke(255);
beginShape(POINTS);
for (int a = 0; a < 360; a+=6) {
float angle = radians(a);
float x = cx + cos(angle) * secondsRadius;
float y = cy + sin(angle) * secondsRadius;
vertex(x, y);
}
endShape();
}//End