FastBond3挑战部分+宠物烘烤控制器
该项目使用了ESP32-S3,继电器,温度传感器,实现了宠物烘烤控制器的设计,它的主要功能为:使用M5Stack Dial-ESP32-S3 作为主控的宠物烘烤控制器,它由主控ESP32 S3与继电器模块,DS18S20温度传感器实现。。
标签
FastBond第三季
King
更新2024-11-05
60

使用M5Stack Dial-ESP32-S3 作为主控与继电器模块,DS18S20温度传感器实现,其中包含硬件选择、功能实现、安全性以及用户交互等,特别是在其工作的时候,还包括超温,风循环等功能。


下面是基于M5Stack Dial-ESP32-S3的宠物烘烤控制器的设计方案概述:


一、硬件功能介绍

1. M5Stack Dial-ESP32-S3模块

M5Stack Dial是一款多功能嵌入式开发板,集成了各种智能家居控制应用所需的功能和传感器,它基于ESP32-S3芯片设计,具有高性能和低功耗的特点。

主要组件和功能:

主控制器:M5StampS3,基于ESP32-S3芯片,支持Wi-Fi和各种外设接口SPI、I2C、UART、ADC等。

显示屏:1.28英寸圆形TFT触摸屏,提供直观的用户界面。

旋转编码器:可准确记录旋钮的位置和方向,提供更好的交互体验。

RTC电路:实时时钟电路,用于时间管理。

蜂鸣器和屏下按钮:提供声音反馈和额外的用户输入方式。

显示屏与编码器、按键:圆形TFT触摸屏与按键,用于显示状态和设置温度参数调整。


2. 传感器

DS18S20传感器是一款由美国DALLAS(Maxim Integrated Products)公司生产的数字温度传感器。

产品特点

单线接口:DS18S20在与微处理器连接时,仅需一条口线即可实现微处理器与DS18S20的双向通讯,极大地节省了I/O引脚资源。

测温范围广:其测温范围为-55℃~+125℃,适用于各种环境下的温度测量。

高精度:DS18S20提供了9位高精度的摄氏温度测量,固有测温分辨率为0.5℃。


主要部件与功能

DS18S20内部包含三个主要部件:64位激光刻制的唯一ROM序列号、温度传感器以及非易失性温度报警触发器TH和TL,ROM序列号用于区分不同的DS18S20传感器,温度传感器用于测量温度,而非易失性温度报警触发器TH和TL则用于设置温度报警的上下限。


供电方式

DS18S20可以采用两种供电方式:外部供电方式和寄生电源供电方式。

外部供电方式:DS18S20可以外接3.3V或5V的电源,GND引脚接地。


3、加热模块

使用继电器控制加热元件的工作原理

加热元件通常是通过继电器工作的原理将电能直接转换为热能。当电流流过加热元件产生热量。这种热量随后被传递给烘烤室内的空气,从而实现烘烤效果。


IO控制继电器的作用

IO控制继电器是一种用于控制电路的开关设备,它可以通过输入信号数字信号来控制输出电路加热元件的通断。在烘烤设备中,IO控制继电器可以接收来自微处理器或其他控制器的指令,根据指令来控制加热元件的加热功率和时间,从而实现精确的温度控制。

通过IO控制继电器,可以根据预设的温度曲线来精确控制加热元件的加热功率和时间,从而实现烘烤过程中的温度控制。


控制方式:

image.png

电路原理图:

image.png

image.png




4、风扇:用于循环空气或排出烘烤过程中产生的湿气,和内部温度的循环,使热量均匀。


主控与继电器,温度传感器连接示意图:


image.png



image.png

B口连接位置示意图:

image.png



二、软件设计具体功能

使用Visual Studio Code开发平台进行开发,利用PlatformIO进行软件开发,使用的是C编程语言实现控制逻辑。

设计直观易用的用户界面,提高用户体验。


风扇:

当设备接收到5V供电时,风扇立即启动。

风扇持续运行,为烘箱内部提供持续的吹风,这是为了防止烘箱内部温度过高,同时也是为了保护PTC发热片免受高温损害。

超温保护机制:

设备内置超温保护开关,最高温度限制可设定为50度或70度(根据具体需求选择)。

一旦温度超过设定的最高温度限制,设备将自动停止加热并启动报警机制(如蜂鸣器或LED指示灯),以防止温度过高对设备造成损害。

M5Stack Dial主控功能:

当M5Stack Dial主控供电并开机后,将显示开机界面,并展示www.eetree.cn等相关信息。

用户可以通过扭动编码器来选择不同的功能选项,并点击M5按键进入温度设定界面。

在温度设定界面中,用户可以通过转动编码器来增加或减少设定的温度值。

温度检测与加热控制:

