HC04-Arduino UNO-LED开关
像所有新手一样先用蓝牙实现LED的开关。以为很简单,但依然遇见了不少问题。
一、硬件连接
int LED = 13; void setup() { Serial.begin(9600); pinMode(LED,OUTPUT); //设置数字13 口为输出接口 } void loop() { while(Serial.available()) //检测:【串口】如果数据写入,则执行。 { char recive_data; recive_data = Serial.read(); Serial.print(recive_data); if(recive_data=='1'){ digitalWrite(LED,HIGH);} //IO口13设置为高电平,点亮数字13口LED else if(recive_data=='0'){ digitalWrite(LED,LOW);} } }首先说一下我的电路连线,我是直接利用了Arduino的RX(pin0)和TX(pin1)口和HC04的TXD和RXD相连,然后VCC接5V,LED接pin13口。当我将上图写好的程序编译完成,想要上传时,就遇见了一个问题,请看下图。
这是什么情况呢,问了一下D老师。说是Arduino 的串口被其他设备干扰了。具体来说,蓝牙模块的 TX 和 RX 引脚连接到了 Arduino 的引脚 0(RX)和引脚 1(TX)上,而这两个引脚也是计算机通过 USB 与 Arduino 通信时使用的串口引脚。电脑通过 USB 上传程序或打开串口监视器时,会与蓝牙模块争抢引脚,导致冲突(上传失败、数据混乱等)。
解决办法呢就很粗暴了,就是在烧录之前拔掉蓝牙模块的VCC或者GND,或者直接拔掉整个模块。
当然还有别的一劳永逸的解决方式,引用SoftwareSerial。Arduino Uno 等开发板通常只有一个硬件串口。SoftwareSerial是 Arduino 的一个库,它允许你使用任意两个数字输入/输出引脚来模拟串行通信(也就是虚拟出一个串口)。简单来说,它可以让你的 Arduino 用其他引脚“假装”成 RX 和 TX,与串口设备(比如蓝牙模块、GPS 模块、传感器等)进行通信。
那这个SoftwareSerial怎么用呢?
二、SoftwareSerial 的基本用法
SoftwareSerial有个头文件哈,不要忘了。
SoftwareSerial mySerial= SoftwareSerial(rxPin, txPin)
mySerial:用户自定义软件串口对象
rxPin:软串口接收引脚
txPin:软串口发送引脚
以下是用SoftwareSerial写的代码。BT是我设定的串口名称,pin8是新串口的rx引脚,与蓝牙模块的tx引脚连,pin9是新串口的tx引脚。其中我还多加了一个部分,也就是可以通过电脑(Arduino IDE的串口监视器)发给Arduino的数据转发到蓝牙上,手机蓝牙串口模块显示接受的数据。
#include <SoftwareSerial.h> //库文件 SoftwareSerial BT(8, 9); //SoftwareSerial mySerial(rxPin, txPin)。设置蓝牙与板子的连接端口。 pin 8 接蓝牙的 TXD pin 9 接蓝牙的 RXD char recive_data; //定义一个变量存数据。 int LED = 13; //在setup中启动串口 void setup() { Serial.begin(9600); //硬件串口(与电脑通信) BT.begin(9600); //软件串口(与蓝牙通信)。这里的BT名称是设置蓝牙与板子连接时的串口名称 pinMode(LED,OUTPUT); } void loop() //从电脑或者蓝牙中读取数据 { if (Serial.available()) //从电脑读取数据。检测:【串口】如果数据写入,则执行。 { recive_data = Serial.read(); //把写入的数据给到自定义变量 X BT.print(recive_data); //把数据给蓝牙 } if (BT.available()) //从蓝牙读取数据。检测:【蓝牙】如果数据写入,则执行。 { recive_data = BT.read(); //把检测到的数据给到自定义变量 X Serial.print(recive_data); //把从蓝牙得到的数据显示到串口监视器 } if(recive_data=='1'){ digitalWrite(LED,HIGH);} else if(recive_data=='0'){ digitalWrite(LED,LOW);} }三、其他
其实运行过程还遇见了一个小问题,就是在判读数据为0/1时,我发现LED怎么都不亮。百思不得其解时,还是D老师帮我解决的。
问题出在我用的双引号if(recive_data == "1")。单引号 '1' 表示字符,而双引号 "1" 表示字符串。而我最开始定义的变量为char字符类型,所以实际上我是在将一个字符和一个字符串来比较,所以结果永远为假,那么digitalWrite(LED,HIGH)永远不会执行。
