Skip to content

Commit 15c4afd

Browse files
Add files via upload
1 parent f5340b2 commit 15c4afd

File tree

3 files changed

+484
-0
lines changed

3 files changed

+484
-0
lines changed

examples/ButtonDemo/ButtonDemo.ino

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
程序目的:
3+
检测按钮是否按下,如果按下串口打印按钮编号 + is pressed。
4+
一、硬件材料
5+
1*Arduino uno开发板
6+
7*按钮/按键
7+
二、电路接线
8+
Arduino UNO 的 GND 接 所有按钮 的 引脚1
9+
Arduino UNO 的 2 接 1号按钮 的 引脚2
10+
Arduino UNO 的 3 接 2号按钮 的 引脚2
11+
Arduino UNO 的 4 接 3号按钮 的 引脚2
12+
Arduino UNO 的 5 接 4号按钮 的 引脚2
13+
Arduino UNO 的 6 接 5号按钮 的 引脚2
14+
Arduino UNO 的 7 接 6号按钮 的 引脚2
15+
Arduino UNO 的 8 接 7号按钮 的 引脚2
16+
详见接线图
17+
三、程序上传
18+
第1步:打开Arduino软件,依次点击 -> 工具 -> 开发板选择"Arduino Mega"
19+
第2步:依次点击 -> 工具 -> 端口选择你自己电脑Arduino的COM口,一般是com3开始,如COM3,COM7
20+
第3步:点击上传(Arduino软件左上角对勾旁边的图标)
21+
四、程序原理
22+
采用非阻塞式实现消抖
23+
五、预期效果
24+
1、如果按下按钮,串口打印按钮编号 + is pressed。
25+
2、支持多个按钮同时按下
26+
六、可能的问题
27+
1、接线不对
28+
仔细核对接线图接线
29+
七、参考的资料
30+
Arduino的例程
31+
File → Examples → 02.Digital → Debounce
32+
33+
文件 → 示例 → 02.Digital → Debounce
34+
Arduino教程
35+
https://space.bilibili.com/103589285/video?tid=0&page=4&keyword=&order=pubdate
36+
https://www.geek-workshop.com/thread-2719-1-1.html
37+
https://www.yiboard.com/forum-70-1.html
38+
八、特别注意
39+
1、Arduino UNO的D13不支持INPUT_PULLUP。
40+
2、因为采用INPUT_PULLUP,所以默认是高电平,按下是低电平。如果电路是下拉输入,需要改动相对应的代码。
41+
*/
42+
#define startButton 2 //0号按钮
43+
#define buttonPin1 3 //1号按钮
44+
#define buttonPin2 4 //2号按钮
45+
#define buttonPin3 5 //3号按钮
46+
#define buttonPin4 6 //4号按钮
47+
#define buttonPin5 7 //5号按钮
48+
#define buttonPin6 8 //6号按钮
49+
//把所有按钮放入一个数组以便于操作
50+
const int buttonPins[7] = {startButton, buttonPin1, buttonPin2, buttonPin3, buttonPin4, buttonPin5, buttonPin6};
51+
#define buttonON LOW //按钮按下时为低电平
52+
struct Button{
53+
int buttonState = !buttonON; //按钮状态变量,与按钮按下时的状态取反
54+
int lastButtonState = !buttonON; //按钮状态初始化,与按钮按下时的状态取反
55+
long lastDebounceTime = 0; //记录抖动变量
56+
long debounceDelay = 30; //抖动时间变量
57+
bool flag = false; //按钮flag
58+
};
59+
Button button, buttons[7]; //新建1个按钮,和按钮数组,数组含有七个按钮
60+
61+
// the setup function runs once when you press reset or power the board
62+
void setup() {
63+
Serial.begin(9600); //初始化串口,波特率为9600
64+
initButtons(); //初始化所有按键串口
65+
}
66+
67+
// the loop function runs over and over again forever
68+
void loop() {
69+
getButton(startButton); //适用于单个按钮
70+
for(int i = 0; i < sizeof(buttonPins) / sizeof(buttonPins[0]); i++){
71+
getButton(buttonPins[i],i); //适用于多个按钮
72+
}
73+
}
74+
/*********************************************************
75+
* 函数功能:按钮初始化函数,设置为上拉输入
76+
* 入口参数:无
77+
* 返回 值:无
78+
*********************************************************/
79+
void initButtons(){
80+
pinMode(startButton, INPUT_PULLUP); //适用于单个按钮
81+
for(int i = 0; i < sizeof(buttonPins) / sizeof(buttonPins[0]); i++){
82+
pinMode(buttonPins[i], INPUT_PULLUP); //适用于多个按钮
83+
}
84+
}
85+
86+
/*********************************************************
87+
* 函数功能:按钮输入读取,采用非阻塞式按键消抖,适用于多个按钮
88+
* 入口参数:int按钮引脚,int按钮数组编号,此时可选0 1 2
89+
* 返回 值:无
90+
*********************************************************/
91+
void getButton(int _buttonPin,int _buttonIndex){
92+
int reading = digitalRead(_buttonPin); //读取状态
93+
if(reading != buttons[_buttonIndex].lastButtonState){ //如果状态改变
94+
buttons[_buttonIndex].lastDebounceTime = millis(); //更新时间
95+
} //如果等待大于debounceDelay
96+
if((millis() - buttons[_buttonIndex].lastDebounceTime) > buttons[_buttonIndex].debounceDelay){
97+
if(reading != buttons[_buttonIndex].buttonState){ //读取状态不等于按钮状态
98+
buttons[_buttonIndex].buttonState = reading; //更新状态
99+
if(buttons[_buttonIndex].buttonState == buttonON){//判断按钮是否真的按下
100+
Serial.print(_buttonIndex); //打印按钮编号
101+
Serial.println(" is pressed"); //输出按钮按下的文字
102+
buttons[_buttonIndex].flag = true; //按钮flag为真
103+
}
104+
else{
105+
buttons[_buttonIndex].flag = false; //按钮flag为假
106+
}
107+
}
108+
}
109+
buttons[_buttonIndex].lastButtonState = reading; //更新last状态
110+
}
111+
112+
/*********************************************************
113+
* 函数功能:按钮输入读取,采用非阻塞式按键消抖,适用于单个按钮
114+
* 入口参数:int按钮引脚
115+
* 返回 值:无
116+
*********************************************************/
117+
void getButton(int _buttonPin){
118+
int reading = digitalRead(_buttonPin); //读取状态
119+
if(reading != button.lastButtonState){ //如果状态改变
120+
button.lastDebounceTime = millis(); //更新时间
121+
} //如果等待大于debounceDelay
122+
if((millis() - button.lastDebounceTime) > button.debounceDelay){
123+
if(reading != button.buttonState){ //读取状态不等于按钮状态
124+
button.buttonState = reading; //更新状态
125+
if(button.buttonState == buttonON){ //判断按钮是否真的按下
126+
Serial.println("button is pressed"); //输出按钮按下的文字
127+
button.flag = true; //按钮flag为真
128+
}
129+
else{
130+
button.flag = false; //按钮flag为假
131+
}
132+
}
133+
}
134+
button.lastButtonState = reading; //更新last状态
135+
}

