#include <Arduino.h>
#include <U8g2lib.h>//导入U8G2库,显示器
#include "OneButton.h"//导入onebutton库,按键多状态
#include <FastLED.h>//导入WS2812,控制RGB LES
#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
/***RGB LEDS库配置***/
#define NUM_LEDS 4 // 定义LED灯的数量,根据你的灯带长度修改这个值
#define DATA_PIN 13 // 定义连接WS2812B的数据线所连接的Arduino引脚,根据你的连接修改这个值
CRGB leds[NUM_LEDS]; // 创建一个CRGB数组来代表LED灯带
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 kaiguanFlag = 1; //设置开关标志
bool zhongduan = 0;
unsigned long startTime = 0; //一键杀菌时间
unsigned long startTime2 = 0; //一键护理时间
unsigned long startTime3 = 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.setDebounceTicks(50);//按钮去抖动50毫秒
button1.setClickTicks(500);//时间判定500毫秒 半秒
button1.attachDoubleClick(doubleClick1);//当button1双击时,运行doubleClick1函数
// 1000ms后,开启长按
button1.setPressTicks(800);//长按时间判定800毫秒后算长按
button1.attachDuringLongPress(longPress1);//长按
//RGB LEDS相关
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS); // 初始化LED灯带,指定芯片类型、数据引脚和颜色顺序
FastLED.setBrightness(255); // 设置全局亮度,范围0-255
daijixianshi();
}
void loop()
{
// put your main code here, to run repeatedly:
zhongduan = 0;
button1.tick();//开盒按键触发
if (digitalRead(huliPin) == 0) //一键护理按键按下
{
delay(10); // 消抖
if (digitalRead(huliPin) == LOW) {
// 设置倒计时为10分钟后
fan();//打开风扇
delay(1000);//延迟1秒
fanChou();//打开风扇和臭氧
startTime2 = millis() + 20000;
}
}
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 startTime0 = 0; //定义起始时间
startTime0 = millis();
while (millis() - startTime0 <= 3000)
{
delay(100);
Serial.println(time);
if (digitalRead(hongganPin) == LOW)
{
time += 10;
if (time > 60) {
time = 10;
}
Serial.println(time);//屏幕时间显示
xianshi(time);
startTime0 = millis(); //将开始时间重置为最新按下按键的时候。
continue;
}
}
fanJia();
startTime3 = millis() + (time * 1000); //time*x,x代表倒计时单位,秒1000,分钟60000
}
shajundaojishi();
hulidaojishi();
honggandaojishi(startTime3);
}
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() { //风扇和臭氧继电器打开
led_blue();
Serial.println("风扇和臭氧继电器打开,蓝灯,黄灯亮");
byte fanchou = B00000110; // 二进制表示,表示LED的点亮模式
// 使用shiftOut函数发送数据到74HC595
shiftOut(dataPin, clockPin, MSBFIRST, fanchou);
// 上升沿锁存数据
digitalWrite(latchPin, HIGH);
delayMicroseconds(1); // 保持高电平一小段时间
digitalWrite(latchPin, LOW); // 然后拉低
}
void fanJia() { //风扇和加热丝继电器打开
led_yellow();
Serial.println("风扇和加热丝继电器打开,红灯,黄灯亮");
byte fanjia = B00000101; // 二进制表示,表示LED的点亮模式
// 使用shiftOut函数发送数据到74HC595
shiftOut(dataPin, clockPin, MSBFIRST, fanjia);
// 上升沿锁存数据
digitalWrite(latchPin, HIGH);
delayMicroseconds(1); // 保持高电平一小段时间
digitalWrite(latchPin, LOW); // 然后拉低
}
void hulidaojishi()//循环调用:一键护理带屏幕倒计时
{
// 如果startTime被设置了(即倒计时已开始)
if (startTime2 > 0) {
unsigned long currentTime2 = millis();
if (currentTime2 < startTime2) {
// 计算剩余时间(分钟)
unsigned int remainingMinutes2 = (startTime2 - currentTime2) / 1000;
if (remainingMinutes2 == 17) {
fanJia();
}
if (remainingMinutes2 == 5) {
fan();
}
// 清除屏幕
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_logisoso62_tn);
u8g2.setCursor(0, 63); // 重置光标位置
if (remainingMinutes2 < 10) {
u8g2.print("0"); // 如果倒计时小于10,前面补0
}
u8g2.print(remainingMinutes2); // 显示倒计时数字
} while ( u8g2.nextPage() );
} else {
// 如果倒计时结束,则清除startTime和显示消息
motorstop();
startTime2 = 0;
daijixianshi();
}
}
}
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.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();
}
}
}
void honggandaojishi(unsigned long time3) { //循环调用:烘干显示倒计时函数
// 如果startTime被设置了(即倒计时已开始)
if (time3 > 0) {
unsigned long currentTime3 = millis();
if (currentTime3 < time3) {
// 计算剩余时间(分钟)
unsigned int remainingMinutes3 = (time3 - currentTime3) / 1000;
// 清除屏幕
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_logisoso62_tn);
u8g2.setCursor(0, 63); // 重置光标位置
if (remainingMinutes3 < 10) {
u8g2.print("0"); // 如果倒计时小于10,前面补0
}
u8g2.print(remainingMinutes3); // 显示倒计时数字
} while ( u8g2.nextPage() );
} else {
// 如果倒计时结束,则清除startTime和显示消息
motorstop();
startTime3 = 0;//传参函数,在对传参判断时,不能通过修改实参的代名词的值来改变判断
daijixianshi();
}
}
}
void xianshi(int x) { //屏幕显示设置时间
// 清除屏幕
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_logisoso62_tn);
u8g2.setCursor(0, 63); // 重置光标位置
u8g2.print(x); // 显示倒计时数字
} while ( u8g2.nextPage() );
}
void doubleClick1() {//开盒按键双击触发函数
Serial.println("双击触发");
if (zhongduan == 0) {
if (kaiguanFlag == 1) {
Serial.println("开盒键触发");
delay(1000);
kaihemove();
} else {
Serial.println("关盒键触发");
delay(1000);
guanhemove();
}
}
}
void longPress1() {//开盒按键双击触发函数
startTime = 0;
startTime2 = 0;
startTime3 = 0;
daijixianshi();
motorstop();
}
void daijixianshi() { //待机显示函数
led_white();
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 13); // 重置光标位置
u8g2.print("hello world"); // 显示倒计时数字
} while ( u8g2.nextPage() );
}
void led_blue() { //led亮蓝色
//FastLED.setBrightness(255);
fill_solid(leds, NUM_LEDS, CRGB::Blue);
FastLED.show();
delay(5000);
}
void led_yellow() { //led亮黄色
// FastLED.setBrightness(255);
fill_solid(leds, NUM_LEDS, CRGB::Yellow);
FastLED.show();
delay(5000);
}
void led_white() { //led亮白色
// FastLED.setBrightness(255);
fill_solid(leds, NUM_LEDS, CRGB::White);
FastLED.show();
delay(5000);
}