序:
能力有限,难免有错,有问题请联系我,
QQ1519256298 hytga@163.com
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__); }
到这里基本上所有的代码都已经上传完毕,,