您可以使用案例中使用的典型技巧,在单个 unsigned int 中编码多字节字符文字,在 Arduino uno 和 Mega 2560 上是 16 位小端格式。
参考 C 标准 ISO/IEC 9899:201x § “6.4.4.4 字符常量”。
第 10 小段解释了我们的案例:
整数字符常量的类型为 int。整数的值
包含单个字符的字符常量,该字符映射到
单字节执行字符是
映射字符的表示解释为整数。这
包含多个字符的整数字符常量的值
字符(例如,'ab'),或包含字符或转义序列
不映射到单字节执行字符,是
实现定义。如果一个整数字符常量包含一个
单个字符或转义序列,其值是结果
当一个 char 类型的对象的值是单
字符或转义序列转换为 int 类型。
在我们的例子中,“实现定义”的管理方式如下所述。
在这种情况下,多字节字符常量'bt'可以编码为16位整数0x6274,其中'b'=0x62和't'=0x74。
编译器还应该足够聪明,可以将多字节字符序列转换为 int 值。
在下面的 sn-p 中,我们认为 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();
}
}
}