0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

怎样通过蓝牙将ArduinoUno连接到Android

454398 来源:wv 2019-10-05 17:30 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

第1步:电路

怎样通过蓝牙将ArduinoUno连接到Android

组件:

1 x Arduino Uno

3 x 220欧姆电阻器

1 x绿色LED

1 x黄色LED

1 x红色LED

1 x TMP36温度传感器

1 x JY-MCU蓝牙从模块(请参阅介绍)

1 x面包板

电线

连接:

步骤1):将Arduino的地线和5V连接到面包板。

步骤2):将LED放在面包板上,并将其阴极接地。将它们的阳极分别通过220欧姆电阻连接到数字引脚:黄色到引脚3,绿色到引脚4,红色到引脚5。

步骤3):将TMP36传感器放在面包板上,将其引脚连接到5V,接地和A0 Arduino引脚。

步骤4):将提供的电缆的一侧连接到JY-MCU蓝牙模块,另一侧连接到面包板;连接如下:

VCC 《-》 5V

GND 《-》 GND TXD 《-》引脚0(Rx)

RXD 《-》引脚1(Tx)

该草图还将使用数字引脚13上的Arduino内置LED。

由于TXD转到Rx,而RXD转到,蓝牙模块的连接可能会有些混乱。 Tx:这是一个解释。发送和接收是针对每个设备的,因此,蓝牙模块的TXD引脚发出的传输必须由Arduino在Rx引脚0上接收;同样,从Arduino Tx引脚1发出的传输也必须到达其RXD引脚上的JY-MCU蓝牙模块。

警告:蓝牙模块可能会干扰PC与Arduino的通信:对电路板进行编程时,请断开VCC。 (在我的测试中,情况并非如此,但请确保它不会造成任何伤害)。

步骤2:Arduino代码-简介

Arduino监听命令以点亮某些LED或显示其状态。另外,定时器中断使它可以通过TMP36传感器检查温度:如果温度大于阈值,则LED点亮;否则,指示灯熄灭。每n秒(其中n是通过应用设置的参数)会向该应用发送状态报告。简单的命令结构使应用程序可以将参数和值发送到Arduino,反之亦然。

程序中定义的命令结构为:

CMD RED | GREEN | YELLOW =开|关

CMD TMAX | SECONDS =值

CMD SECONDS =值

CMD状态

状态消息结构为:

状态红色|绿色|黄色| TMAX | SECONDS | TEMP | THIGH = value

Arduino将以完整状态回答STATUS命令,而在中断时它将报告较短的版本。

示例:

CMD RED = ON将红色LED点亮

CMD GREEN = OFF将绿色LED熄灭

您可以通过在Arduino IDE的串行监视器中发出命令并查看响应来测试草图:确保在底部的下拉选项中选择“回车”。

您可以从附件中下载草图代码。下一步将对此进行详细说明。

步骤3:Arduino代码-详细信息

上一步中所述的命令和消息结构

//串行参数:COM11 9600 8 N 1

// r或 n结束命令行

//蓝牙处于针脚0和1,速度为9600

//命令结构//CMD RED | GREEN | YELLOW = ON | OFF

//CMD TMAX | SECONDS = value

//CMD SECONDS = value

//CMD STATUS

//状态消息结构

//STATUS RED | GREEN | YELLOW | TMIN | TMAX | SECONDS | TEMP | THIGH = value

温度控制所需变量的初始化

float maxTemp = 30.0;//当温度》 maxTemp

int maxTempSensor =(int)((maxTemp/100 + .5)* 204.8);

浮点温度= 0.0;

以后可以更改maxTemp,但是程序需要使用默认值开始。 maxTempSensor是将maxTemp转换为Arduino ADC转换器提供的0-1023范围;温度比较将通过我们希望尽快执行的中断例程执行:直接比较整数Pin输出值而不是浮点温度更为有效。我们仍然要报告温度,程序会将其以相同的名称存储在变量中。

如果您不熟悉温度转换公式,可以在这里查看。

maxSeconds也可以使用命令进行更改,但再次需要默认值

int maxSeconds = 10;//每maxSeconds

Pin常量声明发送状态消息

const int ledPin = 13;//温度指示灯

const int tempPin = A0;//T36温度传感器模拟输入引脚

const int led1Pin = 3;//黄色

const int led2Pin = 4;//Green

const int led3Pin = 5;//红色

中断例程中使用并从其外部访问的变量

volatile int tempVal;

volatile int seconds = 0;

volatile boolean tempHigh = false;

volatile boolean statusReport = false;

