top drop menu

Recent Post

레이블이 NodeMCU인 게시물을 표시합니다. 모든 게시물 표시
레이블이 NodeMCU인 게시물을 표시합니다. 모든 게시물 표시

화요일, 11월 6

알리익스프레스에서 주문한 각종 부품들이 모두 도착

20181107_082212


생각 날때 몇가지 주문했었던 같은데 그새 모두 도착했다. 그런데 뭐할려고 주문했는지 명학하지 않다는게 문제 ㅋㅋ

당장 사용하지 않더라도 언제가 필요할일이 생기도록 해야지.

일단 자동드릴은 하나 만들어야 하는데 부품은 다 모인것 같은데 문제는 모터를 넣을 홀더가 적당하게 없다. 3cm 정도 지금의 원형통이 필요하다.


20181107_082445_001


이건 누르고 있는 동안에만 전류가 흐르는 스위치이다. 드릴에 사용할려고 구입하기는 했는데 …


20181107_082454


릴레이, 중복 주문해서 갑자기 쓸데없이 많아 졌다.


20181107_082510


DC어답터를 전선과 연결하게 해주는 부품. 이것도 드릴 만들때 필요하다.


20181107_082519


NodeMCU(호환제품)을 장착해서 dc어답터로 전원을 공급 받아서 여러가지를 연결해서 사용할 수 있는 부품이다.

하나 사용해 보니 좋아서 추가 구입했다. 전원 공원을 일원화 할 수 있는 점에서 좋다. 조금 불안 하기도 한듯 .


20181107_082528


미니 빵판. 간단한것 만들때는 좋다. 칼라별 세트로 싸가 팔길래 구입.


20181107_082541


전선 연결할때 연결부위를 수축시켜 감싸주는 튜브. 깔끔하고 안전하게 마무리 할때 필요하다.

다양한 크기가 셋트로 되어 있다.


이제 뭘 만들지?

NodeMCU(혹 아두이노)를 이용하여 웹소켓 통신하기(3)

이번에는 안드로이드 클라이언트를 만들어 보자. 쉽게 할 수 있는 방법을 찾아 보니 딱히 없다. 기본으로 제공하는게 없는 모양이다. 못 찾아서 그럴수도 …
그래서 웹소켓 라이브러리를 이용하기로 했다. 먼저 gradle에 추가해 주자.
implementation 'com.neovisionaries:nv-websocket-client:2.4'
레이아웃은 간단히 응답 메세지를 출력할 텍스트뷰를 배치하고 그 밑에 두개의 버튼을 추가하였다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="
http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     tools:context=".MainActivity">

    <TextView
         android:id="@+id/tv_result"
         android:textSize="24dp"
         android:textColor="@color/colorAccent"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentTop="true"
         android:layout_centerHorizontal="true"
         android:layout_marginTop="66dp"
         android:text="TextView" />

    <Button
         android:id="@+id/button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentStart="true"
         android:layout_alignParentTop="true"
         android:layout_marginStart="76dp"
         android:layout_marginTop="157dp"
         android:text="Red" />

    <Button
         android:id="@+id/button2"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignBottom="@+id/button"
         android:layout_alignParentEnd="true"
         android:layout_marginEnd="77dp"
         android:text="Green" />


</RelativeLayout>
이제 메인액티비에 코드를 작성하자.
public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();
     Button bt_red, bt_green;
     TextView result;

    WebSocket ws = null;
    @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);

        WebSocketFactory factory = new WebSocketFactory().setConnectionTimeout(5000);
         try{
             ws = factory.createSocket("ws://server_ip:port"); //''로 하면 에러남 이런 아니 왜?
             ws.addListener(new WebSocketAdapter(){
                 @Override
                 public void onTextMessage(WebSocket websocket, String text) throws Exception {
                     super.onTextMessage(websocket, text);
                     Log.d(TAG, "received: " + text);
                     //응답받은 것을 화면에 출력
                     result.setText(text);
                 }
             });
             ws.connectAsynchronously();
         } catch (Exception e) {
             e.printStackTrace();
         }

        bt_red = (Button) findViewById(R.id.button);
         bt_green = (Button) findViewById(R.id.button2);
         result = (TextView) findViewById(R.id.tv_result);

        bt_red.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View view) {
                 sendMessage(view, "red");
             }
         });

        bt_green.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View view) {
                 sendMessage(view, "green");
             }
         });
     }

    @Override
     protected void onDestroy() {
         super.onDestroy();

        if(ws != null){
             ws.disconnect();
             ws = null;
         }
     }

    public void sendMessage(View view, String message) {
         if(ws.isOpen()){
             ws.sendText(message);
         }
     }
}

Screenshot_20181106-225918

월요일, 11월 5

NodeMCU(혹 아두이노)를 이용하여 웹소켓 통신하기(2)

