Arduino的状态机 [英] Arduino State Machine

查看:951
本文介绍了Arduino的状态机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是从别人谁回答我原来的问题<一个跨岗位href=\"http://stackoverflow.com/questions/23986447/executing-multiple-functions-commands-on-arduino\">here.

我不知道如何去执行3项功能后,我(以及在将来引进超过3甚至更多)。

我只是想淡入/眨眼的RGB LED的颜色选择(也许在今后引进更多的功能),其中的RGB数据从iOS的回来,送到的 RFDuino BLE模块

发送一个变脸的字符串由 RFduinoBLE_onReceive(字符*数据,INT LEN) Arduino上结束。

拿起模块

   - (IBAction为)fadeButton pressed:(ID)发送{
    [rfduino发送:[@变脸dataUsingEncoding:NSUTF8StringEncoding]];
} - (IBAction为)blinkBut​​ton pressed:(ID)发送{
    [rfduino发送:[@闪烁dataUsingEncoding:NSUTF8StringEncoding]];
}

选定颜色:

   - (空)的setColor
{
    的NSLog(@颜色:RGB%F%F%F,红,绿,蓝);    *的UIColor色=的UIColor colorWithRed:红,绿:绿色蓝色:蓝色阿尔法:1.0];    [colorSwatch setHighlighted:YES];
    [colorSwatch setTintColor:颜色];    uint8_t有TX [3] = {红* 255,绿色* 255,蓝色* 255};
    NSData的*数据= [NSData的dataWithBytes:(无效*)及TX长度:3];    [rfduino发送:数据]
}

这是原来我怎么设置RGB颜色:

 无效RFduinoBLE_onReceive(字符*数据,INT LEN){
    如果(LEN&GT; = 3){
        //获取RGB值。
        uint8_t有红色=数据[0];
        uint8_t有绿色=数据[1];
        uint8_t有蓝色=数据[2];        //为每个LED设置PWM。
        analogWrite(rgb2_pin,红色);
        analogWrite(rgb3_pin,绿色);
        analogWrite(rgb4_pin,蓝);
    }
}

这是所提供的答案,现在在编译Arduino的,但我不知道如何去实际执行我的功能在哪里?

 的#include&LT; RFduinoBLE.h&GT;INT状态;
字符的命令;
字符串十六进制串;// RGB引脚。
INT redPin = 2;
INT grnPin = 3;
INT bluPin = 4;无效设置(){
  状态= 1;  pinMode(redPin,OUTPUT);
  pinMode(grnPin,OUTPUT);
  pinMode(bluPin,OUTPUT);  //这是我们希望出现在广告中的数据
  //(该设备名称长度加上广告的长度必须与LT = 18个字节。
  RFduinoBLE.deviceName =iOS版;
  RFduinoBLE.advertisementInterval =毫秒(300);
  RFduinoBLE.txPowerLevel = -20;
  RFduinoBLE.advertisementData =RGB;  //开始BLE堆栈。
  RFduinoBLE.begin();
}空隙环(){
  // RFduino_ULPDelay(无限);
}无效processCommand(INT命令字符串十六进制){
  //十六进制?
  //命令?
}无效RFduinoBLE_onReceive(字符*数据,INT LEN){
  的for(int i = 0; I&LT; LEN,我++){
    的statemachine(数据由[i]);
  }
}无效的statemachine(char数据){
  开关(州){
    情况1:
      如果(数据== 1){
        状态= 2;
      }
    打破;
    案例2:
      如果(数据=='B'||数据=='F'||数据=='C'){
        命令=数据;
        十六进制串=;
        状态= 3;
      }否则如果(数据!= 1){//状态2岁的,如果我们收到另一个为0x01。
        状态= 1;
      }
    打破;
    案例3:
      如果((数据&GT; ='一'和;&放大器;数据&下; ='Z')||(数据&GT ='0'和;&放大器;数据&下; ='9')){
        十六进制串=十六进制串+数据;
        如果(hexstring.length()== 6){
          状态= 4;
        }
      }否则如果(数据== 1){
        状态= 2;
      }其他{
        状态= 1;
      }
    打破;
    情况4:
      如果(数据== 3){
        processCommand(命令,十六进制串);
        状态= 1;
      }否则如果(数据== 1){
        状态= 2;
      }其他{
        状态= 1;
      }
    打破;
  }
}

