温度远程监测系统-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2427|回复: 6

[分享] 温度远程监测系统

[复制链接]
发表于 2020-5-10 12:26 | 显示全部楼层 |阅读模式
本帖最后由 yun8023ying 于 2020-5-13 11:04 编辑

首先感谢blinker平台!!!
最初的想法是把数据存在sd卡中,制作一个网页获取sd卡内的数据,以折线图展示出来。后来卡在了网页获取数据这块,偶然发现 奈何大大 的 blinker教程,实现起来真的是简单方便啊!!!
材料:
esp 8266
10k电阻
10k ntc 热敏电阻B值3950

软件:
Arduino ide

全部程序分为4个部分
1、blinker 平台接入
2、手机app对接
3、ntc温度获取
4、数据平滑处理5、超温/低温微信报警
6、温度与加热制冷联动
7、其他小功能

1、blinker 平台接入:
有老师傅详解,我就不多说了
原始网页:https://www.arduino.cn/thread-83174-1-1.html  

看完上面的网页,
你的手机上应该下载好app,并获取到中获取到的Secret Key
你的 Arduino ide应该可以选择 esp8266了。


2、基础代码示例

原始网页在这:https://diandeng.tech/doc/getting-start-arduino

[mw_shl_code=arduino,true]#define BLINKER_WIFI

#include <Blinker.h>

char auth[] = "刚才手机上的那串 Secret Key";
char ssid[] = "你家无线名";
char pswd[] = "无线密码";

// 新建组件对象
BlinkerButton Button1("btn-abc");
BlinkerNumber Number1("num-abc");

int counter = 0;

// 按下按键即会执行该函数
void button1_callback(const String & state) {
    BLINKER_LOG("get button state: ", state);
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

// 如果未绑定的组件被触发,则会执行其中内容
void dataRead(const String & data)
{
    BLINKER_LOG("Blinker readString: ", data);
    counter++;
    Number1.print(counter);
}

void setup() {
    // 初始化串口
    Serial.begin(115200);

    BLINKER_DEBUG.stream(Serial);

    // 初始化有LED的IO
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);
    // 初始化blinker
    Blinker.begin(auth, ssid, pswd);
    Blinker.attachData(dataRead);
    Button1.attach(button1_callback);
}

void loop() {
    Blinker.run();
}[/mw_shl_code]

先复制进去点一下编译,不报错再来下一步


微信图片_20200505184959.jpg
 楼主| 发表于 2020-5-10 12:46 | 显示全部楼层
本帖最后由 yun8023ying 于 2020-5-26 14:59 编辑

ntc 温度获取
[mw_shl_code=arduino,true]
int B =3950;            //  为NTC型热敏电阻B值
float Rt,V1,V2,X ;      //为测量温度下热敏电阻的阻值  单位为Ω
float R1 = 10000.00 ;   //为热敏电阻标称温度下的阻值  单位为Ω
float R2 = 9600.00;     //分压电阻
float V = 4.90;         //电压
float C;                //温度值

  X = analogRead(A0);// 读取传感器值
   V1 = X/1024*V  ;      //电压
   Rt = V1/(V-V1)*R2 ;    // 上拉  用这个公式
    // Rt = (V-V1)/V1*R2 ;    // 下拉用这个公式
   C = 1/(1/(298.15) + log(Rt/R1)/B) -273.15; //计算当前的温度值[/mw_shl_code]

C = 1/(1/(298.15) + log(Rt/R1)/B) -273.15
这个公式参考了网上前辈的帖子,十分准确和查表的结果基本一致

关于电阻的接法:
730e0cf3d7ca7bcb50542fa6b5096b63f624a808.png 这里有一个小问题,没弄明白。
资料上说8226的模拟输入只支持1v输入,当vcc接3.3,R1、R2都是10k的时候这里电压是1.65v,应该超量程了显示1024才对,实际上并没有。是我理解不对么?



数据平滑处理
由于供电,探头质量等等原因,得出的温度数值会有抖动,幅度在1.5度以内。
下面我们做一下求平均数
20个值相加除以20
这样就稳定啦

