ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring MVC2 - 7. Web Socket( Led on/off, 서보모터 제어)
    JAVA/웹 프로그래밍 - Spring 2020. 12. 24. 21:13

    아래의 글을 이어서 진행해보자.

    designatedroom87.tistory.com/346

     

    Spring MVC2 - 6 - (2). SpringMVC2에 아두이노와 시리얼 통신(버튼)

    앞의 내용과 이어지는 부분이 있다. designatedroom87.tistory.com/345 Spring MVC2 - 6 - (1). SpringMVC2에 아두이노와 시리얼 통신 아래의 내용에 이어지는 내용이다. designatedroom87.tistory.com/344?catego..

    designatedroom87.tistory.com

     

    아두이노에서 Web으로 데이터를 전송하는 건 문제없다.
    그런데, 클라이언트에서 아두이노로 데이터를 전송할 수 있게끔 하기 위해서는 Web Socket을 이용해야 한다.

    1. 서버와 jsp간의 통신을 먼저 알아보자.

    스프링을 이용한 웹 소켓을 진행해보자.  ( 단어 선택이 적당한지는 모르겠다. ) 
    스프링 처리하는 순서를 잘 익혀야 한다.

    라이브러리를 다운로드하는 것이 우선이다.

    pom.xml에 추가하면 된다.

    웹 브라우저를 띄워 maven repository를 검색한다.

    그리고 나서, spring websocket을 검색한다. 버전은 신경쓰지 않는다.

    버전은 기존의 버전과 일치시킨다.

    아래의 내용을 pom.xml에 추가한다.

    <!-- websocket -->
    	<!-- https://mvnrepository.com/artifact/org.springframework/spring-websocket -->
    	<dependency>
    	    <groupId>org.springframework</groupId>
    	    <artifactId>spring-websocket</artifactId>
    	    <version>${org.springframework-version}</version>
    	</dependency>

     

     

    그리고 해당 사이트에서 websocket을 검색하고. java websocket을 선택한다.

    아래의 문장을 pom.xml에 추가한다.

    <dependency>
    	    <groupId>javax.websocket</groupId>
    	    <artifactId>javax.websocket-api</artifactId>
    	    <version>1.1</version>
    	</dependency>

     

     

    pom.xml의 전체 내용

    더보기
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.iot</groupId>
      <artifactId>springmvc2</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>war</packaging>
      
       <properties>
    		<java-version>1.8</java-version>
    		<maven.compiler.source>1.8</maven.compiler.source>
    		<maven.compiler.target>1.8</maven.compiler.target>
    		<org.springframework-version>5.2.9.RELEASE</org.springframework-version>
    		<org.aspectj-version>1.6.10</org.aspectj-version>
    		<org.slf4j-version>1.6.6</org.slf4j-version>
    	</properties>
    	
    	<dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-api -->
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-api</artifactId>
        <version>9.0.39</version>
    </dependency>
    
    
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.2.9.RELEASE</version>
        <scope>test</scope>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.9.RELEASE</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.9.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    
    <!-- mybatis -->
    <!-- mybatis 프레임워크 사용하기 위해 -->
    		<dependency>
    		    <groupId>org.mybatis</groupId>
    		    <artifactId>mybatis</artifactId>
    		    <version>3.5.5</version>
    		</dependency>
    		<!-- mybatis와 spring 연동하기 위해 -->
    		<dependency>
    		    <groupId>org.mybatis</groupId>
    		    <artifactId>mybatis-spring</artifactId>
    		    <version>2.0.5</version>
    		</dependency>
    <!-- jdbc Connection Pool -->
    		<dependency>
    	        <groupId>com.zaxxer</groupId>
    	        <artifactId>HikariCP</artifactId>
    	        <version>3.4.5</version>
    	    </dependency>
    
    <!-- Logging -->
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>slf4j-api</artifactId>
    			<version>${org.slf4j-version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>jcl-over-slf4j</artifactId>
    			<version>${org.slf4j-version}</version>
    			<scope>runtime</scope>
    		</dependency>
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>slf4j-log4j12</artifactId>
    			<version>${org.slf4j-version}</version>
    			<scope>runtime</scope>
    		</dependency>
    		<dependency>
    			<groupId>log4j</groupId>
    			<artifactId>log4j</artifactId>
    			<version>1.2.15</version>
    			<exclusions>
    				<exclusion>
    					<groupId>javax.mail</groupId>
    					<artifactId>mail</artifactId>
    				</exclusion>
    				<exclusion>
    					<groupId>javax.jms</groupId>
    					<artifactId>jms</artifactId>
    				</exclusion>
    				<exclusion>
    					<groupId>com.sun.jdmk</groupId>
    					<artifactId>jmxtools</artifactId>
    				</exclusion>
    				<exclusion>
    					<groupId>com.sun.jmx</groupId>
    					<artifactId>jmxri</artifactId>
    				</exclusion>
    			</exclusions>
    			<scope>runtime</scope>
    		</dependency>
    		<!-- Spring -->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-context</artifactId>
    			<version>${org.springframework-version}</version>	<!-- 위에서 받은 버전을 가지고 올 수 있다. -->
    			<exclusions>
    				<!-- Exclude Commons Logging in favor of SLF4j -->
    				<exclusion>
    					<groupId>commons-logging</groupId>
    					<artifactId>commons-logging</artifactId>
    				 </exclusion>
    			</exclusions>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-webmvc</artifactId>
    			<version>${org.springframework-version}</version>
    		</dependency>
    	
    	<!-- websocket -->
    	<!-- https://mvnrepository.com/artifact/org.springframework/spring-websocket -->
    	<dependency>
    	    <groupId>org.springframework</groupId>
    	    <artifactId>spring-websocket</artifactId>
    	    <version>${org.springframework-version}</version>
    	</dependency>
    	
    	<dependency>
    	    <groupId>javax.websocket</groupId>
    	    <artifactId>javax.websocket-api</artifactId>
    	    <version>1.1</version>
    	</dependency>
    				
    	</dependencies>
    </project>

     

     

    web.xml로 이동하자.

    web의 시작점이다. 테스트를 좀 더해봐야 한다.

    웹소켓을 사용하기 위해서 웹소켓에 대한 정보를 올려야 한다.

    web.xml

    더보기
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
      <display-name>El</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
      
      <!--	<context-param>은 서블릿(dispatcher) 실행 전에  호출
      		모든 서블릿과 필터들로부터 공유된 루트경로의 스프링을 정의한다.
      		어떤 경로를 지정하고 파일을 설정한다.
      -->
      <context-param>
      	<param-name>contextConfigLocation</param-name>	<!-- 정해진 값으로, 컨텍스트 설정 위치 -->
      	<param-value>/WEB-INF/root-context.xml</param-value>
      </context-param>
      
      <!-- <listener>는 스프링 컨테이너를 만드는 역할을 한다.
      		즉, 위에서 설정된 서블릿과 필터들을 스프링 컨테이너에 만드는 역할을 한다.
      		기본 설정 파일을 로드한다.
      -->
      <listener>
      	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      
       <servlet>
      	<servlet-name>dispatcher</servlet-name>
      	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      	<init-param>
      		<param-name>contextConfigLocation</param-name>
      		<param-value>
      			/WEB-INF/servlet-context.xml	<!-- bean 설정 -->
      			/WEB-INF/websocket-context.xml	<!-- bean 설정 -->
      		</param-value>
      	</init-param>
      	<load-on-startup>1</load-on-startup>
      </servlet>
      
      <servlet-mapping>
      	<servlet-name>dispatcher</servlet-name>
      	<url-pattern>/</url-pattern>
      </servlet-mapping>
      
    </web-app>

     

     

    servlet-context는 DB에 대한 정보를 담고 있다.

    servlet-context.xml

    더보기
    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:beans="http://www.springframework.org/schema/beans"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
    	xmlns:websocket="http://www.springframework.org/schema/websocket"
    	xsi:schemaLocation="http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.3.xsd
    		http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
    		http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
    		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
    <!-- mybaties DB 설정 -->
    <beans:bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
    	<beans:property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></beans:property>
    	<beans:property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:xe"></beans:property>
    	<beans:property name="username" value="hr"></beans:property>
    	<beans:property name="password" value="1234"></beans:property>
    </beans:bean>
    
    <!-- 어노테이션을 사용하기 위한 설정 -->
    <context:component-scan base-package="db,springmvc2" />
    <mybatis-spring:scan base-package="db" />
    <annotation-driven />
    
    <!--DB연결에 필요한 내용은 dataSource에 있다. 
    	dataSource는 DriverManager에서 만들었는데, 이번에는 다른 경로를 통해 생성한다.
    	DB datasource bean 생성
    -->
    <beans:bean id="ds" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
    	<beans:constructor-arg ref="hikariConfig"></beans:constructor-arg>
    </beans:bean>
    
    <!--mybaties 사용 bean 생성(SQL문법에 대한 부분)-->
    <beans:bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    	<beans:property name="dataSource" ref="ds"></beans:property>
    </beans:bean>
    
    <!-- resources 처리 (나중에 CSS에 대한 것들을 처리한다.) -->
    <resources location="resources" mapping="/resources/**"></resources>
    
    <!-- ViewResolver 처리 -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    	<beans:property name="order" value="2" />	
    	<beans:property name="prefix" value="/WEB-INF/view/" />
    	<beans:property name="suffix" value=".jsp" />
    </beans:bean>
    
    </beans:beans>

     

     

    WEB-INF폴더에 websocket-context.xml을 만든다.

    websocket-context는 웹 소켓에 대한 내용을 담으면 된다.

    websocket-context.xml

    더보기
    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:beans="http://www.springframework.org/schema/beans"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
    	xmlns:websocket="http://www.springframework.org/schema/websocket"
    	xsi:schemaLocation="http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.3.xsd
    		http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
    		http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
    		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
    <!-- 어노테이션을 사용하기 위한 설정 -->
    <context:component-scan base-package="websocket" />
    <annotation-driven />
    
    <!-- resources 처리 (나중에 CSS에 대한 것들을 처리한다.) -->
    <resources location="resources" mapping="/resources/**"></resources>
    
    <!-- ViewResolver 처리 -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    	<beans:property name="order" value="2" />	
    	<beans:property name="prefix" value="/WEB-INF/view/" />
    	<beans:property name="suffix" value=".jsp" />
    </beans:bean>
    
    <!-- websocket bean설정 -->
    <beans:bean id="echoHandler" class="websocket.EchoHandler" />
    
    <websocket:handlers>
    	<websocket:mapping handler="echoHandler" path="/websocket" />	<!-- endPoint를 설정하는 부분 -->
    	<websocket:handshake-interceptors>
    		<beans:bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor" />
    	</websocket:handshake-interceptors>
    </websocket:handlers>
    
    <!-- 위에서 만든 웹 소켓을 스프링 이용해야 한다. -->
    <beans:bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor" ></beans:bean>
    
    </beans:beans>

     

     

    websocket 패키지를 src/main/java폴더에 만든다.

    EchoHandler.java를 websocket패키지에 만든다.

    EchoHandler.java

    더보기
    package websocket;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.web.socket.CloseStatus;
    import org.springframework.web.socket.TextMessage;
    import org.springframework.web.socket.WebSocketMessage;
    import org.springframework.web.socket.WebSocketSession;
    import org.springframework.web.socket.handler.TextWebSocketHandler;
    
    public class EchoHandler extends TextWebSocketHandler
    {
    	//	접속되는 정보를 관리
    	List<WebSocketSession> sessions = new ArrayList<WebSocketSession>();
    	
    	//	Constructor
    	public EchoHandler() 
    	{
    		//	객체의 생성시점을 알아내기 위해 출력
    		System.out.println("생성자 echo Handler");
    	}
    	
    	//	소켓이 연결이 되었을 때, 호출되는 메소드
    	@Override
    	public void afterConnectionEstablished(WebSocketSession session) throws Exception 
    	{
    		System.out.println("새로운 접속 : " +session);
    		System.out.println("메시지 분리 : " +session.getUri().getQuery());
    		this.sessions.add(session);
    	}
    	
    	//	메시지가 왔을 때, 호출되는 메소드
    	@Override
    	public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception 
    	{
    		//	전송하는 역할만 한다.
    		System.out.println("메시지 전달되었음 : " +message);
    		//	String senderId = session.getId();	//	ID를 확인하고 싶을 때
    		
    		for (WebSocketSession sess : this.sessions)
    		{
    			sess.sendMessage( new TextMessage( (CharSequence)message.getPayload() ) );
    		}
    		
    	}
    	
    	//	닫힐 때, 호출되는 메소드
    	@Override
    	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception 
    	{
    		System.out.println("접속 종료 : " +session);
    		this.sessions.remove(session);
    	}
    	
    	//	에러가 났을 때, 호출되는 메소드
    	@Override
    	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception 
    	{
    		System.out.println("에러발생 : " +session);
    		this.sessions.remove(session);
    	}
    }

     

     

    서버를 실행해 보자. 콘솔 창에 EchoHandler 클래스의 생성자에서 구현한 출력 내용이 나온다.

    아래와 같다.

     

     

    간혹 생성자가 2번 호출되는 경우가 있는데 아마도

    <context:component-scan base-package="websocket" />  과

    <beans:bean id="echoHandler" class="websocket.EchoHandler" /> 에서 생성되는 것 같다.

     

     

    웹 소켓을 자바스크립트를 통해 만들 것이다.

    IndexController에 메소드 하나를 추가하자.

    jsp(client web)를 통해 서버 웹 소켓과 통신한다.
    웹페이지에서 localhost:9090/sockettest url로 접속을 한다.

    //	/sockettest URL로 접속하면 socketclient.jsp파일이 보여진다.
    	@RequestMapping(value = "/sockettest", method = RequestMethod.GET)
    	public String SocketTest(Locale locale, Model model)
    	{
    		//	logger.info("SocketTest The client locale is {}.", locale);
    		System.out.println("socket connect");
    		System.out.println(model.getAttribute("data"));
    		
    		return "socketclient";
    	}

     

     

    WEB-INF/view폴더에 socketclient.jsp파일을 하나 만든다.

    socketclient.jsp 파일의 용도는 웹 페이지가 서버에 접속하기 위해서 존재한다.

    socketclient.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    
    <body>
    
    <div>${message}</div>
    
    <div id="output"></div>
    <button onclick="ws.send('hello')">hello전송</button><p>	<!-- 웹 소켓을 통해서 문자열을 전송 -->
    <script>
    	//	head에는 보통 함수를 정의하고, body는 계속 호출해야 할 것들을 해주는 의미
    	
    	//	아래에서 웹 소켓 전송이 이뤄진다.
    	var ws = new WebSocket("ws://localhost:9090/websocket?data=1234");	//	해당 주소로 소켓을 생성해서 열린다.
    	
    	ws.onopen = function() {console.log('open')}
    	
    	ws.onmessage = function(event) { console.log(event.data); output.innerHTML = event.data; }
    	
    	ws.onopen = function(event) {console.log('close')}
    	
    	ws.onopen = function(event) {console.log('error')}
    	
    </script>
    
    </body>
    </html>

     

    위의 jsp파일에 아래의 문장을 보자.

    나만 접속할 것이 아니라 남들도 접속하려면 localhost대신에 나의 ip주소를 써줘야 한다.

    서버의 주소( 나의 주소 )를 알려면 cmd창에 ipconfig를 입력하면 된다.

    여기서는 그냥 ip주소를 적으면 문제가 생기니 일단은 localhost라 적는다.

     

     

    그리고 서버를 실행하고 웹 브라우저를 띄운다. 주소 창에 http://localhost:9090/sockettest 를 입력한다.

    콘솔 화면 창에 아래와 같은 문구가 뜬다.

     

     

    그리고, Chrome 브라우저에서 아래와 같이 도구 더보기 -> 개발자 도구를 선택 해보자.

     

     

    그리고 다음과 같이 Network를 선택해보자.

     

    그리고, 주소 창에 http://localhost:9090/sockettest 을 입력하자.

    아래와 같이 창이 뜬다. 이를 이용해 디버깅을 할 수 있다.

     

     

    IndexController의 기존의 SocketTest메소드를 다음과 같이 변경하자.

    //	/sockettest URL로 접속하면 socketclient.jsp파일이 보여진다.
    	@RequestMapping(value = "/sockettest", method = RequestMethod.GET)
    	public String SocketTest(Locale locale, Model model, String data)
    	{
    		//	logger.info("SocketTest The client locale is {}.", locale);
    		System.out.println("socket connect");
    		System.out.println(data);
    		model.addAttribute("message", "welcome to homepage");	//	socketclient.jsp에 전달
    		
    		return "socketclient";
    	}

     

     

    서버를 재실행하고 http://localhost:9090/sockettest 로 접속해보자.

    그리고, http://localhost:9090/sockettest?data=5678 로도 접속해보자.

     

     

     

    서버에서 웹소켓이 동작한다. 이 웹 소켓은 서버 웹 소켓이다.

    그러면 서버 웹 소켓은 springmvc2프로젝트에서 동작한다. 에코핸들러는 서버 웹소켓이다.

    웹과 시리얼(어플리케이션 : 메인함수로 만든 자바 프로젝트)  을 통신시켜야 한다. 

    즉, 웹과 아두이노의 통신을 구현하려는 것이다.
    순수하게 자바 프로젝트를 통해서 웹 서버에 접속해서
    서버에도 데이터를 주고 자바도 받도록 한다.

     

    ArduinoToSerial프로젝트로 이동해서 src폴더 하위로 websocket2라는 패키지를 하나 만든다.

    그리고 ArduinoToSerial프로젝트를 Maven Project로 변경한다.

    Maven Project로 변경하는 방법은 아래의 글에 자세히 나온다.

    designatedroom87.tistory.com/336?category=909022

     

    프로젝트를 Maven 프로젝트로 변경하기

    아래의 내용을 참고해보자. designatedroom87.tistory.com/334?category=909022 Maven 설치 및 설정 우리가 앞에서 서블릿에서 게시판 만들기에서 이미지 업로드 시에 cos.jar파일을 WEB-INF/lib폴더에 추가해..

    designatedroom87.tistory.com

    Maven Project로 변경하는 이유는 라이브러리 관리를 편하게 하려고 하기 위함이다.

    아래와 같이 Packaging은 jar로 둔다.

     

    가장 먼저 해야할 작업은 pom.xml에 아래의 내용을 추가하자.

     <dependencies>
      	<dependency>
      		<groupId>org.java-websocket</groupId>
      		<artifactId>Java-WebSocket</artifactId>
      		<version>1.5.1</version>
      	</dependency>
      </dependencies>

     

    pom.xml의 전체 내용

    더보기
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>ArduinoToSerial</groupId>
      <artifactId>ArduinoToSerial</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
              <release>14</release>
            </configuration>
          </plugin>
        </plugins>
      </build>
      
       <dependencies>
      	<dependency>
      		<groupId>org.java-websocket</groupId>
      		<artifactId>Java-WebSocket</artifactId>
      		<version>1.5.1</version>
      	</dependency>
      </dependencies>
      
    </project>

     

     

    패키지websocket2에 2개의 java파일을 만든다.

    각 각 WebsocketClient클래스, SocketMain 클래스이다.

    WebsocketClient.java

    더보기
    package websocket2;
    
    import java.net.http.WebSocket;
    import java.net.http.WebSocket.Listener;
    import java.util.concurrent.CompletionStage;
    import java.util.concurrent.CountDownLatch;
    
    //	자바에서 지원하는 기본적인 소켓을 만든 것이다.
    //	WebSocket.Listener를 통해, 웹 소켓에 접속할 것이다.
    public class WebsocketClient implements WebSocket.Listener
    {
    	//	웹 소켓에서 전송되는 데이터 수를 정하는 변수
    	//	만약, 3번만 데이터를 수신하고 싶으면 3으로 설정
    	//	웹 소켓이 닫히게 된다. onClose함수가 자동으로 실행된다.
    	private final CountDownLatch latch;	//	몇번을 받을 것인가?
    	
    	//	사용할 횟수만큼 매개변수로 전달하면 된다.
    	public WebsocketClient( CountDownLatch latch) {
    		this.latch = latch;
    	}
    	
    	@Override
    	//	서버에 접속했을 때, 호출된다.
    	public void onOpen(WebSocket webSocket) {
    		System.out.println("arduino websocket open");
    		Listener.super.onOpen(webSocket);
    	}
    	
    	@Override
    	public CompletionStage<?> onClose(WebSocket webSocket, int statusCode, String reason) {
    		System.out.println("arduino websocket close");
    		return Listener.super.onClose(webSocket, statusCode, reason);
    	}
    	
    	@Override
    	public void onError(WebSocket webSocket, Throwable error) {
    		System.out.println("arduino websocket error");
    		Listener.super.onError(webSocket, error);
    	}
    	
    	@Override
    	//	메시지(텍스트)가 도착했을 때, 호출되는 함수
    	public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
    		System.out.println("arduino recv message : " +data);
    		
    		this.latch.countDown();		
    		
    		return Listener.super.onText(webSocket, data, last);
    	}
    }

     

     

    SocketMain.java

    더보기
    package websocket2;
    
    import java.net.URI;
    import java.net.http.HttpClient;
    import java.net.http.WebSocket;
    import java.util.concurrent.CountDownLatch;
    
    public class SocketMain {
    	public static void main(String[] args) {
    		try {
    			CountDownLatch latch = new CountDownLatch(10);	//	데이터를 10번만 받겠다는 의미
    			URI uri = URI.create("ws://localhost:9090/websocket");
    			WebsocketClient listener = new WebsocketClient(latch);
    			
    			WebSocket ws = HttpClient.newHttpClient().newWebSocketBuilder().buildAsync(
    					uri, listener).join();
    			
    			ws.sendText("java app sendmessage", true);
    			latch.await(); 	
    			
    		}catch(Exception e) { e.printStackTrace();	}
    	}
    }

     

     

    서버를 실행하자. 여기서의 서버는 당연히 springmvc2이다.

    그리고 나서, SocketMain.java를 실행하자.

    콘솔 창의 출력결과는 아래와 같다.

    그러면 아두이노에서 웹 소켓을 이용할 수 있는 환경을 갖추게 되었다.
    이번에는 메시지를 보내보자.

     

    서버를 실행시키고, 웹 페이지를 띄워서 http://localhost:9090/sockettest로 이동해보자.

    그리고 나서, 메인함수를 실행시키자.

    그러면 웹 페이지와 콘솔 창에 메시지가 뜬다.
    그리고 웹페이지의 hello전송 버튼을 클릭하면 웹 페이지와 콘솔 창에 hello라고 뜬다.

    아래가 그 결과 화면이다.

     

     

    웹 페이지에서 ON/OFF버튼의 눌림에 따라 아두이노의 LED를 켜고 끄는 것을 구현해보자. 

    순수하게 서버 소켓이 열려있을 때 접속해서 정보를 주고 정보를 다시 자바로 보낸다.
    이를 위해서는 반드시 uri와 listener(처리 클래스)가 있어야 한다.
    listener : 이벤트를 발생했을 때 처리한다.

    서버 웹 소켓과 클라이언트가 연결이 되었다.
    서버로 데이터를 보내면, 서버에서는 모든 클라이언트에 데이터를 전송이 가능하다.
    이 데이터를 자바가 받아서 아두이노와 시리얼 통신을 하면 된다.

    다시 springmvc2프로젝트로 이동한다.

    WEB-INF/view폴더에 arduinoled.jsp파일을 하나 만들자.

    arduinoled.jsp 전체 내용

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    
    <body>
    <button onclick="ws.send('1')">LED ON</button><p>
    <button onclick="ws.send('0')">LED OFF</button><p>
    <script>
    	var ws = new WebSocket("ws://localhost:9090/websocket");
    	
    	ws.onopen = function() {console.log('open')}
    	
    	ws.onmessage = function(event) { console.log(event.data); output.innerHTML = event.data; }
    	
    	ws.onopen = function(event) {console.log('close')}
    	
    	ws.onopen = function(event) {console.log('error')}
    </script>
    
    </body>
    </html>

     

     

    그리고, IndexController로 이동한다.

    그리고 메소드를 하나 추가한다.

    //	/socketled URL로 접속하면 arduinoled.jsp파일이 보여진다.
    	@RequestMapping(value = "/socketled", method = RequestMethod.GET)
    	public String SocketLED(Locale locale, Model model, String data)
    	{
    		//	logger.info("SocketTest The client locale is {}.", locale);
    		System.out.println("socket led connect");
    		System.out.println(data);
    		
    		return "arduinoled";
    	}

     

     

    IndexController.java 전체 내용

    더보기
    package springmvc2;
    
    import java.util.List;
    import java.util.Locale;
    
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.servlet.ModelAndView;
    
    import db.NumInterface;
    import db.Test;
    
    @Controller	//	자동으로 IndexController 객체 생성
    //@RequestMapping("/aaa/")	//	url에서 localhost:9090/aaa/index
    public class IndexController 
    {	
    	@Autowired				//	구현한 객체를 자동으로 주입하기 위해 쓴 키워드
    	@Qualifier(value="num")	//	NumInterImple객체를 자동으로 넣기 위해서 @Autowired를 선언
    	private NumInterface service;	//	sql 구현 객체를 사용하는 인터페이스
    	
    	@RequestMapping("/index1")
    	public String index1() {	
    		System.out.println("index.jsp실행");
    		return "index.jsp";	
    	}
    	
    	@RequestMapping("/index2")
    	public String index2() {	
    		System.out.println("/WEB-INF/index.jsp실행");
    		return "/WEB-INF/index.jsp";	
    	}
    	
    	@RequestMapping("/index3")
    	public String index3() {	
    		System.out.println("/WEB-INF/view/index.jsp실행");
    		return "/WEB-INF/view/index.jsp";	
    	}
    	
    	@RequestMapping("/index4")
    	public String index4() {	
    		System.out.println("index4 뷰 리졸버 실행");
    		return "index4";	
    	}
    	
    	@RequestMapping("/index5")
    	public ModelAndView index5(String page, String count) {	
    		System.out.println("index5 뷰 리졸버 실행 : "+page + " " +count);
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("page",page);
    		mv.addObject("count",count);
    		mv.setViewName("index5");
    		return mv;	
    	}
    	
    	@RequestMapping("/index6")
    	public ModelAndView index6(HttpServletRequest request) {	
    		
    		String page = request.getParameter("page");
    		String count = request.getParameter("count");
    		
    		System.out.println("index6 뷰 리졸버 실행 : "+page + " " +count);
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("page",page);
    		mv.addObject("count",count);
    		mv.setViewName("index6");
    		return mv;	
    	}
    	
    	@RequestMapping("/serialdata")
    	public void serialdata(String data, HttpServletRequest request) {
    		System.out.println("web data : " +data);
    		
    		//	아두이노로부터 전송된 데이터를 활용하여 처리
    		
    		//	DB처리
    		
    		//	web jsp에 데이터를 보내는 처리
    		ServletContext app = request.getServletContext();	//	전역 저장 객체
    		app.setAttribute("data", data);
    	}
    	
    	@RequestMapping("/serialdb")
    	public void serialdb(String data, HttpServletRequest request) {
    		System.out.println("web DB data : " +data);
    		
    		//	DB 처리
    		/*
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		 
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		*/
    		service.update();
    		
    		if (service.insert() == true) System.out.println("입력 성공");
    		else						System.out.println("입력 실패");
    	}
    	
    	@RequestMapping("/serial1")
    	public String serialdata1() {
    		return "arduino1";
    	}
    	
    	@RequestMapping("/serial2")
    	public ModelAndView serialdata(HttpServletRequest request) {
    		ModelAndView mv = new ModelAndView();
    		
    		ServletContext app = request.getServletContext();	//	전역 저장 객체
    		String data = (String)app.getAttribute("data");
    		
    		mv.addObject("data",data);
    		mv.setViewName("arduino2");	//	arduino페이지로 이동
    		
    		return mv;
    	}
    	
    	@RequestMapping("/serialdbview")
    	public ModelAndView serialdbview() {
    		//	DB 처리
    		/*
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		 
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		*/
    		
    		int data = service.select();
    		
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("data",data);
    		mv.setViewName("serialdbview");
    		
    		return mv;
    	}
    	/*
    	@RequestMapping("/serialdbtable")
    	public void serialdbtable(String data, HttpServletRequest request) {
    		System.out.println("web DB data : " +data);
    		
    		//	DB 처리
    	
    		//ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		//NumInterface service = context.getBean("num", db.NumInterImple.class);
    		
    		service.insert();
    	}
    	*/
    	
    	@RequestMapping("/serialdbtableview")
    	public ModelAndView serialdbtableview() {
    		//	DB 처리
    		/*
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		 
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		*/
    		
    		List<Test> list = service.getList();
    		
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("list",list);
    		mv.setViewName("serialdbtableview");
    		
    		return mv;
    	}
    	
    	//	/sockettest URL로 접속하면 socketclient.jsp파일이 보여진다.
    	@RequestMapping(value = "/sockettest", method = RequestMethod.GET)
    	public String SocketTest(Locale locale, Model model, String data)
    	{
    		//	logger.info("SocketTest The client locale is {}.", locale);
    		System.out.println("socket connect");
    		System.out.println(data);
    		model.addAttribute("message", "welcome to homepage");	//	socketclient.jsp에 전달
    		
    		return "socketclient";
    	}
    	
    	//	/socketled URL로 접속하면 arduinoled.jsp파일이 보여진다.
    	@RequestMapping(value = "/socketled", method = RequestMethod.GET)
    	public String SocketLED(Locale locale, Model model, String data)
    	{
    		//	logger.info("SocketTest The client locale is {}.", locale);
    		System.out.println("socket led connect");
    		System.out.println(data);
    		
    		return "arduinoled";
    	}
    }

     

     

    서버를 실행해서 웹 페이지를 띄우고 http://localhost:9090/socketled 로 접속하고
    SocketMain.java를 실행한다.

    웹 페이지의 LED ON 혹은 LED OFF를 클릭하면 콘솔 화면 창에 1과 0이 번갈아 출력됨을 볼 수 있다.

    web clinet(jsp) 에서 LED ON 혹은 LED OFF버튼의 눌림에 따라 데이터를 Server로 전달해서

    자바 어플리케이션으로 데이터를 전달한 과정이다.
    이제 자바가 시리얼 통신을 통해 아두이노로 데이터를 전달하면 된다.

     

     

    ArduinoToSerial 프로젝트의 src폴더의 default package에

    SerialWebsocket.java파일과 WebsocketClientArduino.java 파일을 만든다.

    SerialWebsocket 클래스를 하나 만들어서 웹에서 받은 데이터를 아두이노로 전송하도록 한다.

    호출은 Serial.java에서 한다.

    아래의 onText메소드에서 아두이노로 데이터를 전송한다.

    WebsocketClientArduino.java 전체 내용

    더보기
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.http.WebSocket;
    import java.net.http.WebSocket.Listener;
    import java.util.concurrent.CompletionStage;
    import java.util.concurrent.CountDownLatch;
    
    //	자바에서 지원하는 기본적인 소켓을 만든 것이다.
    //	WebSocket.Listener를 통해, 웹 소켓에 접속할 것이다.
    public class WebsocketClientArduino implements WebSocket.Listener
    {
    	//	웹 소켓에서 전송되는 데이터 수를 정하는 변수
    	//	만약, 3번만 데이터를 수신하고 싶으면 3으로 설정
    	//	웹 소켓이 닫히게 된다. onClose함수가 자동으로 실행된다.
    	private final CountDownLatch latch;	//	몇번을 받을 것인가?
    	private OutputStream out;
    	
    	//	사용할 횟수만큼 매개변수로 전달하면 된다.
    	public WebsocketClientArduino( CountDownLatch latch, OutputStream out) {
    		this.latch = latch;
    		this.out = out;
    	}
    	
    	@Override
    	//	서버에 접속했을 때, 호출된다.
    	public void onOpen(WebSocket webSocket) {
    		System.out.println("arduino websocket open");
    		Listener.super.onOpen(webSocket);
    	}
    	
    	@Override
    	public CompletionStage<?> onClose(WebSocket webSocket, int statusCode, String reason) {
    		System.out.println("arduino websocket close");
    		return Listener.super.onClose(webSocket, statusCode, reason);
    	}
    	
    	@Override
    	public void onError(WebSocket webSocket, Throwable error) {
    		System.out.println("arduino websocket error");
    		Listener.super.onError(webSocket, error);
    	}
    	
    	@Override
    	//	메시지(텍스트)가 도착했을 때, 호출되는 함수
    	public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
    		System.out.println("arduino recv message : " +data);
    		this.latch.countDown();		
    		
    		try {this.out.write(data.toString().getBytes());} 
    		catch (IOException e) {e.printStackTrace();}
    		
    		return Listener.super.onText(webSocket, data, last);
    	}
    }

     

     

    SerialWebsocket.java에서는 웹 소켓 생성하고, 데이터 전송하고 그리고 데이터가 들어올 때까지 계속 기다린다.
    웹 소켓은 한 번만 생성하면 끝이므로 생성자에서 해도 된다 ( 한 번만 접속하면 끝 ).

    단순히 웹 소켓에 접속하는 역할을 한다. 웹 소켓을 생성을 하면서 WebsocketClientArduino를 생성한다.

    SerialWebsocket.java 전체 내용

    더보기
    import java.io.OutputStream;
    import java.net.URI;
    import java.net.http.HttpClient;
    import java.net.http.WebSocket;
    import java.util.concurrent.CountDownLatch;
    
    public class SerialWebsocket implements Runnable 
    {
    	OutputStream out;
    	
    	//	Constructor
    	public SerialWebsocket(OutputStream out) {this.out = out;}
    	
    	@Override
    	public void run() {
    		try {
    			CountDownLatch latch = new CountDownLatch(10);	//	데이터를 10번만 받겠다는 의미
    			URI uri = URI.create("ws://localhost:9090/websocket");
    			WebsocketClientArduino listener = new WebsocketClientArduino(latch, out);
    			
    			WebSocket ws = HttpClient.newHttpClient().newWebSocketBuilder().buildAsync(
    					uri, listener).join();
    			
    			ws.sendText("java app sendmessage", true);
    			latch.await(); 	
    			
    		}catch(Exception e) { e.printStackTrace();	}
    
    	}
    }

     

     

    그리고 Serial.java에서 SerialWebsocket를 호출한다.

     

    Serial.java의 전체 내용

    더보기
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import gnu.io.CommPort;
    import gnu.io.CommPortIdentifier;
    import gnu.io.SerialPort;
    
    public class Serial 
    {
    	void connect(String port) 
    	{
    		CommPort commPort = null;
    		SerialPort serialPort = null;
    		
    		try 
    		{
    			CommPortIdentifier com = CommPortIdentifier.getPortIdentifier(port);
    			
    			//	com포트를 확인하는 작업
    			if (com.isCurrentlyOwned())
    				System.out.println("Error : "+port +"포트를 사용중입니다.");
    			
    			//	포트가 열려있으면
    			else
    			{
    				commPort = com.open(this.getClass().getName(),2000);
    				
    				//	획득한 포트를 객체가 사용할 수 있는지 여부 확인
    				if (commPort instanceof SerialPort)	//	commPort가 SerialPort로 사용할 수 있는지 확인
    				{
    					serialPort = (SerialPort)commPort;
    					
    					//	정상적으로 포트를 사용할 수 있을 경우
    					//	포트에 필요한 정보를 입력해 준다.
    					serialPort.setSerialPortParams(
    							9600,						//	바운드레이트 
    							SerialPort.DATABITS_8, 
    							SerialPort.STOPBITS_1, 
    							SerialPort.PARITY_NONE);	//	오류제어 비트
    				}
    				System.out.println("comport성공");
    				
    				InputStream in = serialPort.getInputStream();
    				OutputStream out = serialPort.getOutputStream();
    				
    				(new Thread(new SerialRead(in))).start();
    				new Thread(new SerialWrite(out)).start();
    				(new Thread(new SerialWebsocket(out))).start();
    			}
    		}	//	end try
    		catch(Exception e) {}
    	}
    }

     

     

    그리고 아두이노와 LED를 연결하자.

    웹으로부터 LED ON( '1' ) 을 전달받으면 LED를 켜고,  LED OFF( '1' ) 를 전달받으면 LED를 끄면 된다.

    아래는 아두이노와 LED를 연결한 것으로, 11번핀을 출력핀으로 쓴다. 남색선은 아두이노의 11번핀에 연결한다.

    붉은 선은 GND에 연결한다.

    아래의 글을 참고해도 좋다.

    designatedroom87.tistory.com/181?category=896892

     

    LED(analog pin, digital pin)

    하드웨어 연결 LED를 켜고 끄는 것을 만들어보자. 아두이노 보드 연결은 다음과 같이 세팅을 한다. 붉은 선은 7번핀과 연결하고 검은 선은 GND와 연결된 선이다. 저항은 모두 220옴이다. 핀들은 반

    designatedroom87.tistory.com

     

     

     

    아두이노의 소스 파일은 아래와 같다.

    아두이노 소스 파일

    더보기
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
    
      pinMode(11, OUTPUT);
    
      digitalWrite(11, LOW);
    }
    
    void loop() {}
    
    void serialEvent()
    {
      byte recv = Serial.read();
    
      if (recv == '1')      digitalWrite(11, HIGH);
      else if (recv == '0') digitalWrite(11, LOW);
    }

     

     

    실행할 때, 전체 종료를 하고 반드시 서버를 먼저 실행하고

    웹 페이지를 띄워서 http://localhost:9090/socketled 로 이동한다.

    메인함수를 실행해야 한다. 

    여기서는 Main.java를 실행해야 한다.

    아래와 같은 결과를 얻는다.

     

     

    이번에 추가적인 내용으로, 아두이노에 서보 모터를 연결한다. 

    서보모터는 0~180사이의 값으로 회전이 가능하다.

    springmvc2프로젝트의 arduinoled.jsp에 슬라이드를 추가해서 이 슬라이드 된 값을 아두이노로 전달해서

    이 전달받은 값으로 회전 시키자.

     

     

    서보 모터와 아두이노의 연결은 아래의 글을 참고하자.

    designatedroom87.tistory.com/247?category=899480

     

    서보 모터의 기본적인 연결 및 동작

    서보모터와 관련한 함수 하드웨어 연결 서보 모터는 3개의 선으로 구성되어 있는데, 아래의 세 선이 서보 모터에 연결된 선이다. 이 선 색을 중심으로 보면 서보 모터의 가운데는 VCC에, 갈색은 GN

    designatedroom87.tistory.com

     

     

    arduinoled.jsp 전체 내용

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    
    <body>
    <button onclick="ws.send('1')">LED ON</button><p>
    <button onclick="ws.send('0')">LED OFF</button><p>
    
    <input type="range" id="vol" name="vol" min="0" max="180" onchange="ws.send(this.value)">
     
    <script>
    	var ws = new WebSocket("ws://localhost:9090/websocket");
    	
    	ws.onopen = function() {console.log('open')}
    	
    	ws.onmessage = function(event) { console.log(event.data); output.innerHTML = event.data; }
    	
    	ws.onopen = function(event) {console.log('close')}
    	
    	ws.onopen = function(event) {console.log('error')}
    </script>
    
    </body>
    </html>

     

     

    아래는 아두이노의 소스파일인데 두 개 중에 하나를 선택해서 사용하면 된다.

    첫 번째는 C언어에서 제공하는 atoi함수를 사용하여 구현한 것이고

    두 번째는 atoi함수를 사용하지 않고 약간의 노가다를 해서 구현한 것이다.

    두 개 모두 검증이 끝난 것이므로 아무거나 사용해도 된다.

    아두이노 소스 파일1

    더보기
    #include <Servo.h>
    
    Servo servo;
    
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      
      servo.attach(6);  //  6번핀
    
      servo.write(0);
    }
    
    void loop() {}
    
    void serialEvent()
    {
      byte data[1024] = {0,}; 
      
      Serial.readBytes(data, sizeof(data) - 1);
    
      int motor = atoi(data); 
      
      servo.write(motor);
    }

     

     

    아두이노 소스 파일2

    더보기
    #include <Servo.h>
    
    Servo servo;
    
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      
      servo.attach(6);  //  6번핀
    
      servo.write(180);
    }
    
    void loop() {}
    
    //  '9'를 9로 변환하는 함수
    int CharToInt(char cInt)
    {
      return cInt - '0';
    }
    
    //  자리수를 리턴하는 함수
    //  2이면 두 자리수를 의미하므로 100을 리턴한다.
    int GetDigit(int digit)
    {
      int ret = 1;
      
      for ( int i = 0; i < digit; i++ )
        ret *= 10;
    
      return ret;
    }
    
    void serialEvent()
    {
      char data[1024] = {0,}; 
    
      //  입력되어 들어온 데이터의 길이를 저장.
      int len = Serial.readBytes(data, sizeof(data) - 1);
      
      int motor = 0;  //  회전시킬 모터의 값
      
      for ( int i = 0; i < len; i++ )
      {
        int l_val = CharToInt(data[i]) * GetDigit(len - 1 - i);
    
          motor += l_val;
      }
      servo.write(motor);
    }

     

     

    서버를 실행하고 웹 페이지를 띄우고 http://localhost:9090/socketled 으로 접속하자.

    그리고 Main.java를 실행시킨다.

    콘솔 창에 다음과 같이 뜬다.

     

     

     

    현재까지의 프로젝트

    ArduinoToSerial &amp; springmvc2.zip
    2.72MB

    댓글

Designed by Tistory.