编辑:最后code

 的#include&LT; RFduinoBLE.h&GT;//国家财产。
INT状态= 1;
字符的命令;
字符串十六进制串;// RGB引脚。
INT redPin = 2;
INT grnPin = 3;
INT bluPin = 4;//设置功能,以RGB引脚设置为输出引脚。
无效设置(){
  pinMode(redPin,OUTPUT);
  pinMode(grnPin,OUTPUT);
  pinMode(bluPin,OUTPUT);  //这是我们希望出现在广告中的数据
  //(该设备名称长度加上广告的长度必须与LT = 18个字节。
  RFduinoBLE.deviceName =iOS版;
  RFduinoBLE.advertisementInterval =毫秒(300);
  RFduinoBLE.txPowerLevel = -20;
  RFduinoBLE.advertisementData =RGB;  //开始BLE堆栈。
  RFduinoBLE.begin();
}空隙环(){
  开关(命令){
    情况1:
      //闪烁。
    打破;
    案例2:
      // 褪色。
    打破;
  }  // RFduino_ULPDelay(无限);
}//转换为十六进制的字符串实际HEX值。
//这是需要的正确的ASCII值转换为十六进制
//每个字符的值。
字节GETVAL(焦三){
  如果(c取代; ='0'和;&放大器;℃下='9')返回(字节)(三 - '0');
  否则返回(字节)(C - 'A'+ 10);
}//过程中的每个功能/命令。
无效processCommand(INT命令字符串十六进制){
  开关(命令){
    案例'B':
      命令= 1; //设置闪烁模式。
    打破;
    案例'F':
      命令= 2; //设置淡入淡出模式。
    打破;
    情况下C:
      //我们把2个字符一起为
      //使用16进制做并设置颜色。
      字节红色= GETVAL(hex.charAt(1))+(GETVAL(hex.charAt(0))≤; 4;);
      字节绿色= GETVAL(hex.charAt(3))+(GETVAL(hex.charAt(2))&LT;&4;);
      字节蓝色= GETVAL(hex.charAt(5))+(GETVAL(hex.charAt(4))≤; 4;);      //设置颜色。
      的setColor(红,绿,蓝);
    打破;
  }
}//设置每个RGB销的颜色。
无效的setColor(字节红,绿字节,字节蓝){
  analogWrite(redPin,红色);
  analogWrite(grnPin,绿色);
  analogWrite(bluPin,蓝);
}//这个函数从无线电返回的数据。
无效RFduinoBLE_onReceive(字符*数据,INT LEN){
  的for(int i = 0; I&LT; LEN,我++){
    的statemachine(数据由[i]);
  }
}//主状态机功能,它处理
//数据取决于字节接收。
无效的statemachine(char数据){
  开关(州){
    情况1:
      如果(数据== 1){
        状态= 2;
      }
    打破;
    案例2:
      如果(数据=='B'||数据=='F'||数据=='C'){
        命令=数据;
        十六进制串=;
        状态= 3;
      }否则如果(数据!= 1){//状态2岁的,如果我们收到另一个为0x01。
        状态= 1;
      }
    打破;
    案例3:
      如果((数据&GT; ='一'和;&放大器;数据&下; ='Z')||(数据&GT ='0'和;&放大器;数据&下; ='9')){
        十六进制串=十六进制串+数据;
        如果(hexstring.length()== 6){
          状态= 4;
        }
      }否则如果(数据== 1){
        状态= 2;
      }其他{
        状态= 1;
      }
    打破;
    情况4:
      如果(数据== 3){
        processCommand(命令,十六进制串);
        状态= 1;
      }否则如果(数据== 1){
        状态= 2;
      }其他{
        状态= 1;
      }
    打破;
  }
}


