1 天气数据收集和存储程序开源分享-德赢Vwin官网 网
×

天气数据收集和存储程序开源分享

消耗积分:0 | 格式:zip | 大小:0.03 MB | 2023-02-09

20153

分享资料个

描述

该项目是一个相当简单的天气数据收集和存储程序。

天气数据由 Arduino 记录,并通过向网络服务器发送特制的 GET 请求每 10 分钟发送到数据库。

或者,您也可以将输出发送到 20x4 LCD。

先决条件:

您必须已经配置了 Web 服务器、数据库和服务器端脚本语言,它们可以处理 HTTP GET 请求的查询字符串中的名称/值对。如果您使用的是 Windows,在典型的 LAMP/WAMP/WIMP 堆栈上启动和运行非常容易,但让所有这些一起工作超出了本文的范围。

在我的例子中,我已经配置了一台 Windows 7 机器来运行一个标准的 WIMP 堆栈——

  • Windows 7 上的 Microsoft IIS 7.5
  • PHP 7.1.24 - windows.php.net/download/
  • MySQL 社区 8.0.13 - dev.mysql.com/downloads
  • 我还使用 PHPMyAdmin 的副本来帮助进行数据库配置 - phpmyadmin.net/
  • 必须启用 mysqli PHP 扩展

重要的提示:

这个项目完全忽略了任何表面上的安全(不要按原样将它放在 Internet 上,但它对您的 LAN 没问题)并且我的数据库优化可能需要一些工作。

概述:

本文的重点是将数据从传感器中获取到我们的数据库中,然后提取该数据并以某种方式显示它,让我们知道接下来会发生什么。

从现在开始,本文假设您有一个可用的 Web 服务器、PHP 和 MySQL。

数据库配置:

对于这个项目,我创建了一个名为 weatherdata 的数据库,并在该数据库中创建了一个名为 master 的表。

除了每个数据库条目的唯一标识符之外,我们还想记录 4 件事:

  • 时间;
  • 温度
  • 气压
  • 湿度

所以我们需要 5 个我命名如下的字段:

  • 流体;
  • 时间戳
  • 温度
  • 压力
  • 湿度

这是 phpMyAdmin 的样子:

 
pYYBAGPjQgGADkRWAACmUhfINtk350.png
表格字段设置
 

使用 phpMyAdmin 创建数据库 weatherdata。跳过从界面创建表并在 MySQL 命令行客户端中使用下面的脚本来创建表和字段:

CREATE TABLE master 
( 
    uid INT(11) NOT NULL AUTO_INCREMENT,  
    timestamp DATETIME NOT NULL,  
    temperature DOUBLE(8,4) NOT NULL,  
    pressure DOUBLE(8,4) NOT NULL,  
    humidity DOUBLE(8,4) NOT NULL,  
    PRIMARY KEY (uid)
);

测试注意事项:

您可以通过在浏览器的地址栏中手动输入 WEBSERVER_IP_ADDRESS/processincoming.php?t=9.30&p=98.80&h=75.70 并按回车键来测试设置(如果需要,可以更改值)。如果服务器正确处理它,您将看到这些值记录在数据库中并且它工作正常。如果它不起作用,则某处存在配置或设置错误。

服务器端处理

数据库输入是通过 Arduino 每 10 分钟向 Web 服务器发送一次 GET 请求来完成的,请求的查询字符串中包含温度、压力和湿度值。

在 Arduino 代码中,构建并发送 URL 字符串:

urlString = "GET /processincoming.php?t=" + temperatureToDB + "&p=" + 
    pressureToDB + "&h=" +  humidityToDB + " HTTP/1.1"; 
sendDataToServer(urlString);

sendDataToServer() 函数接受完整的字符串并将其发送到局域网中位于 192.168.1.35 的 Web 服务器:

void sendDataToServer(String stringToSend) {    
    //make sure i'm sending what I think I'm sending    
    Serial.println(stringToSend);      
    if (client.connect(server, 80))      
    {         
        client.println(stringToSend);         
        client.println("Host: 192.168.1.35");         
        client.println("Connection: close");         
        client.println();     
    }         
        else     
    {        
        Serial.println("connection failed");     
    }
} 

我们发送的完整请求如下所示:

GET /processincoming.php?t=9.30&p=98.80&h=75.70 HTTP/1.1

应该很明显,但 t = 温度值,p = 压力值和 h = 湿度值

我在这里要注意的一件事是,此页面请求不会产生通常会发送到浏览器的任何输出(除了默认响应标头之外)。一旦 Arduino 发送数据,它就完成了直到下一个周期并且不需要解析响应,甚至不需要等待响应。

提示:为您的网络服务器提供 LAN 上的静态 IP 地址。如果您依赖 DHCP,您可能会发现自己在修改 Arduino 代码以说明每次服务器重新启动时主机 IP 都会发生变化。

此处包含的代码 (WeatherStation_v1_webclient_no_lcd.ino) 编译为 1304 字节,因此适用于较小的设备。

显示数据:

文件 weather.php 负责显示我们的天气数据。显示页面是由脚本生成的简单 HTML 表格,不需要除 mysqli 之外的任何其他 PHP 扩展。

默认情况下,此页面显示长达 3 小时的数据,因此我们的 Arduino 应该至少运行了那么长时间才能记录足够的数据量。如果您尝试在没有足够数据点的情况下运行它,您将收到数组错误。

收集数据至少 3 小时后,输出 HTML 应如下所示:

 
pYYBAGPjQgWAcWtvAAJnY3OMQGU841.png
在 iPhone 上显示 weather.php
 

最后,随附的原理图附有 LCD 输出 - 可以忽略。

备选方案

在这种情况下,不要忽视 LCD,您将需要它。我还包括第二个 Arduino 程序,它结合了上述内容并输出到 20x4 LCD。

可以在此处找到 LCD 组件的完整描述:https ://create.arduino.cc/projecthub/ragingradish/improved-weatherstation-20x4-18dd89

程序的 LCD 部分已更新,以确认以太网已启动并正在运行,但其他方面没有变化。

为了将数据发送到服务器,添加并初始化了适当的库,然后将条件插入到循环中:

//send data to server every 10 minutes  
if ((mainLoop == 0) || (mainLoop % 10 == 0))  
{    
    temperatureToDB = currentTemp;    
    pressureToDB = currentPressure;    
    humidityToDB = currentHumid;    
    urlString = "GET /processincoming.php?t=" + temperatureToDB + "&p=" +
       pressureToDB + "&h=" +  humidityToDB + " HTTP/1.1";    
    sendDataToServer(urlString);  
}

运行 LCD 版本的代码是 WeatherStation_20x4_v1_webclient.ino 并编译为 2090 字节。你需要一个有足够内存的设备来运行它。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"//www.hzfubeitong.com/m/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="https://m.elecfans.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'天气数据收集和存储程序开源分享',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.hzfubeitong.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);