[mw_shl_code=arduino,true]const int num = 20;     // 平均的总数
int readings[num];      // 定义存储读入数值的数组
int readIndex = 0;      // 定义指示数组数值的索引
float total = 0.00;     // 定义存储数组数值的总数
float average = 0.00;      // 定义数组数值的平均数

void setup()
{
    for (int thisReading = 0; thisReading < num; thisReading++) {
    readings[thisReading] = 0;
  }
}

void loop() {
  total = total - readings[readIndex];// 总值中,减去数组的最后一个数值
  readings[readIndex] = C;            // 将温度存储到数组的最后一位。
  total = total + readings[readIndex];    // 将最新读入的数值加入到总值中
  readIndex = readIndex + 1;  // 将数组指示索引值加1
  // 判断数组指示索引是否超出数组范围,
  // 如果是,将数组指示索引重置为0
  if (readIndex >= num) {
    readIndex = 0;
  }
  average = total / num;    // 计算平均值 [/mw_shl_code]
}

 楼主| 发表于 2020-5-10 12:51 | 显示全部楼层
本帖最后由 yun8023ying 于 2020-5-12 13:13 编辑

更新,加入微信提醒功能 微信图片_20200512130839.jpg

代码如下
[mw_shl_code=arduino,true]  average = total/num/1000;    // 计算平均值
    if (average > 30) {
   Blinker.push("警告!!!温度过高,当前已经超过30度");
   Blinker.sms("警告!!!温度过高,当前已经超过30度");
   Blinker.wechat("警告!!!", "超温提示", "警告!!!温度过高,当前已经超过30度");
   Blinker.wechat("警告!!!温度过高,当前已经超过30度");
  }
    if (average < 20) {
   Blinker.push("警告!!!温度过低,当前已经不足20度");
   Blinker.sms("警告!!!温度过低,当前已经不足20度");
   Blinker.wechat("警告!!!", "低温提示", "警告!!!温度过低,当前已经不足20度");
   Blinker.wechat("警告!!!温度过低,当前已经不足20度");
  }[/mw_shl_code]
 楼主| 发表于 2020-5-10 12:52 | 显示全部楼层
本帖最后由 yun8023ying 于 2020-5-26 14:53 编辑

全部代码如下

[mw_shl_code=arduino,true]#define BLINKER_WIFI
#include <Blinker.h>

char auth[] = "faa0000004e";
char ssid[] = "1234";
char pswd[] = "88888888";

// 新建组件对象
BlinkerButton Button1("btn-abc");  //定义为案件
BlinkerNumber Number1("num-abc");  //定义为数字
BlinkerNumber ntc1("snwd");
BlinkerNumber ntc2("ygwd");

int counter = 0;
float ntc1_read = 0, ntc2_read = 0;  //组件名已用再起个名

const int num = 20;     // 平均的总数 const 数值固定
int readings[num];      // 定义存储读入数值的数组
int readIndex = 0;      // 定义指示数组数值的索引
float total = 0.00;     // 定义存储数组数值的总数
float average = 0.00;   // 定义数组数值的平均数

const int B =3950;      //  为NTC型热敏电阻B值
float Rt,V1,V2,X ;      //为测量温度下热敏电阻的阻值  单位为Ω
float R1 = 10000.00 ;   //为热敏电阻标称温度下的阻值  单位为Ω
float R2 = 9800.00;     //分压电阻
float V = 3.30;         //电压
float C;                //温度值

