序:
能力有限,難免有錯,有問題請聯繫我,
QQ1519256298 [email protected]
Pdf下載http://pan.baidu.com/s/1hqiWB56
爲了提高博客的活躍,,如果你需要源代碼,請留下郵箱,,,謝謝大家啊,,不然才兩個評論,讓我情何以堪啊
這個文檔主要講解怎麼使用CC3200把數據傳到Yeelink和怎麼獲取Yeelink上的數據。
關鍵字:Yeelink,TCP,HTTP,Socket,JSON,DNS,STA和AP模式
你可以先百度下上面的關鍵字,對這些最好有一個概念,因爲別人講的比較好。
Yeeklink:作爲一個開放的公共物聯網接入平臺,目的是爲服務所有所有的愛好者和開發者,使傳感器數據的接入、存儲和展現變得輕鬆簡單。
TCP:一般性的建立TCP連接需要兩個參數:IP 和端口。這裏我們使用dns獲取其ip,
HTTP:web瀏覽器使用的就是HTTP協議,這個是建立在tcp的基礎上,本文只是簡單地模仿了HTTP的格式,
Socket:怎麼建立TCP連接,就需要用到socket,這個很像linux的socket。
Json:json是一種數據的傳輸格式,譬如 {"name":阿湯哥,"age":100 } 這個的數據的含義是:名字叫阿湯哥,年齡是100歲,,簡單明瞭的協議。
STA:當CC3200需要連上路由器的wifi的時候就叫STA模式,,當用電腦連上CC3200的wifi就叫AP模式。
yeelink上的各種截圖及結果截圖
直接使用tcp測試工具把數據上傳,
post上傳數據
get,獲取數據
結果:
軟件流程:
首先,CC3200作爲了一個STA,通過路由器的網絡連上因特網,使用DNS獲取Yeelink的ip,Yeelink的端口號是80端口,一般80端口是用作HTTP的,我們模仿HTTP的協議把數據傳到Yeelink上,數據的傳輸格式是JSON格式 。
首先,需要在common找到如下的定義,並根據你的網絡情況進行更改
#define SSID_NAME "需要更改" /* AP SSID */
#define SECURITY_TYPE SL_SEC_TYPE_WPA_WPA2/* 加密類型,一般的都是這個Security type (OPEN or WEP or WPA*/
#define SECURITY_KEY "需要更改" /* Password of the secured AP */
#define SSID_LEN_MAX 32
#define BSSID_LEN_MAX 6
你的yeelink的設備號等相關信息:
//yeelink的設備地址,需要根據你的情況進行更改
#define mainYEELINK_DEVICE_ID 20555
//yeelink的傳感器地址,需要根據你的情況進行更改
#define mainYEELINK_TestNum_ID 38264
//yeelink的key號,需要根據你的情況進行更改
#define mainYEELINK_API_KEY "5d4c9fb6b2ba9386d497e6cf6a2a9f75"
//設備地址,需要根據你的情況進行更改
#define mainYEELINK_TestSwitch_ID 38265
HTTP的數據
//http的post數據格式,不需要更改
char g_cPostData[] = "POST /v1.1/device/%d/sensor/%d/datapoints HTTP\/1.1\r\n"
"Host:api.yeelink.net\r\n"
"Accept: *\/\* \r\n"
"U-ApiKey: %s \r\n"
"Content-Length: %d \r\n"
"Content-Type: application/json;charset=utf-8\r\n"
"Connection: close\r\n"
"\r\n"
"%s";
//http的get數據格式
char g_cGetData[] = "GET /v1.1/device/%d/sensor/%d/datapoints HTTP\/1.1\r\n"
"Host:api.yeelink.net\r\n"
"Accept: *\/\* \r\n"
"U-ApiKey: %s \r\n"
"Content-Length: 0 \r\n"
"Connection: close\r\n"
"\r\n\r\n";
創建任務,在main函數中更改
//
// Create HTTP Server Task
//
lRetVal = osi_TaskCreate(vYeelinkTask, (signed char*)"vYeelinkTask",
OSI_STACK_SIZE, NULL, OOB_TASK_PRIORITY, NULL );
任務:連接上網絡,獲取yeelink的ip,發送post數據和get數據
post數據:就是把你的數據傳輸到yeelink上,可以實現的功能:上傳傳感器的值
get數據:就是把yeelink的數據傳到CC3200,可以實現的功能:遠程遙控家裏的設備
static void vYeelinkTask(void *pvParameters) {
unsigned long ip,temp = 0;
char buffer[20];
UART_PRINT("success:%s %d\r\n",__FUNCTION__,__LINE__);
scNetStaInit();
delay();
while(1) {
ip = lGetYeelinkIp();
if (ip != 0) {
//這個主要就是實現JSON的數據
//{"value":12}\r\n
snprintf(buffer,20,"{\"value\":%d}\r\n",temp++);
//這個主要就是合成HTTP協議
//這個具體可以看g_cPostData
snprintf(g_buffer,300,g_cPostData,mainYEELINK_DEVICE_ID,mainYEELINK_TestNum_ID,mainYEELINK_API_KEY,strlen(buffer),buffer);
UART_PRINT("\r\n Send:\r\n%s\r\n",g_buffer);
//發送數據,參數:數據,,數據長度,ip,端口
vSendOneDataWithIpPort(g_buffer,strlen(g_buffer),ip,mainYEELINK_PORT);
delay();
delay();
snprintf(g_buffer,300,g_cGetData,mainYEELINK_DEVICE_ID,mainYEELINK_TestSwitch_ID,mainYEELINK_API_KEY);
UART_PRINT("\r\n Send:\r\n%s\r\n",g_buffer);
vSendOneDataWithIpPort(g_buffer,strlen(g_buffer),ip,mainYEELINK_PORT);
delay();
delay();
}
delay();
}
}
連接網絡
//設置sta模式並連接到網絡
//返回0 ,連接成功
//返回-1,連接失敗
static signed char scNetStaInit(void) {
SlSecParams_t secParams = {0};
unsigned short len, config_opt;
long lRetVal = -1;
//主要是設置成默認的狀態,這個在httpserver就有了
lRetVal = ConfigureSimpleLinkToDefaultState();
if(lRetVal < 0)
{
if (DEVICE_NOT_IN_STATION_MODE == lRetVal)
UART_PRINT("Failed to configure the device in its default state\n\r");
LOOP_FOREVER();
}
//需要先調用這個
lRetVal = sl_Start(0, 0, 0);
if (lRetVal < 0)
{
UART_PRINT("Failed to start the device \n\r");
LOOP_FOREVER();
}
// staring simplelink
g_uiSimplelinkRole = sl_Start(NULL,NULL,NULL);
// 設置成sta模式
if(g_uiSimplelinkRole != ROLE_STA )
{
//Switch to STA Mode
lRetVal = sl_WlanSetMode(ROLE_STA);
ASSERT_ON_ERROR(lRetVal);
lRetVal = sl_Stop(SL_STOP_TIMEOUT);
g_usMCNetworkUstate = 0;
g_uiSimplelinkRole = sl_Start(NULL,NULL,NULL);
}
//密碼
secParams.Key = (signed char*)SECURITY_KEY;
//密碼長度
secParams.KeyLen = strlen(SECURITY_KEY);
//加密類型
secParams.Type = SECURITY_TYPE;
//進行連接,參數有 SSID ,密碼
lRetVal = sl_WlanConnect((signed char*)SSID_NAME, strlen(SSID_NAME), 0, &secParams, 0);
ASSERT_ON_ERROR(lRetVal);
//判斷有沒有連接成功。其實就是判斷g_ulStatus響應的位有沒有設置成功
//g_ulStatus的值在SimpleLinkWlanEventHandler這個函數內被更改
//SimpleLinkWlanEventHandler是一個回調函數,主要的就是作用就是
//當CC3200連上網絡或者斷開網絡的時候會被調用
while((!IS_CONNECTED(g_ulStatus)) || (!IS_IP_ACQUIRED(g_ulStatus)))
{
//進行循環,等待成功
}
return 0;
}
獲取yeelink網址對應的ip地址,使用的是dns服務
//獲取yeelink網址對應的ip地址
unsigned long lGetYeelinkIp(void) {
unsigned long ip;
signed int retval;
retval = Network_IF_GetHostIP(mainYEELINK_SITE,&ip);
if (retval < 0) {
return 0;
} else {
return ip;
}
}
//這個函數是我從nerwork_if文件拷貝出來的.不能直接包含那個文件
//因爲會引起重複定義的錯誤。所以你直接
long Network_IF_GetHostIP( char* pcHostName,unsigned long * pDestinationIP )
{
long lStatus = 0;
//利用這個函數就可以把www。yeelink。net轉成IP,,
//當然你也可以不用這個函數,,直接把IP規定住,
//怎麼手動查www。yeelink。net: win系統下,ping一下這個www。yeelink。net網址就會出現ip信息
lStatus = sl_NetAppDnsGetHostByName((signed char *) pcHostName,
strlen(pcHostName),
pDestinationIP, SL_AF_INET);
ASSERT_ON_ERROR(lStatus);
UART_PRINT("Get Host IP succeeded.\n\rHost: %s IP: %d.%d.%d.%d \n\r\n\r",
pcHostName, SL_IPV4_BYTE(*pDestinationIP,3),
SL_IPV4_BYTE(*pDestinationIP,2),
SL_IPV4_BYTE(*pDestinationIP,1),
SL_IPV4_BYTE(*pDestinationIP,0));
return lStatus;
}
發送數據
char g_buffer[300];
//發送數據給指定的ip和端口號,只有一次
//執行過程
//1、新建連接
//2、發送數據、
//3、斷開連接
void vSendOneDataWithIpPort(unsigned char *data,unsigned long len,unsigned long ip,unsigned long port) {
SlSockAddrIn_t sAddr;
int iAddrSize;
int iSockID;
int iStatus;
int count = 0,size;
//filling the TCP server socket address
//使用的是socket
//這個我忘了,基本是固定不變
sAddr.sin_family = SL_AF_INET;
//端口信息,
sAddr.sin_port = sl_Htons((unsigned short)port);
//ip信息
sAddr.sin_addr.s_addr = sl_Htonl((unsigned int)ip);
iAddrSize = sizeof(SlSockAddrIn_t);
// creating a TCP socket
//創建一個tcp連接
iSockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);
if( iSockID < 0 )
{
UART_PRINT("Error:%s %d\r\n",__FUNCTION__,__LINE__);
}
// connecting to TCP server
//連接到tcp的服務器,參數:socket的句柄,目的地址信息
iStatus = sl_Connect(iSockID, ( SlSockAddr_t *)&sAddr, iAddrSize);
if( iStatus < 0 )
{
// error
iStatus = sl_Close(iSockID);
if (iStatus < 0)
UART_PRINT("Error:%s %d\r\n",__FUNCTION__,__LINE__);
}
//連接完成最好不要直接就發送數據,經我的測試是,馬上發送數據可能會成功,但是數據卻沒有傳過去
delay();
//發送數據,參數:socket的句柄,數據指針,數據長度,最後一個參數沒有作用
iStatus = sl_Send(iSockID, data, len, 0 );
if( iStatus <= 0 )
{
// error
iStatus = sl_Close(iSockID);
if (iStatus < 0)
UART_PRINT("Error:%s %d\r\n",__FUNCTION__,__LINE__);
}
//接收數據。,參數:sockeet的句柄,緩衝區,緩衝器大小,返回的是接收的數據大小
//請注意這個函數可能是阻塞的
//阻塞的意思就是,會一直等到有數據才返回,或者有問題才返回
size = sl_Recv(iSockID,g_buffer,300,0);
transHeader = (SlTransceiverRxOverHead_t *)g_buffer;
g_buffer[size] = 0;
UART_PRINT("\r\nReceive:\r\n%s\r\n",g_buffer);
//關閉連接
iStatus = sl_Close(iSockID);
if (iStatus < 0)
UART_PRINT("Error:%s %d\r\n",__FUNCTION__,__LINE__);
}
到這裏基本上所有的代碼都已經上傳完畢,,