我目前正在从事一个涉及Android应用程序的项目,该应用程序通过arduino控制LED灯条。这是通过蓝牙模块完成的。我遇到的问题是该应用程序涉及诸如控制LED灯条的亮度和色相的功能。因此,当对应用程序上的这些组件中的任何一个进行更改时,会将值发送到arduino,以便其更新值。发送诸如“ bt + 50!”之类的消息。前两个字母标识要更改的分量(bt =亮度),“ +”表示实际值的开头,“!”表示结束。
我想帮助我弄清楚如何拆分和拼接传入的消息,以便我可以首先确定哪个组件已更改,然后能够提取整数值,例如:
if(message_id == 'bt'){
brightness = message_value;
}
目前,我只是在测试普通单色LED灯上的东西。而且我只实现了非常简单的代码,该代码可对从蓝牙序列接收到的单个字母消息起作用。
我尝试使用内置的C字符串函数,但是由于我是C语言的新手,并且我是python背景的人,所以很难使事情正常工作。
// Bluetooth module used - HC-06
#include <SoftwareSerial.h>
SoftwareSerial BlueTooth(5, 6); // (TXD, RXD) of HC-06
char BT_input; // to store input character received via BT.
void setup()
{
pinMode(13, OUTPUT); // Arduino Board LED Pin
BlueTooth.begin(9600);
}
void loop()
{
if (BlueTooth.available())
{
BT_input=(BlueTooth.read());
if (BT_input=='n')
{
digitalWrite(13, HIGH);
BlueTooth.println("Now LED is ON");
}
else if (BT_input=='f')
{
digitalWrite(13, LOW);
BlueTooth.println("Now LED is OFF");
}
}
}
我希望从传入消息中提取message_id和message_value,以便能够更新我的LED灯条。
答案 0 :(得分:3)
您可以使用string
变量将所有read
值存储到其中,一旦读取!
,它将开始处理它。
#include <SoftwareSerial.h>
SoftwareSerial BlueTooth(5, 6); // (TXD, RXD) of HC-06
char input; // to store input character received via BT.
String data;
void setup()
{
pinMode(13, OUTPUT); // Arduino Board LED Pin
BlueTooth.begin(9600);
}
void loop()
{
if (BlueTooth.available())
{
input=(BlueTooth.read());
if (input != '!') {
data += input;
}
else{
String message_id = String(data.substring(0,2)); //gets only "bt"
data.remove(0,3); //data becomes "50" since '!' is not added to data
int message_value = data.toInt();
if(message_id == "bt"){
brightness = message_value;
}
}
}
}
答案 1 :(得分:0)
您可以使用一种典型的技巧来将您的多字节字符文字编码为单个unsigned int
,这在Arduino uno和Mega 2560上是16位的小字节序格式。
参考C标准 ISO / IEC 9899:201x §“ 6.4.4.4字符常量” 。
第10项解释了我们的情况:
一个整数字符常量的类型为int。整数值 字符常量,包含一个映射到 单字节执行字符是 映射字符的表示形式,解释为整数。的 包含多个的整数字符常量的值 字符(例如'ab'),或包含字符或转义序列 没有映射到单字节执行字符的是 实现定义。如果整数字符常量包含一个 单个字符或转义序列,其值就是结果 当类型为char的对象的值是单个对象的对象时 字符或转义序列将转换为int类型。
在本例中,“实现定义”的管理如下所述。
在这种情况下,多字节char常量'bt'
可以编码为16位整数0x6274
,其中'b'=0x62
和't'=0x74
。
编译器还应该足够聪明,可以将int值中的多字节char序列转换为
。在下面的代码段中,我们认为char数组msg
保存了接收到的消息,并且我们使用了一个简单且功能强大的switch
语句(需要一个整数)来强制转换msg
变量为无符号整数。
char msg[10];
...
switch (*((unsigned int *)msg))
{
case 'tb': //Note the reverse order of command characters due to endianess
int value = atoi(msg+2); //Convert number to int
.... //do something
break;
.... //other cases
}
将msg
指针变量投射到一个指向无符号整数的指针,编译器将按照上述方法将前2个字符解释为整数,并根据它们的值执行切换。
下面的示例将您的代码修改为使用开关。假定命令的固定长度等于MAX_MSG_LEN
(命令2个字符,值和消息末尾2个字符):
// Bluetooth module used - HC-06
#include <SoftwareSerial.h>
SoftwareSerial BlueTooth(5, 6); // (TXD, RXD) of HC-06
#define MAX_MSG_LEN 5 //Max message length
#define OFFSET_TO_VALUE //Offset in input buffer to value
char BT_input[10]; // to store input characters received via BT.
void setup()
{
pinMode(13, OUTPUT); // Arduino Board LED Pin
BlueTooth.begin(9600);
}
void loop()
{
if (BlueTooth.available())
{
/*
* Read in the message up to the '!'
*/
int i=0;
do
{
BT_input[i] = (BlueTooth.read());
} while (i<MAX_MSG_LEN && BT_input[i++]!='!');
/*
* If message length is exactly what we expect
* we can process the message.
* Note that because of endianess the command
* chare are rversed.
*/
if (i == MAX_MSG_LEN)
{
switch (*((unsigned int *)BT_input))
{
case 'tb': // command 'bt'
process_brigthness(atoi(BT_input + OFFSET_TO_VALUE));
break;
case 'no': // command 'on'
{
digitalWrite(13, HIGH);
BlueTooth.println("Now LED is ON");
break;
}
case 'fo': // command 'of' for off
{
digitalWrite(13, LOW);
BlueTooth.println("Now LED is OFF");
break;
}
default: // unknown command
{
unknown_command();
break;
}
}
}
else
{
/*
* Process communication error
*/
communication_error();
}
}
}
或使用输入流和命令结构的并集:
// Bluetooth module used - HC-06
#include <SoftwareSerial.h>
SoftwareSerial BlueTooth(5, 6); // (TXD, RXD) of HC-06
#define MAX_MSG_LEN 5 //Max message length
#define OFFSET_TO_VALUE //Offset in input buffer to value
union tag_BT_input // to store input characters received via BT.
{
char stream[MAX_MSG_LEN];
struct
{
unsigned int cmd; //Command
char val[2]; //value
char eom; //End of message marker '!'
}msg;
} BT_input;
void setup()
{
pinMode(13, OUTPUT); // Arduino Board LED Pin
BlueTooth.begin(9600);
}
void loop()
{
if (BlueTooth.available())
{
/*
* Read in the message up to the '!'
*/
int i=0;
do
{
BT_input.stream[i] = (BlueTooth.read());
} while (i<MAX_MSG_LEN && BT_input.stream[i++]!='!');
/*
* If message length is exactly what we expect
* we can process the message.
* Note that because of endianess the command
* chare are rversed.
*/
if (i == MAX_MSG_LEN)
{
switch (BT_input.msg.cmd)
{
case 'tb': // command 'bt'
process_brigthness(atoi(BT_input.msg.val));
break;
case 'no': // command 'on'
{
digitalWrite(13, HIGH);
BlueTooth.println("Now LED is ON");
break;
}
case 'fo': // command 'of' for off
{
digitalWrite(13, LOW);
BlueTooth.println("Now LED is OFF");
break;
}
default: // unknown command
{
unknown_command();
break;
}
}
}
else
{
/*
* Process communication error
*/
communication_error();
}
}
}