最近更新于 2024-05-05 14:18
前言
前几天做了一个机器人综合创新实验,老师让我们设计一个东西,然后做一定实现,因为和我们专业关系不是很大,所以对于实现方面并没有很高的要求,主要是 PPT 能够做描述就行。然后课上我们组商议后决定做一个智能风扇相关的,就先在 tb 上买了一个感应风扇的成品零件,昨天快递到了,我用了一晚上加今天一个上午折腾出了本文的内容(都知道我在这方面懂得多一点点,所以就是我做实操了)
做出这个以后,我再去看了老师给的两个店铺,要买的零件可以报给老师统一经费购买。挨着翻了一遍,我又有了新的构想,凑了九十几块钱的东西(超过100要单独给老师说明,没必要了),等后面老师买好了,我再做新构想的东西,后续再写续篇。
这里组内自己花钱买的感应风扇成品零件,主体框架是木质的,我已经拼好了
这个图上包含了一个电机和一个LED指示灯,计划保留使用
LED 除了接正负极,还有一个 S 极,给正电压时 LED 才会亮
这个是电机驱动板。先测试了一下,大致弄明白了控制原理。V 就是正极(这里用 5V),G 就是 GND,IN-B 和 IN-A 用于控制电机运转的,给 B 加正极电压,风扇就是正转送风(所以固定用这个引脚输入),给 A 加正极电压就是反向,其实就是控制右边 OUT 哪个是负极,左边 B 给正电压,右边 B 就是负极,左边 A 给正电压,右边 A 就是负极。另外根据给的正电压相比于 GND 的大小,输出的 AB 间的电压也会跟随变大变小,所以可以通过控制左边输入信号电压的高低调节风速。这个模块也计划保留使用
这个就是控制板。电机驱动板最终就接在这上面,人体感应器、LED 指示灯都是接在这上面,然后 DC 接口输入接一个电池盒装 3 节 5 号电池,也就是 4.5V 供电,我试过用 5V 也行,这个模块计划中不使用,直接用 Arduino 替代,就能根据需要扩展功能,逻辑也能自己编写
这个就是人体感应传感器。实际就是检测红外线,大概接近人体体温的东西移动就能触发。这传感器上面也有个指示灯,触发时会亮起来,然后 S 输出高电平。
还有个电池盒,这个就没啥说的了,用来插控制板上供电,计划也不使用它,直接用充电宝输入 5V
上面的就是购买的成品主要元器件了,然后我实现的时候添加的自己的元器件:
-
Arduino UNO
用来作控制板
-
LCD 1602(I2C 接口)
用来显示开关状态和风扇电机供给的电压大小等级,以及温度
-
触摸开关
用于控制电机的的输入信号源开断
2023.5.1
在折腾二的时候,发现我搞错了,所以本文关于触摸按钮控制的代码应该是存在问题的。我发现这个触摸按钮和普通的按键按钮是不一样的,它自己会记录开关状态,初始是输出低电平,摸一次后它就一直输出高电平,再摸一次它才变成低电平。我是当成普通按钮来用写代码逻辑的:按下不放就一直是高电平,只要放开就变低电平。当时我也发现不对经,但是没意识到这种情况,还误打误撞的让程序恰好“正常”工作了。当然,这开关自己能记录状态,也就不需要代码逻辑去实现了,反而更简单了。
-
DS18B20 温度传感器
用于测室温
-
电磁继电器(一路)
触摸按钮最终就是作用于这个电磁继电器用于控制电机输入信号的开断
-
电位器
用于控制电机驱动板信号输入端的电压大小,进而控制风扇的转速
接线
画了张草图,挺丑的哈哈
红色代表正极(5V)
黑色代表 GND
蓝色代表信号
打叉的地方代表线是接在一起的
最开始电机我是用 Arduino 供电的,但是发现电机一运行起来就导致 5V 接口降压,影响其它零件工作,所以给电机单独使用一个电源。
2023.4.30
在折腾二时,发现忘记画 LCD1602 的接线了,这里补充 SDA – A4,SCL – A5
软件环境
Arduino IDE 2.0.4
Arduino 库:
- LiquidCrystal I2C (by Frank de Brabander) 1.1.2
- OneWire (by Jim Studt…) 2.3.7
- Dallas Temperature (by Miles Burton) 3.9.0
代码
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// 引脚
#define FAN_VOLTAGE_PIN A0 // 读取电机驱动板输入信号电压大小
#define POWER_SWITCH_PIN 8 // 读取触摸按钮状态
#define ELECTRO_RELAY_PIN 9 // 控制电磁继电器
#define TEMPERATURE_PIN 10 // 读取温度传感器数据
#define HUMAN_BODY_PIN 11 // 读取人体感应传感器状态
// 温度传感器
OneWire oneWire(TEMPERATURE_PIN); // 创建单总线引脚
DallasTemperature temperature(&oneWire); // 温度传感器实例
// LCD 实例
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup()
{
// LCD 初始化
lcd.init();
lcd.backlight();
lcd.clear();
// 引脚初始化
pinMode(A0, INPUT);
pinMode(POWER_SWITCH_PIN, INPUT_PULLUP);
pinMode(ELECTRO_RELAY_PIN, OUTPUT);
// 初始化温度传感器
temperature.begin();
}
void loop()
{
static bool powerStatus = false; // 电源状态
static int powerSwitchStatus = LOW; // 电源开关状态
static unsigned int startTime = 0; // 开关长按计时
static int lastPowerSwitchStatus = LOW; // 上一次的电源开关状态
static char lcdString[17]; // 缓冲 LCD 屏显示内容
static float temperatureC = 0; // 温度值
// 读取温度
temperature.requestTemperatures();
temperatureC = temperature.getTempCByIndex(0);
// 电源开关
powerSwitchStatus = digitalRead(POWER_SWITCH_PIN);
if (powerSwitchStatus != lastPowerSwitchStatus)
{
startTime = millis();
if (millis() - startTime > 1000)
{
if (powerSwitchStatus == HIGH)
{
powerStatus = LOW;
}
else
{
powerStatus = HIGH;
}
}
lastPowerSwitchStatus = powerSwitchStatus;
}
// LCD 显示处理
lcd.clear();
lcd.setCursor(0, 0);
memset(lcdString, 0, sizeof(lcdString));
if (powerSwitchStatus)
{
sprintf(lcdString, "Level: %d", analogRead(FAN_VOLTAGE_PIN));
if (digitalRead(HUMAN_BODY_PIN) == HIGH)
{
digitalWrite(ELECTRO_RELAY_PIN, HIGH);
}
else
{
digitalWrite(ELECTRO_RELAY_PIN, LOW);
}
}
else
{
sprintf(lcdString, "Power off");
digitalWrite(ELECTRO_RELAY_PIN, LOW);
}
lcd.print(lcdString);
lcd.setCursor(0, 1);
memset(lcdString, 0, sizeof(lcdString));
sprintf(lcdString, "Temperature: %dC", (int)temperatureC);
lcd.print(lcdString);
}
关闭时
按触摸按钮开启后
开启且感应到人的时候(电位器给到最大时)
电位器调节到其他电压时