examples/LedDemo/LedDemo.ino

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
程序目的:
3+
1、批量化操作LED。
4+
2、无阻塞实现呼吸灯。
5+
一、硬件材料
6+
1*Arduino uno开发板
7+
10*LED
8+
二、电路接线
9+
Arduino UNO 的 GND 接 所有LED 的 负极
10+
Arduino UNO 的 2 接 1号LED 的 正极
11+
Arduino UNO 的 3 接 2号LED 的 正极
12+
Arduino UNO 的 4 接 3号LED 的 正极
13+
Arduino UNO 的 5 接 4号LED 的 正极
14+
Arduino UNO 的 6 接 5号LED 的 正极
15+
Arduino UNO 的 7 接 6号LED 的 正极
16+
Arduino UNO 的 8 接 7号LED 的 正极
17+
Arduino UNO 的 9 接 8号LED 的 正极
18+
Arduino UNO 的 10 接 9号LED 的 正极
19+
Arduino UNO 的 11 接 10号LED 的 正极
20+
详见接线图
21+
三、程序上传
22+
第1步:打开Arduino软件,依次点击 -> 工具 -> 开发板选择"Arduino Mega"
23+
第2步:依次点击 -> 工具 -> 端口选择你自己电脑Arduino的COM口,一般是com3开始,如COM3,COM7
24+
第3步:点击上传(Arduino软件左上角对勾旁边的图标)
25+
四、程序原理
26+
采用非阻塞式实现呼吸灯
27+
五、预期效果
28+
1、支持多个LED同时呼吸灯
29+
六、可能的问题
30+
1、接线不对
31+
仔细核对接线图接线
32+
七、参考的资料
33+
File → Examples → 01.Basics → Fade
34+
35+
文件 → 示例 → 01.Basics → Fade
36+
Arduino教程
37+
https://space.bilibili.com/103589285/video?tid=0&page=4&keyword=&order=pubdate
38+
https://www.geek-workshop.com/thread-2719-1-1.html
39+
https://www.yiboard.com/forum-70-1.html
40+
八、特别注意
41+
1、因为采用正逻辑,高电平点亮,低电平熄灭。如果电路是负逻辑,需要改动相对应的代码。
42+
2、结合实际项目情况,选用合适的写法。一种是整体法,另一种是分块法。
43+
*/
44+
45+
#define ledPin1 2 //1号LED
46+
#define ledPin2 3 //2号LED
47+
#define ledPin3 4 //3号LED
48+
#define ledPin4 5 //4号LED
49+
#define ledPin5 6 //5号LED
50+
#define ledPin6 7 //6号LED
51+
#define ledPin7 8 //7号LED
52+
#define ledPin8 9 //8号LED
53+
#define ledPin9 10 //9号LED
54+
#define ledPin10 11 //10号LED
55+
//所有LED存入数组以便于批量化操作
56+
const int ledPins[13] = {ledPin1, ledPin2,
57+
ledPin3, ledPin4,
58+
ledPin5, ledPin6,
59+
ledPin7, ledPin8,
60+
ledPin9, ledPin10};
61+
62+
#define LEDON HIGH//点亮LED灯
63+
#define LEDOFF LOW //熄灭LED灯
64+
65+
struct Led {
66+
long previousMillis; //存储事件发生的最后时间。
67+
int brightness = 0; //定义整数型变量brightness与其初始值,此变量用来表示LED的亮度。
68+
bool flag; //判断标志
69+
};
70+
Led led[2]; //新建2个led
71+
72+
// the setup function runs once when you press reset or power the board
73+
void setup() {
74+
Serial.begin(9600); //初始化串口,波特率为9600
75+
initLEDs(); //初始化所有LED
76+
}
77+
78+
// the loop function runs over and over again forever
79+
void loop() {
80+
//下面3个子函数采用整体的思维,也就是亮度计算和输出亮度是在同一个函数实现
81+
ledBreath(ledPin2, 1, 100); //led2以每100ms变化亮度1的速度呼吸
82+
ledBreath(ledPin4, 5, 10); //led4以每10ms变化亮度5的速度呼吸
83+
ledBreath(ledPin5, 10, 200);//led5以每200ms变化亮度10的速度呼吸
84+
//下面2个if采用分块的思维,也就是亮度计算和输出亮度是2个维度
85+
if (ledBreath(ledPin8, 0, 1, 50) == true) {
86+
analogWrite(ledPin8 , led[0].brightness);
87+
}
88+
if (ledBreath(ledPin9, 1, 5, 100) == true) {
89+
analogWrite(ledPin9, led[1].brightness);
90+
}
91+
}
92+
/*********************************************************
93+
* 函数功能:LED初始化函数
94+
* 入口参数:无
95+
* 返回 值:无
96+
*********************************************************/
97+
void initLEDs() {
98+
for (int i = 0; i < sizeof(ledPins) / sizeof(ledPins[0]); i++) {
99+
pinMode(ledPins[i], OUTPUT); //所有LED引脚设置为输出
100+
digitalWrite(ledPins[i], LEDOFF); //所有LED熄灭
101+
}
102+
}
103+
/*********************************************************
104+
* 函数功能:LED呼吸灯效果,采用非阻塞式按键消抖,适用于多个LED
105+
* 入口参数:int LED引脚,int LED数组编号(0 1 2)、int 亮度变化亮、int 变化间隔
106+
* 返回 值:无
107+
*********************************************************/
108+
void ledBreath(int _ledPin, int _fadeAmount, int _period) {
109+
static unsigned long breathPeriod = millis(); //亮度变化的时间片刻
110+
static int brightness = 0; //亮度值
111+
if (millis() - breathPeriod >= _period) { //是否已经过去了"_period" ms。
112+
breathPeriod = millis(); //记录亮度变化的时间片刻
113+
brightness += _fadeAmount; //亮度值增加或减少
114+
if (brightness <= 0 || brightness >= 255) { //是否达到临界点
115+
_fadeAmount = -_fadeAmount; //达到临界点,亮度变化量翻转
116+
}
117+
analogWrite(_ledPin, brightness); //输出LED亮度
118+
}
119+
}
120+
/*********************************************************
121+
* 函数功能:LED呼吸灯效果,采用非阻塞式按键消抖,适用于多个LED
122+
* 入口参数:int LED数组编号(0 1 2)、int 亮度变化亮、int 变化间隔
123+
* 返回 值:无
124+
*********************************************************/
125+
bool ledBreath(int _ledPin, int _index, int _fadeAmount, int _period) { //_fadeAmount为每次led变化的亮度值,_period为led每次变化的间隔时间
126+
if (millis() - led[_index].previousMillis >= _period){ //是否已经过去了"_period" ms。
127+
led[_index].previousMillis = millis(); //记录亮度变化的时间片刻
128+
led[_index].flag = true; //将状态标志记录为true
129+
led[_index].brightness += _fadeAmount; //每次led的亮度变化_fadeAmount
130+
if (led[_index].brightness <= 0 || led[_index].brightness >= 255) { //达到临界点,亮度变化量翻转
131+
_fadeAmount = -_fadeAmount;
132+
}
133+
Serial.print(_index + 1);
134+
Serial.print("号led的亮度为:");
135+
Serial.println(led[_index].brightness); //打印出led的亮度值
136+
}
137+
else { //如果未达到"_period" ms,那么就把状态记为false
138+
led[_index].flag = false;
139+
}
140+
return led[_index].flag; //返回flag值
141+
}

0 commit comments

Comments
 (0)