// 按下按键即会执行该函数
void button1_callback(const String & state)
{
  BLINKER_LOG("get button state: ", state);
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

// 如果未绑定的组件被触发,则会执行其中内容
void dataRead(const String & data)
{
  BLINKER_LOG("Blinker readString: ", data);
  counter++;
  Number1.print(counter);
}

void heartbeat()  //心跳包,定时发送数据到服务器
{
    ntc1.print( ntc1_read);
    ntc2.print(ntc2_read);
}

void dataStorage()  //注册
{
  Blinker.dataStorage("snwd", ntc1_read);
  Blinker.dataStorage("ygwd", ntc2_read);
}

void setup()
{  Serial.begin(9600);
  BLINKER_DEBUG.stream(Serial);//开启调试
  BLINKER_DEBUG.debugAll();
  // 初始化有LED的IO
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);   //默认亮灯??
  Blinker.begin(auth, ssid, pswd);   // 初始化blinker
  Blinker.attachHeartbeat(heartbeat);//开启心跳包上传功能
  Blinker.attachDataStorage(dataStorage);//开启历史数据存储功能
  Blinker.attachData(dataRead);
  Button1.attach(button1_callback);

    for (int thisReading = 0; thisReading < num; thisReading++) {
    readings[thisReading] = 0;
  }
}

void loop() {
   X  = analogRead(A0);// 读取传感器值
   V1 = X/1024*V  ;      //电压
   Rt = V1/(V-V1)*R2 ;    // 上拉
   C  = 1/(1/(298.15) + log(Rt/R1)/B) -273.15; //计算当前的温度值
   C  = C *1000;                        //数组不能放小数,扩大以提高精度
  total = total - readings[readIndex];// 总值中,减去数组的最后一个数值
  readings[readIndex] = C;            // 将温度存储到数组的最后一位。
  total = total + readings[readIndex];    // 将最新读入的数值加入到总值中
  readIndex = readIndex + 1;  // 将数组指示索引值加1
  // 判断数组指示索引是否超出数组范围,
  // 如果是,将数组指示索引重置为0
  if (readIndex >= num) {
    readIndex = 0;
  }
  average = total/num/1000;    // 计算平均值
    if (average > 30) {
   Blinker.push("警告!!!温度过高,当前已经超过30度");
   Blinker.sms("警告!!!温度过高,当前已经超过30度");
   Blinker.wechat("警告!!!", "超温提示", "警告!!!温度过高,当前已经超过30度");
   Blinker.wechat("警告!!!温度过高,当前已经超过30度");
  }
    if (average < 20) {
   Blinker.push("警告!!!温度过低,当前已经不足20度");
   Blinker.sms("警告!!!温度过低,当前已经不足20度");
   Blinker.wechat("警告!!!", "低温提示", "警告!!!温度过低,当前已经不足20度");
   Blinker.wechat("警告!!!温度过低,当前已经不足20度");
  }
  ntc1_read = average -1;  //本来想弄两个探头的,但是8266只有一个模拟输入
  ntc2_read = average;

  Blinker.run();
  Blinker.delay(500);

}[/mw_shl_code]
发表于 2020-5-26 11:19 | 显示全部楼层
你好,这个微信提醒是怎么实现的,最后的总代码里并没有这个功能呀
 楼主| 发表于 2020-5-26 14:49 | 显示全部楼层
赵巴拉巴拉 发表于 2020-5-26 11:19
你好,这个微信提醒是怎么实现的,最后的总代码里并没有这个功能呀

加在loop里面就行,我更新了。你再看下
发表于 2020-5-27 17:31 | 显示全部楼层
yun8023ying 发表于 2020-5-10 12:46
ntc 温度获取
[mw_shl_code=arduino,true]
int B =3950;            //  为NTC型热敏电阻B值

平滑处理思路好,只是初始化时将数组写入0,会在设备重启后的一段时间显示值不对,建议在初始化时读一次传感器值,并把这个值写入数组,这样在设备重启后的值更接近实际。
比如在setup()中加入:
X  = analogRead(A0);// 读取传感器值
V1 = X/1024*V  ;      //电压
Rt = V1/(V-V1)*R2 ;    // 上拉
C  = 1/(1/(298.15) + log(Rt/R1)/B) -273.15; //计算当前的温度值
C  = C *1000;     
for (int thisReading = 0; thisReading < num; thisReading++) {
    readings[thisReading] = C;
  }
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 09:40 , Processed in 0.145873 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表