Volatile是一个特殊的关键字,可防止编译器执行某些优化:在中断内修改的所有变量例程,并且必须在例程之外进行访问,必须将其声明为volatile,以表明其值可以随时更改,并确保在需要时从内存中读取最新的正确值。

命令字符串变量(稍后将对此进行说明)

字符串inputString =“”;

String command =“”;

字符串值=“”;

布尔stringComplete = false;

setup()函数

void setup(){

//开始串行连接

Serial.begin(9600);

Serial.print(“ Max T:”);

Serial.print(maxTemp);

Serial.print(“ Sensor:”);

Serial.println(maxTempSensor);

inputString.reserve(50);

command.reserve(50) ;

value.reserve(50);

pinMode(ledPin,OUTPUT);

digitalWrite(ledPin,LOW);

pinMode(led1Pin,OUTPUT);

pinMode(led2Pin,OUTPUT) ;

pinMode(led3Pin,OUTPUT);

digitalWrite(led1Pin,LOW);

digitalWrite(led2Pin,LOW);

digitalWrite(led3Pin,LOW);

字符串的reserve方法分配作为参数提供的字节数。

需要以下代码来初始化计时器中断并将其设置为每秒触发一次,这是Arduino可以完成的最慢的时间。有关详细信息,请参见此处。

cli();//禁用全局中断

//初始化Timer1以中断@ 1000毫秒

TCCR1A = 0;//将整个TCCR1A寄存器设置为0

TCCR1B = 0;//与TCCR1B

相同//将比较匹配寄存器设置为所需的计时器计数:

OCR1A = 15624;//打开CTC模式:

TCCR1B | =(1 《//为1024个预分频器设置CS10和CS12位:

TCCR1B | =(1 《 TCCR1B | =(1 《//启用计时器比较中断:

TIMSK1 | =(1 《 sei();//启用全局中断

}

定时器中断例程:我们无法更改其名称,但内容是完全可定制的。/p》

ISR(TIMER1_COMPA_vect)

{

tempVal = AnalogRead(tempPin);

if(tempVal》 maxTempSensor){

digitalWrite(ledPin,HIGH);

tempHigh = true;

}

else {

digitalWrite(ledPin,LOW);

tempHigh = false;

}

温度值-或如上文所述,从传感器读取其0-1023整数表示形式,并将其与阈值进行比较:当上面的内置LED点亮并且tempHigh设置为true时,否则关闭LED并 tempHigh设置为false。

如果(秒++》 = maxSeconds){

statusReport = true;

秒= 0;

}

}

请记住,每秒触发一次中断,但是我们希望报告系统状态的频率降低:秒变量在每次迭代时递增,直到达到s报告到期时的值;稍后将在主循环中通过检查statusReport标志来完成此操作。通常,永远不要执行太慢的操作,例如从中断例程中将数据写入串行。

loop()函数在接收到指令后便会解释并执行命令,然后如果计时器发出标志,则会报告状态打断。为了从串行缓冲区读取字符串,loop()依赖于将在最后定义的serialEvent()函数:该例程在每次loop()运行之间运行。它没有得到广泛的记录,并且可能不适用于所有的Arduino模型。无论如何,将其内容嵌套在主循环中并不难(请参见本步骤的结尾)。

void loop(){

int intValue = 0;

if(stringComplete){ boolean stringOK = false;

if(inputString.startsWith(“ CMD”)){

inputString = inputString.substring(4);

首先,我们检查接收到的字符串是否以“ CMD”开头:如果是这样,我们可以丢弃前四个字符,否则稍后会出现错误。

int pos = inputString.indexOf(‘=’);

if(pos》 -1){

command = inputString.substring(0,pos);

value = inputString。 substring(pos + 1,inputString.length()-1);//提取最多 n个被排除的命令

有两种类型的命令:设置值的命令,在其中找到分隔空格的“ =”值对,以及该命令是单个指令(STATUS)。如果pos处出现“ =”,则字符串将分为命令(左部分)和值(右部分),并将“ =”插入中间,并在行尾添加末尾字符。

如果(command.equals(“ RED”)){//RED = ON | OFF

value.equals(“ ON”)? digitalWrite(led3Pin,HIGH):digitalWrite(led3Pin,LOW);

stringOK = true;

}

否则if(command.equals(“ GREEN”)){//GREEN = ON | OFF

value.equals(“ ON”)吗? digitalWrite(led2Pin,HIGH):digitalWrite(led2Pin,LOW);

stringOK = true;

}

否则if(command.equals(“ YELLOW”)){//YELLOW = ON | OFF

value.equals(“ ON”)吗? digitalWrite(led1Pin,HIGH):digitalWrite(led1Pin,LOW);

stringOK = true;

}

我们检查并执行LED命令;请注意,代码仅检查值ON:如果您写入GREEN = ASD,它将被解释为GREEN = OFF。它不是完美的,但是它使事情变得简单得多。每次识别并执行命令时都会设置stringOK = true,以便以后标记错误的命令。

否则,如果(command.equals(“ TMAX”)){//TMAX =值

intValue = value.toInt();

如果(intValue》 0){

maxTemp = (float)intValue;

maxTempSensor =(int)((maxTemp/100 + .5)* 204.8);

stringOK = true;

}

}

否则,如果(command.equals(“ SECONDS”)){//SECONDS = value

intValue = value.toInt();

如果(intValue》 0){

maxSeconds = intValue;

stringOK = true;

}

}

当值应为数字时,我们需要将其转换并测试它确实是一个数字。对于MaxTemp,我们还按照变量定义部分中的说明计算传感器值

}//pos》 -1

else if(inputString.startsWith(“ STATUS”)){

Serial.print(“ STATUS RED =”);

Serial.println(digitalRead(led3Pin ));

Serial.print(“ STATUS GREEN =”);

Serial.println(digitalRead(led2Pin));

Serial.print(“ STATUS YELLOW =”);

Serial.println(digitalRead(led1Pin));

Serial.print(“ STATUS TMAX =“);

Serial.println(maxTemp);

Serial.print(” STATUS SECONDS =“);

Serial.println(maxSeconds);

Serial.print(“ STATUS TEMP =”);

Serial.println(temperature);

Serial.print(“ STATUS THIGH =”);

Serial.println(tempHigh);

stringOK = true ;

}//inputString.starts With(“ STATUS”)

如果命令是STATUS,则程序仅将所有信息输出到串行。

}//inputString.startsWith (“ CMD”)

stringOK吗? Serial.println(“ Command Executed”):Serial.println(“ Invalid Command”);

指示是否已收到有效或无效命令。

//清除字符串以进行下一次迭代

inputString =“”;

stringComplete = false;

}//stringComplete

下一次命令迭代的变量内务处理。

if(statusReport){

temperature =(tempVal * 0.0048828125-.5)* 100;

Serial.print(“ STATUS TEMP =”);

Serial.println(temperature);

Serial.print(“ STATUS THIGH =”);

Serial.println(tempHigh);

statusReport = false;

}

}

如果中断例程已引发statusReport标志,则将打印一些信息请注意,此时要计算当前温度值:因此,如果在statusReport时间间隔之间发出STATUS命令,则会得到旧的温度值。

如前所述,只要新数据进入硬件串行RX,就会发生serialEvent()。该例程在每次loop()运行之间运行,因此在循环内部使用delay可以延迟响应。可能有多个字节的数据。

无效的serialEvent(){

而(Serial.available()){

//获得新的字节:

char inChar =(char)Serial.read();

//将其添加到inputString:

inputString + = inChar;

//如果传入字符是换行符或回车符,则设置标志

//,因此主循环可以对此做一些事情:

if(inChar ==‘ n’|| inChar ==‘ r’){

stringComplete = true;

}

}

}

从串行读取每个字节并将其添加到输入字符串,直到遇到“ n”或“ r”表示字符串结尾:在这种情况下,设置由loop()检查的stringComplete标志。同时使用回车符 r和换行符 n确保代码能够从各种输入(包括Arduino IDE串行监视器以外的其他串行终端)检测字符串结尾。

关于蓝牙和串行的注意事项

在许多示例中,包括JY-MCU卖方的示例,您可以找到连接在不同Arduino数字引脚(例如10和11)上的蓝牙模块,以及通过SoftwareSerial库访问。根据我的测试结果,当该模块仅用于发送信息时,SoftwareSerial可以完美运行,但是在接收命令时Arduino Uno不够快。我没有尝试降低SoftwareSerial连接的速度(在示例中通常设置为2400bps),因为MIT AppInventor应用似乎不支持蓝牙连接速度设置。

使用SoftwareSerial,serialEvent()不会工作:需要重命名它(例如mySerialEvent())并在loop()的开头显式调用它。

步骤4:App Inventor代码-简介

在使用Android应用之前,您需要将Bluetooth模块与智能手机配对。

给Arduino开发板通电,打开在Android手机上的蓝牙上并搜索附近的蓝牙设备:JY-MCU模块将显示为HC-06,配对密码为1234。

蓝牙Arduino连接的关键组件应用程序是蓝牙客户端,而Arduino板将充当服务器:这意味着应用程序将始终启动连接。给Arduino开发板供电时,蓝牙模块红色LED开始闪烁;按下应用程序的“连接到设备”按钮,然后从列表中选择模块:红色LED指示灯将变为稳定,连接状态将变为“已连接”。

同样,这与蓝牙无关Master/Slave,但仍可能令人困惑:您的Bluetooth模块需要为Slave,但它(或Arduino草图)在客户端中将充当Server-与Android应用程序进行服务器通信。

您可以直接从Android Play商店安装Bluetooth Arduino Connection App,或者您可以通过下载附件将完整的应用程序代码导入到MIT App Inventor项目中。

蓝牙Arduino连接应用程序是使用MIT App Inventor 2开发的;以下步骤将提供详细说明。

步骤5:App Inventor代码-详细信息

Arduino蓝牙连接应用程序的关键组件是:

用于蓝牙配对设备的ListPicker(ListPicker1)

3个按钮,每个按钮控制相应的配色板LED(RedLedBtn,GreenLedBtn,YellowLedBtn)

发送状态命令(GetStatusBtn)的按钮

带有关联按钮的按钮文本框以设置状态报告间隔(SecondsBtn和SecondsTxBx)

巨大的多行状态标签,显示从Arduino板(状态)接收的信息

上一步(BluetoothClient1)

一个时钟组件,该时钟组件在客户端连接时每秒触发一次中断(Clock1)

以下是基于以下内容的应用代码说明:上面的图片。

图1

Variabl当打开应用程序屏幕时,将设置并初始化LED的状态和间隔。

图2

连接ListPicker对象ListPicker1使用两种方法:

已准备好可用(配对)的蓝牙设备的列表,并显示给用户

当用户选择设备时,将调用Bluetooth Client对象的Connect方法为了开始连接:如果成功,它将显示在适当的标签中,并激活Clock中断,以便可以接收来自设备的消息。

图3

在这里,我们演示如何向Arduino板发送命令。

按下GetStatusBtn时,将调用Bluetooth Client对象的SendText方法并执行文本命令发出:注意,在“ CMD STATUS”字符串的末尾添加了“ n”,以便Arduino草图中的serialEvent()函数能够知道消息何时结束。

代码打开或关闭LED稍微复杂一点:

我们使用相应的变量来跟踪其当前状态:如果打开,我们想将其关闭,反之亦然;因此,首先,我们将变量更改为布尔值

,然后使用新状态更新按钮标签

最后,调用BluetoothClient1.SendText来传输命令。

其他命令的代码非常相似,因此未显示。

图4

每次Clock1计时器触发,该例程被执行:它等效于Arduino的serialEvent();。如果BluetoothClient1接收到字节,则将它们复制到状态标签中。请注意,Bluetooth客户端对象具有一种返回所接收消息长度的方法。

步骤6:结论

在此指导中,我演示了一个通过蓝牙连接Arduino开发板和Android智能手机的有用方法。通信是双向的,因此开发板不仅向应用程序报告其状态,而且还从应用程序接收命令。

此外,一个简单的扩展程序允许将Arduino的命令发送给应用程序。电话:例如:按下板上的按钮即可拍照或发送短信。

Arduino草图可以作为远程命令处理的基础,它使用中断来执行一些操作-检查温度并打开LED警报-并发送状态心跳信号:该技术不仅可以通过蓝牙通信应用,还可以通过以太网等其他方式应用。

MIT App Inventor应用程序使用中断同样:它等效于Arduino的loop()+ serialEvent()函数的重复,并且类似地用于接收消息。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Android
    +关注

    关注

    12

    文章

    3985

    浏览量

    133066
  • 蓝牙
    +关注

    关注

    119

    文章

    6221

    浏览量

    177542
  • Arduino
    +关注

    关注

    190

    文章

    6515

    浏览量

    195966
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    nordic NRF54蓝牙设备在Google Pixel 10上“听诊”蓝牙信道示例

    今年早些时候发布的Android 16系统首次引入了支持蓝牙®信道探测的公共API,实现了智能手机的精准测距功能。然而直到近期,市面上仍未出现支持蓝牙6.0及信道探测技术的手机硬件。这一局面在
    发表于 11-26 17:44

    通过JTAG连接到物联网板时,FAQ_MA35D1_There没有响应是怎么回事?

    R0、R145、R146、R147、R149、R151 上的 151 Ω更改为 R41、R42、R43、R44、R45。 FAQ_MA35D1_There尝试通过 JTAG2 连接到物联网板时没有响应。 FAQ_MA3
    发表于 09-03 08:28

    外围设备通过手机连接到BLE应用程序,为什么不能连接到Infineaon BLE?

    使用 ch06_ex01_periab \" le 项目创建了外围设备。\" \" 使用像 LightBlue 这样的移动应用程序,我能够连接到这个外围设备并更改特征值。 我已经使用 \"
    发表于 07-07 08:06

    CYW20706基于硅的蓝牙模块(CYBT-343151-02)连接到定制板上的MCU,怎样才能将链接配置为未确认数据模式?

    CYW20706 基于硅的蓝牙模块(CYBT-343151-02)连接到定制板上的 MCU。 它在确认数据模式下工作,没有问题 但是我怎样才能将链接配置为未确认数据模式
    发表于 06-27 08:23

    是否可以通过SLAVE FIFO模式或GPIF2个MPEG-TS解调器连接到FX2LP?

    AN58069 解释了如何通过 MPEG-TS 接口以 SLAVE FIFO 模式一个 Dmod 连接到 FX2LP。 如果我想通过 MPEG-TS 接口
    发表于 05-21 07:20

    是否可以智能插头直接连接到充当控制器的imx8mm?

    运行具有物质层的 yocto mickledore 图像。 是否可以智能插头直接连接到充当控制器的 imx8mm?
    发表于 04-08 08:08

    是否允许通过0Ohm电阻器RTC_XTALO微处理器的输出直接连接到0V8电源?

    通过 0Ohm 电阻器 RTC_XTALO 微处理器的输出直接连接到 0V8 电源? 我认为最好通过 1kOhm 电阻器将此引脚 B25 (RTC_XTALO)
    发表于 04-04 06:24

    蓝牙适配器连接技巧

    常重要的。市面上主要有以下几种类型的蓝牙适配器: USB蓝牙适配器 :这是最常见的类型,通过USB接口连接到电脑或其他设备。 内置蓝牙适配器
    的头像 发表于 02-06 17:05 2662次阅读

    从Delphi、C++ Builder和Lazarus连接到MySQL数据库

    平台。 基于 MyDAC 的应用程序可以直接连接到 MySQL 服务器或通过 MySQL 客户端库工作。MySQL 数据访问组件旨在帮助程序员更快、更轻松地开发 MySQL 数据库应用程序。 MyDAC 完全替代了标准 MySQL 连接
    的头像 发表于 01-20 13:47 1318次阅读
    从Delphi、C++ Builder和Lazarus<b class='flag-5'>连接到</b>MySQL数据库

    使用插件Excel连接到MySQL/MariaDB

    使用插件 Excel 连接到 MySQL/MariaDB 适用于 MySQL 的 Devart Excel 插件允许您将 Microsoft Excel 连接到 MySQL 或 MariaDB
    的头像 发表于 01-20 12:38 1129次阅读
    使用插件<b class='flag-5'>将</b>Excel<b class='flag-5'>连接到</b>MySQL/MariaDB

    从Delphi、C++ Builder和Lazarus连接到Oracle数据库

    从 Delphi、C++ Builder 和 Lazarus 连接到 Oracle 数据库 Oracle 数据访问组件 (ODAC) 是一个组件库,它为 32 位和 64 位平台提供从 Delphi
    的头像 发表于 01-15 10:01 1346次阅读

    EE-194:AD1836A评估板连接到ADSP-21161N SHARC EZ-KIT Lite

    电子发烧友网站提供《EE-194:AD1836A评估板连接到ADSP-21161N SHARC EZ-KIT Lite.pdf》资料免费下载
    发表于 01-07 14:31 0次下载
    EE-194:<b class='flag-5'>将</b>AD1836A评估板<b class='flag-5'>连接到</b>ADSP-21161N SHARC EZ-KIT Lite

    EE-321:Blackfin处理器连接到AD7656 SAR ADC

    电子发烧友网站提供《EE-321:Blackfin处理器连接到AD7656 SAR ADC.pdf》资料免费下载
    发表于 01-06 16:04 0次下载
    EE-321:<b class='flag-5'>将</b>Blackfin处理器<b class='flag-5'>连接到</b>AD7656 SAR ADC

    EE-219:字符LCD面板连接到ADSP-21262 SHARC DSP

    电子发烧友网站提供《EE-219:字符LCD面板连接到ADSP-21262 SHARC DSP.pdf》资料免费下载
    发表于 01-05 10:10 0次下载
    EE-219:<b class='flag-5'>将</b>字符LCD面板<b class='flag-5'>连接到</b>ADSP-21262 SHARC DSP

    在实际的电气连接中,是直接Exposed Thermal Pad连接到AGND吗?

    在阅读ADS8568数据手册时,在第6页至第9页无Exposed Thermal Pad介绍,通过查找的方式发现也无Exposed Thermal Pad相关介绍。请问在实际的电气连接中,直接
    发表于 12-24 06:04