基于wemos d1开发版读取 DS18B20 传感器的温度及-127度问题

      在使用wemos的过程中,发现对于DS18B20的文章很少,大多数都是Arduino板的文章,虽然代码通用。但是还是有一些坑的。在这里就不讨论代码了,主要记录一下那几点坑及和Arduino板的一些区别。

      1、如果你一直显示-127度,那么排除你物理接线有问题,可能有以下原因:

           1)你的io口不对,wemos 板io口和通过DallasTemperature包代码添加的口差异很大,而且写D*也是不生效的,你需要写和Arduino板一样的纯数字,但是这里也是坑的开始,这里写出数字和wemos板的io口是不对应的,就拿2为例,你如果插入D2就会读到-127度,因为没有读到硬件。如果你写的2,需要插入到 D9 中。其他的话需要一 一测试。

      wemos在DS18B20时和Arduino板的区别

      ·1、他们所对应的io口差异很大,Arduino板和代码输入的io口一直,但是wemos板差异很大。而且在用DallasTemperature包读取过程中,weoms的插口和gpio口值也没有关系,比如D2对应GPIO16,但是你代码写16,插在D2口你也是拿不到数据的

 

       2、Arduino板载读取DS18B20时是需要绑定一个4.7k的电阻的,这个和网上说的一致。而且DS18B20可以接在5V或者3.3V都可以正常工作。

 

      3、wemos板读取DS18B20不需要特意绑定一个电阻。而且5V和3.3V都可以读到数据。但是在5V的时候数据不稳定,所以必须使用3.3V输入。

好的,下面是一个基于51单片机的PID温度控制系统的程序,使用DS18B20作为温度传感器,数码管显示温度和设定温度,通过按键设置期望的温度: ```c #include <reg51.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int #define DQ P2_7 sbit D1 = P0^0; // 数码管D1 sbit D2 = P0^1; // 数码管D2 sbit D3 = P0^2; // 数码管D3 sbit D4 = P0^3; // 数码管D4 sbit KEY_UP = P3^1; // 上键 sbit KEY_DOWN = P3^0; // 下键 float temperature = 0; // 当前温度 float setpoint = 40; // 设定温度 float kp = 2.0; // 比例系数 float ki = 0.5; // 积分系数 float kd = 1.0; // 微分系数 float error = 0.0, error_sum = 0.0, error_diff = 0.0; float last_error = 0.0, output = 0.0; void delayms(uint ms) // 延时函数 { uint i, j; for (i = 0; i < ms; i++) { for (j = 0; j < 120; j++) { _nop_(); _nop_(); _nop_(); _nop_(); } } } void ds18b20_init() // 初始化DS18B20 { DQ = 1; delayms(10); DQ = 0; delayms(80); DQ = 1; delayms(10); } uchar ds18b20_read_byte() // 读取一个字节 { uchar i, j, value = 0; for (i = 0; i < 8; i++) { DQ = 0; _nop_(); _nop_(); value >>= 1; if (DQ) { value |= 0x80; } _nop_(); _nop_(); DQ = 1; } return value; } void ds18b20_write_byte(uchar value) // 写入一个字节 { uchar i; for (i = 0; i < 8; i++) { DQ = 0; _nop_(); _nop_(); if (value & 0x01) { DQ = 1; } value >>= 1; _nop_(); _nop_(); DQ = 1; } } float ds18b20_read_temperature() // 读取温度 { uchar tl, th; float temp = 0.0; ds18b20_init(); ds18b20_write_byte(0xCC); ds18b20_write_byte(0x44); delayms(100); ds18b20_init(); ds18b20_write_byte(0xCC); ds18b20_write_byte(0xBE); tl = ds18b20_read_byte(); th = ds18b20_read_byte(); temp = th; temp <<= 8; temp |= tl; temp /= 16.0; return temp; } void display(uint num) // 数码管显示 { uchar digit[4] = {0}; digit[0] = num % 10; digit[1] = num % 100 / 10; digit[2] = num % 1000 / 100; digit[3] = num / 1000; if (digit[3]) { D1 = 1; } else { D1 = 0; } D2 = 1; P1 = digit[2]; delayms(5); D2 = 0; if (digit[3] || digit[2]) { D3 = 1; } else { D3 = 0; } D4 = 1; P1 = digit[1]; delayms(5); D4 = 0; P1 = digit[0]; } void main() { EA = 1; // 开全局中断 TMOD = 0x01; // 定时器0工作在模式1 TH0 = 0xFC; // 定时器0初值为65536-50000=15536 TL0 = 0x00; TR0 = 1; // 启动定时器0 ET0 = 1; // 开定时器0中断 ds18b20_init(); // 初始化DS18B20 while (1) { if (KEY_UP == 0) // 上键按下 { setpoint += 1.0; delayms(10); } if (KEY_DOWN == 0) // 下键按下 { setpoint -= 1.0; delayms(10); } temperature = ds18b20_read_temperature(); // 读取温度 error = setpoint - temperature; // 计算误差 error_sum += error; // 累计误差 error_diff = error - last_error; // 计算误差变化率 output = kp * error + ki * error_sum + kd * error_diff; // 计算输出 if (output < 0.0) // 输出不能为负数 { output = 0.0; } // 控制温度,这里用printf代替实际控制操作 printf("Temperature: %.2f, Setpoint: %.2f, Output: %.2f\n", temperature, setpoint, output); temperature += output; display((uint)(temperature * 10)); // 显示温度 } } void timer0_isr() interrupt 1 // 定时器0中断服务程序 { TH0 = 0xFC; // 定时器0初值为65536-50000=15536 TL0 = 0x00; } ``` 这个程序使用了定时器0来实现一个简单的延时,从而避免了使用延时函数的问题。在主循环中,通过读取上下按键来设置设定温度,然后使用PID算法计算控制输出来控制温度,使用DS18B20读取温度值,并通过数码管显示温度和设定温度。控制输出不能为负数,因此在计算输出时需要进行判断。注意,在使用DS18B20时需要正确连接电路,以及正确初始化和读取传感器
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值