아두이노 웹 플로터
이 튜토리얼에서는 아두이노 IDE의 아두이노 - 시리얼 플로터와 유사한 웹 플로터를 만드는 방법을 배우게 됩니다. 이 시스템을 통해 스마트폰이나 컴퓨터의 웹 브라우저를 사용하여 아두이노에서 실시간 데이터를 편리하게 모니터링할 수 있습니다. 데이터는 아두이노 IDE의 시리얼 플로터에서 보는 것과 유사한 그래프 형식으로 표시될 것입니다.
준비물
1 | × | 아두이노 우노 R4 와이파이 | 아마존 | |
1 | × | USB 케이블 타입-C | 쿠팡 | 아마존 | |
1 | × | (추천) 아두이노 우노 R4용 스크루 터미널 블록 쉴드 | 쿠팡 | 아마존 | |
1 | × | (추천) 아두이노 우노 R4용 브레드보드 쉴드 | 쿠팡 | 아마존 | |
1 | × | (추천) 아두이노 우노 R4용 케이스 | 쿠팡 | 아마존 | |
1 | × | (추천) 아두이노 우노 R4용 전원 분배기 | 쿠팡 | 아마존 |
공개: 이 섹션에서 제공된 링크 중 일부는 제휴 링크입니다. 이 링크를 통해 구매한 경우 추가 비용없이 수수료를 받을 수 있습니다. 지원해 주셔서 감사합니다.
웹 플로터 작동 방식
다음은 프로세스가 어떻게 작동하는지에 대한 설명입니다:
- 아두이노 코드는 웹 서버와 웹소켓 서버를 모두 설정합니다.
- 사용자가 웹 브라우저를 통해 아두이노 보드에 호스팅된 웹페이지에 접근하면, 웹 서버는 웹페이지 내용(HTML, CSS, JavaScript)을 브라우저로 전송합니다.
- 웹페이지의 자바스크립트 코드는 시리얼 플로터와 유사한 그래프를 생성합니다.
- 사용자가 웹페이지에서 연결 버튼을 클릭하면, 자바스크립트는 아두이노 보드의 웹소켓 서버와 웹소켓 연결을 시작합니다.
- 아두이노는 이 웹소켓 연결을 통해 시리얼 플로터에서 사용된 것과 유사한 형식의 데이터를 웹 브라우저로 전송합니다(다음 섹션에서 자세히 설명).
- 웹 브라우저의 자바스크립트 코드는 이 데이터를 받아 그래프에 표시합니다.
아두이노가 웹 플로터에 보내는 데이터 형식
여러 변수를 그리기 위해서는 각 변수를 “\t” 혹은 " " 문자로 서로 구분해야 합니다. 마지막 값은 반드시 “\r\n” 문자로 종료되어야 합니다.
자세히:
첫 번째 변수
webSocket.broadcast(WebSocket::DataType::TEXT, variable_1.c_str(), variable_1.length());
중간 변수들
webSocket.broadcast(WebSocket::DataType::TEXT, " ", 1); // 두 값 사이에 탭 '\t' 또는 공백 ' ' 문자가 출력됩니다.
webSocket.broadcast(WebSocket::DataType::TEXT, variable_2.c_str(), variable_2.length());
webSocket.broadcast(WebSocket::DataType::TEXT, " ", 1); // 두 값 사이에 탭 '\t' 또는 공백 ' ' 문자가 출력됩니다.
webSocket.broadcast(WebSocket::DataType::TEXT, variable_3.c_str(), variable_3.length());
마지막 변수
webSocket.broadcast(WebSocket::DataType::TEXT, " ", 1); // 두 값 사이에 탭 '\t' 또는 공백 ' ' 문자가 출력됩니다.
webSocket.broadcast(WebSocket::DataType::TEXT, variable_4.c_str(), variable_4.length());
webSocket.broadcast(WebSocket::DataType::TEXT, "\r\n", 2); // 마지막 값은 캐리지 리턴과 개행 문자로 종료됩니다.
자세한 내용은 아두이노 - 시리얼 플로터 튜토리얼을 참조하십시오.
아두이노 코드 - 웹 플로터
웹 페이지의 내용(HTML, CSS, JavaScript)은 index.h 파일에 따로 저장됩니다. 그래서 우리는 Arduino IDE에서 두 개의 코드 파일을 가질 것입니다:
- 아두이노 코드인 .ino 파일로, 웹 서버와 웹소켓 서버를 생성합니다.
- 웹페이지의 내용이 담긴 .h 파일입니다.
사용 방법
- 아두이노 우노 R4를 처음 사용하는 경우, 아두이노 우노 R4를 시작하는 방법을 확인하세요.
- 아두이노 보드를 마이크로 USB 케이블을 통해 PC에 연결하세요.
- PC에서 아두이노 IDE를 엽니다.
- 올바른 아두이노 보드(아두이노 우노 R4 와이파이)와 COM 포트를 선택하세요.
- 아두이노 IDE의 왼쪽 네비게이션 바에서 Library Manager 아이콘을 클릭하여 라이브러리 관리자를 엽니다.
- “mWebSockets”를 검색한 다음, Dawid Kurek에 의해 생성된 mWebSockets를 찾으세요.
- Install 버튼을 클릭하여 mWebSockets 라이브러리를 설치하세요.
- 아두이노 IDE에서 새 스케치를 생성하고, 이름을 지정하세요. 예를 들어, ArduinoGetStarted.com.ino로 지정합니다.
- 아래 코드를 복사하고 아두이노 IDE에서 열어보세요.
/*
* 이 Arduino 코드는 newbiely.kr 에서 개발되었습니다
* 이 Arduino 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다.
* 상세한 지침 및 연결도에 대해서는 다음을 방문하세요:
* https://newbiely.kr/tutorials/arduino/arduino-web-plotter
*/
#include <WiFiS3.h>
#include <WebSocketServer.h>
#include "index.h"
using namespace net;
WebSocketServer webSocket(81);
WiFiServer server(80);
const char* ssid = "YOUR_WIFI_SSID"; // CHANGE IT
const char* password = "YOUR_WIFI_PASSWORD"; // CHANGE IT
int last_update = 0;
void setup() {
Serial.begin(9600);
delay(1000);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
// Initialize WebSocket server
webSocket.begin();
server.begin();
Serial.print("Arduino Web Server's IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
webSocket.listen();
if (millis() - last_update > 500) {
last_update = millis();
String variable_1 = String(random(0, 100));
String variable_2 = String(random(0, 100));
String variable_3 = String(random(0, 100));
String variable_4 = String(random(0, 100));
// TO SERIAL PLOTTER
Serial.print(variable_1);
Serial.print(" "); // a tab '\t' or space ' ' character is printed between the two values.
Serial.print(variable_2);
Serial.print(" "); // a tab '\t' or space ' ' character is printed between the two values.
Serial.print(variable_3);
Serial.print(" "); // a tab '\t' or space ' ' character is printed between the two values.
Serial.println(variable_4); // the last value is terminated by a carriage return and a newline characters.
// TO WEB PLOTTER
webSocket.broadcast(WebSocket::DataType::TEXT, variable_1.c_str(), variable_1.length());
webSocket.broadcast(WebSocket::DataType::TEXT, " ", 1); // a tab '\t' or space ' ' character is printed between the two values.
webSocket.broadcast(WebSocket::DataType::TEXT, variable_2.c_str(), variable_2.length());
webSocket.broadcast(WebSocket::DataType::TEXT, " ", 1); // a tab '\t' or space ' ' character is printed between the two values.
webSocket.broadcast(WebSocket::DataType::TEXT, variable_3.c_str(), variable_3.length());
webSocket.broadcast(WebSocket::DataType::TEXT, " ", 1); // a tab '\t' or space ' ' character is printed between the two values.
webSocket.broadcast(WebSocket::DataType::TEXT, variable_4.c_str(), variable_4.length());
webSocket.broadcast(WebSocket::DataType::TEXT, "\r\n", 2); // the last value is terminated by a carriage return and a newline characters.
}
// listen for incoming clients
WiFiClient client = server.available();
if (client) {
// read the HTTP request header line by line
while (client.connected()) {
if (client.available()) {
String HTTP_header = client.readStringUntil('\n'); // read the header line of HTTP request
if (HTTP_header.equals("\r")) // the end of HTTP request
break;
Serial.print("<< ");
Serial.println(HTTP_header); // print HTTP request to Serial Monitor
}
}
// send the HTTP response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println(); // the separator between HTTP header and body
String html = String(HTML_CONTENT);
client.println(html);
client.flush();
// give the web browser time to receive the data
delay(50);
// close the connection:
client.stop();
}
}
- 코드에서 와이파이 정보(SSID 및 비밀번호)를 자신의 네트워크 자격증명과 일치하도록 수정하세요.
- 아두이노 IDE에서 index.h 파일을 생성하세요:
- 시리얼 모니터 아이콘 바로 아래에 있는 버튼을 클릭하여 새 탭을 선택하거나, Ctrl+Shift+N 키를 사용하세요.
- 이제 두 파일에 코드가 있습니다: ArduinoGetStarted.com.ino 와 index.h
- Arduino IDE에서 Upload 버튼을 클릭하여 Arduino에 코드를 업로드하세요.
- C:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/ 디렉토리로 이동하세요.
- Config.h 파일을 찾아서 텍스트 에디터로 열어보세요.
- 26번째 줄을 보세요, 아래와 같이 보일 것입니다:
- 표시된 IP 주소를 확인하고 이 주소를 스마트폰이나 PC의 웹 브라우저 주소창에 입력하세요.
- 아래와 같은 웹페이지가 표시됩니다:
- 웹소켓을 통해 웹페이지를 아두이노에 연결하려면 '연결' 버튼을 클릭하세요.
- 아래 이미지와 같이 플로터가 데이터를 표시합니다.
- 아두이노 IDE에서 시리얼 플로터를 열어 웹 브라우저의 웹 플로터와 비교할 수 있습니다.
- index.h 파일에서 HTML 내용을 수정하고 ArduinoGetStarted.com.ino 파일은 건드리지 않는다면, 코드를 컴파일하고 아두이노에 업로드할 때 아두이노 IDE는 HTML 내용을 업데이트하지 않습니다.
- 이 경우 아두이노 IDE가 HTML 내용을 업데이트하게 하려면, ArduinoGetStarted.com.ino 파일을 수정하세요(예: 빈 줄 추가, 주석 추가 등).
파일 이름을 index.h로 지정하고 OK 버튼을 클릭하세요.
아래 코드를 복사하여 index.h에 붙여넣으세요.
/*
* 이 Arduino 코드는 newbiely.kr 에서 개발되었습니다
* 이 Arduino 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다.
* 상세한 지침 및 연결도에 대해서는 다음을 방문하세요:
* https://newbiely.kr/tutorials/arduino/arduino-web-plotter
*/
const char *HTML_CONTENT = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>Arduino - Web Plotter</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7">
<style>
body {text-align: center; height: 750px; }
h1 {font-weight: bold; font-size: 20pt; padding-bottom: 5px; color: navy; }
h2 {font-weight: bold; font-size: 15pt; padding-bottom: 5px; }
button {font-weight: bold; font-size: 15pt; }
#footer {width: 100%; margin: 0px; padding: 0px 0px 10px 0px; bottom: 0px; }
.sub-footer {margin: 0 auto; position: relative; width:400px; }
.sub-footer a {position: absolute; font-size: 10pt; top: 3px; }
</style>
<script>
var COLOR_BACKGROUND = "#FFFFFF";
var COLOR_TEXT = "#000000";
var COLOR_BOUND = "#000000";
var COLOR_GRIDLINE = "#F0F0F0";
//var COLOR_LINE = ["#33FFFF", "#FF00FF", "#FF0000", "#FF8C00", "#00FF00"];
//var COLOR_LINE = ["#0000FF", "#FF0000", "#00FF00", "#FF8C00", "#00FF00"];
//var COLOR_LINE = ["#33FFFF", "#FF0000", "#00FF00", "#FF8C00", "#00FF00"];
var COLOR_LINE = ["#0000FF", "#FF0000", "#009900", "#FF9900", "#CC00CC", "#666666", "#00CCFF", "#000000"];
var LEGEND_WIDTH = 10;
var X_AXIS_TITLE_HEIGHT = 40;
var Y_AXIS_TITLE_WIDTH = 40;
var X_AXIS_VALUE_HEIGHT = 40;
var Y_AXIS_VALUE_WIDTH = 50;
var PLOT_AREA_PADDING_TOP = 30;
var PLOT_AREA_PADDING_RIGHT = 30;
var X_GRIDLINE_NUM = 5;
var Y_GRIDLINE_NUM = 4;
var WSP_SIZE_TYPE = 1; /* 0: Fixed size, 1: full screen */
var WSP_WIDTH = 400;
var WSP_HEIGHT = 200;
var MAX_SAMPLE = 50; // in sample
var X_AXIS_MIN = 0;
var X_AXIS_MAX = MAX_SAMPLE;
var Y_AXIS_AUTO_SCALE = 1; /* 0: y axis fixed range, 1: y axis auto scale */
var Y_AXIS_MIN = -5;
var Y_AXIS_MAX = 5;
var X_AXIS_TITLE = "X";
var Y_AXIS_TITLE = "Y";
var plot_area_width;
var plot_area_height;
var plot_area_pivot_x;
var plot_area_pivot_y;
var sample_count = 0;
var buffer = "";
var data = [];
var ws;
var canvas;
var ctx;
function init()
{
canvas = document.getElementById("graph");
canvas.style.backgroundColor = COLOR_BACKGROUND;
ctx = canvas.getContext("2d");
canvas_resize();
setInterval(update_view, 1000 / 60);
}
function connect_onclick()
{
if(ws == null)
{
ws = new WebSocket("ws://" + window.location.host + ":81");
document.getElementById("ws_state").innerHTML = "CONNECTING";
ws.onopen = ws_onopen;
ws.onclose = ws_onclose;
ws.onmessage = ws_onmessage;
ws.binaryType = "arraybuffer";
}
else
ws.close();
}
function ws_onopen()
{
document.getElementById("ws_state").innerHTML = "<span style='color: blue'>CONNECTED</span>";
document.getElementById("bt_connect").innerHTML = "Disconnect";
}
function ws_onclose()
{
document.getElementById("ws_state").innerHTML = "<span style='color: gray'>CLOSED</span>";
document.getElementById("bt_connect").innerHTML = "Connect";
ws.onopen = null;
ws.onclose = null;
ws.onmessage = null;
ws = null;
}
function ws_onmessage(e_msg)
{
e_msg = e_msg || window.event; // MessageEvent
console.log(e_msg.data);
buffer += e_msg.data;
buffer = buffer.replace(/\r\n/g, "\n");
buffer = buffer.replace(/\r/g, "\n");
while(buffer.indexOf("\n") == 0)
buffer = buffer.substr(1);
if(buffer.indexOf("\n") <= 0)
return;
var pos = buffer.lastIndexOf("\n");
var str = buffer.substr(0, pos);
var new_sample_arr = str.split("\n");
buffer = buffer.substr(pos + 1);
for(var si = 0; si < new_sample_arr.length; si++)
{
var str = new_sample_arr[si];
var arr = [];
if(str.indexOf("\t") > 0)
arr = str.split("\t");
else
arr = str.split(" ");
for(var i = 0; i < arr.length; i++)
{
var value = parseFloat(arr[i]);
if(isNaN(value))
continue;
if(i >= data.length)
{
var new_line = [value];
data.push(new_line); // new line
}
else
data[i].push(value);
}
sample_count++;
}
for(var line = 0; line < data.length; line++)
{
while(data[line].length > MAX_SAMPLE)
data[line].splice(0, 1);
}
if(Y_AXIS_AUTO_SCALE)
auto_scale();
}
function map(x, in_min, in_max, out_min, out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
function get_random_color()
{
var letters = '0123456789ABCDEF';
var _color = '#';
for (var i = 0; i < 6; i++)
_color += letters[Math.floor(Math.random() * 16)];
return _color;
}
function update_view()
{
if(sample_count <= MAX_SAMPLE)
X_AXIS_MAX = sample_count;
else
X_AXIS_MAX = 50;
ctx.clearRect(0, 0, WSP_WIDTH, WSP_HEIGHT);
ctx.save();
ctx.translate(plot_area_pivot_x, plot_area_pivot_y);
ctx.font = "bold 20px Arial";
ctx.textBaseline = "middle";
ctx.textAlign = "center";
ctx.fillStyle = COLOR_TEXT;
// draw X axis title
if(X_AXIS_TITLE != "")
{
ctx.fillText(X_AXIS_TITLE, plot_area_width / 2, X_AXIS_VALUE_HEIGHT + X_AXIS_TITLE_HEIGHT / 2);
}
// draw Y axis title
if(Y_AXIS_TITLE != "")
{
ctx.rotate(-90 * Math.PI / 180);
ctx.fillText(Y_AXIS_TITLE, plot_area_height / 2, -Y_AXIS_VALUE_WIDTH - Y_AXIS_TITLE_WIDTH / 2);
ctx.rotate(90 * Math.PI / 180);
}
ctx.font = "16px Arial";
ctx.textAlign = "right";
ctx.strokeStyle = COLOR_BOUND;
for(var i = 0; i <= Y_GRIDLINE_NUM; i++)
{
var y_gridline_px = -map(i, 0, Y_GRIDLINE_NUM, 0, plot_area_height);
y_gridline_px = Math.round(y_gridline_px) + 0.5;
ctx.beginPath();
ctx.moveTo(0, y_gridline_px);
ctx.lineTo(plot_area_width, y_gridline_px);
ctx.stroke();
ctx.strokeStyle = COLOR_BOUND;
ctx.beginPath();
ctx.moveTo(-7 , y_gridline_px);
ctx.lineTo(4, y_gridline_px);
ctx.stroke();
var y_gridline_value = map(i, 0, Y_GRIDLINE_NUM, Y_AXIS_MIN, Y_AXIS_MAX);
y_gridline_value = y_gridline_value.toFixed(1);
ctx.fillText(y_gridline_value + "", -15, y_gridline_px);
ctx.strokeStyle = COLOR_GRIDLINE;
}
ctx.strokeStyle = COLOR_BOUND;
ctx.textAlign = "center";
ctx.beginPath();
ctx.moveTo(0.5, y_gridline_px - 7);
ctx.lineTo(0.5, y_gridline_px + 4);
ctx.stroke();
for(var i = 0; i <= X_GRIDLINE_NUM; i++)
{
var x_gridline_px = map(i, 0, X_GRIDLINE_NUM, 0, plot_area_width);
x_gridline_px = Math.round(x_gridline_px) + 0.5;
ctx.beginPath();
ctx.moveTo(x_gridline_px, 0);
ctx.lineTo(x_gridline_px, -plot_area_height);
ctx.stroke();
ctx.strokeStyle = COLOR_BOUND;
ctx.beginPath();
ctx.moveTo(x_gridline_px, 7);
ctx.lineTo(x_gridline_px, -4);
ctx.stroke();
var x_gridline_value;
if(sample_count <= MAX_SAMPLE)
x_gridline_value = map(i, 0, X_GRIDLINE_NUM, X_AXIS_MIN, X_AXIS_MAX);
else
x_gridline_value = map(i, 0, X_GRIDLINE_NUM, sample_count - MAX_SAMPLE, sample_count);;
ctx.fillText(x_gridline_value.toString(), x_gridline_px, X_AXIS_VALUE_HEIGHT / 2 + 5);
ctx.strokeStyle = COLOR_GRIDLINE;
}
//ctx.lineWidth = 2;
var line_num = data.length;
for(var line = 0; line < line_num; line++)
{
// draw graph
var sample_num = data[line].length;
if(sample_num >= 2)
{
var y_value = data[line][0];
var x_px = 0;
var y_px = -map(y_value, Y_AXIS_MIN, Y_AXIS_MAX, 0, plot_area_height);
if(line == COLOR_LINE.length)
COLOR_LINE.push(get_random_color());
ctx.strokeStyle = COLOR_LINE[line];
ctx.beginPath();
ctx.moveTo(x_px, y_px);
for(var i = 0; i < sample_num; i++)
{
y_value = data[line][i];
x_px = map(i, X_AXIS_MIN, X_AXIS_MAX -1, 0, plot_area_width);
y_px = -map(y_value, Y_AXIS_MIN, Y_AXIS_MAX, 0, plot_area_height);
ctx.lineTo(x_px, y_px);
}
ctx.stroke();
}
// draw legend
var x = plot_area_width - (line_num - line) * LEGEND_WIDTH - (line_num - line - 1) * LEGEND_WIDTH / 2;
var y = -plot_area_height - PLOT_AREA_PADDING_TOP / 2 - LEGEND_WIDTH / 2;
ctx.fillStyle = COLOR_LINE[line];
ctx.beginPath();
ctx.rect(x, y, LEGEND_WIDTH, LEGEND_WIDTH);
ctx.fill();
}
ctx.restore();
}
function canvas_resize()
{
canvas.width = 0; // to avoid wrong screen size
canvas.height = 0;
if(WSP_SIZE_TYPE)
{ // full screen
document.getElementById('footer').style.position = "fixed";
var width = window.innerWidth - 20;
var height = window.innerHeight - 20;
WSP_WIDTH = width;
WSP_HEIGHT = height - document.getElementById('header').offsetHeight - document.getElementById('footer').offsetHeight;
}
canvas.width = WSP_WIDTH;
canvas.height = WSP_HEIGHT;
ctx.font = "16px Arial";
var y_min_text_size = ctx.measureText(Y_AXIS_MIN.toFixed(1) + "").width;
var y_max_text_size = ctx.measureText(Y_AXIS_MAX.toFixed(1) + "").width;
Y_AXIS_VALUE_WIDTH = Math.round(Math.max(y_min_text_size, y_max_text_size)) + 15;
plot_area_width = WSP_WIDTH - Y_AXIS_VALUE_WIDTH - PLOT_AREA_PADDING_RIGHT;
plot_area_height = WSP_HEIGHT - X_AXIS_VALUE_HEIGHT - PLOT_AREA_PADDING_TOP;
plot_area_pivot_x = Y_AXIS_VALUE_WIDTH;
plot_area_pivot_y = WSP_HEIGHT - X_AXIS_VALUE_HEIGHT;
if(X_AXIS_TITLE != "")
{
plot_area_height -= X_AXIS_TITLE_HEIGHT;
plot_area_pivot_y -= X_AXIS_TITLE_HEIGHT;
}
if(Y_AXIS_TITLE != "")
{
plot_area_width -= Y_AXIS_TITLE_WIDTH;
plot_area_pivot_x += Y_AXIS_TITLE_WIDTH;
}
ctx.lineWidth = 1;
}
function auto_scale()
{
if(data.length >= 1)
{
var max_arr = [];
var min_arr = [];
for(var i = 0; i < data.length; i++)
{
if(data[i].length >= 1)
{
var max = Math.max.apply(null, data[i]);
var min = Math.min.apply(null, data[i]);
max_arr.push(max);
min_arr.push(min);
}
}
var max = Math.max.apply(null, max_arr);
var min = Math.min.apply(null, min_arr);
var MIN_DELTA = 10.0;
if((max - min) < MIN_DELTA)
{
var mid = (max + min) / 2;
max = mid + MIN_DELTA / 2;
min = mid - MIN_DELTA / 2;
}
var range = max - min;
var exp;
if (range == 0.0)
exp = 0;
else
exp = Math.floor(Math.log10(range / 4));
var scale = Math.pow(10, exp);
var raw_step = (range / 4) / scale;
var step;
potential_steps =[1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0];
for (var i = 0; i < potential_steps.length; i++)
{
if (potential_steps[i] < raw_step)
continue;
step = potential_steps[i] * scale;
Y_AXIS_MIN = step * Math.floor(min / step);
Y_AXIS_MAX = Y_AXIS_MIN + step * (4);
if (Y_AXIS_MAX >= max)
break;
}
var count = 5 - Math.floor((Y_AXIS_MAX - max) / step);
Y_AXIS_MAX = Y_AXIS_MIN + step * (count - 1);
ctx.font = "16px Arial";
var y_min_text_size = ctx.measureText(Y_AXIS_MIN.toFixed(1) + "").width;
var y_max_text_size = ctx.measureText(Y_AXIS_MAX.toFixed(1) + "").width;
Y_AXIS_VALUE_WIDTH = Math.round(Math.max(y_min_text_size, y_max_text_size)) + 15;
plot_area_width = WSP_WIDTH - Y_AXIS_VALUE_WIDTH - PLOT_AREA_PADDING_RIGHT;
plot_area_pivot_x = Y_AXIS_VALUE_WIDTH;
}
}
window.onload = init;
</script>
</head>
<body onresize="canvas_resize()">
<h1 id="header">Arduino - Web Plotter</h1>
<canvas id="graph"></canvas>
<br>
<div id="footer">
<div class="sub-footer">
<h2>WebSocket <span id="ws_state"><span style="color: gray">CLOSED</span></span></h2>
</div>
<button id="bt_connect" type="button" onclick="connect_onclick();">Connect</button>
</div>
</body>
</html>
)=====";
아래와 같은 오류가 표시됩니다:
In file included from c:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/utility.h:3:0,
from c:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/WebSocket.h:5,
from c:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/WebSocketServer.h:5,
from C:\Users\YOU_ACCOUNT\Documents\Arduino\ArduinoGetStarted.com\ArduinoGetStarted.com.ino:2:
C:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/platform.h:54:12: fatal error: Ethernet.h: No such file or directory
# include <Ethernet.h>
^~~~~~~~~~~~
compilation terminated.
exit status 1
이 오류를 수정하려면:
#define NETWORK_CONTROLLER ETHERNET_CONTROLLER_W5X00
아래와 같이 이 줄을 변경하고 저장하세요:
#define NETWORK_CONTROLLER NETWORK_CONTROLLER_WIFI
아두이노 IDE에서 코드를 아두이노에 업로드하려면 Upload 버튼을 클릭하세요.
시리얼 모니터를 엽니다.
시리얼 모니터에서 결과를 확인하세요.
COM6
Connecting to WiFi...
Connected to WiFi
Arduino Web Server's IP address IP address: 192.168.0.2
Autoscroll
Clear output
9600 baud
Newline
※ 주의:
코드 설명, 줄별로
위의 아두이노 코드에는 줄별로 설명이 포함되어 있습니다. 코드의 주석을 읽어주세요!