JDY-24M蓝牙应用探索

1.入门级应用–手机连接蓝牙控制
本次将使用3个jdy-24m互相组网控制,三个蓝牙地址0077,0088,0099。
实现:连接三个蓝牙中任意一个,发送指令控制对应的arduino的灯珠上的亮度。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
arduino代码
int serialData=0; //串口数据变量
byte variable[80];//数组
byte index = 0;//数据位
int a=0;//亮度初始为0
void setup() {
Serial.begin(9600);
pinMode(9,OUTPUT);//9号引脚接灯正极,避免灯珠烧坏,随便串上一个电阻
}
void loop() {
while( Serial.available()>0 )//当串口有收到数据
{ //当串口有数据时
byte serialData = Serial.read();// 由于Serial.read()每次只读取一个字节,而一个字节八位,每次读取两个16进制位(例0x16是一个字节,可以看成0001 0110 八位),这也是为什么数据位数要偶数才行,然后赋给serialData
variable[index++] = serialData;//index每次+1,variable[0]为读取到的第一个字节,variable[1]为读取到的第二个字节…
//这一段是让数据位不错乱的,下边我写了接收数据长度10,如果数据长度不小心发了9,数据位index没有变为0,就会一直叠加下去。然后这里是有一个矫正的作用。
byte forward[]={0xF1};
xunhuan:
if ((variable[0] != forward[0]) && index >= 1 ){
for(int i=0; i < index; i++)
{
variable[i] = variable[i+1];
}
index–;
goto xunhuan;
}
//当数据位为10位时候,就执行。
if (index==10)
{//把接收到一串字节,整齐并在一行
for (int i=0;i<10;i++)
{Serial.print(variable[i], HEX);
delay(10);}
Serial.println("");
//把接收到一串字节,每个字节单独拿出来
for (int i=0;i<10;i++)
{ Serial.println(variable[i], HEX);
}
//上面这两个for循环其实也可以不用,只不过在实践的时候还是显示出来比较好,可以好判断有没有收到,然后数据规律是什么。

if (variable[8]>=0x00 && variable[8] <= 0xff) //读取这段数据的第9位,0xFF转化成10进制就是255,就是最亮的,0x00就是对应0,亮度为0x00到0xff之间。
{
a=variable[8];//把亮度值赋给a
}
index=0;//数据位清0
}
}
analogWrite(9,a);//执行亮度语句放在while( Serial.available()>0 )外部,采用变量a不断执行灯的亮度电平。
}

2.升级版应用–arduino代替手机发送指令控制
本次将使用3个jdy-24m互相组网控制,三个蓝牙地址0077,0088,0099。
实现:一个作为主控发送指令控制另外两个arduino的灯珠,主控端为一个光照探测装置。当亮度超过800,自身灯珠亮,同时就会发送指令让另外两个arduino的灯珠亮,若小于800,则变暗。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
主控发射端代码,另外两个受控端代码跟之前的一样。
#define ADpin A5//A5引脚读取AD值
#define LED 13 //灯珠13号引脚
int ADBuffer = 0;//亮度AD值初始化为0
void setup()
{
lcd.begin(16,2); //初始化LCD1602显示屏
lcd.print(“Welcome to use!”); //液晶显示Welcome to use!
delay(1000); //延时1000ms
lcd.clear(); //液晶清屏
pinMode(LED,OUTPUT);
Serial.begin(9600); //波特率9600

}
void loop()
{
ADBuffer = analogRead(ADpin); //读取亮度AD值
delay(100);
lcd.setCursor(0,0); //设置液晶开始显示的指针位置
lcd.print(“Brightness =”); //液晶显示“Brightness =”
lcd.setCursor(0,1); //设置液晶开始显示的指针位置
lcd.print(ADBuffer);
if (ADBuffer>800)//大于八百就亮
{analogWrite(LED,255);//自身灯珠亮
delay(100);
Serial.write(c,15);//发送C数组指令,让另外两灯亮
}
else{
analogWrite(LED,0);//自身灯珠灭
delay(100);
Serial.write(b,15);//发送b数组指令,让另外两灯灭
}
}
在这里插入图片描述LCD显示屏接线图
在这里插入图片描述
光敏电阻接线图

3.终极应用–获取反馈数据
在这里插入图片描述
在这里插入图片描述
如图,常量反馈,发送F101000088110000 程序里写了获取variable[7]]这一位,这里是11,那边就反馈回来一段数据,然后读取第九位就是55。
变量反馈,发送F1010000882210000 程序里写了获取variable[7]]这一位,这里是22,那边就反馈回来变量数组的一段数据,然后读取第九位是光照亮度。
详情看代码。
在这里插入图片描述
0099蓝牙端的代码

在这里插入图片描述
亮度探测端代码
0099蓝牙对应的

