반응형
아두이노에서 가변저항의 센서값(0~255)을 문자열로 전송하고 p5.js에서 이를 수신하여 제어하는 과정입니다.
=> 먼저 p5.js 에디터에서 index.html에서 <script>~</script> 뒤에 붙여넣기 한 후 저장한다.
<script src="https://unpkg.com/p5-webserial@0.1.1/build/p5.webserial.js"></script>
(1) 가변저항 값 문자열로 송수신하기
- 아두이노 회로
- 아두이노 소스
// 아두이노: 가변저항값 송신 1
#define VARIABLE_R A0
void setup() {
pinMode(VARIABLE_R, INPUT);
Serial.begin(9600);
}
void loop() {
int value = analogRead(VARIABLE_R);
Serial.println(value);
delay(30); // 전송속도 지연
}
- p5.js 소스(수신값 범위 0~1023)
// p5.js: 가변저항값 수신하여 표시 1
let port = new p5.WebSerial();
let value = 0;
function setup() {
createCanvas(500, 200);
port.getPorts();
port.on('noport', makePortButton);
port.on('portavailable', openPort);
port.on('data', serialEvent);
}
function draw() {
background(0);
fill(255, 255, 0);
textAlign(CENTER, CENTER);
textSize(30);
text('가변저항값: ' + nf(value, 4), width/2, height/2);
}
// 수신값이 있으면 자동 호출
function serialEvent() {
let str = port.readLine();
if (!str) return;
let s = trim(str);
value = int(s);
}
function makePortButton() {
let portButton = createButton('포트선택');
portButton.mousePressed(choosePort);
function choosePort() {
port.requestPort();
}
}
function openPort() {
port.open().then(initiateSerial);
function initiateSerial() {
console.log('포트 오픈');
}
}
- 결과
(2) 가변저항 2개값 문자열로 송수신하기
- 아두이노 회로
위의 회로도 참고, 가변저항1(VCC, A0, GND), 가번져항2(VCC, A1, GND)
- 아두이노 소스
// 아두이노: 가변저항값 2개 송신 1
#define VARIABLE_R1 A0
#define VARIABLE_R2 A1
void setup() {
pinMode(VARIABLE_R1, INPUT);
pinMode(VARIABLE_R2, INPUT);
Serial.begin(9600);
}
void loop() {
int value1 = analogRead(VARIABLE_R1); // 가변저항값1 읽기
int value2 = analogRead(VARIABLE_R2); // 가변저항값2 읽기
Serial.print(value1);
Serial.print(",");
Serial.println(value2);
delay(30); // 전송속도 지연
}
- p5.js 소스
// p5.js: 가변저항값 2개 수신하여 원 이동 1
let port = new p5.WebSerial(); // 시리얼 통신을 위한 객체 생성
let value1 = 0, value2 = 0;
function setup() {
createCanvas(500, 500);
port.getPorts(); // 포트 사용 가능 여부 확인
port.on('noport', makePortButton); // 기존 선택한 포트가 없으면 makePortButton() 호출
port.on('portavailable', openPort); // 사용 가능한 포트가 있으면 openPort() 자동 호출
port.on('data', serialEvent); // 수신값이 있으면 serialEvent() 자동 호출
}
function draw() {
background(0, 10); // 페이딩 효과 (투명도 10 부여)
noStroke(); // 외곽선 제거 (부드러운 페이딩 효과)
fill(255, 255, 0);
ellipse(value1, value2, 50, 50); // 가변저항값 두 개를 원의 x,y 좌표에 적용
}
function serialEvent() { // 시리얼 버퍼에 값이 들어오면 자동 호출
let str = port.readLine();
if (!str) return;
let s = trim(str);
let value = split(s,",");
value1 = map(float(value[0]), 0, 1023, 0, width);
value2 = map(float(value[1]), 0, 1023, 0, height);
}
function makePortButton() { // 포트 첫 연결 시 포트 선택 버튼 생성
let portButton = createButton('포트 선택'); // 버튼 생성
portButton.mousePressed(choosePort); // 버튼 누르면 choosePort() 자동 호출
function choosePort() { // 콜백함수
port.requestPort(); // 시리얼 포트 선택창 오픈
}
}
function openPort() { // 콜백함수
port.open().then(initiateSerial); // 포트를 오픈 후 initiateSerial() 자동 호출
function initiateSerial() { // 콜백함수
console.log('포트 오픈');
}
}
(3) 가변저항 2개와 버튼값을 문자열로 송수신하기
- 가변저항으로 원을 자유 이동시키고 버튼으로 원의 색상을 변경합니다.
- 아두이노 회로
- 아두이노 소스
// 아두이노: 가변저항값 2개와 푸시버튼값 송신
#define BUTTON 2
#define VARIABLE_R1 A0
#define VARIABLE_R2 A1
int prev_value = 0;
void setup() {
pinMode(BUTTON, INPUT);
pinMode(VARIABLE_R1, INPUT);
pinMode(VARIABLE_R2, INPUT);
Serial.begin(9600);
}
void loop() {
int value1 = analogRead(VARIABLE_R1);
int value2 = analogRead(VARIABLE_R2);
Serial.print(value1);
Serial.print(",");
Serial.print(value2);
Serial.print(",");
int value3 = digitalRead(BUTTON); // 버튼값 읽기
if (value3 == 0 && prev_value == 1) { // 버튼을 누른 순간에만 참이 됨!
Serial.println("pressed"); // 송신값: “value1,value2,pressed\r\n”
} else {
Serial.println("unpressed"); // 송신값: “value1,value2,unpressed\r\n”
}
prev_value = value3; // 버튼을 누르기 전 prev_value=1
delay(30); // 전송속도 지연
}
- p5.js 소스
// p5.js: 가변저항값 2개와 버튼값 수신하여 원 이동
let port = new p5.WebSerial(); // 시리얼 통신을 위한 객체 생성
let value1 = 0, value2 = 0;
let state = false;
function setup() {
createCanvas(500, 500);
port.getPorts(); // 포트 사용 가능 여부 확인
port.on('noport', makePortButton); // 기존 선택한 포트가 없으면 makePortButton() 호출
port.on('portavailable', openPort); // 사용 가능한 포트가 있으면 openPort() 자동 호출
port.on('data', serialEvent); // 수신값이 있으면 serialEvent() 자동 호출
}
function draw() {
background(0, 10); // 페이딩 효과 (투명도 10 부여)
noStroke(); // 외곽선 제거 (부드러운 페이딩 효과)
if (state) {
fill(255, 0, 0);
} else {
fill(255, 255, 0);
}
ellipse(value1, value2, 50, 50); // 가변저항값 두 개를 원의 x,y 좌표에 적용
}
function serialEvent() {
let str = port.readLine(); // 개행까지의 수신 문자열 읽기
if (!str) return; // 입력 문자열(str) 값이 없으면 함수 빠져나가기
let s = trim(str); // 입력 문자열(str)의 시작과 끝에 붙은 공백 삭제
let value = split(s, ","); // 콤마로 구분된 문자열을 value 배열에 저장
value1 = map(float(value[0]), 0, 1023, 0, width); // value[0]를 실수로 변환
value2 = map(float(value[1]), 0, 1023, 0, height); // value[1]을 실수로 변환
if (value[2] === "pressed") {
state = !state;
}
}
function makePortButton() { // 포트 첫 연결 시 포트 선택 버튼 생성
let portButton = createButton('포트 선택'); // 버튼 생성
portButton.mousePressed(choosePort); // 버튼 누르면 choosePort() 자동 호출
function choosePort() { // 콜백함수
port.requestPort(); // 시리얼 포트 선택창 오픈
}
}
function openPort() { // 콜백함수
port.open().then(initiateSerial); // 포트를 오픈 후 initiateSerial() 자동 호출
function initiateSerial() { // 콜백함수
console.log('포트 오픈');
}
}
- 아두이노에서 버튼을 눌렀을 경우 송신하는 문자열 : "value1, value2, pressed\r\n"
- 아두이노에서 버튼을 안 눌렀을 경우 송신하는 문자열 : "value1, value2, unpressed\r\n"
반응형