在设备运行过程中,温度检测模块实时工作,不断监测烘箱内部的温度。

加热模块和继电器处于待机状态,等待IO指令进行加热操作。

当实际温度低于设定温度时(例如设定温度为30度,实际温度为25度),M5Stack Dial将发出指令,驱动继电器模块启动加热功能。

当实际温度达到设定温度时,加热功能将自动停止,以避免温度过高。

 

 

硬件外设框架:

 image.png

代码:


// 定义TemperatureSensor类
class TemperatureSensor {
public:
// 构造函数,初始化传感器连接引脚等
TemperatureSensor(uint8_t pin)
: ds(pin), initialized(false), conversionInProgress(false), lastRequestTime(0) {}

// 初始化传感器
void begin() {
if (initializeSensor()) {
initialized = true;
requestTemperature(); // 开始第一次温度转换
}
}



// 更新温度数据
void update() {
if (!initialized) return;
if (conversionInProgress && millis() - lastRequestTime >= 750) {
// 检查转换时间是否已过
readTemperature();
requestTemperature(); // 开始下一次转换
}
}


// 获取摄氏度温度
float getCelsius() const {
return celsius;
}


// 获取华氏度温度
float getFahrenheit() const {
return fahrenheit;
}





// 请求温度转换
void requestTemperature() {
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // 开始温度转换
conversionInProgress = true;
lastRequestTime = millis();
}


// 读取温度数据
void readTemperature() {
byte data[9];
ds.reset();
ds.select(addr);
ds.write(0xBE); // 读取暂存器
for (byte i = 0; i < 9; i++) {
data[i] = ds.read();
}


// 根据传感器类型和配置计算原始温度值
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3;
if (data[7] == 0x10) {
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw & ~7;
else if (cfg == 0x20) raw = raw & ~3;
else if (cfg == 0x40) raw = raw & ~1;
}
celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
conversionInProgress = false;
}


// 初始化传感器,包括搜索地址、校验CRC和识别芯片类型
bool initializeSensor() {
if (!ds.search(addr)) {
Serial.println("No more addresses.");
ds.reset_search();
delay(250);
return false;
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return false;
}
type_s = identifyChip(addr[0]);
if (type_s == 255) {
Serial.println("Device is not a DS18x20 family device.");
return false;
}
return true;
}


// 根据传感器的第一个字节识别芯片类型
byte identifyChip(byte firstByte) {
switch (firstByte) {
case 0x10:
Serial.println("Chip = DS18S20");
return 1;
case 0x28:
Serial.println("Chip = DS18B20");
return 0;
case 0x22:
Serial.println("Chip = DS1822");
return 0;
default:
return 255;
}
}
};


// 创建TemperatureSensor对象,并连接到数字引脚1
TemperatureSensor sensor(1);

// setup函数,在Arduino板上电或重置时运行一次
void setup() {
// 配置M5Dial(此处代码略,具体配置依赖于M5Dial库)
auto cfg = M5.config();
M5Dial.begin(cfg, true, false);
Serial.begin(115200); // 初始化串口通信
sensor.begin(); // 初始化温度传感器
drawInit(); // 初始化显示(此处代码略,具体实现依赖于图形库)
pinMode(2, OUTPUT); // 将数字引脚2设置为输出(此行代码似乎与主要功能无关)
}


// loop函数,在Arduino运行时不断循环执行
void loop() {
sensor.update(); // 更新温度数据
M5Dial.update(); // 更新M5Dial状态
// 以下代码处理M5Dial的用户交互逻辑(略去具体细节)
// ...
// 显示当前温度
Serial.print("Temperature = ");
Serial.print(sensor.getCelsius());
Serial.println(" Fahrenheit");
delay(100); // 延时100毫秒
}

// 绘制初始化界面的函数(略去具体实现)
void drawInit() {
// ...
}

// 绘制选择界面的函数(略去具体实现)
void drawChose() {
// ...
}




  // 显示对应的 温度时间信息
  info.setTextColor(TFT_WHITE, TFT_BLUE);
  if (chose_mode == 1)
  {
    info.drawString("www.eetree.cn", 30, 10, &FreeMono9pt7b);
    info.drawString("2024 DigiKey third", -1, 30, &FreeMono9pt7b);
    info.drawString("temperature", 30, 50, &FreeMono9pt7b);
    info.pushSprite(20, 120);
  }



