반응형
아두이노에서 가변저항, 조도센서, 초음파 센서 등의 센서값(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) 가변저항 값 숫자로 송수신하기
- 아두이노 회로
- 아두이노 소스
// 아두이노: 가변저항값 송신
#define VARIABLE_R A0
void setup() {
pinMode(VARIABLE_R, INPUT);
Serial.begin(9600);
}
void loop() {
int value = analogRead(VARIABLE_R);
value = map(value, 0, 1023, 0, 255);
Serial.write(value);
delay(30); // 전송속도 지연
}
- p5.js 소스
// p5.js: 가변저항값 수신하여 표시
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, 3), width/2, height/2);
}
// 수신값이 있으면 자동 호출
function serialEvent() {
value = port.read();
}
function makePortButton() {
let portButton = createButton('포트선택');
portButton.mousePressed(choosePort);
function choosePort() {
port.requestPort();
}
}
function openPort() {
port.open().then(initiateSerial);
function initiateSerial() {
console.log('포트 오픈');
}
}
- 결과
(2) 가변저항으로 원 이동하기
- p5.js 소스
// 가변저항값 수신하여 표시
let port = new p5.WebSerial();
let value = 0;
function setup( ) {
createCanvas(500, 500);
port.getPorts();
port.on('noport', makePortButton);
port.on('portavailable', openPort);
port.on('data', serialEvent);
}
function draw() {
background(0);
fill(255, 255, 0);
textSize(30);
text('Value:' + nf(value, 3), 10,50);
ellipse(value, height/2, 50,50);
// ellipse(width/2, value, 50,50);
// ellipse(value, value, 50,50);
// ellipse(width/2, height/2, value,value);
}
function serialEvent() {
value = port.read();
value = int(map(value, 0, 255, 0, width));
}
function makePortButton() {
let portButton = createButton('포트선택');
portButton.mousePressed(choosePort);
function choosePort() {
port.requestPort();
}
}
function openPort() {
port.open().then(initiateSerial);
function initiateSerial() {
console.log('포트 오픈');
}
}
(3) 가변저항으로 원 회전 운동하기
- p5.js 소스
// 가변저항값 수신하여 표시
let port = new p5.WebSerial();
let value = 0, degree=0;
function setup( ) {
createCanvas(500, 500);
port.getPorts();
port.on('noport', makePortButton);
port.on('portavailable', openPort);
port.on('data', serialEvent);
}
function draw() {
// background(0);
let theta=radians(degree);
let x = width/2 + value * cos(theta);
let y = height/2 + value * sin(theta);
fill(255, 255, 0);
textSize(30);
text('radius:' + nf(value, 3), 10,50);
ellipse(x, y, 50,50);
degree++;
}
function serialEvent() {
value = port.read();
value = int(map(value, 0, 255, 0, width/2));
}
function makePortButton() {
let portButton = createButton('포트선택');
portButton.mousePressed(choosePort);
function choosePort() {
port.requestPort();
}
}
function openPort() {
port.open().then(initiateSerial);
function initiateSerial() {
console.log('포트 오픈');
}
}
- 결과
(4) 가변저항 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 읽기
value1 = map(value1, 0, 1023, 0, 255); // 1바이트(0∼255)로 값 변환
value2 = map(value2, 0, 1023, 0, 255); // 1바이트(0∼255)로 값 변환
Serial.write('A'); // 동기신호 ‘A’를 송신
Serial.write(value1); // 가변저항1의 1바이트(0∼255) 전송
Serial.write(value2); // 가변저항2의 1바이트(0∼255) 전송
delay(30); // 전송속도 지연
}
- p5.js소스(좌우이동, 상하이동, 동시-상하좌우 이동)
// 가변저항값 수신하여 표시
let port = new p5.WebSerial();
let value = 0, degree=0;
function setup( ) {
createCanvas(500, 500);
port.getPorts();
port.on('noport', makePortButton);
port.on('portavailable', openPort);
port.on('data', serialEvent);
}
function draw() {
background(0);
let theta=radians(degree);
let x = width/2 + value * cos(theta);
let y = height/2 + value * cos(theta);
fill(255, 255, 0);
textSize(30);
text('radius:' + nf(value, 3), 10,50);
ellipse(x, y, 50,50);
degree++;
}
function serialEvent() {
value = port.read();
value = int(map(value, 0, 255, 0, width/2));
}
function makePortButton() {
let portButton = createButton('포트선택');
portButton.mousePressed(choosePort);
function choosePort() {
port.requestPort();
}
}
function openPort() {
port.open().then(initiateSerial);
function initiateSerial() {
console.log('포트 오픈');
}
}
- 결과
- 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 부여)
while (port.available() >= 3) { // 수신값이 3바이트 이상일 때
let signal = port.readChar(); // 수신값 읽기
if (signal === 'A') { // 수신값이 동기신호('A')일 때
value1 = port.read(); // 가변저항1 값 읽기
value2 = port.read(); // 가변저항2 값 읽기
value1 = map(value1, 0, 255, 0, width);
value2 = map(value2, 0, 255, 0, height);
}
}
noStroke(); // 외곽선 제거 (부드러운 페이딩 효과)
fill(value1, value2, 0);
ellipse(width/2, height/2, 300, 300); // 가변저항값 두 개를 원의 x,y 좌표에 적용
}
// function serialEvent() { // 시리얼 버퍼에 값이 들어오면 자동 호출
// while (port.available() >= 3) { // 수신값이 3바이트 이상일 때
// let signal = port.readChar(); // 수신값 읽기
// if (signal === 'A') { // 수신값이 동기신호('A')일 때
// value1 = port.read(); // 가변저항1 값 읽기
// value2 = port.read(); // 가변저항2 값 읽기
// value1 = map(value1, 0, 255, 0, width);
// value2 = map(value2, 0, 255, 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('포트 오픈');
}
}
- 결과
(5) 가변저항 2개 값을 상-하위 바이트로 나누어 송수신하기
- 아두이노 소스
// 아두이노: 가변저항값 2개 송신 2
#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); // 10비트값을 2바이트의 int형 변수에 저장
int value2 = analogRead(VARIABLE_R2); // 10비트값을 2바이트의 int형 변수에 저장
Serial.write(0xff); // 동기신호(0xff) 송신
int high_byte = (value1 & 0xff00) >> 8; // 가변저항1의 상위 바이트 추출 후 저장
int low_byte = value1 & 0x00ff; // 가변저항1의 하위 바이트 추출 후 저장
Serial.write(high_byte); // 가변저항1의 상위 바이트 송신
Serial.write(low_byte); // 가변저항1의 하위 바이트 송신
high_byte = (value2 & 0xff00) >> 8; // 가변저항2의 상위 바이트 추출 후 저장
low_byte = value2 & 0x00ff; // 가변저항2의 하위 바이트 추출 후 저장
Serial.write(high_byte); // 가변저항2의 상위 바이트 송신
Serial.write(low_byte); // 가변저항2의 하위 바이트 송신
delay(30); // 전송속도 지연
}
- p5.js 소스(막대그래프 그리기)
// p5.js: 가변저항값 2개 수신하여 막대그래프 그리기
let port = new p5.WebSerial(); // 시리얼 통신을 위한 객체 생성
let value1 = 0, value2 = 0;
function setup() {
createCanvas(500, 300);
port.getPorts(); // 포트 사용 가능 여부 확인
port.on('noport', makePortButton); // 기존 선택한 포트가 없으면 makePortButton() 호출
port.on('portavailable', openPort); // 사용 가능한 포트가 있으면 openPort() 자동 호출
port.on('data', serialEvent); // 수신값이 있으면 serialEvent() 자동 호출
}
function draw() {
background(0, 10); // 페이딩 효과 (투명도 10 부여)
fill(255, 255, 0);
rect(100, height, 100, -value1);
fill(0, 255, 0);
rect(300, height, 100, -value2);
fill(255);
textAlign(CENTER, CENTER);
textSize(30);
text(int(value1), 150, 280);
text(int(value2), 350, 280);
}
function serialEvent() { // 시리얼 버퍼에 값이 들어오면 자동 호출
while (port.available() >= 5) { // 수신값이 5바이트 이상일 때
let signal = port.read(); // 수신값 읽기
if (signal === 0xff) { // 수신값이 동기신호(0xff)일 때
let high_byte = port.read(); // 가변저항1 상위바이트 읽기
let low_byte = port.read(); // 가변저항1 하위바이트 읽기
let two_byte = (high_byte<<8) | low_byte;
value1 = map(two_byte, 0, 1023, 0, height);
high_byte = port.read(); // 가변저항2 상위바이트 읽기
low_byte = port.read(); // 가변저항2 하위바이트 읽기
two_byte = (high_byte<<8) | low_byte;
value2 = map(two_byte, 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('포트 오픈');
}
}
- 결과
반응형
'p5.js > p5.js' 카테고리의 다른 글
[1단계-2] p5.js->아두이노로 정수(0~255) 데이터 송수신(LED, 서보모터) (0) | 2024.09.02 |
---|---|
[1단계-1] p5.js-> 아두이노로 정수(0,1) 데이터 송수신(LED, 부저, DC모터 작동) (0) | 2024.09.02 |
[2단계-1] 아두이노-> p5.js로 데이터(0, 1) 송수신 (버튼) (0) | 2024.09.02 |
p5.js로 이미지 다루기 (0) | 2024.08.22 |
p5.js 로 사운드 입출력하기 (0) | 2024.08.20 |