-데이터를 주고 받기 위해 일정 포맷이 필요 - 비교적 쉬운 json사용
아두이노 json 사용하기
스케치-라이브러리포함하기-zip라이브러리 추가 -ArduinoJson로 자동완성
html문서에서 서블릿으로 값 전송 -> 값을 받은 서블릿파일은 json데이터 형식으로 아두이노에 데이터 전송
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<form action="Exam01">
<table border="1px black">
<tr>
<td></td>
<td>ON</td>
<td>OFF</td>
</tr>
<tr>
<td>LED</td>
<td><input type="radio" name="led" value="1"></td>
<td><input type="radio" name="led" value="0" checked="checked"></td>
</tr>
</table>
<input type="submit" value="제어">
<!-- checked : 기본값 -->
</form>
</body>
</html>
Insert title here
ON | OFF | |
LED |
package test;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/Exam01")
public class Exam01 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter(); //출력스트림 객체생성
String led = request.getParameter("led");
//html로 받아온 데이터led
System.out.println(led);
//콘솔창에 출력
//JSON data 아두이노로 전송
// \:escape code
if(led.equals("1")) {
out.print("{\"LED\":\"1\"}");
}else if(led.equals("0")) {
out.print("{\"LED\":\"0\"}");
}
}
}
#include <ArduinoJson.h>
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "id"; //wifi-id
const char* password = "pw"; //wifi-pw
String result = "";
int ledPin = 18;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
}
void loop() {
if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
HTTPClient http;
http.begin("http://ip4주소:8090/IoT/Exam01"); //Specify the URL //localhost가 아닌 ipv4 주소를 입력해야 아두이노에서 접근
int httpCode = http.GET(); //Make the request
if (httpCode > 0) { //Check for the returning code
Serial.println(httpCode);
result = http.getString();
Serial.println(result);
//위주소에서 가져온 값을 저장하고 시리얼모니터에 출력
DynamicJsonBuffer jsonBuffer;
//json데이터를 유동적으로 다룰 수 있는 메모리 공간
JsonObject& root = jsonBuffer.parseObject(result);
String LED = root["LED"]; //현재 상태
if(LED == "1"){
digitalWrite(ledPin,1);
}else if(LED == "0"){
digitalWrite(ledPin,0);
}
}
else {
Serial.println("Error on HTTP request");
}
http.end(); //Free the resources
}
delay(1000);
}
index.html에서 전송받은 값을 Json데이터형식으로 변환해 아두이노로 전송하게되면
서블릿 콘솔창에는 led is null 이라는 오류와 html로 넘어온 값(1 or 0)이 출력되고, 아두이노로부터 계속해서 요청이 오기 때문에 null도 함께 출력되는 것을 볼 수 있다.
잠시 java의 메모리 구조를 살펴보자
heap 영역 : 선언된 변수, 배열, 레퍼런스변수(new키워드) 등 => new키워드 붙이면 메모리에 직접적으로 생성된다. 잘안쓰이면 Garbage Collection에의해 불필요한 메모리 자동으로 삭제됨
stack영역 : static이나 static이 붙은 변수, main => main에서 static없는 메소드는 호출안됨
static이 없는 메소드 호출시 클래스명.메소드(); 또는 new 키워드로 변수 없이 클래스명.메소드();
Exam메모리와 Exam호출 자바 클래스를 만들어 살펴보았다. => 다이나믹 웹 프로젝트에서 잠시 자바 환경으로 바꿔 작업해줌 (템플릿이 다름) open perspective 체크해준다
import java.util.ArrayList;
public class Exam메모리 {
//클래스내 필드선언
public static int num = 5;
public int num2 = 10;
public static void main(String[] args) {
Exam메모리 ex1 = new Exam메모리();
ex1.addNumber(5,3);
new Exam메모리().addNumber(5, 3);
//static이 없는 메소드 호출시 클래스명.메소드(); 또는 new 키워드로 변수 없이 클래스명.메소드(); 할 수 있다!
printLunch();
//static 메소드 특징 기울임꼴, 다른클래스에서 호출가능
ArrayList<String> list = new ArrayList<>();
list.add("문자열");
ArrayList<int[]> list2 = new ArrayList<int[]>();
int[] ages = new int[27];
list2.add(ages);
list2.add(new int[] {1,3,4});
}
public void addNumber(int num1, int num2) {
System.out.println(num1+num2);
}
public static void printLunch() {
System.out.println("뭐먹지");
}
}
public class Exam호출 {
public static void main(String[] args) {
Exam메모리.printLunch();
//다른클래스에서 호출할때, static은 어디서나 호출가능하지만, 어디에있는지 클래스명 명시하기
new Exam메모리().addNumber(5,3);
//static이아니라면 해당클래스를 new라는 키워드로 호출해서 heap영역에 올려서 사용하기
System.out.println(Exam메모리.num); //static- stack영역
System.out.println(new Exam메모리().num2); //new키워드
Exam메모리.num = 1000;
new Exam메모리().num2 = 1000;
//static변수는 stack영역에 올라가있음
//어느클래스에서 사용할수있어서 다르클래스에서 값 수정시 모든클래스에 반영됨
System.out.println(Exam메모리.num);
System.out.println(new Exam메모리().num2);
//heap영역의 변수는 변경 값 올라가지만 다음코드진행되면서 사라짐 다시 호출했을때 들어있던 처음 값이 10이므로 바로 사용되지 않아 변경값 사라져 처음 값
}
}
html에서 값을 가져올 수는 있었지만 아두이노에서 요청할 때 led라는 key값이 없어서 오류가 남 -> 값을 static으로 변경해서 항상 존재하는 값으로 만들어줌
변수에 static 키워드를 붙이고, static 키워드에 led 정보를 넣어서 어느클래스에서든 그 정보를 가져올 수 있게함 ! 다른 클래스에서도 정보를 유지하게함
package test;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/Send")
public class Send extends HttpServlet {
private static final long serialVersionUID = 1L;
public static String led = "0"; //static 필드 선언부
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
led = request.getParameter("led"); //index.html led 키값을 받아옴
response.sendRedirect("index.html"); //값만 받아서 바로 페이지로 보내줌
}
}
package test;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/Exam01")
public class Exam01 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
String led = Send.led; //send클래스의 led를 새로운 지역변수 led에 담아줌
//send.led는 static-stack영역, String led는 지역변수
//JSON data를 출력
// \:escape code
if(led.equals("1")) {
out.print("{\"LED\":\"1\"}");
}else if(led.equals("0")) {
out.print("{\"LED\":\"0\"}");
}
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<form action="Send"> //send로 보냄
<table border="1px black">
<tr>
<td></td>
<td>ON</td>
<td>OFF</td>
</tr>
<tr>
<td>LED</td>
<td><input type="radio" name="led" value="1"></td>
<td><input type="radio" name="led" value="0" checked="checked"></td>
</tr>
</table>
<input type="submit" value="제어">
<!-- checked : 기본값 -->
</form>
</body>
</html>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "??";
const char* password = "??";
String result = "";
int ledPin=18;
void setup() {
pinMode(18,OUTPUT);
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
}
void loop() {
if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
HTTPClient http;
http.begin("http://192.168.137.1:8090/IoT/Exam01"); //Specify the URL
int httpCode = http.GET(); //Make the request
if (httpCode > 0) { //Check for the returning code
Serial.println(httpCode);
result = http.getString();
Serial.println(result);
//위주소에서 가져온 값을 저장하고 시리얼모니터에 출력
DynamicJsonBuffer jsonBuffer;
//json데이터를 유동적으로 다룰 수 있는 메모리 공간
JsonObject& root = jsonBuffer.parseObject(result);
String LED = root["LED"];
if(LED=="1"){
digitalWrite(ledPin,1);
}else if(LED=="0"){
digitalWrite(ledPin,0);
}
}
else {
Serial.println("Error on HTTP request");
}
http.end(); //Free the resources
}
delay(1000);
}