第32课 ENC28J60联网 读取服务器信息

我是潘,曾经是个工程师。这是为 Ardui.Co 制作的 “Arduino 公开课” 系列的入门教程。上一节课,我们已成功让 Arduino 连接到网络,现在要让 Arduino 做的第一件事情:访问网络,并读取服务器上的信息。有任何疑问请在评论区提出,我会逐一回答。

IoT 中,指令一般由中枢(服务器)向节点发送,但在一些特殊环境中,比如,节点没有固定的IP地址(尤其在内陆,DDNS 动态域名服务非常不稳定,从互联网访问家庭宽带IP很难实现)。换种思维,让 Arduino 主动去抓取服务器上的指令,或者其他信息?这很容易实现,与家里的电脑访问web一样,让 Arduino 访问服务器即可。

下面是访问 ardui.co 的完整程序:

我们要用到 IDE 内置的 AVR库(后面的课程介绍) “pgmspace.h”,以启用”虚拟内存“功能,节省SRAM。变量 website[],用到 ”PROGMEM“,作用就是将变量信息存储在 FLASH,使用时再调用。FLASH 速度比 SRAM 慢,此方法会影响运行速度。

不过,谁叫 UNO 只有 2KB SRAM 呢?在资源消耗极高的程序中,必须精打细算:》如果是 Arduino Mege 2560,SRAM 容量大很多,且可以扩展,但是后话了。

第二个要点是,确认目标服务器的地址,比如 “ ardui.co ”。这个地址通过 DNS 服务器转换为真实的 IP。上节课使用了静态设置 staticSetup()  或者 dhcpSetup()  两种方式来设置 Arduino 的 IP、DNS 等信息,现在通过 dnsLookup() 方法来检查 DNS 服务器是否正常:

确认连接到 DNS 服务器后,就可以开始 Web 之旅了。

EtherCard 提供了一个便捷的方法 browseUrl() 访问服务器,其数据结构如下:

看起来很复杂,第1个、第2个形参(urlbuf、urlbuf_varpart)分别是地址固定部分,后者变量;第3个形参 hoststr 很好理解,即网址;第4个形参 callback,为回调函数名称,当连接结束时调用的函数。举个例子:

PSTR() 属于AVR 编程的知识,简单理解为,将地址固定的部分存储在 FLASH 中,以达到节省 Arduino 内存(SRAM)的目的。“test.php” 为我们要访问的文件,可以是html,也可以是txt,只要编码一致,后缀不限。“website” 即我们的网址 “ardui.co” 。难点在于其中的回调函数 :“response_callback” 。

先复习一下,上节课用到的缓冲区声明:

该声明的作用为设置缓冲区的大小,这个缓冲区用于储存外来数据包,当调用 browseUrl() 方法后,服务器反馈的数据包都在里面。这里设计的回调函数 response_callback() 作用是读取缓冲区的信息:

通过这个函数,串口会打印出缓冲区里面所有的信息:

红色框框是头文件信息,网站的服务器、缓存控制、编码等基本信息会呈现在这里,紧接着才是网页的内容。头文件信息没有太大用处,需要过滤掉。这里不需要特别的方法或者函数。利用 C 语言的指针,指向头文件结束的位置即可:

数值 “265” 是头文件的大小,将头文件拷贝到文本编辑器,就可以查到:

这是一个指针,指向缓存开始加上265个byte的位置。

所有知识难点都已经介绍完了,要注意的是:

响应函数必须保留,否则程序是不工作的。另外,millis() > timer 的设计是为了延时,如果不需要频繁抓取,可以增加 timer。

上面并非整个网页的内容,而是缓冲区(Ethernet::buffer)所有的信息,一开始设置为 700 bytes,(尝试设置为1000 bytes 呢?)。另外,由于 Arduino 与中文网站的编码不一致,因此显示乱码。

 

Leave a Reply

Your email address will not be published. Required fields are marked *