#include <Arduino.h>
#include <U8g2lib.h>//导入U8G2库
#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屏幕的初始化
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引脚
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; // 上一次点击的时间
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();
}
void loop()
{
// put your main code here, to run repeatedly:
//双击开盒按键开盒未完成
//只修改一键护理功能
// put your main code here, to run repeatedly:
zhongduan = 0;
if (digitalRead(kaihePin) == 0 and zhongduan == 0)
{ //开盒按键被按下
if (kaiguanFlag == 1) {
Serial.println("开盒键触发");
delay(1000);
kaihemove();
} else {
Serial.println("关盒键触发");
delay(1000);
guanhemove();
}
}
if (digitalRead(huliPin) == 0) //一键护理按键按下
{
huli = 0;
//yijianhuli();
hulidaojishi();
}
if (digitalRead(shajunPin) == 0) //杀菌按键按下
{
yijianshajun();
}
if (digitalRead(hongganPin) == 0) //烘干按键按下
{
yijianhonggan();
}
}
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 yijianhuli() { //一键护理动作,不带屏幕倒计时
buttonPressTime = millis(); //记录当前时间
delay(500);
Serial.println("护理键触发");
fan();
// Serial.println(millis()-buttonPressTime);
while (huli and digitalRead(kaihePin) == 1)
{
if (millis() - buttonPressTime >= 0 and (millis() - buttonPressTime) <= 1000)
{
// Serial.println(millis());
fanChou();
}
if ((millis() - buttonPressTime) > 1000 and (millis() - buttonPressTime) <= 5000 )
{ //实际时间3分钟
fanJia();
}
if ((millis() - buttonPressTime) > 5000 and (millis() - buttonPressTime) <= 10000)
{ //实际时间12分钟
fan();
}
if ((millis() - buttonPressTime) > 10000 and (millis() - buttonPressTime) <= 15000)
{ //实际时间5分钟
motorstop();
huli = 0;
}
}
motorstop();
zhongduan = 1;
delay(500);//延时0.5秒防止直接判定触发开/关盒功能
Serial.println("跳出");
huli = 1;
}
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);
// 等待一秒
}
}
motorstop();
zhongduan = 1;
delay(500);//延时0.5秒防止直接判定触发开/关盒功能
Serial.println("跳出");
Serial.println(zhongduan);
huli = 1;
}
void yijianshajun() { //杀菌动作
buttonPressTime = millis(); //记录当前时间
delay(500);
Serial.println("杀菌键触发");
fan();
// Serial.println(millis()-buttonPressTime);
while (shajun and digitalRead(kaihePin) == 1)
{
if (millis() - buttonPressTime >= 0 and (millis() - buttonPressTime) <= 1000)
{
fanChou();
}
if ((millis() - buttonPressTime) > 1000 and (millis() - buttonPressTime) <= 5000 )
{ //实际时间3分钟
fan();
}
if ((millis() - buttonPressTime) > 10000 and (millis() - buttonPressTime) <= 15000)
{ //实际时间7分钟
motorstop();
shajun = 0;
}
}
motorstop();
zhongduan = 1;
delay(500);//延时0.5秒防止直接判定触发开/关盒功能
Serial.println("跳出");
shajun = 1;
}
void yijianhonggan() { //一键烘干动作
buttonPressTime = millis(); //记录当前时间
delay(500);
Serial.println("烘干键触发");
fan();
// Serial.println(millis()-buttonPressTime);
while (honggan and digitalRead(kaihePin) == 1)
{
if (millis() - buttonPressTime >= 0 and (millis() - buttonPressTime) <= 1000)
{ //实际时5秒
// Serial.println(millis());
fanJia();
}
if ((millis() - buttonPressTime) > 1000 and (millis() - buttonPressTime) <= 5000 )
{ //实际时间10分钟
fan();
}
if ((millis() - buttonPressTime) > 10000 and (millis() - buttonPressTime) <= 15000)
{ //实际时间1分钟
motorstop();
honggan = 0;
}
}
motorstop();
zhongduan = 1;
delay(500);//延时0.5秒防止直接判定触发开/关盒功能
Serial.println("跳出");
honggan = 1;
}
void daojishi(int countdown) { //屏幕显示倒计时函数
// 倒计时变量,单位为秒
//static int countdown = 15;
for (countdown; countdown >= 0; countdown--) {
// 清除屏幕
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);
// 等待一秒
}
}
void xianshi() { //屏幕显示设置时间
int countdown = 15;
// 清除屏幕
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(countdown); // 显示倒计时数字
} while ( u8g2.nextPage() );
}