Arduino 状态机 [英] Arduino State Machine

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

问题描述

这是回答我最初问题的人的交叉帖子这里.

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

我不确定如何执行我所追求的 3 个函数(以及将来引入 3 个以上的函数).

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).

我只是试图淡化/闪烁 RGB LED 的选定颜色(并且可能在未来引入更多功能),其 RGB 数据从 iOS 返回并发送到 RFDuino BLE 模块.

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.

向Arduino端的RFduinoBLE_onReceive (char *data, int len)拾取的模块发送淡入淡出"字符串.

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

选择的颜色:

- (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 颜色的方式:

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

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

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

最终代码

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

在 iOS 端,你可以使用这样的东西 -

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天全站免登陆