ESP8266 Non-OS SDK開發探坑之六-簡單的TCP控制服務

Starting with ESP8266 — Light a LED

Starting with ESP8266 (2)–Touch to control relay status-circuit design & electronic components selection

Starting with ESP8266(3) — Touch to control Relay-Programming & PCB design

Starting with ESP8266(4)–User parameters securely save & load on flash

Starting with ESP8266(5)–Simple HTTP configure server

Starting with ESP8266(6)–Simple TCP command server

這邊承接上文,用esp8266 sdk 開發tcp server, 對接收到的請求進行處理。

建立連接和回調函數什麼的沒啥好說的

接收回調函數裏主要完成對接收到的消息的解包。

其實TCP Server完全可以做成和web server一樣用http協議進行通信,然後在數據域內填充POST請求參數,或者json數據。這裏我再造造輪子,讓大家有更多的選擇。我簡單定義了個交互協議(格式),就是首先兩個字節的固定幀頭,定義在User_config.h

 

1

#define COMM_PREFIX 0x417A // Az

我這裏爲了調試方便,用了ascii碼的Az做幀頭,實際用的時候並不理想,因爲內容部分很容易出現Az字樣,存在一定的問題。第3、4字節是長度字段,unsigned short,高字節在前,低字節在後的編碼。後面即是數據。數據部分我懶得做json解析了,只支持固定的幾個命令。

 

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

LOCAL void ICACHE_FLASH_ATTR

TCPServRecvCB(void *arg, char *pDataRecv, unsigned short length)

{

struct espconn *pEspConn = arg;

char respBuf[64];

os_memset(respBuf,0,sizeof(respBuf));

 

TRACE("recved:%02x%02x%02x%02x%s,len:%d\r\n",pDataRecv[0],pDataRecv[1],pDataRecv[2],pDataRecv[3],pDataRecv+4,length);

if(length>=COMM_HEADLEN && (pDataRecv[0]==(COMM_PREFIX >> 8)) && (pDataRecv[1] == (COMM_PREFIX & 0xff )) ){

uint16 len;

len = (pDataRecv[2]<<8) + pDataRecv[3];

if(length-COMM_HEADLEN == len){

if(os_strncmp(pDataRecv+COMM_HEADLEN,"relay-on",8)){

        GPIO_OUTPUT_SET(GPIO_ID_PIN(RELAY_PIN), RELAY_ON);

        RelayStatus = RELAY_ON;

}

}else{

os_sprintf(respBuf,"unrecognized command");

goto EXIT_RESPONSE;

}

os_sprintf(respBuf,"ok");

}else{

os_sprintf(respBuf,"length check failed");

}

}else{

os_sprintf(respBuf,"frame head check error");

}

EXIT_RESPONSE:

TCPResponse(pEspConn,respBuf,os_strlen(respBuf));

}

響應函數裏封裝了響應頭,也是固定幀頭和長度信息+數據域:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

LOCAL void ICACHE_FLASH_ATTR

TCPResponse(void *arg, const char *pData, uint16 length){

    struct espconn * pEspConn = arg;

char respBuf[64];

os_memset(respBuf,0,sizeof(respBuf));

os_printf("response:%s\r\n",pData);

 

respBuf[0] = REPORT_PREFIX >> 8;

respBuf[1] = REPORT_PREFIX & 0xff;

respBuf[2] = length>>8;

respBuf[3] = length & 0xff;

os_memcpy(respBuf+4,pData,length);

 

#ifdef TCP_SERV_SSL_ENABLE

        espconn_secure_sent(pEspConn, respBuf, length+4);

#else

        espconn_sent(pEspConn,respBuf, length+4);

#endif

}

這篇比較簡單,繼續插播我打的板,這回實物到了:

AC-DC繼電器控制版(智能開關)

  AC供電版散件

DC供電版

DC供電版散件

代碼見:

原博客:

http://www.straka.cn/blog/esp8266-6-tcp-command-server/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章