【问题标题】:Arduino State MachineArduino状态机
【发布时间】:2014-06-03 02:01:05
【问题描述】:

这是回答我最初问题here的人的交叉帖子。

我不确定如何执行我所追求的 3 个功能(以及将来引入甚至更多的功能)。

我只是尝试淡化/闪烁 RGB LED 的选定颜色(将来可能会引入更多功能),其 RGB 数据从 iOS 返回并发送到RFDuino BLE module

向 Arduino 端 RFduinoBLE_onReceive (char *data, int len) 拾取的模块发送一个“fade”字符串。

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

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

所选颜色:

- (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];
}

这是我最初设置 RGB 颜色的方式:

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);
    }
}

这是现在在 Arduino 上编译的提供的答案,但我不知道如何实际执行我的函数以及在哪里执行?

#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;
  }
}

编辑:最终代码

#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;
  }
}

【问题讨论】:

    标签: objective-c arduino rgb led


    【解决方案1】:

    有一些代码here 可用于将十六进制字符转换为字节。

    因此,您可以将其添加到现有代码中 -

    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);
    }
    

    在 iOS 端,你可以使用类似的东西 -

    -(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];
    }
    

    【讨论】:

    • \001%c%02x%02x%02x\003 是什么?
    • 它是一种字符串格式,它返回一个以字符 0x01 开头的字符串,后跟命令字符,后跟三个字节,表示为两位十六进制数字,如果需要,前导 0 后跟字符 0x03跨度>
    猜你喜欢
    • 2020-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    相关资源
    最近更新 更多