蓝牙控制的机器人代码不明

时间:2018-06-30 15:24:21

标签: embedded microcontroller arduino-uno robotics

我正在制作一个蓝牙控制的机器人,但是我无法编写代码。 因此,我在互联网上进行搜索,但不明白为什么我们不能直接使用“ Serial.read()”的输出,而不是像下面的代码那样使用char字符串来存储其值?

这是我看到的代码(来自电路摘要): 有四个轮子,因此有四个马达。

#define frm1 2         //front right motor
#define frm2 3         
#define flm1 4         //front left motor
#define flm2 5
#define rrm1 6         //rear right motor
#define rrm2 7
#define rlm1 8         //rear left motor
#define rlm2 9

char str[2], i;

void forward()
{
  digitalWrite(frm1, HIGH);
  digitalWrite(frm2, LOW);
  digitalWrite(flm1, HIGH);
  digitalWrite(flm2, LOW);
  digitalWrite(rrm1, HIGH);
  digitalWrite(rrm2, LOW);
  digitalWrite(rlm1, HIGH);
  digitalWrite(rlm2, LOW);
}

void right()
{
  digitalWrite(frm1, LOW);
  digitalWrite(frm2, HIGH);
  digitalWrite(flm1, HIGH);
  digitalWrite(flm2, LOW);
  digitalWrite(rrm1, LOW);
  digitalWrite(rrm2, HIGH);
  digitalWrite(rlm1, HIGH);
  digitalWrite(rlm2, LOW);
}

void backward()
{
  digitalWrite(frm1, LOW);
  digitalWrite(frm2, HIGH);
  digitalWrite(flm1, LOW);
  digitalWrite(flm2, HIGH);
  digitalWrite(rrm1, LOW);
  digitalWrite(rrm2, HIGH);
  digitalWrite(rlm1, LOW);
  digitalWrite(rlm2, HIGH);
}

void left()
{
  digitalWrite(frm1, HIGH);
  digitalWrite(frm2, LOW);
  digitalWrite(flm1, LOW);
  digitalWrite(flm2, HIGH);
  digitalWrite(rrm1, HIGH);
  digitalWrite(rrm2, LOW);
  digitalWrite(rlm1, LOW);
  digitalWrite(rlm2, HIGH);
}

void hault()
{
  digitalWrite(frm1, LOW);
  digitalWrite(frm2, LOW);
  digitalWrite(flm1, LOW);
  digitalWrite(flm2, LOW);
  digitalWrite(rrm1, LOW);
  digitalWrite(rrm2, LOW);
  digitalWrite(rlm1, LOW);
  digitalWrite(rlm2, LOW);
}

void setup() {
  Serial.begin(9600);
  pinMode(frm1, OUTPUT);
  pinMode(frm2, OUTPUT);
  pinMode(flm1, OUTPUT);
  pinMode(flm2, OUTPUT);
  pinMode(rrm1, OUTPUT);
  pinMode(rrm2, OUTPUT);
  pinMode(rlm1, OUTPUT);
  pinMode(rlm2, OUTPUT);
}

这是我不了解的循环。 字符串在这里有什么用?str [i-1]有什么帮助?

void loop() {
  while(Serial.available())
  {
    char ch = Serial.read();
    str[i++] = ch;    

    if(str[i-1] == '1')
    {
      forward();
      i=0;
    }
    else if(str[i-1]== '2')
    {
      left();
      i=0;
    }
    else if(str[i-1] == '3')
    {
      backward();
      i=0;
    }
    else if(str[i-1] == '4')
    {
      right();
      i=0;
    }
    else if(str[i-1] == '5')
    {
      hault();
      i=0;
    }
    delay(100);
  }
}

1 个答案:

答案 0 :(得分:1)

使用索引变量i没有任何目的。首先,在str [i ++] = ch中,作者在将字符存储在str []中之后将i递增,然后立即使用str [i-1]引用添加的字符。然后,他们将i = 0设置为零,这将清除最初从未使用的缓冲区!这是一种更好的方法:

void loop() {

    while (Serial.available()) {
        switch (Serial.read()) {
            case '1':
                forward();
                break;
            case '2':
                left();
                break;
            case '3':
                backward();
                break;
            case '4':
                right();
                break;
            case '5':
                hault();
                break;
            default:
                break;
        }
        delay(100);
    }

}

请注意,一旦串行数据输入停止,循环(与原始循环一样)将退出。可能需要也可能不需要。

还请注意,您可能希望对来自Serial.read()的输入进行双缓冲,以避免以更高的波特率丢弃字符-但是,原始代码并未这样做:

void loop() {
    char ch;
    char str[16];
    int i, j = 0;

    // buffer up to 16 chars
    while(Serial.available()) {
        ch = Serial.read();
        str[i++] = ch;
        if (i >= 16)
            break;
    }

    // process buffered characters
    for (j=0; j<i; j++) {
        switch (str[j]) {
            case '1':
                forward();
                break;
            case '2':
                left();
                break;
            case '3':
                backward();
                break;
            case '4':
                right();
                break;
            case '5':
                hault();
                break;
            default:
                break;
        }
        delay(100);
    }
    // reset buffer
    i = 0;
}

使用16个字符的缓冲区的原因是普通UART最多缓冲16个字符。您当然可以调整大小。