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

yun8023ying 发表于 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

#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();
}

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


yun8023ying 发表于 2020-5-10 12:46

本帖最后由 yun8023ying 于 2020-5-26 14:59 编辑

ntc 温度获取

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; //计算当前的温度值

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

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



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

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

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

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

yun8023ying 发表于 2020-5-10 12:51

本帖最后由 yun8023ying 于 2020-5-12 13:13 编辑

更新,加入微信提醒功能

代码如下
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度");
}

yun8023ying 发表于 2020-5-10 12:52

本帖最后由 yun8023ying 于 2020-5-26 14:53 编辑

全部代码如下

#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;      // 定义存储读入数值的数组
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 = 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;// 总值中,减去数组的最后一个数值
readings = C;            // 将温度存储到数组的最后一位。
total = total + readings;    // 将最新读入的数值加入到总值中
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);

}

赵巴拉巴拉 发表于 2020-5-26 11:19

你好,这个微信提醒是怎么实现的,最后的总代码里并没有这个功能呀

yun8023ying 发表于 2020-5-26 14:49

赵巴拉巴拉 发表于 2020-5-26 11:19
你好,这个微信提醒是怎么实现的,最后的总代码里并没有这个功能呀

加在loop里面就行,我更新了。你再看下

zj_1217 发表于 2020-5-27 17:31

yun8023ying 发表于 2020-5-10 12:46
ntc 温度获取

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 = C;
}
页: [1]
查看完整版本: 温度远程监测系统