DS18B20双温度监测控制冰酒发酵
本帖最后由 armduino 于 2022-3-25 09:25 编辑用一个温度传感器程序比较简单,用两个或多个DS18B20传感器只需要一根总线,但是涉及到地址识别问题,程序略微复杂。
结合自己的实际需要,程序增改如下:
/* *****************************************************************
* DS18B20是Dallas Semiconductor Corp.生产的1-Wire接口温度传感器,该独特的1-Wire接口仅需要一个用于与微控制器的双向通信的数字针
* DS18B20温度传感器相当精确,无需外部组件即可工作,它可以测量-55°C至+ 125°C的温度,精度为±0.5°C.
* 用户可以将温度传感器的分辨率配置为9,10,11或12位.但是,上电时的默认分辨率为12位(即0.0625°C精度)
* 该传感器可以由3V至5.5V电源供电,并且在主动温度转换期间仅消耗1mA电流
* 使用点灯科技的APP开发控制界面
* *****************************************************************/
#define BLINKER_WIFI
//#define BLINKER_ESP_SMARTCONFIG
#include <Blinker.h>
#include<OneWire.h>
#include<DallasTemperature.h>
#define TEMPERATURE_PRECISION 10
#define BUS2 2 //for NodeMCU GPIO13=D7,温度传感器黄色线接针脚D7(或者GPIO2),然后并一个4.7K电阻接到3V3
//DS18B20的针脚定义:面朝印字面,左为GND,右为VCC,中间为数字输出引脚(接4.7-10k上拉电阻)
OneWire onewire(BUS2);//通过将传感器的信号引脚传递到其构造函数来创建单线对象,这个单线对象让我们与任何单线设备进行通信,而不仅仅是DS18B20
DallasTemperature sensors(&onewire);//为了与DS18B20传感器进行通信,我们需要创建DallasTemperature库的对象,并将单线对象的引用作为参数传递
// arrays to hold device address
DeviceAddress insideThermometer, outsideThermometer;//定义地址变量
//联接好两个温度传感器后,可以先用示例程序oneWireSearch上传到MCU 获取传感器的地址如下,也就是说可以直接赋参
//DeviceAddress insideThermometer = {0x28,0x61,0x64,0x11,0xB8,0x6A,0x69,0x8E};
//DeviceAddress outsideThermometer = {0x28,0x45,0xDB,0x07,0xD6,0x01,0x3C,0x39};
char auth[] ="6d8268190a67";// "Your Device Secret Key";
char ssid[] = "TP-LINK_2F98";//Your WiFi network SSID or name";
char pswd[] = "xxxxxx";//Your WiFi network WPA password or WEP key";
uint32_t read_time = 0;
float temp_read1=0;
float temp_read2=0;
// 新建组件对象
BlinkerButton Button1("cooler1");
BlinkerButton Button2("cooler2");
BlinkerNumber TEMP1("temp1");
BlinkerNumber TEMP2("temp2");
bool b1_state=false;
bool b2_state=false;
int relayPin1=5;//LC-ESP12F开发板占用引脚5用于继电器触发信号,GPIO5=D1 for NodeMCU
int relayPin2=12; //备用 GPIO12=D6
// 按下按键即会执行该函数
void button1_callback(const String & state){
BLINKER_LOG("get button1 state: ", state);
//digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
if (state=="on" ){
b1_state=true;
digitalWrite(relayPin1,HIGH);
Button1.print("on");
}
else if (state=="off"){
b1_state=false;
digitalWrite(relayPin1,LOW);
Button1.print("off");
}
}
void button2_callback(const String & state) {
BLINKER_LOG("get button2 state: ", state);
//digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
if(state=="on"){
b2_state=true;
digitalWrite(relayPin2,HIGH);
Button2.print("on");
}
else if (state=="off"){
b2_state=false;
digitalWrite(relayPin2,LOW);
Button2.print("off");
}
}
// 如果未绑定的组件被触发,则会执行其中内容
void dataRead(const String & data){
BLINKER_LOG("Blinker readString: ", data);
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
Blinker.vibrate();
uint32_t BlinkerTime = millis();
Blinker.print("millis", BlinkerTime);
}
void heartbeat(){
TEMP1.print(temp_read1);
TEMP2.print(temp_read2);
}
void dataStorage(){
Blinker.dataStorage("temp1", temp_read1);
Blinker.dataStorage("temp2", temp_read2);
}
// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
// zero pad the address if necessary
if (deviceAddress < 16) Serial.print("0");
Serial.print(deviceAddress, HEX);
}
}
// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if(tempC == DEVICE_DISCONNECTED_C)
{
Serial.println("Error: Could not read temperature data");
return;
}
Serial.print("Temp C: ");
Serial.print(tempC);
Serial.print(" | Temp F: ");
Serial.print(DallasTemperature::toFahrenheit(tempC));
}
// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
Serial.print("Resolution: ");
Serial.print(sensors.getResolution(deviceAddress));
Serial.println();
}
// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
Serial.print("Device Address: ");
printAddress(deviceAddress);
Serial.print(" ");
printTemperature(deviceAddress);
Serial.println();
}
void setup()
{
Serial.begin(115200);
BLINKER_DEBUG.stream(Serial);
pinMode(relayPin1,OUTPUT);
pinMode(relayPin2,OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
Blinker.begin(auth,ssid, pswd);
Blinker.attachData(dataRead);
Blinker.attachHeartbeat(heartbeat);
Blinker.attachDataStorage(dataStorage);
Button1.attach(button1_callback);
Button2.attach(button2_callback);
BLINKER_LOG("Awesome! Uploading is OK!");
sensors.begin();//该功能搜索总线上连接的传感器,并为每个传感器设置 位分辨率(12位)
//sensors.setResolution( TEMPERATURE_PRECISION );
// locate devices on the bus
Serial.print("\nLocating devices...");
Serial.print("Found ");
Serial.print(sensors.getDeviceCount(), DEC); //获取传感器设备数量
Serial.println(" devices.");
// report parasite power requirements
// bool isParasitePowerMode(void)返回是否需要总线寄生供电,需要则返回true
Serial.print("Parasite power is: ");
if (sensors.isParasitePowerMode()) Serial.println("ON");
else Serial.println("OFF");
// Search for devices on the bus and assign based on an index. Ideally,
// you would do this to initially discover addresses on the bus and then
// use those addresses and manually assign them (see above) once you know
// the devices on your bus (and assuming they don't change).
//
// method 1: by index
if (!sensors.getAddress(outsideThermometer, 0))Serial.println("Unable to find address for Device 0");
if (!sensors.getAddress(insideThermometer, 1)) Serial.println("Unable to find address for Device 1");
// method 2: search()
// search() looks for the next device. Returns 1 if a new address has been
// returned. A zero might mean that the bus is shorted, there are no devices,
// or you have already retrieved all of them. It might be a good idea to
// check the CRC to make sure you didn't get garbage. The order is
// deterministic. You will always get the same devices in the same order
//
// Must be called before search()
//oneWire.reset_search();
// assigns the first address found to insideThermometer
//if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
// assigns the seconds address found to outsideThermometer
//if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer");
// show the addresses we found on the bus
Serial.print("Device 0 Address: ");
printAddress(outsideThermometer); //28616411B86A698E
Serial.println();
Serial.print("Device 1 Address: ");
printAddress(insideThermometer); //2845DB07D6013C39
Serial.println();
// set the resolution to 9 bit per device
sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);
sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);
Serial.print("Device 0 Resolution: ");
Serial.print(sensors.getResolution(outsideThermometer), DEC); //12
Serial.println();
Serial.print("Device 1 Resolution: ");
Serial.print(sensors.getResolution(insideThermometer), DEC); //9
Serial.println();
}
void loop(){
Blinker.run();
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); //该功能向总线上的所有传感器发送命令以执行温度转换
Serial.println("DONE");
// print the device information
//printData(insideThermometer);
//printData(outsideThermometer);
uint16_t data_time= 3000;
if (read_time == 0 || (millis() - read_time) >= data_time) {
read_time = millis();
float t1 = sensors.getTempC (insideThermometer);
float t2 = sensors.getTempC (outsideThermometer);
//float t1 = sensors.getTempCByIndex(1);//该功能读取并返回传感器的温度读数.deviceIndex只是总线上传感器的位置,如果您仅在总线上使用一个DS18B20,请将其设置为0
//float t2 = sensors.getTempCByIndex(0);
//static char temperatureTemp;
//dtostrf(t1, 6, 1, temperatureTemp);//data to string function 把浮点数或整型数转换成字符串,保留一位小数
temp_read1 = t1;
temp_read2 = t2;
Serial.print("当前温度 t1 = ");
Serial.print(t1);
Serial.print((char)176);//shows degrees character
Serial.print("C|");
Serial.print("当前温度 t2 = ");
Serial.print(t2);
Serial.print((char)176);//shows degrees character
Serial.println("C|");
//print the temperature in Fahrenheit
//Serial.print((sensors.getTempCByIndex(0) * 9.0) / 5.0 + 32.0);
//Serial.print((char)176);//shows degrees character
//Serial.println("F");
if (t1>=8){
digitalWrite(relayPin1,HIGH);//制冷机启动
}
else if (t1<=5){
digitalWrite(relayPin1,LOW);
}
}
/*
* DallasTemperature.h库中的其他有用功能
* DallasTemperature对象可以使用一些有用的功能,下面列出了其中几个:
* setResolution() 该功能将DS18B20的内部模数转换器的分辨率设置为9位,10位,11位或12位,分别对应于0.5°C,0.25°C,0.125°C和0.0625°C的增量
* bool getWaitForConversion()函数返回waitForConversion标志的值.当您要检查温度转换是否完成时,此功能很有用.
* setHighAlarmTemp()&setLowAlarmTemp()功能可设置设备的内部高温和低温警报(以摄氏度为单位),有效范围是-55至125°C
* bool hasAlarm() 如果温度超过上限和下限警报温度设置时设备处于警报状态,此功能将返回true.
*/
}
楼主 为什么我看有的 是上拉到5v上啊 而且官方文档也是上拉到5v的 我看到都是上拉3.3,另外,esp板子输出引脚都是3.3V。
板子内置了上拉电阻,可以不要外接电阻,抽空再测试一下。
页:
[1]