이전 포스팅에 이어 nodeMCU에 Arduino를 포팅하는 걸로 해보겠습니다.
먼저 https://sandbox.sktiot.com/IoTPortal/sdk/sdkList# 로 접속해 Arduino용 sdk를 받아야합니다.
빨간 네모를 눌러 샘플코드를 하나 다운로드합니다.
그리고 녹색네모를 다운받아 확장자를 zip으로 바꿔주면 GMMP 라이브러리가 나타납니다.
GMMP라이브러리는 Arduino에서 zip으로 라이브러리추가를 해줍니다.
먼저 Arduino 소스코드입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | #include <Time.h> #include <ESP8266WiFi.h> #include <GMMP.h> #define USER_CONTROL_LED 0x80 #define LED_PIN 5 #define DEREGISTRATION_DEVICE_SWITCH_PIN 4 byte serverIp[] = {211, 115, 15, 213}; const int nServerPort = 31011; const char* pszDomainCode = "<your domain code>"; const char* pszGWAuthID = "<your gateway auth ID>"; const char* pszGWMFID = "<your gateway manufacturer ID>"; const char* pszDeviceMFID = "<your device manufacturer ID>"; char* deviceId[LEN_DEVICE_ID]; byte mac[] = {0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22}; // Modify this with your ID address int Recv(GMMPHeader* pstGMMPHeader, void* pBody) { U8 cMessageType = pstGMMPHeader->ucMessageType; //메세지 타입 분석 info(F("MsgType: ")); infoln(cMessageType); if (cMessageType == OPERATION_CONTROL_REQ) { // GMMP_Control_Request stControlReqHdr* pstReqHdr = (stControlReqHdr*) pBody; infoln(F("ControlReq has been received.")); char cResult = 0x00; int len = 0; if (pstReqHdr->usMessageBody) { len = strlen((char*) pstReqHdr->usMessageBody); } if (len > 0) { info(F("Control Msg Body: ")); infoln((char*) pstReqHdr->usMessageBody); } long nTID = Char2int((char*) pstGMMPHeader->usTID, sizeof(pstGMMPHeader->usTID)); debug(F("Received TID: ")); debugln(nTID); int ret = GO_Control((char*) pstReqHdr->usGWID, (char*) pstReqHdr->usDeviceID, nTID, (char)pstReqHdr->ucControlType, cResult); if (ret != GMMP_SUCCESS) { errorln(F("ControRes Err!!")); free(pBody); return 1; } infoln(F("ControlRes has been sent.")); infoln(pstReqHdr->ucControlType); if (pstReqHdr->ucControlType != USER_CONTROL_LED) { error(F("Unknown Control Msg: ")); errorln(pstReqHdr->ucControlType); free(pBody); return 1; } if (pstReqHdr->usMessageBody[0] == '1') { digitalWrite(LED_PIN, HIGH); infoln(F("LED ON")); } else if (pstReqHdr->usMessageBody[0] == '0') { digitalWrite(LED_PIN, LOW); infoln(F("LED OFF")); } else { errorln(F("Unknown Control Msg Body; it must be '1' or '0'.")); free(pBody); return 1; } delay(1000); ret = GO_Notifi((char*) pstReqHdr->usGWID, (char*) pstReqHdr->usDeviceID, (char)pstReqHdr->ucControlType, cResult, (char*) pstReqHdr->usMessageBody, 0); if (ret != GMMP_SUCCESS) { error(F("NotiReq Err: ")); errorln(ret); free(pBody); return 1; } infoln(F("Control NotiReq has been sent.")); } else if (cMessageType == OPERATION_NOTIFICATION_RSP) { //GMMP_Control_Notification_Response stNotificationRspHdr* pstRspHdr = (stNotificationRspHdr*) pBody; if (pstRspHdr->ucResultCode != 0x00) { error(F("NotiRes Err: ")); errorln(pstRspHdr->ucResultCode); free(pBody); return 1; } infoln(F("NotiRes has been received.")); } free(pBody); return 0; } #define BUF_SIZE 10 GMMPHeader header; void *pBody = NULL; char sendBuf[BUF_SIZE]; void setup(void) { Serial.begin(115200); infoln(F("Start setup()")); info(F("Free memory size: ")); pinMode(LED_PIN, OUTPUT); pinMode(DEREGISTRATION_DEVICE_SWITCH_PIN, INPUT); infoln(freeRam()); //ans Initialize(serverIp, nServerPort, pszDomainCode, pszGWAuthID, mac); SetCallFunction(Recv); int ret = GO_Reg(NULL, pszGWMFID); if (ret != GMMP_SUCCESS) { errorln(F("RegReq Error!!")); for(;;); } infoln(F("GW RegReq has been sent.")); } void loop(void) { info(hour()); info(F(":")); info(minute()); info(F(":")); infoln(second()); delay(1000); int ret = GetReadData(&header, &pBody); if (ret != E_WOULDBLOCK) { infoln(F("******** NOT E_WOULDBLOCK *********")); info(F("Free memory size: ")); infoln(freeRam()); } } | cs |
LED 제어하는 부분만 빼고 다 제거하였습니다.
nodeMCU의 D1이 LED, D2가 button입니다.
아직 button의 기능은 없습니다.
기본적으로 Ethernet.h를 include하는데 ESP8266WiFi.h를 include했습니다.
아래는 GMMP.cpp의 include 부분입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //#include <Ethernet.h> //ans #include <ESP8266WiFi.h> //ans #include <WiFiUdp.h> //ans #include <User_interface.h> //ans #include <Time.h> #include "GMMP.h" const char* ssid="your ap ssid"; const char* pwd="your ap password"; //EthernetUDP Udp; //ans WiFiUDP Udp; //ans ESP8266WiFiClass Wifi; //ans #define TIMEZONE 9 // KST //ans //#define TIMEZONE 0 // GMT //ans | cs |
마찬가지로 Ethernet.h 대신 ESP8266WiFi.h를 include했고, 시간설정을 위해 WiFiUdp.h도 include했습니다.
TIMEZONE은 한국시간에 맞춰 KST 기준으로 바꿨습니다.
ssid와 pwd는 AP의 ssid와 pwd입니다. 아직은 수동으로^^;;
Initialize 부분입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | int Initialize(byte* serverIp, const int nPort, const char* pszDomainCode, const char* pszGWAuthID, byte* mac) { infoln(F("Initialize()")); InitMemory(); infoln(F("Getting IP")); Wifi.begin(ssid,pwd); //ans while(Wifi.status()!=WL_CONNECTED){ //waiting for conneting delay(1000); info("."); } info(F("Obtained IP: ")); infoln(Wifi.localIP()); //ans delay(3000); //ans /* ans if (Ethernet.begin(mac)) { info(F("Obtained IP: ")); infoln(Ethernet.localIP()); delay(3000); } else { fatalln(F("Failed to get IP.")); for (;;); } */ setTime(); if(SetServerInfo(serverIp, nPort, pszGWAuthID, pszDomainCode) != 0) { return LIB_PARAM_ERROR; } SetTID(0); return GMMP_SUCCESS; } | cs |
Line 11 : ssid와 pwd로 AP에 접속시키는 부분입니다. 여기는 ESP8266WiFi.cpp에 있습니다.
특이한 점은 mac주소를 같이 넘겨주면 AP에 접속을 하지 못합니다.
1 | int ESP8266WiFiClass::begin(char* ssid, char *passphrase, int32_t channel, const uint8_t* bssid) | cs |
ESP8266WiFi.cpp에서 begin함수를 보면 ssid, password, channel, bssid를 받게되어 있습니다.
물론 헤더파일을 보면
1 | int begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL); | cs |
ssid를 제외한 나머지 파라메터는 초기화가 되어있어 파라메터를 쓰지않아도 됩니다.
일단 채널도 알 수는 없으니, ssid와 password만 넘기면 됩니다.
근데 왜 mac주소를 넘겼을때 AP에 접속을 못하느냐인데
begin함수를 살펴보면, mac주소를 세팅하는 부분이 나옵니다.
1 2 3 4 5 6 7 8 | if (bssid) { conf.bssid_set = 1; memcpy((void *) &conf.bssid[0], (void *) bssid, 6); } else { conf.bssid_set = 0; } | cs |
보시면 mac주소(bssid)가 넘어오면 bssid_set=1이 되고, 없으면 bssid_set=0이 됩니다.
station mode 설정 구조체인 station_config를 보면 아래와 같은 주석이 달려있습니다.
1 2 3 4 5 6 7 | struct station_config { uint8 ssid[32]; uint8 password[64]; uint8 bssid_set; // Note: If bssid_set is 1, station will just connect to the router // with both ssid[] and bssid[] matched. Please check about this. uint8 bssid[6]; }; | cs |
bssid_set=1이면 router에 접속해야하고, ssid와 bssid를 match해야 된다고 합니다.
이 bssid는 device의 mac이 아닌 AP의 mac인듯 합니다.
BSSID(Basic Service Set)는 무선 LAN 표준인 802.11에서 48bit의 BSS(Basic Service Set)을 구분하기 위해 사용한다. 보통은 AP의 MAC주소를 사용하지만 IBSS(Independent basic Service Set)나 AD HOC을 사용할 경우 임의의 값으로 생성된다. 출처 위키
Line 12~15 : 위에서 접속은 시키지만 접속하는데 시간이 좀 걸립니다. 그래서 접속 될때까지
기다리도록 while문으로 처리했습니다.
Line 16~18 : 할당받은 IP를 가져와 뿌려줍니다.
Line 20~28 : 기존 코드인데 문제가 있어 위의 코드로 변경했습니다.
Line 31 : 시간정보를 가져옵니다.
1 2 3 4 5 | void setTime() { Udp.begin(NTP_PORT); setSyncProvider(getNtpTime); } | cs |
기존의 EthernetUDP 대신 include한 WiFiUDP로 바꿔주어서 따로 수정할 건 없습니다.
추가
Network.cpp 에서 아래부분 수정해 주세요.
1 2 3 4 5 6 7 8 | //#include <Ethernet.h> //ans#include <ESP8266WiFi.h> //ans #include "Network.h" #include "GMMP_Operation.h" int g_socket = -1; //EthernetClient client; //ans WiFiClient client; //ans | cs |
1 2 3 4 5 6 7 8 9 10 11 12 | int WriteTCP(char* pBuf, int nLen) { debug(F("WriteTCP(): ")); debugln(nLen); if (pBuf == NULL || nLen <= 0) return LIB_PARAM_ERROR; //client.write(pBuf, nLen); //ans client.write_P(pBuf, nLen); //ans return GMMP_SUCCESS; } | cs |
'Study > ESP8266(WIFI),ESP32(BLE,WIFI)' 카테고리의 다른 글
skthingplug 접속 못하는 문제및 접속 순서 (0) | 2016.01.08 |
---|---|
arduino에서 nodeMCU(ESP8266)의 freeRAM 값 얻어오기 (0) | 2016.01.07 |
nodeMCU(ESP8266) skt thing plug 앱으로 원격제어 (0) | 2015.12.23 |
arduino에서 ESP8266 사용하기 (2) | 2015.12.23 |
nodeMCU AP모드에서 공유기에 접속시키기2 (5) | 2015.12.21 |