Yeelink平台使用——远程控制 RT Thread + LwIP+ STM32

原创 2013年12月03日 20:43:08

1.前言

    【2014年4月重写该博文】
    经过若干时间的努力终于搞定了STM32+LwIP和yeelink平台的数据互通,在学习的过程中大部分时间花在以太网协议栈学习上,但是在RT Thread的帮助下却很快实现了yeelink平台的应用。
    【选择STM32理由】
    1.常用的32位MCU,Cortex-M3内核,运算速度快,RAM和FLASH容量较大。
    2.价格便宜,很容易买到。
    【选择RT-Thread理由】
    1.RT-Thread具有丰富的组件包括LwIP,省去了移植网络协议栈的困扰。
    【网卡芯片ENC28J60】
    1.SPI接口,占用较少的GPIO,适合引脚数较少的MCU。
    2.价格便宜,容易买到。

2.有用的资料

    【代码仓库
    代码仓库位于CSDN Code,方便交流。请不要使用任何版本的IE浏览器打开代码仓库,请使用谷歌或者火狐浏览器,如果使用国产双核浏览器,请切换至极速模式。在博客和代码仓库留言中我经常发现无法下载代码的情况,我再windows和ubuntu中反复实验始终没有问题,后来才才发现我除了买火车票之外从来不用IE浏览器,而很多网友使用了低版本的IE浏览器,低版本的IE浏览器正是问题所在。
    【相关博文】
    【Yeelink Http请求格式分析
    【Yeelink平台查询开关量——套接字编程 Windows平台】——如果还不熟悉RT-Thread或者socket的话,试试这个吧。
    【平台说明】
    RT-Thread版本1.2.0
    编译器版本:IAR EWARM 6.5
    【操作说明】
    【1.1请务必修改Http请求内容——见tcpclient_yeelink.c,包括设备编号,传感器编号和用户API
    【1.2请详细核对ENC28J60相关接口,包括SPI接口,中断接口,相关时钟等。请认真修改enc28j60.c和stm32f10x_it.c中相关函数。如果SPI总线上还有其他设备,请务必确认该从设备CS端口存在上拉电阻或把与CS端口连接的GPIO端口配置为输出高电平。
    【1.3】由于ENC28J60无法自动识别交叉线和非交叉线,请把目标板连接路由器
    【1.4】如果您还是学生,并且您所在的高校需要通过网页拨号上网,你可能无法成功运行以下代码。我只能说一声抱歉了。

    【2】请务必修改目标板IP地址(路由器地址和子网掩码),默认的IP地址为192.168.1.30——见rtconfig.h,目标板并没有打开DHCP。
#define RT_LWIP_IPADDR0192
#define RT_LWIP_IPADDR1168
#define RT_LWIP_IPADDR2
#define RT_LWIP_IPADDR3 30
    【3】请先查看目标板IP地址,建议使用putty。待目标板启动之后按下tab键,可查看目标板支持的指令。之后输入list_ip()——查看目标板IP地址相关信息,等同于windows中的ipconfig和linux中的ifconfig。


图1 按下TAB键

图2 查看IP地址
【4】输入httpclient() 执行HTTP请求。仅执行一次HTTP请求。

图3 HTTP请求结果
【5】代码以CSDN代码仓库为准

3.参考代码

