Bluetooth-контролируемый код бота не понятен - PullRequest
0 голосов
/ 30 июня 2018

Я создаю бота, управляемого Bluetooth, но я не могу написать код. Поэтому я искал в Интернете, но не понимаю, почему мы не можем использовать вывод «Serial.read ()» напрямую вместо строки символов для хранения его значения, как это сделано в приведенном ниже коде?

Вот код, который я видел (из дайджеста схемы): Есть 4 колеса и, следовательно, 4 мотора.

#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 голосов
/ 02 июля 2018

Нет смысла в использовании индексной переменной i. Сначала в str [i ++] = ch автор увеличивает i после сохранения символа в str [], а затем сразу же ссылается на добавленный символ, используя 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 символов. Можно, конечно, отрегулировать размер.

...