아두이노 우노의 클럭 주파수 16MHz 에 비해 CPU 클럭 주파수가 무려 80MHz인 아두이노 NodeMCU의 엄청난 연산 응력을 활용하여 스마트 폰에서 만족할 만한 속도로 real time 파형을 볼 수 있는 Arduino NodeMCU Scope 프로그램을 작성하기로 한다.
실시간 파형 관측을 위한 아날로그 신호는 A0 핀에 가변 저항을 연결하여 부드럽게 파형이 움직이는 모습을 관찰할 수 있다.
좌측의 아날로그 파형 은 손으로 가변저항을 여유 있게 돌려 얻은 전압 파형이다.
이 디지털 파형은 LED_Blink 실험 장치에서 1초 및 0.1초로 ON OFF 시킬 때 발생된 LED 양단의 전압을 캐치한 스코프 파형이다.
0.1초의 경우 듀티 파형이 조밀한 편이다.
그래픽 프로그램에서 선 굵기를 아주 가늘게 조절하게되면 보다 세밀한 파형 관찰이 가능할 것이다.
아래에서는 HTML SVG의 그래픽 기능 중심으로 하는 프로그램의 구조 및 내용을 살펴보기로 한다. 단 여기서는 LED_Blink 프로그램에 의해 발생된 디지털 듀티 파형 관찰을 위한 프로그램 중심으로 설명하기로 한다.
setup()과 loop()프로그램에서 WiFi 연결과 관련된 부분은 전혀 변동이 없으므로 생략하고 HTML 과 SVG 프로그램 중심으로 설명하기로 한다.
아래의 프로그램은 HTML 도입부문이며 태그 <html>과 대응하는 </html>는 거의 프로그램 끝부분에 위치한다.
// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println(""); // do not forget this one
client.println("<!DOCTYPE HTML>");
client.println("<html>");
일단 스마트 폰이 가상 ip를 주소창에 입력하여 엔터 키를 눌러 웹의 Request에 의해 연결되면 웹브라우저의 배경 색이 노란색으로 바뀌고 태그 <head>에서 시작하여 Arduino NodeMCU Webserver Scope 라는 텍스트 출력 후 태그 </head>로 끝맺는다.
//배경 색 문자 색 사이즈 HTML CSS 설정
client.println("<head>");
client.println("<style>");
client.println("body {");
client.println("background-color: yellow;");
client.println("}");
client.println("p {");
client.println("color:red;");
client.println("font-size:250%;");
client.println("}");
client.println("</style>");
client.println("<title>Page Title</title>");
client.println("<h2> Arduino NodeMCU Webserver Scope</h1>");
client.println("</head>");
계속하여 태그 <body>를 시작하는데 이에 대응하는 태그</body>는 프로그램의 거의 끝 부분에 위치하며 그 중간에 스코프의 그랙을 담당하는 중요한 부분들이 포함된다.
client.println("<body>");
⚫
⚫
⚫
client.println("<a href=\"/on\"\" class='button'>Data Refresh </button></a>");
client.println("</body>");
client.println("</html>");
delay(1);
Serial.println("Client disonnected");
태그 <body> 이후 가장 중요한 Scalable Vector Graphics의 태그 <svg... 가 시작된다.
스코프 화면 크기를 높이 200 폭 500으로 정의한다 아울러 CSS처럼 style 파라메터들도 함께 정의 되며 스코프 화면 색, 중앙선 및 윤곽선등이 표현되며 />로 끝난다.
client.println("<svg height='200' width='500'>");
client.println("<rect height='200' width='500' style='fill:rgb(0,220,230);stroke-width:10;stroke:rgb(0,0,0)' />");
client.println("<rect height='100' width='500' style='fill:rgb(0,220,230);stroke-width:10;stroke:rgb(0,0,0)' />");
아래의 analogRead() 항에서 아두이노 NodeMCU는 3.3V를 1023으로 받아들인다. 위에 정의된 스코프 화면 폭이 200 이므로 analogRead() 항을 5로 나누어 비슷하게 맞춘다.
int y1 = 200-val; 프로글램의 의미는 이미 앞 블로그에서 설명 했으므로 생략한다.
그 다음 i=1에서 500까지 500회에 걸쳐 읽어 들인 데이터를 line 명령을 사용하여 연결 출력한다.
다음은 (0,0)에서 (200,200)까지 직선을 긋는 HTML SVG 의 line 명령 사례이다.
이 명령문에서 “와 ”를 모조리 ‘와 ’로 바꾸고 난 후 좌표 데이터에 해당하는 부분을 따로 분리해 좌표 데이터를 변수로 출력한다.
<line x1="0" y1="0" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2" />
이 명령문에서 “와 ”를 모조리 ‘와 ’로 바꾸고 난 후 좌표 데이터에 해당하는 부분을 따로 분리해 좌표 데이터를 변수로 출력한다.
<line x1=‘0’ y1=‘0’ x2=‘200’ y2=‘200’ style=‘stroke:rgb(255,0,0);stroke-width:2’ />
다음과 같이 줄 바꿈하여 프로그램을 쪼갠 후 client(“와 ”);를 앞뒤로 입력한다. 단 숫자 데이터인 0,0,200,200은 프로그램에서 변수 x1,y1,x2,y2에 해당하므로 이들 값을 출력하는 것으로 대체한다.
<line x1=‘
0
’ y1=‘
0
’ x2=‘
200
’ y2=‘
200
’ style=‘stroke:rgb(255,0,0);stroke-width:2’ />
실제 프로그램 된 아래의 사례를 참조하기 바란다.
int val = analogRead(A0)/5;
int y1 = 200-val;
for(int i=1;i<500;i++){
// 아나로그입력 생성(0-1023):1023=3.3V
int x1 = (i-1);
int x2 = i;
int val = analogRead(A0)/5;
int y2 = 200-val;
client.println("<line x1='");
client.println(x1);
client.println("' y1='");
client.println(y1);
client.println("' x2='");
client.println(x2);
client.println("' y2='");
client.println(y2);
client.println("'");
client.println("' style='stroke:rgb(255,0,0);stroke-width:2' />");
client.println("Sorry, your browser does not support inline SVG.");
y1 = y2;
}
앞에서 500회까지 샘플링 출력이 끝나면 </svg> 태그로 그래픽 작업을 종료한다. 그 다음에 다시 새호이 그래픽을 하여면 한번 화면을 flush해 주는 작업이 필요하다.
client.println("</svg>");
client.flush();
client.println("<br><br>");
끝으로 CSS 명령을 사용하여 버튼의 배경색 테두리 색 폰트 사이즈 등을 지정한다. 이 부분은 다시 태그 <head>로 시작해서 </head>태그로 끝 맺음 하도록 한다.
//버튼 HTML CSS 설정
client.println("<head>");
client.println("<style>");
client.println(".button {");
// client.println("background-color: #4CAF50;");
client.println("background-color: green;");
client.println("border: none;");
client.println("color: white;");
client.println("padding: 15px 32px;");
client.println("text-align: center;");
client.println("text-decoration: none;");
client.println("display: inline-block;");
client.println("font-size: 20px;");
client.println("margin: 14px 20px;");
client.println("cursor: pointer;");
client.println("}");
client.println("</style>");
client.println("</head>");
마지막으로 CS에서 설정된 환경대로 Data Refresh 버튼이 나타나는데 이 버튼을 누르면 스마트 폰에서 flush 작업과 함께 아두이노 NodeMCU 웹서버와 통신하는데 시간이 좀 걸린다.
// client.println("<a href=\"/on\"\"><button>Data Refresh </button></a><br />");
client.println("<a href=\"/on\"\" class='button'>Data Refresh </button></a>");
client.println("</body>");
client.println("</html>");
delay(1);
Serial.println("Client disonnected");
아래에 실행이 성공할 수 있도록 프로그램 전문을 수록하니 참조하기 바란다. 물론 자신의 스마트폰 핫스팟ID와 비밀번호를 입력을 잊지 말기 바라며, 참고로 상당히 긴 명령 줄들이 있는지 혹시 끓어지는지 여부를 한번 살펴보기 바란다.
Webserver_nodemcu_html_svg_realtime_var_resistor_01
#include <ESP8266WiFi.h>
const char* ssid = "AndroidHotspot1234";//자신의 스마트폰 핫스팟 ID입력
const char* password = "00000000";//자신의 스마트폰 핫스팟 비밀번호 입력
int ledPin = 2; //
WiFiServer server(80);
void setup() {
Serial.begin(115200);
delay(10);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
// Set WiFi to station mode and disconnect from an AP if it was previously connected
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
Serial.println("Setup done");
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address
Serial.print("Use this URL to connect: ");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/");
}
void loop() {
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Wait until the client sends some data
Serial.println("new client");
while(!client.available()){
delay(1);
}
// Read the first line of the request
String request = client.readStringUntil('\r');
Serial.println(request);
client.flush();
// Match the request
int value = LOW;
if (request.indexOf("/LED=ON") != -1) {
digitalWrite(ledPin, LOW);
value = HIGH;
}
if (request.indexOf("/LED=OFF") != -1) {
digitalWrite(ledPin, HIGH);
value = LOW;
}
// Set ledPin according to the request
// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println(""); // do not forget this one
client.println("<!DOCTYPE HTML>");
client.println("<html>");
//배경 색 문자 색 사이즈 HTML CSS 설정
client.println("<head>");
client.println("<style>");
client.println("body {");
client.println("background-color: yellow;");
client.println("}");
client.println("p {");
client.println("color:red;");
client.println("font-size:250%;");
client.println("}");
client.println("</style>");
client.println("<title>Page Title</title>");
client.println("<h2> Arduino NodeMCU Webserver Scope</h1>");
client.println("</head>");
client.println("<body>");
client.println("<svg height='200' width='500'>");
client.println("<rect height='200' width='500' style='fill:rgb(0,220,230);stroke-width:10;stroke:rgb(0,0,0)' />");
client.println("<rect height='100' width='500' style='fill:rgb(0,220,230);stroke-width:10;stroke:rgb(0,0,0)' />");
int val = analogRead(A0)/5;
int y1 = 200-val;
for(int i=1;i<500;i++){
// 아나로그입력 생성(0-1023):1023=3.3V
int x1 = (i-1);
int x2 = i;
int val = analogRead(A0)/5;
int y2 = 200-val;
client.println("<line x1='");
client.println(x1);
client.println("' y1='");
client.println(y1);
client.println("' x2='");
client.println(x2);
client.println("' y2='");
client.println(y2);
client.println("'");
client.println("' style='stroke:rgb(255,0,0);stroke-width:2' />");
client.println("Sorry, your browser does not support inline SVG.");
y1 = y2;
}
client.println("</svg>");
client.flush();
client.println("<br><br>");
//버튼 HTML CSS 설정
client.println("<head>");
client.println("<style>");
client.println(".button {");
// client.println("background-color: #4CAF50;");
client.println("background-color: green;");
client.println("border: none;");
client.println("color: white;");
client.println("padding: 15px 32px;");
client.println("text-align: center;");
client.println("text-decoration: none;");
client.println("display: inline-block;");
client.println("font-size: 20px;");
client.println("margin: 14px 20px;");
client.println("cursor: pointer;");
client.println("}");
client.println("</style>");
client.println("</head>");
// client.println("<a href=\"/on\"\"><button>Data Refresh </button></a><br />");
client.println("<a href=\"/on\"\" class='button'>Data Refresh </button></a>");
client.println("</body>");
client.println("</html>");
delay(1);
Serial.println("Client disonnected");
Serial.println("");
}//프로그램 끝
'아두이노프로세싱 프로그래밍' 카테고리의 다른 글
| 삼색 LED에 의한 아두이노 NodeMCU에서 인터럽트 가능한 핀 확인 실험 (0) | 2017.02.18 |
|---|---|
| NodeMCU 1.0 WiFi Webserver에 의한 스마트폰 다음지도 마커표시 보완 (0) | 2017.02.16 |
| Blink LED 코드를 이용한 Arduino NodeMCU Scope용 디지털 듀티 신호 생성 (0) | 2017.02.15 |
| HTML SVG 그래픽 언어 사용 NodeMCU WiFi Webserver 코딩에 의한 가변저항 전압 스마트폰 실시간 모니터링 프로그램 (0) | 2017.02.12 |
| 아두이노 NodeMCU 웹서버가 그려주는 HTML+SVG 아날로그 시계 출력예제 I (0) | 2017.02.12 |