解决方案

有一些code的这里,您可以用十六进制字符转换为字节。

所以,你可以将它添加到您现有的code -

 字节GETVAL(字符C)
{
       如果(c取代; ='0'和;&放大器;℃下='9')
         回报(字节)(C - '0');
       其他
         回报(字节)(C-A+ 10)
}无效processCommand(INT命令字符串十六进制)
{
      开关(命令){
           案例'B':
              命令= 1; //设置闪烁模式
               打破;
           案例'F':
              命令= 2; //设置淡入淡出模式
              打破;
           情况下C:
              字节红色= GETVAL(hex.charAt(1))+(GETVAL(hex.charAt(0))≤; 4;);
              字节绿色= GETVAL(hex.charAt(3))+(GETVAL(hex.charAt(2))&LT;&4;);
              字节蓝色= GETVAL(hex.charAt(5))+(GETVAL(hex.charAt(4))≤; 4;);
              的setColor(红,绿,蓝);
     }
}无效的setColor(字节红,绿字节,字节蓝)
{//为每个LED设置PWM。
        analogWrite(rgb2_pin,红色);
        analogWrite(rgb3_pin,绿色);
        analogWrite(rgb4_pin,蓝);
}

在iOS的一面,你可以使用这样的事情 -

   - (无效)sendCommand:(char)的命令ARG1:(字节)ARG1 ARG2:(字节)参数3:(字节){ARG3    * NSString的CommandString中= [的NSString stringWithFormat:@\\ 001%C%02X%02X%02X \\ 003,指挥,ARG1,ARG2,ARG3]    NSData的* commandData = [CommandString中dataUsingEncoding:NSASCIIStringEncoding];    [rfduino发送:数据]
} - (IBAction为)fadeButton pressed:(ID)发送{
    [个体经营sendCommand:'F'ARG1:ARG2 0:0参数3:0];
} - (IBAction为)blinkBut​​ton pressed:(ID)发送{
    [个体经营sendCommand:'B'ARG1:ARG2 0:0参数3:0];
} - (无效)的setColor
{
    的NSLog(@颜色:RGB%F%F%F,红,绿,蓝);    *的UIColor色=的UIColor colorWithRed:红,绿:绿色蓝色:蓝色阿尔法:1.0];    [colorSwatch setHighlighted:YES];
    [colorSwatch setTintColor:颜色];    [个体经营sendCommand:C ARG1:红* 255 ARG2:绿* 255 ARG3:蓝色* 255];
}

This is a cross-post from someone who answered my original question here.

I'm not sure how to go about executing the 3 functions I'm after (as well as introducing even more than 3 in the future).

I am simply trying to Fade/Blink the selected Colour of an RGB LED (and perhaps introduce more functions in the future) where its RGB data is coming back from iOS and sent to an RFDuino BLE module.

Sends a "fade" string to the module picked up by RFduinoBLE_onReceive (char *data, int len) on the Arduino end.

- (IBAction)fadeButtonPressed:(id)sender {
    [rfduino send:[@"fade" dataUsingEncoding:NSUTF8StringEncoding]];
}

- (IBAction)blinkButtonPressed:(id)sender {
    [rfduino send:[@"blink" dataUsingEncoding:NSUTF8StringEncoding]];
}

Selected Color:

- (void)setColor
{
    NSLog(@"colors: RGB %f %f %f", red, green, blue);

    UIColor *color = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];

    [colorSwatch setHighlighted:YES];
    [colorSwatch setTintColor:color];

    uint8_t tx[3] = { red * 255, green * 255, blue * 255 };
    NSData *data = [NSData dataWithBytes:(void*)&tx length:3];

    [rfduino send:data];
}

This is originally how I set the RGB colour:

