学习了前两章之后,本章只要把前两章的内容结合起来,然后编写后台处理温度数据就好了。
在这里,我们需要编写两个路由,一个路由用于处理显示温度,另一个处理更新温度,代码如下:
package main
import (
"github.com/gin-gonic/gin"
"fmt"
)
var (
temp string = "0.0"
)
func main() {
r := gin.Default()
//显示温度
r.GET("/", func(c *gin.Context) {
c.String(200, fmt.Sprintf("The Temperature is: %s ℃", temp))
})
//更新温度
r.GET("/update", func(c *gin.Context) {
temp = c.DefaultQuery("temp", "0.0")
c.String(200, "okay")
})
r.Run(":8000")
}
下面我们运行测试一下,更新一下温度,并查看温度,可以看到温度变成我们更新的温度了。
下面,我们将7.2节的程序改一改,在sendHttpGet方法里添加获取DS18B20传感器温度代码。
#include <EtherCard.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// 将DS18B20的数据口连接到2号引脚
#define ONE_WIRE_BUS 2
// 初始连接在单总线上的单总线设备
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static uint8_t server_ip[] = { 192, 168, 1, 105 };
byte Ethernet::buffer[700];
static byte session;
static uint32_t timer;
char path[100];
static void sendHttpGet () {
Serial.println("Sending HttpGet...");
sensors.requestTemperatures(); // 获取温度
int temp = sensors.getTempCByIndex(0) * 100; //方便转换
char temp_str[100];
sprintf(temp_str, "temp is: %d.%d", temp/100, temp%100); //arduino里面没法用%f
Serial.println(temp_str); //打印温度
Stash::prepare(PSTR("GET /update?temp=$D.$D HTTP/1.0" "\r\n"
"Host:" "\r\n"
"\r\n"), temp/100, temp%100);
session = ether.tcpSend();
Serial.println("finished");
}
void setup () {
Serial.println("Web DS18B20 Demo");
Serial.begin(9600);
sensors.begin();// 加载DS18B20库
if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0)
Serial.println("Failed to access Ethernet controller");
else
Serial.println("Ethernet controller initialized");
if (!ether.dhcpSetup())
Serial.println("DHCP failed");
else
Serial.println("DHCP succeeded");
ether.printIp("IP: ", ether.myip);
//设置服务器ip和端口号
ether.copyIp(ether.hisip, server_ip);
ether.hisport = 8000;
}
void loop () {
if (millis() > timer) { // 每隔10秒发一次请求
timer = millis() + 10000;
//发送请求
sendHttpGet();
}
//接受数据包
ether.packetLoop(ether.packetReceive());
const char* reply = ether.tcpReply(session);
if (reply != 0) {
Serial.println("Got a response!");
Serial.println(reply);
Serial.println();
}
}
可以看到,得到了"okay"的正确返回。同时,查看浏览器,看看温度是否正确。
到这里,我们的应用就做好了,现在我们可以把代码上传到服务器上,看看能不能更新和获取温度了。
当然如果你对后端熟悉,你可以将温度的数据存储在数据库里;如果你对前端很熟悉,可以把温度绘制成曲线显示在网页上,以下是笔者使用前端的echarts绘图库实现的一个简单的温度曲线绘制,读者感兴趣的话可以进行尝试。(代码放在了本章的server2文件夹里面)
到这里,我们网络案例部分就结束了,我们在这章成功利用以太网模块,使用Http协议将数据传输到远端的web服务器,下面我从协议以及模块上对物联网做一下总结与补充。
一般情况下,物联网设备的资源都是受到限制的,我们在把温度发送到服务器的时候,可以发现请求的信息的头以及返回的信息头都占据了很大的一部分,这使得我们的流量和资源在很大程度上的浪费掉了。在实际中,有些专门为物联网传输设计的通信协议,如COAP、MQTT等等,如果读者感兴趣的话,可以继续深入研究。
另外,在模块选择上,以太网模块即插即用,适合家庭应用,配置简单,所以笔者选它来作为讲解的材料,不过缺点就是要接根网线。还有WiFi模块,如ESP8266模块,可以让Arduino无线连接路由器上网,不过WiFi如果在调试的时候还可以把WiFi名称和WiFi密码写死,如果真正用的时候,就需要通过某种方式对它进行配置,然后连接路由器,比较麻烦,所以笔者这里也没有选择WiFi作为学习的素材。另外,笔者还使用过GSM模块,它使用2G网络,没有地点的限制,也不需要进行配置,只要插一张有网费的中国移动手机卡(中国电信好像也可以,中国联通不行)就行,缺点也有,应该就是价格比较高,还有功耗比较大。
- 目录
- 上一节:ENC28J60模块的使用
- 下一节:其它案例