从arduino上的传入蓝牙序列中提取值

时间:2019-06-26 11:22:07

标签: c bluetooth arduino

我目前正在从事一个涉及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灯条。

2 个答案:

答案 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();
        }
    }
}