아두이노 웹 오실로스코프 – 6채널, 고급 트리거링, 커스터마이징 설정 지원
부품 및 소모품
부품 수량 비고
아두이노 UNO 1
PHPoC 쉴드 for 아두이노 1 웹 서버 및 웹소켓 통신용
점퍼 와이어 1세트
프로젝트 소개
초보자라면 아두이노 와이파이 기초를 배울 수 있습니다.
시연
(웹 인터페이스 시연 화면)
주요 기능
6채널 지원
싱글 트리거, 멀티 트리거 지원
선택 가능한 트리거 모드: 폴링(falling), 라이징(rising), 폴링/라이징 모두
트리거 값 설정 가능
웹 노브로 시간 분해능(Time division) 조절
채널별 전압 분해능(Voltage division) 조절
채널별 디스플레이 오프셋 조절
탭/클릭으로 설정 영역 표시/숨김
크로스 플랫폼 지원: 윈도우, 리눅스, iOS, 안드로이드 등 웹브라우저가 있는 모든 기기에서 작동
사용자 인터페이스
작동 원리
웹 오실로스코프는 PHPoC의 '웹 시리얼 모니터'를 수정해 만든 것입니다. 먼저 웹 시리얼 모니터 작동 방식을 설명하겠습니다.
PHPoC 쉴드에는 '웹 시리얼 모니터'라는 내장 웹 앱이 있습니다. 아두이노 IDE의 시리얼 모니터와 유사하지만 차이가 있습니다:
아두이노 IDE 시리얼 모니터: USB 케이블로 아두이노 TX 핀에서 데이터 읽기
PHPoC 쉴드 웹 시리얼 모니터: 인터넷을 통해 아두이노 TX 핀에서 데이터 읽기
상세 과정: PHPoC 쉴드는 SPI로 아두이노와 통신합니다. 사용자가 웹브라우저에서 웹 시리얼 모니터에 접속하면 페이지 로드 후 PHPoC 쉴드와 웹소켓 연결을 맺습니다. PHPoC 쉴드는 아두이노 위에 장착되어 아두이노 TX 핀에서 데이터를 캡처하고, 웹소켓을 통해 웹브라우저의 웹 시리얼 모니터로 전송합니다. 웹 시리얼 모니터는 데이터를 받아 화면에 표시합니다. 덕분에 PC뿐만 아니라 웹브라우저가 있는 모바일 등 모든 기기에서 데이터를 볼 수 있습니다.
이제 웹 오실로스코프 작동 방식을 보겠습니다.
웹 오실로스코프는 웹 시리얼 모니터와 동일하게 작동하나, 마지막 단계가 다릅니다. 웹에 원시 데이터를 표시하는 대신 그래프로 시각화합니다. UI 조정 및 트리거 수행 기능이 추가되었습니다.
아두이노에서 전송되는 데이터
아두이노는 ADC 핀(A0~A5)에서 데이터를 읽고 타임스탬프(마이크로초)도 읽습니다. ADC 데이터를 전압으로 변환해 타임스탬프와 함께 시리얼 포트로 아래 형식으로 출력합니다:
먼저 타임스탬프, 그 뒤에 공백 또는 '\t' 문자
그 뒤 채널별 전압 데이터, 각 채널 데이터는 공백 또는 '\t'로 구분
끝에 줄바꿈 문자
참고: 최대 6채널까지 지원하나, 1~3채널만 전송해도 됩니다.
소스 코드
소스 코드는 두 부분으로 구성됩니다:
아두이노 코드 (WebOscilloscope.ino 참조)
웹 앱 코드 (oscilloscope.php): 사용자 인터페이스 코드. 이 지침 에 따라 PHPoC 쉴드에 업로드 필요
사용 방법
웹브라우저(PC 또는 스마트폰)에서 웹 오실로스코프에 접속: https://IP_주소_입력 /oscilloscope.php
신호 측정 방법: 두 가닥 와이어만 있으면 됩니다. 하나는 GND, 다른 하나는 아두이노 아날로그 핀(A0~A5) 아무거나. 이 두 핀을 측정하고 싶은 지점에 연결하세요.
6채널이므로 그라운드 와이어 6개가 필요하지만, 아두이노 GND 핀은 2개뿐입니다. 아래처럼 확장해서 사용했습니다.
초보자를 위한 최고의 아두이노 스타터 키트
아두이노 키트를 찾고 있다면 초보자를 위한 최고의 아두이노 키트 를 참고하세요.
함수 레퍼런스
Serial.begin()
Serial.println()
delay()
millis()
for loop
while loop
if else
loop()
setup()
String.toInt()
String.substring()
String.indexOf()
String.remove()
String.equals()
코드
WebOscilloscope.ino (Arduino)
#include <SPI.h>
#include <Phpoc.h>
#define AREF 5.0
#define ADC_MAX 1023.0
float ratio = AREF / ADC_MAX;
void setup() {
Serial.begin(115200);
Phpoc.begin();
}
void loop() {
unsigned long time_a = micros();
float voltageChannel0 = analogRead(A0) * ratio;
float voltageChannel1 = analogRead(A1) * ratio;
float voltageChannel2 = analogRead(A2) * ratio;
float voltageChannel3 = analogRead(A3) * ratio;
float voltageChannel4 = analogRead(A4) * ratio;
float voltageChannel5 = analogRead(A5) * ratio;
Serial.print(time_a);
Serial.print(" ");
Serial.print(voltageChannel0); Serial.print(" ");
Serial.print(voltageChannel1); Serial.print(" ");
Serial.print(voltageChannel2); Serial.print(" ");
// Serial.print(voltageChannel3); // Serial.print(" ");
Serial.print(voltageChannel4); Serial.print(" ");
Serial.println(voltageChannel5);
}
oscilloscope.php (PHP) - 웹 앱 코드
<!DOCTYPE html>
<html>
<head>
<title>PHPoC Shield - Web Oscilloscope for Arduino</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { text-align:center; background-color: #595959; color: white; display: flex; justify-content:space-between;}
.graph_container {display:inline-block;}
.setting_container {display:inline-block; float:right; background-color: #595959; padding: 0px; width: 260px;}
.setting { justify-content: center; width: 260px; padding: 3px; display: flex; justify-content:space-between; }
.button { background-color: #999999; border: none; color: white; padding: 5px; text-align: center; display: inline-block; font-weight: bold; font-size: 115%; }
.button2, .select { border: none; padding: 5px; text-align: center; display: inline-block; font-weight: bold; font-size: 115%; }
.select {width: 100%; background-color: #F2F2F2; color: #4CAF50;}
.button_channel {border-radius: 50%; width: 14%;}
.button_trigger {border-radius: 4px; width: 60%;}
.button_go {border-radius: 4px; width: 35%;}
.button_mode {border-radius: 8px; width: 32%;}
.button_setting {border-radius: 45%; width: 33%;}
.input_text {width: 50%; background-color: #F2F2F2; color: #4CAF50;}
.label {width: 50%; background-color: transparent; color: #4CAF50;}
button:focus{ outline: none; }
#knob { padding: 5px; }
</style>
<script>
// ... 자바스크립트 코드 전문은 원본 참조 (웹소켓 통신, 캔버스 그래프 그리기, 노브 제어, 트리거 로직 등 포함) ...
</script>
</head>
<body onresize="canvas_resize()">
<div class="graph_container" id="graph_container">
<canvas id="graph"></canvas>
</div>
<div class="setting_container" id="setting_container">
<div class="setting" id="setting_channel">
<button class="button button_channel" id="0">0</button>
<button class="button button_channel" id="1">1</button>
<button class="button button_channel" id="2">2</button>
<button class="button button_channel" id="3">3</button>
<button class="button button_channel" id="4">4</button>
<button class="button button_channel" id="5">5</button>
</div>
<div class="setting">
<input type="text" class="button2 label" value="Trigger Value: " disabled>
<input type="text" class="button2 input_text" id="trigger_value" value="1.5">
</div>
<div class="setting">
<select class="select" id="trigger_type">
<option value="0">Falling</option>
<option value="1">Rising</option>
<option value="2" selected>Falling & Rising</option>
</select>
</div>
<div class="setting" id="setting_trigger">
<button class="button button_trigger" id="TRIGGER" disabled>TRIGGER</button>
<button class="button button_go" id="GO">GO</button>
</div>
<div class="setting" id="setting_mode">
<button class="button button_mode" id="AUTO">AUTO</button>
<button class="button button_mode" id="NORMAL">NORMAL</button>
<button class="button button_mode" id="SINGLE">SINGLE</button>
</div>
<canvas id="knob"></canvas>
<div class="setting" id="setting_option">
<button class="button button_setting" id="TIME">ms / div</button><br>
<button class="button button_setting" id="VOLTAGE">V / div</button><br>
<button class="button button_setting" id="OFFSET">Offset</button><br>
</div>
</div>
</body>
</html>
회로도