一起學習CC3200系列教程之Yeelink傳數據

序:

能力有限,難免有錯,有問題請聯繫我,

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";



我是直接使用官方的httpserver的例程進行更改的,設置是:使用freertos系統

創建任務,在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__);

}

到這裏基本上所有的代碼都已經上傳完畢,,


















發佈了44 篇原創文章 · 獲贊 13 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章