int serialData=0; //串口数据变量
byte variable[80];//数组
byte index = 0;//数据位
void setup() {
Serial.begin(9600);//波特率9600
}
void loop() {
while( Serial.available()>0 ){ //当串口有数据时
byte serialData = Serial.read();//Serial.read()每次只读取一个字节,然后赋给serialData
variable[index++] = serialData;//serialData依次赋给variable[0],variable[1] ,variable[2]…
//这部分是数据位矫正的代码,防止发送数据长度不够,没有把index清0(保证数据长度正确的话,这个可以不加)
byte forward[]={0xF1};
xunhuan:
if ((variable[0] != forward[0]) && index >= 1 ){
for(int i=0; i < index; i++)
{
variable[i] = variable[i+1];
}
index–;
goto xunhuan;
}
//数据长度为10时候(ps:地址后面数据第一位就是variable[7],)
if (index==10)
{/这里是显示全部接受数据的,可以不用管先。
for (int i=0;i<10;i++)
{Serial.print(variable[i], HEX);
delay(10);}
Serial.println("");
for (int i=0;i<10;i++)
{ Serial.println(variable[i], HEX);
}
/
delay(100);

Serial.println(variable[9], HEX);//读取variable[9],即是数据长度为10的最后一位。
index=0;//数据位清0
}

}

}

0088对应的光照探测代码:
unsigned char c[15]={0x41,0x54,0x2B,0x4D,0x45,0x53,0x48,0x00,0x00,0x99,
0x99,0x99,0x55,0x0d,0x0a};//c为没有变量的数组,发送给的地址是0099
byte variable[80];
byte index = 0;
#define ADpin A5
int ADBuffer = 0;
void setup()
{
Serial.begin(9600); //波特率9600
}
void loop()
{ ADBuffer = analogRead(ADpin); //读取AD值
int B=ADBuffer/10;
unsigned char b[15]={0x41,0x54,0x2B,0x4D,0x45,0x53,0x48,0x00,0x00,0x99,
0x99,0x99,B,0x0d,0x0a};//b为带有变量的数据,发送给的地址是0099
while( Serial.available()>0 ){
byte serialData = Serial.read();//如果串口缓存有数
variable[index++] = serialData;
byte forward[]={0xF1};
xunhuan:
if ((variable[0] != forward[0]) && index >= 1 ){
for(int i=0; i < index; i++)
{
variable[i] = variable[i+1];
}
index–;
goto xunhuan;
}
delay(500);
//数据长度为10时候(ps:发送的数据地址后面数据第一位就是variable[7],)
if (index==10){
if( variable[7]==0x11)//读取variable[7]位的数据,如果是11,就发送c数组
{
delay(100);
Serial.write(c,15);
}
if( variable[7]==0x22)//读取variable[7]位的数据,如果是11,就发送b数组
{
delay(100);
Serial.write(b,15);
}
index=0;//数据位清0
}
}
}

总结:
根据前面初步探索已经知道发送数据,arduino以16进制发送
41542b4d45534800+目标蓝牙地址+数据+0d0a。
手机app的则是 选择第三特征0ffe3,16进制发送
F10100+四位地址+数据

应用的时候:采用Serial.read()读取收到的数据,Serial.read()每次只读取一个字节,然后赋给serialData,再由variable[index++] = serialData;serialData依次赋给variable[0],variable[1] ,variable[2],…
注意无论是以手机还是arduino发送指令,只需记住variable[7]都是蓝牙地址后面的第一位数据。然后程序里写的if (index=10)是指定发送数据长度是10(长度也可以超过10,但是只读10位),若发送长度是9位长度,则没有相应。例子 从0099兰蓝牙发F10100 0088 1100给0088,,0088是收到了这些信息,但不符合arduino里面写的长度10,故而要发F10100 0088 110000,这里11就是variable[7],也就是第8位,然后后面00 00 就是第9,10位,符合arduino写的程序。

总结
“arduino 读取HEX数据”–应用在手机连接蓝牙控制
“arduino向jdy蓝牙发送16进制指令”–应用在arduino代替手机向蓝牙发送,也可应用收取反馈数据
这两个是最基础的,如果觉得程序杂乱,可以参考这两个。
arduino 读取HEX数据代码:
byte variable[80];
byte index = 0;
void setup()
{
Serial.begin(9600); //波特率9600
}
void loop()
{ while( Serial.available()>0 ){
byte serialData = Serial.read();//如果串口缓存有数
variable[index++] = serialData;
if (index==10){//数据长度为10
for (int i=0;i<10;i++)
{Serial.print(variable[i], HEX);//10个数据并在一起
delay(10);}
Serial.println("");
for (int i=0;i<10;i++)
{ Serial.println(variable[i], HEX);//10个数据分开一行行显示
}
}
}
arduino向jdy蓝牙发送16进制指令
unsigned char a[16]={0x41,0x54,0x2B,0x4D,0x45,0x53,0x48,0x00,0xFF,0xFF,
0x19,0xFF,0x22,0x33,0x0d,0x0a
};
void setup()
{
Serial.begin(9600);
Serial.write(a,16);
}
void loop() {

}
//按下 复位键,发送一次0x41,0x54,0x2B,0x4D,0x45,0x53,0x48,0x00,0xFF,0xFF,
0x19,0xFF,0x22,0x33,0x0d,0x0a

  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值