이제 소켓통신을 이용하여 NodeMCU에 연결되어 있는 두개의 LEd를 제어해 보기로 하자. 먼저 아두이노 코드를 수정해 줘야 한다. 앞 단계를 통해서 소켓데이터를 주고 받을 수 있게 되었다. 이제 구현해야 할것은 단순하다. 소켓으로 들어온 데이터가 red이면 red LED를 켜주고 green 이면 green LED를 켜주면 된다. 코드는 아래와 같다.


…

//LED
int led_red = D4;
int led_green = D7;

//WebSocket
WebSocketsServer webSocket = WebSocketsServer(80);

//Callback function(웹소켓 메세지를 수신하면 실행)
void webSocketEvent(uint8_t num,
                     WStype_t type,
                     uint8_t * payload,
                     size_t length) {
   //웹소켓이벤트의 타입
   switch(type) {
     //클라이언트 연결 해제시
     case WStype_DISCONNECTED:
       Serial.printf("[%u] Disconnected!\n", num);
       break;
       //클라이언트 연결시
     case WStype_CONNECTED:
       {
         IPAddress ip = webSocket.remoteIP(num);
         Serial.printf("[%u] Connected!\n", num);
         Serial.println(ip.toString());
       }
       break;
      
     //클라이언트에게 응답을 보낸다.
   
case WStype_TEXT:
       {
         Serial.printf("[%u] Text: %s\n", num, payload);
         //data에 따라 LED를 제어
         String text = String((char *) &payload[0]);
         if(text=="red"){
           digitalWrite(led_red, HIGH);
         } else {
           digitalWrite(led_red, LOW);
         }
         if(text=="green"){
           digitalWrite(led_green, HIGH);
         } else {
           digitalWrite(led_green, LOW);
         }
         webSocket.sendTXT(num, payload);
       }
       break;

      
     //기타 필요에 따라
     case WStype_BIN:
     case WStype_ERROR:
     case WStype_FRAGMENT_TEXT_START:
     case WStype_FRAGMENT_BIN_START:
     case WStype_FRAGMENT:
     case WStype_FRAGMENT_FIN:
     default:
       break;
   }
}

void setup() {
   Serial.begin(115200);
   connectWifi();

  pinMode(led_red, OUTPUT);
   pinMode(led_green, OUTPUT);

  //Start websocket server
   webSocket.begin();
   webSocket.onEvent(webSocketEvent);//콜백실행

 
}

…

20181106_121014

파이썬에서 다시 red 나 green을 보내면 해당 LED가 켜지는 것을 확인 할 수 있다.

이것을 파이썬으로만 해야 하는 것은 아닌다. 자바스크립트던 뭐던 모두 가능하다. 웹페이지에서 자바스크립트로 이용해서 제어 해보기로 하자. 라즈베리파이 서버의 홈오토메이션에 LED 제어 기능을 추가했다. 

이미지 040

원하는 색상을 선택하면 해당 LED가 켜진다.

<input type="checkbox" id="redLed" onclick="LedControl('redLed');">

체크박스에 스크립트를 연결해 주고

//LED 제어
     function LedControl(color){
         var checkColor = document.getElementById(color).checked;
         if("WebSocket" in window){//브라우저가 지원하는지 체크후
             //웹소켓을 열고
             var ws = new WebSocket("ws://websocketserver_ip:80");
             ws.onopen = function(){
                 //어떤 스위치를 클릭했나?
                 if(color == "redLed"){
                     //데이터를 보내고
                     ws.send("red");
                     document.getElementById("greenLed").checked = false;
                 } else if(color == "greenLed"){
                     ws.send("green");
                     document.getElementById("redLed").checked = false;
                 }
             };
             ws.onmessage = function(evt){
                 var received_msg = evt.data;
                 document.getElementById("colorResult").innerHTML = received_msg + " 선택";
                 ws.close();
             };
             ws.onclose = function(){
                 //alert("Connection is closed...");
             };
         } else {
             alert("웹소켓을 지원하지 않는 브라우저입니다.");
         }
     }


어떤 칼라를 체크했는지 확인후 소켓데이터를 보내면 된다. NodeMCU에서는 이전과 마찬가지로 데이터를 받아서 처리 한다.

NodeMCU(혹 아두이노)를 이용하여 웹소켓 통신하기


이것저것 두서 없이 다루다 보니 웹소켓은 해 본것인지 아닌지 헷갈린다. 중복되면 뭐 어때 자꾸 해봐야 알 수 있는 것인데.
이번에는 NodeMCU에 웹소켓 서버를 설치하고 통신을 시도해 보기로 하자.

20181106_091915

LED 두개를 연결해 두었다. 목표는 웹소켓을 이용 두개의 LED를 제어 해 보는 것이다.
먼저 아두이노 코드를 작성해 보자.
웹소켓에 대한 추가 정보는 아래 사이트에서 확인해 보자.
http://www.websocket.org/aboutwebsocket.html
http://www.zdnet.co.kr/news/news_view.asp?artice_id=20111028085010&lo=zv41


