ETA6103是由串口WiFi模塊E103(esp8266ex芯片)+ USB轉(zhuǎn)串口芯片CH340T構(gòu)成的低成本無線模塊,其對外接口是miniPCIe接口,可以適用于英創(chuàng)ESMARC V4.0以上的所有底板,也可以通過ETA303模塊轉(zhuǎn)成USB接口,用到所有的英創(chuàng)底板之上。
ESMARC底板、ETA6103和ETA303模塊
工作的時候,ETA6103被虛擬成串口設(shè)備,比如/dev/ttyUSB0。對軟件來說,按串口的方式讀寫,發(fā)送AT指令即可建立互聯(lián)網(wǎng)連接。值得注意的是ETA6103最大能支持5個網(wǎng)絡(luò)連接,包括所有的TCP和UDP連接。并且,所有的配置信息、網(wǎng)絡(luò)數(shù)據(jù)都通過同一個串口傳輸。為方便用戶編程,適應(yīng)網(wǎng)絡(luò)編程的習(xí)慣,增加程序的可讀性,英創(chuàng)公司封裝了一個CUartWifi類,提供了配置無線網(wǎng)絡(luò)和建立TCP/UDP傳輸?shù)墓埠瘮?shù),用戶不用關(guān)心具體的AT指令。
1、加載CH340T驅(qū)動
insmod /lib/modules/(Linux versions)/usbserial.ko
insmod /lib/modules/(Linux versions)/ch340.ko
成功后會在/dev目錄下增加一個串口設(shè)備ttyUSBx,通過此串口發(fā)送AT指令,接收信息。
2、連接WiFi
CUartWifi uartWifi(devname);
ret = uartWifi.ConnectToAP("Emtronix\\.20","0987654321");//需要對特殊字符進行轉(zhuǎn)義
ret = uartWifi.SetIPInfo("192.168.201.93","192.168.201.20", "255.255.255.0");
需要注意的是ETA6103的AT指令中ssid需要對特殊字符做轉(zhuǎn)義,假如無線網(wǎng)絡(luò)賬號是"Emtronix.20",ETA6103的AT指令中ssid應(yīng)該輸入"Emtronix\.20",而通過CUARTWifi類發(fā)送的ssid參數(shù)就應(yīng)該是"Emtronix\\.20"。連接上無線網(wǎng)絡(luò)后,可以調(diào)用SetIPInfo設(shè)置IP地址、網(wǎng)關(guān)、子網(wǎng)掩碼,還可以使用Ping工具檢查連接狀況。
3、建立TCP服務(wù)端
char server[] = "*";
ret = uartWifi.Open(server,6002,TCP_TRANS_TYPE,0);
int totalConno = 0;
pthread_mutex_t totalConno_mutex;
pthread_mutex_init(&totalConno_mutex,NULL);
while(1)
{
ret = uartWifi.Accept(0);
......
threadFuncParam.pUartWifi = &uartWifi;
threadFuncParam.conno = ret;
threadFuncParam.pTotalConno = &totalConno;
threadFuncParam.pTotalConnoMutex = &totalConno_mutex;
ConnThreadCreate(&connThread[ret],(void * (*)(void *))&ConnThreadFunc1,&threadFuncParam) ;
}
ETA6103支持的最大網(wǎng)絡(luò)連接數(shù)是5個,包括所有的客戶端連接和服務(wù)端連接。在建立服務(wù)端連接時,首先使用Open函數(shù)開啟服務(wù)端功能,然后馬上進入Accept狀態(tài),每收到一個連接,就為這個新連接開啟一個線程。建立新線程時傳遞參數(shù)要用到下面的結(jié)構(gòu)體:
struct ThreadFuncParam
{
CUartWifi * pUartWifi;
int conno;
int *pTotalConno;
pthread_mutex_t *pTotalConnoMutex;
};
在此線程中調(diào)用WaitEvent等待此連接的數(shù)據(jù)或連接中斷的事件,并做對應(yīng)的處理。這里對接收到的數(shù)據(jù)進行回發(fā),使用do{}while循環(huán)是保證對應(yīng)conn的接收數(shù)據(jù)緩存中的數(shù)據(jù)能全部讀出。在退出此線程時,使用指針對主程序中的TotalConno做了“減一”處理,表示conn連接關(guān)閉。
int ConnThreadFunc1( void* lparam )
{
CUartWifi * pUartWifi = ((struct ThreadFuncParam * )lparam)->pUartWifi;
int conn = ((struct ThreadFuncParam * )lparam)->conno;
int* pTotalConno = ((struct ThreadFuncParam * )lparam)->pTotalConno;
int connClose = 0;
...具體聲明見例程
while(connClose != 1)
{
event = pUartWifi->WaitEvent(conn,2000);
switch(event)
{
case CONN_EVENT_TIMEOUT:
break;
case CONN_EVENT_DATAIN:
do{
readNum = pUartWifi->Recv(conn,buf,1024);
...
pUartWifi->Send(conn,buf,readNum);
}while(readNum == 1024);//不一定是1024,
break;
case CONN_EVENT_CLOSE:
connClose = 1;
break;
case CONN_EVENT_ERROR:
connClose = 1;
break;
default:
break;
}
}
pthread_mutex_lock(((struct ThreadFuncParam * )lparam)->pTotalConnoMutex);
if(*pTotalConno > 0)
*pTotalConno = *pTotalConno - 1;
pthread_mutex_unlock(((struct ThreadFuncParam * )lparam)->pTotalConnoMutex);
return 0;
}
4、建立TCP客戶端連接
客戶端也使用Open建立,第一個參數(shù)為IP地址,得到新連接后使用WaitEvent監(jiān)聽處理此連接的事件,與服務(wù)端程序相似。
ret = uartWifi.Open(remoteIP,remotePort,TCP_TRANS_TYPE,0);
if(ret >= 0 && ret < 5)
{
int connClose = 0;
...具體聲明見例程
while(connClose != 1)
{
event = uartWifi.WaitEvent(conn,2000);
switch(event)
{
case CONN_EVENT_TIMEOUT:
break;
case CONN_EVENT_DATAIN:
do{
readNum = uartWifi.Recv(conn,buf,1024);
}while(readNum == 1024);//不一定是1024,
break;
case CONN_EVENT_CLOSE:
connClose = 1;
break;
case CONN_EVENT_ERROR:
connClose = 1;
break;
default:
break;
}
}
}
5、關(guān)閉連接,斷開網(wǎng)絡(luò)
for(i1=0;i1<MAX_LINK_NUM;i1++)
{
uartWifi.Close(i1);
}
uartWifi.DisconnectToAP();
至此,完成了整個通信過程,如果用戶對此感興趣,可以聯(lián)系我們。我們將提供驅(qū)動和具體的參考例程等資料。
另外,對于對硬件電路有特殊要求的用戶,可以直接使用物理串口連接獨立的E103模塊,此封裝類及以上編程方法同樣適用,只需要將/dev/ttyUSBx修改成/dev/ttySx即可。
成都英創(chuàng)信息技術(shù)有限公司 028-8618 0660