void RFduinoBLE_onReceive (char *data, int len) {
    if (len >= 3) {
        // Get the RGB values.
        uint8_t red = data[0];
        uint8_t green = data[1];
        uint8_t blue = data[2];

        // Set PWM for each LED.
        analogWrite(rgb2_pin, red);
        analogWrite(rgb3_pin, green);
        analogWrite(rgb4_pin, blue);
    }
}

This was the provided answer that now compiles on Arduino, but I have no idea how to actually execute my functions and where?

#include <RFduinoBLE.h>

int state;
char command;
String hexstring;

// RGB pins.
int redPin = 2;
int grnPin = 3;
int bluPin = 4;

void setup () {
  state = 1;

  pinMode(redPin, OUTPUT);
  pinMode(grnPin, OUTPUT);
  pinMode(bluPin, OUTPUT);

  // This is the data we want to appear in the advertisement
  // (the deviceName length plus the advertisement length must be <= 18 bytes.
  RFduinoBLE.deviceName = "iOS";
  RFduinoBLE.advertisementInterval = MILLISECONDS(300);
  RFduinoBLE.txPowerLevel = -20;
  RFduinoBLE.advertisementData = "rgb";

  // Start the BLE stack.
  RFduinoBLE.begin();
}

void loop () {
  //RFduino_ULPDelay(INFINITE);
}

void processCommand (int command, String hex) {
  // hex ?
  // command ?
}

void RFduinoBLE_onReceive (char *data, int len) {
  for (int i = 0; i < len; i++) {
    stateMachine(data[i]);
  }
}

void stateMachine (char data) {
  switch (state) {
    case 1:
      if (data == 1) {
        state = 2;
      }
    break;
    case 2:
      if (data == 'b' || data == 'f' || data == 'c') {
        command = data;
        hexstring = "";
        state = 3;
      } else if (data != 1) { // Stay in state 2 if we received another 0x01.
        state = 1;
      }
    break;
    case 3:
      if ((data >= 'a' && data <= 'z') || (data >= '0' && data <= '9')) {
        hexstring = hexstring + data;
        if (hexstring.length() == 6) {
          state = 4;
        }
      } else if (data == 1) {
        state = 2;
      } else {
        state = 1;
      }
    break;
    case 4:
      if (data == 3) {
        processCommand(command, hexstring);
        state = 1;
      } else if (data == 1) {
        state = 2;
      } else {
        state = 1;
      }
    break;
  }
}

EDIT: Final code

#include <RFduinoBLE.h>

// State properties.
int state = 1;
char command;
String hexstring;

// RGB pins.
int redPin = 2;
int grnPin = 3;
int bluPin = 4;

// Setup function to set RGB pins to OUTPUT pins.
void setup () {
  pinMode(redPin, OUTPUT);
  pinMode(grnPin, OUTPUT);
  pinMode(bluPin, OUTPUT);

  // This is the data we want to appear in the advertisement
  // (the deviceName length plus the advertisement length must be <= 18 bytes.
  RFduinoBLE.deviceName = "iOS";
  RFduinoBLE.advertisementInterval = MILLISECONDS(300);
  RFduinoBLE.txPowerLevel = -20;
  RFduinoBLE.advertisementData = "rgb";

  // Start the BLE stack.
  RFduinoBLE.begin();
}

void loop () {
  switch (command) {
    case 1:
      // Blink.
    break;
    case 2:
      // Fade.
    break;
  }

  //RFduino_ULPDelay(INFINITE);
}

// Converts HEX as a String to actual HEX values.
// This is needed to properly convert the ASCII value to the hex
// value of each character.
byte getVal (char c) {
  if (c >= '0' && c <= '9') return (byte)(c - '0');
  else return (byte)(c - 'a' + 10);
}