먼저 와이파이 연결을 하도록 설정하자.

#include "ESP8266WiFi.h"
//Wifi 연결하기
const char* ssid = "SSID";
const char* password = "PASSSWORD";
void setup() {
   Serial.begin(115200);
   connectWifi();
  
}
void loop() {
}
//wifi
void connectWifi(){
   Serial.print("Connecting to ");
   Serial.print(ssid);
  WiFi.disconnect(true);
   delay(1000);
   WiFi.begin(ssid, password);
   while(WiFi.status() != WL_CONNECTED){
     delay(500);
     Serial.print(".");
   }
  
   Serial.println("");
   Serial.println("WiFi connected");
   Serial.print("IP Address: ");
   Serial.print(WiFi.localIP());
   Serial.println("");
}

이미지 036

웹소켓 라이브러리를 설치해 주자. 라이브러리 매니저으로 들어 가자.
websockets를 검색해서 설치 해준다. 웹소켓 서버 코드를 작성하자.

#include "ESP8266WiFi.h"
#include "WebSocketsServer.h"
//Wifi 연결하기
const char* ssid = "SSID";
const char* password = "PASSWORD";

//WebSocket
WebSocketsServer webSocket = WebSocketsServer(80);
//Callback function(웹소켓 메세지를 수신하면 실행)
void onWebSocketEvent(uint8_t num,
                     WStype_t type,
                     uint8_t * payload,
                     size_t length) {
   //웹소켓이벤트의 타입
   switch(type) {
     //클라이언트 연결 해제시
     case WStype_DISCONNECTED:
       Serial.printf("[%u] Disconnected!\n", num);
       break;
       //클라이언트 연결시
     case WStype_CONNECTED:
       {
         IPAddress ip = webSocket.remoteIP(num);
         Serial.printf("[%u] Connected!\n", num);
         Serial.println(ip.toString());
       }
       break;
      
     //클라이언트에게 응답을 보낸다.
     case WStype_TEXT:
       Serial.printf("[%u] Text: %s\n", num, payload);
       webSocket.sendTXT(num, payload);
       break;
      
     //기타 필요에 따라
     case WStype_BIN:
     case WStype_ERROR:
     case WStype_FRAGMENT_TEXT_START:
     case WStype_FRAGMENT_BIN_START:
     case WStype_FRAGMENT:
     case WStype_FRAGMENT_FIN:
     default:
       break;
   }
}
void setup() {
   Serial.begin(115200);
   connectWifi();
  //Start websocket server
   webSocket.begin();
   webSocket.onEvent(onWebSocketEvent);//콜백실행
}
void loop() {
   //웹소켓 데이터를 기다림
   webSocket.loop();
}

//wifi
void connectWifi(){
   Serial.print("Connecting to ");
   Serial.print(ssid);
  WiFi.disconnect(true);
   delay(1000);
   WiFi.begin(ssid, password);
   while(WiFi.status() != WL_CONNECTED){
     delay(500);
     Serial.print(".");
   }
  
   Serial.println("");
   Serial.println("WiFi connected");
   Serial.print("IP Address: ");
   Serial.print(WiFi.localIP());
   Serial.println("");
}
<웹소켓 서버 코드>

소켓 데이터 수신을 기다렸다. 접속한 클라이언트 ip를 알려 주고 받은 값을 그대로 클라이언트에게 되돌려 주는 코드이다.
이제 라즈베리파이에서 클라이언트 프로그램을 코딩하자.

이미지 037

라즈베리파이에 파이썬 클라이언트를 만들자. 먼저 websocket-client를 설치해야 한다.
파이썬 2와 파이썬3에서 설치및 사용용어에 차이가 있다. 지금 작업중인 파이썬이 몇 버전인지 먼저 체크하고 파이썬3으로 시작하자.

pip3 install websocket-client

클라이언트 코드는 간단하다.

import websocket
#Connect to websocket server
ws = websocket.WebSocket()
ws.connect("ws://websocket server ip")
print("Connected to WebSocket Server")
#Ask the user for some input
inputStr = input("Say something: ")
ws.send(inputStr)
#Wait for server to respond
result = ws.recv()
print("Received: " + result)
#Socket close
ws.close()


이제 실행해 보자. 파이썬3으로 실행해야 한다.

이미지 038
<NodeMCU 결과>

이미지 039
<라즈베리파이 파이썬 결과>

정상적으로 동작하는 것을 확인 할 수 있다. 이렇게 해서 웹소켓을 통해 소켓통신이 가능해 졌다. 이제 이것으로 좀 더 응용을 해 보기로 하자.

다음편에 계속 …
Blogger Widget