#include <rtthread.h>
#include <lwip/netdb.h>
#include <lwip/sockets.h>
#include <led.h>
// Http请求内容
static const char send_data[] =
"GET /v1.0/device/1949/sensor/2511/datapoints HTTP/1.1\r\n"
"U-ApiKey:[your apikey]\r\n"
"Host: api.yeelink.net\r\n\r\n";
void tcpclient(const char* host_name, int port)
{
    (void)port;
   
    char *recv_data;
    int sock, bytes_received;
   
    struct hostent *yeelink_host;
    struct in_addr yeelink_ipaddr;
    struct sockaddr_in yeelink_sockaddr;
   
    recv_data = rt_malloc(1024);
    if (recv_data == RT_NULL)
    {
        rt_kprintf("No memory\r\n");
        return;
    }
    // 第一步 DNS地址解析
    rt_kprintf("calling gethostbyname with: %s\r\n", host_name);
    yeelink_host = gethostbyname(host_name);
    yeelink_ipaddr.s_addr = *(unsigned long *) yeelink_host->h_addr_list[0];
    rt_kprintf("Yeelink IP Address:%s\r\n" , inet_ntoa(yeelink_ipaddr));
   
   
    yeelink_sockaddr.sin_family = AF_INET;
    yeelink_sockaddr.sin_port = htons(80);
    yeelink_sockaddr.sin_addr = yeelink_ipaddr;
    rt_memset(&(yeelink_sockaddr.sin_zero), 0, sizeof(yeelink_sockaddr.sin_zero));
   
    while(1)
    {
        // 第二步 创建套接字
        if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
            rt_kprintf("Socket error\n");
            rt_free(recv_data);
            return;
        }
       
        // 第三步 连接yeelink
        if (connect(sock, (struct sockaddr *)&yeelink_sockaddr, sizeof(struct sockaddr)) == -1)
        {
            rt_kprintf("Connect fail!\n");
            lwip_close(sock);
            rt_free(recv_data);
            return;
        }
       
        // 第4步 发送Http请求
        send(sock,send_data,strlen(send_data), 0);
       
        // 第5步 获得Http响应
        bytes_received = recv(sock, recv_data, 1024 - 1, 0);
        recv_data[bytes_received] = '\0';
       
        // 响应内容为 {"timestamp":"2013-11-19T08:50:11","value":1}
        // 截取“value”之后的内容
        char* actuator_info = rt_strstr( recv_data , "\"value\"");
        int offset = rt_strlen("\"value\":");
        actuator_status = *(actuator_info + offset);
        rt_kprintf("actuator status :%c\r\n",actuator_status);
       
        // 获得开关状态,并设置LED指示灯
        char actuator_status;
        (actuator_status == '1')?rt_hw_led_on(0):rt_hw_led_off(0);
       
        rt_memset(recv_data , 0 , sizeof(recv_data));
       
        // 关闭套接字
        closesocket(sock);
       
        // 延时5S之后重新连接
        rt_thread_delay( RT_TICK_PER_SECOND * 5 );
    }
}

4.总结

    千辛万苦尝试LwIP+Yeelink,但是最终实现起来却非常简单。接下来可以尝试使用Yeelink做一些具体的应用,初步想法做一个智能鱼缸,希望前面的道路可以顺利一些。



相关文章推荐

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

lwip1.4.0之http server实现及POST 实现

lwip1.4.0之http server实现及POST 实现   一、HTTP SERVER的实现  lwip默认的http server 在 apps/httpserver_raw 主要核心...
  • pugu12
  • pugu12
  • 2014年12月15日 14:45
  • 948

LwIP用TCP连接方式在数据量比较大协议栈卡死

这段时间用STM32移植LwIP做语音传输。但是遇到一个问题移植困扰许久,在使用TCP方式做一个client去连接server,由于数据量比较大经常在连接一个多小时候就出现断线而且也ping不通。接下...

RT-Thread LwIP的使用

主要讲解LwIP在OS中的使用流程。

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

RT-thread移植(基于STM32F4xx)

1、将下载的rt-thread-2.0.1解压后,得到如下图所示的文件列表。 在bsp目录下可以找到stm32f40x文件夹,这文件夹里面包括了库函数,其他芯片平台的文件夹统统删掉。在l...

WebSocket学习笔记——无痛入门

本人一直专注于IoT领域,前些时间尝试了REST API使用PHP Slim框架构建应用。传感器数据的上传可以高效的实现,可以定时上传传感器检测结果,而这些检测结果每条都是有用的。若需要实现相关控制功...

嵌入式WebSocket的实现

系统硬件采用STM32+DM9000AEP,具体实现步骤如下,   第一步建立TCP监听端口可以随意,等待浏览器发出http请求。   Chrome浏览器发出的请求 第二步建立握手 ...
  • dddxxxx
  • dddxxxx
  • 2017年08月10日 23:07
  • 339

TCP/IP, WebSocket 和 MQTT

转自:http://www.cnblogs.com/shanyou/p/4085802.html 按照OSI网络分层模型,IP是网络层协议,TCP是传输层协议,而HTTP和MQTT是应用层的...

mqtt服务器搭建成功,微信端可以通过websocket访问,计算机可以访问,安卓可以访问,stm32嵌入式可以访问,一个完整的物联网系统!

mqtt服务器搭建成功,微信端可以通过websocket访问,计算机可以访问,安卓可以访问,stm32嵌入式可以访问,一个完整的物联网系统!...
  • usbfans
  • usbfans
  • 2017年06月04日 01:30
  • 534
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Yeelink平台使用——远程控制 RT Thread + LwIP+ STM32
举报原因:
原因补充:

(最多只允许输入30个字)