// Process each function/command.
void processCommand (int command, String hex) {
  switch (command) {
    case 'b':
      command = 1; // Set blink mode.
    break;
    case 'f':
      command = 2; // Set fade mode.
    break;
    case 'c':
      // We put together 2 characters as is
      // done with HEX notation and set the color.
      byte red = getVal(hex.charAt(1)) + (getVal(hex.charAt(0)) << 4);
      byte green = getVal(hex.charAt(3)) + (getVal(hex.charAt(2)) << 4);
      byte blue = getVal(hex.charAt(5)) + (getVal(hex.charAt(4)) << 4);

      // Set the color.
      setColor (red, green, blue);
    break;
  }
}

// Sets the color of each RGB pin.
void setColor (byte red, byte green, byte blue) {
  analogWrite(redPin, red);
  analogWrite(grnPin, green);
  analogWrite(bluPin, blue);
}

// This function returns data from the radio.
void RFduinoBLE_onReceive (char *data, int len) {
  for (int i = 0; i < len; i++) {
    stateMachine(data[i]);
  }
}

// Main state machine function, which processes
// data depending on the bytes received.
void stateMachine (char data) {
  switch (state) {
    case 1:
      if (data == 1) {
        state = 2;
      }
    break;
    case 2:
      if (data == 'b' || data == 'f' || data == 'c') {
        command = data;
        hexstring = "";
        state = 3;
      } else if (data != 1) { // Stay in state 2 if we received another 0x01.
        state = 1;
      }
    break;
    case 3:
      if ((data >= 'a' && data <= 'z') || (data >= '0' && data <= '9')) {
        hexstring = hexstring + data;
        if (hexstring.length() == 6) {
          state = 4;
        }
      } else if (data == 1) {
        state = 2;
      } else {
        state = 1;
      }
    break;
    case 4:
      if (data == 3) {
        processCommand(command, hexstring);
        state = 1;
      } else if (data == 1) {
        state = 2;
      } else {
        state = 1;
      }
    break;
  }
}

解决方案

There is some code here that you can use to convert hex characters to a byte.

So, you can add this to your existing code -

byte getVal(char c) 
{
       if (c >= '0' && c <= '9')
         return (byte)(c - '0');
       else
         return (byte)(c-'a'+10)
}

void processCommand (int command, String hex)
{
      switch (command) {
           case 'b':
              command = 1;   // set blink mode
               break;
           case 'f':
              command=2;    // set fade mode
              break;
           case 'c':
              byte red=getVal(hex.charAt(1)) + (getVal(hex.charAt(0)) << 4);
              byte green=getVal(hex.charAt(3)) + (getVal(hex.charAt(2)) << 4);
              byte blue=getVal(hex.charAt(5)) + (getVal(hex.charAt(4)) << 4);
              setColor(red,green,blue);
     }
}

void setColor(byte red,byte green,byte blue)
{

// Set PWM for each LED.
        analogWrite(rgb2_pin, red);
        analogWrite(rgb3_pin, green);
        analogWrite(rgb4_pin, blue);
}

On the iOS side you can use something like this -

-(void) sendCommand:(char)command arg1:(Byte)arg1 arg2:(Byte)arg2 arg3:(Byte) arg3 {

    NSString *commandString=[NSString stringWithFormat:@"\001%c%02x%02x%02x\003",command,arg1,arg2,arg3];

    NSData *commandData=[commandString dataUsingEncoding:NSASCIIStringEncoding];

    [rfduino send:data];
}

- (IBAction)fadeButtonPressed:(id)sender {
    [self sendCommand:'f' arg1:0 arg2:0 arg3:0];
}

- (IBAction)blinkButtonPressed:(id)sender {
    [self sendCommand:'b' arg1:0 arg2:0 arg3:0];
}

- (void)setColor
{
    NSLog(@"colors: RGB %f %f %f", red, green, blue);

    UIColor *color = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];

    [colorSwatch setHighlighted:YES];
    [colorSwatch setTintColor:color];

    [self sendCommand:c arg1:red*255 arg2:green*255 arg3:blue*255];
}

这篇关于Arduino的状态机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