获取传感器数据并传入数据库-HTTP/POST/ASP.NET
很久前,做过传感器数据采集相关的小项目,需求是通过单片机IO收集传感器数据,然后通过网络模块(GSM/WI-FI)作为客户端,将数据(JSON)通过TCP/IP协议上传至服务器TCP端口。同时,服务器上运行监听程序,解析JSON随后转存到数据库。
这种模式在实际应用中的效果并不理想,当时遇到的问题有:
Client/Server之间建立连接需要较长时间。 需要维持心跳,如果使用GSM模块会产生较多数据流量。 Server需要监听/解析/转存TCP端口数据的程序,如果数据量较大,稳定性未知。
最近想到用HTTP POST请求,将传感器获取的数据直接POST到Web服务器后,通过后台服务处理存储到数据库,且现在部分项目获取传感器数据后有通过Web方式展现(数据可视化)的需求,编码简单,逻辑清晰。
Web服务端(ASP. NET)
建立ASP.NET空网站,目标框架 .NET Framework4.0,添加一个Web服务。
这里的WebService.asmx作为之后的请求接口
using System;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
///
/// WebService 的摘要说明
///
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。
// [System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService
{
SqlConnection con;//创建连接对象
SqlCommand sc;
public WebService()
{
//如果使用设计的组件,请取消注释以下行
//InitializeComponent();
}
#region 接口测试
[WebMethod]
public void test(string data)
{
string strsql = ConfigurationManager.ConnectionStrings["sqlserverconfig"].ToString();//读取webconfig数据库连接字符串
con = new SqlConnection(strsql);
//添加一条数据记录
string sql = "insert into SensorData (ID,DeviceID,Data,AddTime) Values (1,1,'" + data + "','" + DateTime.Now.ToString() + "')";
try
{
con.Open();//打开连接对象
sc = new SqlCommand(sql, con);//执行SQL
int i= sc.ExecuteNonQuery();//影响的记录条数
con.Close();//关闭对象
}
catch (Exception ex)
{
ex.ToString();
con.Close();
}
}
#endregion
}
对Web.config加入跨域请求说明和允许远程调试说明
此时我们调试WebService.asmx中的test,测试调用。
此时,对应表中会看到新增加的测试记录,至此Web服务器端已经完毕,接下来将其部署到IIS,并运行WebService.asmx。
Arduino+Wi-Fi(ESP8266)HTTP协议发送POST请求
硬件准备:
Arduino UNO ESP 8266 可选的数字传感器(如温湿度、电压电流计) Arduino ESP-8266 3.3V 3.3V GND GND 12 RX 13 TX
#include
SoftwareSerial mySerial(13, 12); // RX, TX
//--------------参数设置 START-------------
String Host="192.168.31.32";//域名或IP
String Port="80";//IIS端口,默认80
String URL="/DataSender/WebService.asmx/test";//接口地址
String Data="data=8888";//请求参数,前半部分必须与WebService.asmx中test方法参数名对应(String data)
String WiFi_SSID="BS-112-Lab";
String WiFi_PSW="i-am-wifi-psw";
//--------------参数设置 END---------------
void setup() {
Serial.begin(57600);//本地调试串口
while (!Serial) {//等待连接
}
mySerial.begin(57600);//软串口
initWifi();//初始化Wi-Fi SSID/PSW
setHttpServer();//设置发送模式
}
void loop() {
if (mySerial.available()) {
Serial.write(mySerial.read());//数据回显
}
if (Serial.available()) {
mySerial.write(Serial.read());
}
postToServer(Data);
}
void Response(){//接受服务器的响应并显示在本地串口
delay(50);
while (mySerial.available()) {
Serial.write(mySerial.read());
}
Serial.write("\n");
}
void initWifi(){
mySerial.println("AT+RST"); // 重启模块
delay(1000);
Response();
mySerial.println("AT");//测试通信,返回OK
Response();
delay(1000);
mySerial.println("AT+CWMODE=3"); // 设置ESP8266模块处于AP兼Station模式
Response();
mySerial.println("AT+CWJAP=\""+WiFi_SSID+"\",\""+WiFi_PSW+"\""); // 连接Wi-Fi
Response();
delay(10000);
}
void setHttpServer(){
mySerial.println("AT+CIPMODE=1");
mySerial.println("AT+CIPSTART=\"TCP\",\""+Host+"\","+Port+""); // 连接服务器的80端口
delay(1000);
Response();
mySerial.println("AT+CIPSEND"); // 进入TCP透传模式,接下来发送的所有消息都会发送给服务器
}
void postToServer(String paras){
//组装HTTP报头
String httpContent="POST "+URL+" HTTP/1.1\r\nHost: "+Host+"\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length:"+paras.length()+"\r\n\r\n"+paras;
Serial.print("==============\nPost Data: "+paras+"\n");
mySerial.print(httpContent); //POST
delay(2000);//POST请求频率,建议2s,小于这个时间建议调高波特率。
Response();
}
烧录代码至Arduino,打开串口监视器即可看到数据发送状态、POST报文和服务器响应。
根据AddTime字段的情况来看,POST的频率可以到每秒两条,效果还是非常理想的。
代码量统计
Arduino: 70行 WebService.asmx:50行
不足150行便实现了传感器数据上传到数据库的流程,可见这种方法短小精悍。