Вы можете использовать типичный трюк, используемый в случаях, в качестве ваших, кодируя многобайтовые литералы символов в одном unsigned int
, что на Arduino uno и Mega 2560 составляет 16 бит в формате с прямым порядком байтов.
Со ссылкой на стандарт C ISO / IEC 9899: 201x § "6.4.4.4 Символьные константы" .
Подпункт 10 объясняет наш случай:
Целочисленная символьная константа имеет тип int. Значение целого числа
символьная константа, содержащая один символ, который отображается на
однобайтовый символ выполнения - это числовое значение
представление сопоставленного символа, интерпретируемого как целое число.
значение целочисленной символьной константы, содержащей более одного
символ (например, «ab») или содержащий символ или escape-последовательность
который не отображается на однобайтовый символ выполнения,
от реализации . Если целочисленная символьная константа содержит
одиночный символ или escape-последовательность, его значение является тем, которое приводит к
когда объект с типом char, значение которого является значением одного
символьная или escape-последовательность преобразуется в тип int.
В нашем случае управление «определяется реализацией», как описано ниже.
В этом случае многобайтовая константа 'bt'
может быть закодирована как 16-битное целое число 0x6274
, где 'b'=0x62
и 't'=0x74
.
Компилятор также должен быть достаточно умен, чтобы преобразовывать многобайтовую последовательность символов в значение типа int.
В следующем фрагменте мы считаем, что массив 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();
}
}
}