#include <Arduino.h>
#include <U8g2lib.h>//导入U8G2库
#include "OneButton.h"
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); //使用12C协议的OLED屏幕的初始化
/***onebutton库配置***/
#define ACTIVE_LOW true
#define ACTIVE_HIGH false
#define PULLUP_ENABLE true
#define PULLUP_DISABLE false
const int kaihePin = 2;//开盒按键
const int huliPin = 3;//护理按键
const int shajunPin = 4;//杀菌按键
const int hongganPin = 5;//烘干按键
const int moazPin = 6;//电机A正限位
const int moafPin = 7;//电机A负限位
const int mobzPin = 8;//电机B正限位
const int mobfPin = 9;//电机B负限位
const int latchPin = 12; // 连接到74HC595的STCP引脚
const int clockPin = 10; // 连接到74HC595的SHCP引脚
const int dataPin = 11; // 连接到74HC595的SER引脚
/**********创建onebutton对象,绑定开盒按键**************/
OneButton button1(kaihePin, ACTIVE_LOW, PULLUP_ENABLE); //预处理写法
bool motorRunning = false; //电机是否运行的标志位
bool motorDirection = HIGH; // 初始方向设为正转(根据实际连接调整)
bool kaiguanFlag = 1; //设置开关标志
unsigned long buttonPressTime = 0; // 记录按键被按下的时间
bool huli = 1;
bool shajun = 1;
bool honggan = 1;
bool zhongduan = 0;
unsigned long lastDebounceTime = 0; // 上一次按键检测的时间
unsigned long debounceDelay = 50; // 消抖延时,单位毫秒
unsigned long pressInterval = 200; // 双击检测的时间间隔,单位毫秒
boolean lastButtonState = HIGH; // 假设使用上拉电阻,所以默认状态是HIGH
int clickCount = 0; // 记录点击次数
unsigned long lastClickTime = 0; // 上一次点击的时间
unsigned long startTime = 0; //一键杀菌时间
void setup() {
// put your setup code here, to run once:
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
Serial.begin(9600);
pinMode(kaihePin, INPUT_PULLUP);//电阻上拉默认高电平
pinMode(moazPin, INPUT_PULLUP);//电阻上拉默认高电平
pinMode(mobzPin, INPUT_PULLUP);//电阻上拉默认高电平
pinMode(moafPin, INPUT_PULLUP);//电阻上拉默认高电平
pinMode(mobfPin, INPUT_PULLUP);//电阻上拉默认高电平
pinMode(huliPin, INPUT_PULLUP);//电阻上拉默认高电平
pinMode(shajunPin, INPUT_PULLUP);//电阻上拉默认高电平
pinMode(hongganPin, INPUT_PULLUP);//电阻上拉默认高电平
//屏幕相关
// u8g2.setBusClock(800000);//设置时钟
u8g2.begin();
// u8g2.enableUTF8Print();
//按键相关
button1.attachDoubleClick(doubleClick1);//当button1双击时,运行doubleClick1函数
daijixianshi();
}
void loop()
{
// put your main code here, to run repeatedly:
zhongduan = 0;
button1.tick();//开盒按键触发
if (digitalRead(huliPin) == 0) //一键护理按键按下
{
huli = 0;
//yijianhuli();
hulidaojishi();
}
if (digitalRead(shajunPin) == 0) //杀菌按键按下
{
delay(10); // 消抖
if (digitalRead(shajunPin) == LOW) {
// 设置倒计时为10分钟后
fan();//打开风扇
delay(1000);//延迟1秒
fanChou();//打开风扇和臭氧
startTime = millis() + 10000;
}
}
if (digitalRead(hongganPin) == 0) //烘干按键按下
{
delay(500);//按键消抖时间,一定要消抖,不然会误触,消抖时间需实际调试
fan();
xianshi(10);
int time = 10; //倒计时时间,初始为10
unsigned long startTime = 0; //定义起始时间
startTime = millis();
while (millis() - startTime <= 3000)
{
delay(100);
Serial.println(time);
if (digitalRead(hongganPin) == LOW)
{
time += 10;
if (time > 60) {
time = 10;
}
Serial.println(time);//屏幕时间显示
xianshi(time);
startTime = millis(); //将开始时间重置为最新按下按键的时候。
continue;
}
}
fanJia();
honggandaojishi(time);
motorstop();
}
shajundaojishi();
}
void kaihemove() { //开盒动作
azstart();
while (digitalRead(moazPin) == LOW) {
}
motorstop();
bzstart();
while (digitalRead(mobzPin) == LOW) {
}
motorstop();
kaiguanFlag = 0;
}
void guanhemove() { //关盒动作
bfstart();
while (digitalRead(mobfPin) == LOW) {
}
motorstop();
afstart();
while (digitalRead(moafPin) == LOW) {
}
motorstop();
kaiguanFlag = 1;
}
void azstart() { //电机A正转
Serial.println("电机A正转,橙色");
byte moastart = B00001000; // 二进制表示,表示LED的点亮模式
// 使用shiftOut函数发送数据到74HC595
shiftOut(dataPin, clockPin, MSBFIRST, moastart);
// 上升沿锁存数据
digitalWrite(latchPin, HIGH);
delayMicroseconds(1); // 保持高电平一小段时间
digitalWrite(latchPin, LOW); // 然后拉低
}
void afstart() { //电机A反转
Serial.println("电机A反转,白色");
byte moafstart = B00010000; // 二进制表示,表示LED的点亮模式
// 使用shiftOut函数发送数据到74HC595
shiftOut(dataPin, clockPin, MSBFIRST, moafstart);
// 上升沿锁存数据
digitalWrite(latchPin, HIGH);
delayMicroseconds(1); // 保持高电平一小段时间
digitalWrite(latchPin, LOW); // 然后拉低
}
void bzstart() { //电机B正转
Serial.println("电机B正转,紫色");
byte mobzstart = B00100000; // 二进制表示,表示LED的点亮模式
// 使用shiftOut函数发送数据到74HC595
shiftOut(dataPin, clockPin, MSBFIRST, mobzstart);
// 上升沿锁存数据
digitalWrite(latchPin, HIGH);
delayMicroseconds(1); // 保持高电平一小段时间
digitalWrite(latchPin, LOW); // 然后拉低
}
void bfstart() { //电机B反转
Serial.println("电机B正转,粉色");
byte mobfstart = B01000000; // 二进制表示,表示LED的点亮模式
// 使用shiftOut函数发送数据到74HC595
shiftOut(dataPin, clockPin, MSBFIRST, mobfstart);
// 上升沿锁存数据
digitalWrite(latchPin, HIGH);
delayMicroseconds(1); // 保持高电平一小段时间
digitalWrite(latchPin, LOW); // 然后拉低
}
void motorstop() { //电机停止
Serial.println("电机停止橙白紫粉熄灭");
byte moastop = B00000000; // 二进制表示,表示LED的点亮模式
// 使用shiftOut函数发送数据到74HC595
shiftOut(dataPin, clockPin, MSBFIRST, moastop);
// 上升沿锁存数据
digitalWrite(latchPin, HIGH);
delayMicroseconds(1); // 保持高电平一小段时间
digitalWrite(latchPin, LOW); // 然后拉低
}
void fan() { //风扇继电器打开
Serial.println("风扇继电器打开,黄灯亮");
byte fan = B00000100; // 二进制表示,表示LED的点亮模式
// 使用shiftOut函数发送数据到74HC595
shiftOut(dataPin, clockPin, MSBFIRST, fan);
// 上升沿锁存数据
digitalWrite(latchPin, HIGH);
delayMicroseconds(1); // 保持高电平一小段时间
digitalWrite(latchPin, LOW); // 然后拉低
}
void fanChou() { //风扇和臭氧继电器打开
Serial.println("风扇和臭氧继电器打开,蓝灯,黄灯亮");
byte fanchou = B00000110; // 二进制表示,表示LED的点亮模式
// 使用shiftOut函数发送数据到74HC595
shiftOut(dataPin, clockPin, MSBFIRST, fanchou);
// 上升沿锁存数据
digitalWrite(latchPin, HIGH);
delayMicroseconds(1); // 保持高电平一小段时间
digitalWrite(latchPin, LOW); // 然后拉低
}
void fanJia() { //风扇和加热丝继电器打开
Serial.println("风扇和加热丝继电器打开,红灯,黄灯亮");
byte fanjia = B00000101; // 二进制表示,表示LED的点亮模式
// 使用shiftOut函数发送数据到74HC595
shiftOut(dataPin, clockPin, MSBFIRST, fanjia);
// 上升沿锁存数据
digitalWrite(latchPin, HIGH);
delayMicroseconds(1); // 保持高电平一小段时间
digitalWrite(latchPin, LOW); // 然后拉低
}
void hulidaojishi()//一键护理带屏幕倒计时
{
fan();//打开风扇
delay(1000);//延迟1秒
fanChou();//打开风扇和臭氧
for (int hulicountdown = 20; hulicountdown >= 0; hulicountdown--)
{
if (huli == 0 and digitalRead(kaihePin) == 1)
{
// 清除屏幕
u8g2.firstPage();
do {
//u8g2.drawBox(0, 0, u8g2.getDisplayWidth(), u8g2.getDisplayHeight()); // 绘制一个全屏的矩形用于清除屏幕
// u8g2.setDrawColor(1); // 重新设置字体颜色
u8g2.setFont(u8g2_font_logisoso62_tn);
u8g2.setCursor(0, 63); // 重置光标位置
if (hulicountdown < 10) {
u8g2.print("0"); // 如果倒计时小于10,前面补0
}
if (hulicountdown == 17) //3分钟后打开风扇和加热丝
{
fanJia();
}
if (hulicountdown == 5) //15分钟后打开风扇和加热丝
{
fan();
}
if (hulicountdown == 0) //15分钟后打开风扇和加热丝
{
motorstop();
}
u8g2.print(hulicountdown); // 显示倒计时数字
} while ( u8g2.nextPage() );
delay(1000);
// 等待一秒
}
}
u8g2.clear();
daijixianshi();
motorstop();
zhongduan = 1;
delay(500);//延时0.5秒防止直接判定触发开/关盒功能
Serial.println("跳出");
Serial.println(zhongduan);
huli = 1;
}
void shajundaojishi()//一键杀菌带屏幕倒计时
{
// 如果startTime被设置了(即倒计时已开始)
if (startTime > 0) {
unsigned long currentTime = millis();
if (currentTime < startTime) {
// 计算剩余时间(分钟)
unsigned int remainingMinutes = (startTime - currentTime) / 1000;
if (remainingMinutes == 7) {
fan();
}
// 清除屏幕
u8g2.firstPage();
do {
//u8g2.drawBox(0, 0, u8g2.getDisplayWidth(), u8g2.getDisplayHeight()); // 绘制一个全屏的矩形用于清除屏幕
// u8g2.setDrawColor(1); // 重新设置字体颜色
u8g2.setFont(u8g2_font_logisoso62_tn);
u8g2.setCursor(0, 63); // 重置光标位置
if (remainingMinutes < 10) {
u8g2.print("0"); // 如果倒计时小于10,前面补0
}
u8g2.print(remainingMinutes); // 显示倒计时数字
} while ( u8g2.nextPage() );
} else {
// 如果倒计时结束,则清除startTime和显示消息
motorstop();
startTime = 0;
daijixianshi();
}
}
// 检查按键2是否被按下
if (digitalRead(kaihePin) == LOW) {
delay(1000); // 消抖
if (digitalRead(kaihePin) == LOW) {
// 清除倒计时
startTime = 0;
daijixianshi();
motorstop();
}
}
}
void honggandaojishi(int countdown) { //烘干显示倒计时函数
// 倒计时变量,单位为秒
//static int countdown = 15;
for (countdown; countdown >= 0; countdown--) {
if (honggan and digitalRead(kaihePin) == 1)
{
// 清除屏幕
u8g2.firstPage();
do {
//u8g2.drawBox(0, 0, u8g2.getDisplayWidth(), u8g2.getDisplayHeight()); // 绘制一个全屏的矩形用于清除屏幕
// u8g2.setDrawColor(1); // 重新设置字体颜色
u8g2.setFont(u8g2_font_logisoso62_tn);
u8g2.setCursor(0, 63); // 重置光标位置
if (countdown < 10) {
u8g2.print("0"); // 如果倒计时小于10,前面补0
}
u8g2.print(countdown); // 显示倒计时数字
} while ( u8g2.nextPage() );
delay(1000);
// 等待一秒
}
}
u8g2.clear();
daijixianshi();
}
void xianshi(int x) { //屏幕显示设置时间
// 清除屏幕
u8g2.firstPage();
do {
//u8g2.drawBox(0, 0, u8g2.getDisplayWidth(), u8g2.getDisplayHeight()); // 绘制一个全屏的矩形用于清除屏幕
// u8g2.setDrawColor(1); // 重新设置字体颜色
u8g2.setFont(u8g2_font_logisoso62_tn);
u8g2.setCursor(0, 63); // 重置光标位置
u8g2.print(x); // 显示倒计时数字
} while ( u8g2.nextPage() );
}
void doubleClick1() {//开盒按键双击触发函数
if (zhongduan == 0) {
if (kaiguanFlag == 1) {
Serial.println("开盒键触发");
delay(1000);
kaihemove();
} else {
Serial.println("关盒键触发");
delay(1000);
guanhemove();
}
}
}
void daijixianshi() { //待机显示函数
// u8g2.clearBuffer();
// u8g2.setFont(u8g2_font_ncenB12_tr);
// u8g2.drawStr(0, 13, "Hello World!"); //显示字符串
// u8g2.sendBuffer();
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 13); // 重置光标位置
u8g2.print("hello world"); // 显示倒计时数字
} while ( u8g2.nextPage() );
}