第2节 硬件端的开发
现在,我们开始实现智能LED灯硬件相关部分的设计。
2.1 硬件连接
选择了Arduino MEGA 、HC-06蓝牙模块、LED灯模块和三引脚按钮开关以后,我们就需要把它们组合起来,为我们所用了。
因为同一个开发板要连接多个外接硬件,这时就需要Arduino扩展板出场了。
Arduino拥有很多的扩展板,其中有一种扩展板可以把Arduino开发板中的引脚,按照引脚-电源VCC-接地GND
这样的组合,一组一组的扩展出来,方便开发者插拔。这个开发板就能很方便的解决我们现在遇到的VCC
接口不够用的问题。
将Arduino开发板和扩展板上下插入后,引脚就扩展出来了,
![](https://i-blog.csdnimg.cn/blog_migrate/bd379752a128ff95ec2c9788408044f7.png)
HC-06蓝牙模块有4个引脚需要与开发板连接,这里我们选择使用MEGA开发板的Serial2
作为蓝牙模块的通信端口。Serial2
使用D16作为TX、D17作为RX,
扩展板引脚 | 连接 | 蓝牙模块引脚 |
---|---|---|
17组V | <—> | 电源VC |
17组G | <—> | 接地GND |
16组S(TX) | <—> | 输入RX |
17组S(RX) | <—> | 输出TX |
![](https://i-blog.csdnimg.cn/blog_migrate/aa788b44c345dec40f19090ab7a3b336.png)
没有选择Serial
(D0和D1引脚)是因为,希望用它来输出调试信息到电脑的串口,如果都使用Serial
的话,同一个通路就会出现两类完全没有联系的信息,
*如果你对蓝牙模块详细的使用方式感到陌生的话,请先参考蓝牙传输一文。
LED灯模块有3个引脚需要与开发板连接。这里我们选择MEGA板的D45
引脚作为LED灯的PWM
控制引脚(当然可以选择任何其它具有PWM功能的引脚),
扩展板引脚 | 连接 | LED灯模块引脚 |
---|---|---|
45组V | <—> | + |
45组G | <—> | G |
45组S | <—> | S |
![](https://i-blog.csdnimg.cn/blog_migrate/701fade47d337f133cbbe9ed23f90d07.png)
*如果你对LED灯模块详细的使用方式感到陌生的话,请先参考控制LED灯一文。
最后,将按钮开关接入Arduino MEGA开发板的D44引脚,
扩展板引脚 | 连接 | LED灯模块引脚 |
---|---|---|
44组V | <—> | 中间未标注 |
44组G | <—> | - |
44组S | <—> | S |
![](https://i-blog.csdnimg.cn/blog_migrate/89443069e4a022ad2048e45904697e84.png)
*如果你对按钮模块详细的使用方式感到陌生的话,请先参考按钮开关一文。
全部组装好后,如下图,
![](https://i-blog.csdnimg.cn/blog_migrate/efed2fa6ed95370288626e6890572b55.png)
2.2 代码实现
2.2.1 亮度调节命令
要控制LED灯,就要给LED灯发送命令。因此我们需要定一个命令的格式,让Arduino开发板读懂操作者的意图。
为了简单,我们将命令定义成最简单的形式:一个命令只有一个字节(1byte),一个字节有八位(8bit)。而调解LED灯模块的PWM引脚刚好有256级,也就是8bit的大小(00000000~11111111,刚好是256级)。所以我们定义,手机控制端每发送给LED灯的每一个字节的内容,就是要求LED灯显示的亮度。
发送的命令 | 对应的亮度 |
---|---|
0x00 | 0级 |
0x01 | 1级 |
… | … |
0x2F | 47级 |
… | … |
0xFF | 255级 |
2.2.2 控制逻辑
初始化时,在
setup()
函数中,//定义LED灯模块使用的引脚编号, //这里使用的是数字引脚45, //这是一个具有PWM功能的引脚 int LED_PIN = 45; //定义按钮开关使用的引脚编号, //这里使用的是数字引脚44, int BUTTON_PIN = 44; void setup() { //设置LED灯的引脚为输出 pinMode(LED_PIN, OUTPUT); //设置按钮开关的引脚为输入 pinMode(BUTTON_PIN, INPUT); //初始化与电脑串口通信的串口, //以后的调试信息就通过Serial发送出去 Serial.begin(9600); //初始化与蓝牙模块通信的串口, //以后通过蓝牙接收调试命令就通过Serial2 Serial2.begin(9600); }
系统运行当中,不断的尝试从蓝牙模块读取命令,一旦接收到命令,就根据命令的内容,调整LED灯的灯光亮度。
//创建读取数据用的缓存 char buffer [1]; void loop() { //如果蓝牙串口可以读取数据 if (Serial2.available()) { //读取数据到buffer中 int nReadSize = Serial2.readBytes(buffer, 1); //如果成功读取到数据,就根据读到的值设置LED灯的亮度 if(nReadSize > 0) { //输出调试信息到电脑上的串口, //电脑串口可以打印出内容 Serial.print("Receive command:"); int cmd = buffer[0]; Serial.println(cmd); //设置LED灯的亮度 analogWrite(LED_PIN, buffer[0]); } } }
增加对按钮开关的逻辑控制,
char buffer[1]; //累计按钮按下和松开的次数, //根据次数来判断当前应该打开电源还是关闭电源 int keyPressCount = 0; //记录前一个按钮的开关状态 int oldButtonState = HIGH; void loop() { int buttonState = digitalRead(BUTTON_PIN); bool powerChange = false; //判断当前是否是按下按钮 if ((buttonState == LOW) && (oldButtonState == HIGH)) { Serial.println("power press down"); keyPressCount++; powerChange = true; oldButtonState = buttonState; } //判断当前是否是松开按钮 if ((buttonState == HIGH) && (oldButtonState == LOW)) { Serial.println("power press up"); keyPressCount++; powerChange = true; oldButtonState = buttonState; } //按键消息累积为偶数时,说明用户完成了一次按钮操作 if (powerChange && (keyPressCount % 2 == 0)) { //如果当前是开灯状态,那么现在就要关闭灯 if (powerOnOff) { Serial.println("power off"); analogWrite(LED_PIN, 0); powerOnOff = false; } //如果当前是关灯状态,那么现在就要开灯 else { Serial.println("power on"); analogWrite(LED_PIN, 255); powerOnOff = true; } return; } if (Serial2.available()) { int nReadSize = Serial2.readBytes(buffer, 1); if (nReadSize > 0) { Serial.println("Receive command"); int cmd = buffer[0]; Serial.println(cmd); //手机遥控调节灯光强度, //说明当前是开灯的状态 powerOnOff = true; analogWrite(LED_PIN, buffer[0]); } } }
将程序部署到Arduino MEGA开发板上。
/*******************************************************************/
本系列课程使用到的Arduino开发板、扩展板以及其他相关的传感器,各位可以根据我们文章中介绍的硬件在淘宝网选购。
您也可以在我们的网店跟我学Arduino编程中购买,这些相关硬件都由我们为您把关购买,为大家节省选择的精力与时间。同时也感谢大家对我们这些码农的支持。
最后再次感谢各位读者对安豆
的支持,谢谢:)
/*******************************************************************/