// 系统运行时的界面
void drawRunning()
{
  float currentTemp = sensor.getCelsius();
  float adc=0;
  runInfo msg;

  background.fillSprite(TFT_BLUE);
  chose.fillSprite(TFT_BLUE);
  info.fillSprite(TFT_BLUE);
  chose.setTextColor(TFT_BLACK, TFT_DARKGREEN);
  float TEMPAD=M5Dial.Encoder.read();
  //printf("TEMPAD %.1f\r\n");
  Serial.print("TEMPAD: ");  
  Serial.println(TEMPAD);  
  Serial.print("\r\n");  
  if (chose_mode == 1)
  {
      if ( TEMPAD )   //编码器正转
      {
      settempture += 5;
        // 将设定值打印到屏幕
      sprintf(buf, "SETTEMP: %.1f ", settempture); // 使用当前温度值
      info.drawString(buf, 0, 0, &FreeMono12pt7b);  // 在屏幕上显示温度
      }
      else
      {
      settempture -= 5;
      // 将设定值打印到屏幕
      sprintf(buf, "SETTEMP: %.1f ", settempture); // 使用当前温度值
      info.drawString(buf, 0, 0, &FreeMono12pt7b);  // 在屏幕上显示温度  
      }
    chose.drawCenterString("temperature", 90, 18, &FreeSansBold12pt7b);
    sprintf(buf, "TEMP: %.1f ", currentTemp);     // 使用当前温度值
    info.drawString(buf, 0, 30, &FreeMono12pt7b); // 在屏幕上显示温度

    sprintf(buf, "TIME: %02d:%02d", msg.timelong / 60, msg.timelong % 60);
    info.drawString(buf, 0, 60, &FreeMono12pt7b);
        if ( TEMPAD <= currentTemp )
    {
     digitalWrite(2, LOW);
    } else
    {
       digitalWrite(2, HIGH);
       TEMPAD = 0;
    }
  }

  info.pushSprite(30, 130);
  chose.pushSprite(30, 20);
  background.pushSprite(0, 0);
}

软件工作流程:

工作流程的详细解释:


初始化 (setup() 函数):

配置M5Dial,包括显示屏、编码器和按钮。

初始化串口通信,以便在串行监视器上打印信息。

初始化温度传感器DS18B20。


调用drawInit()函数来初始化显示屏的背景、选择和信息图层。


选择模式 (loop() 函数中的非运行模式):


不断更新温度传感器的数据。

读取编码器的位置,以检测用户是否在旋转编码器来选择模式。

如果编码器位置发生变化,根据旋转方向更新chose_mode变量。

当按钮A被按下时,切换到运行模式,并播放一个短促的提示音。

如果按钮A被长按3秒,则重置系统到选择模式,并播放一个长提示音。


运行模式 (loop() 函数中的运行模式):

不断更新温度传感器的数据。

读取编码器的值(这里似乎有误用,因为编码器的值通常用于表示旋转的位置或步数,而不是直接作为温度值)。

使用编码器的值来增减设定温度(settempture),这在实际应用中可能不合适,因为编码器的值通常不是线性的温度增量。

根据选择的模式,在屏幕上显示当前温度、设定温度以及可能的时间信息(尽管时间信息在提供的代码中未完全实现或更新)。

如果设定温度与实际温度的关系满足特定条件(设定温度应高于实际温度),则通过引脚2输出高电平信号(可能用于控制加热器)。

否则,输出低电平。


用户界面更新 (drawChose() 和 drawRunning() 函数):

drawChose()函数用于在选择模式下更新用户界面,显示当前选择的模式和一些静态信息。

drawRunning()函数用于在运行模式下更新用户界面,显示设定温度、当前温度以及可能的时间信息。


总结:

具体功能是当给主控供电时,5V输入,风扇就开始工作,因为需要要一直给烘箱内吹风,这是防止高温的一种防止措施之一,也是保护PTC发热片烧坏的原因,第二是超温保护开关,最高温度不能超过50或者70度,避免温度过高;

当M5Stack dial主控供电,开机进入显示界面,出现开机界面,网站www.eetree.cn等相关信息,然后可以通过扭动编码器,可以进入选择,再点M5那个按键,进入温度设定界面,再转动编码器就可以加减温度的设定,在这个操作过程和开机状态,温度检测是实时在工作,加热模块,继电器是待机状态,等待IO给过的指令进行加热;如果设定温度30度,实际温度只有25度,M5Stack dial就会发出指令,驱动继电器模块加温,当达到30度时,就会停止加温。


通过实现这个烘箱的功能实现,我从中还是学习到了不少的知识提升,原计划用IIC实现温度采集,因为经常用,没有用过这个单线的DS18S20,所以就用这个实现一下,看看有什么难度,当然还有开发平台,也是用的之前没有用过的,都是一次新的开始,从中得到了大的提升,有了新的认识,虽然非常的难受,虽然欠缺,但是我还是实现了当初设想的功能,再次感谢电子森林。

软硬件
附件下载
Sch_M5Dial.pdf
PCB_PCB_DS18B20_2024-10-31.json
SCH_DS18B20温度传感器_2024-10-31.json
main.cpp
团队介绍
个人
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号