首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Arduino状态机

Arduino状态机
EN

Stack Overflow用户
提问于 2014-06-03 02:01:05
回答 1查看 609关注 0票数 0

这是一个来自于回答我最初问题这里的人的交叉帖子.

我不知道如何执行我所追求的3个函数(以及在将来引入更多的3个函数)。

我只是试图淡出/闪烁选定的颜色的RGB (也许在未来引入更多的功能),它的RGB数据是从iOS回来并发送到一个RFDuino BLE模块

RFduinoBLE_onReceive (char *data, int len)在Arduino端接收的模块发送一个“淡出”字符串。

代码语言:javascript
复制
- (IBAction)fadeButtonPressed:(id)sender {
    [rfduino send:[@"fade" dataUsingEncoding:NSUTF8StringEncoding]];
}

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

精选颜色:

代码语言:javascript
复制
- (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颜色的:

代码语言:javascript
复制
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上编译的答案,但是我不知道如何实际执行我的函数,在哪里?

代码语言:javascript
复制
#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;
  }
}

编辑:最终代码

代码语言:javascript
复制
#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;
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-03 02:15:14

有一些代码这里可以用来将十六进制字符转换为一个字节。

所以,你可以把这个添加到你现有的代码中-

代码语言:javascript
复制
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方面,您可以使用这样的东西-

代码语言:javascript
复制
-(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];
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24005992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档