Эскиз Arduino - чтение последовательных байтов - PullRequest
1 голос
/ 13 января 2012

У меня на Arduino следующий код, который постоянно проверяет последовательную команду, отправляемую по TCP с использованием библиотеки Wifly.

То, что делает следующий код, разбивает строку наподобие следующей при отправке через последовательный порт:

{power,tv}

Он устанавливает эти свойства соответственно:

char command[32];
char value[32];

Затем он выполняет определенные методы, используя sendCommand(command, value); на основе свойств, установленных в цикле ниже.

Имейте в виду, что это прекрасно работает с библиотекой Wifly.

void loop() {
  Client client = server.available();

  if (client) {

    boolean start_data = false;
    boolean next = false;

    char command[32];
    char value[32];
    int index = 0;

    while (client.connected()) {

      if (client.available()) {
        char c = client.read();
        Serial.print(c);

        if (c == '}') {
          break;
        }

        if(start_data == true) {

          if(c != ',') {

            if(next)
              value[index] = c;
            else
              command[index] = c;

            index++;
          } else {
            next = true;
            command[index] = '\0';
            index = 0;
          }

        }

        if (c == '{') {
          start_data = true;
        }

      }

    }

    value[index] = '\0';

    client.flush();
    client.stop();

    sendCommand(command,value);
  }

}

Вместо использования WiFi я купил несколько модулей Xbee. В основном они также позволяют отправлять последовательные байты. Единственная проблема в том, что я не совсем уверен, как справиться с циклом, учитывая, что while(client.connected()) больше нет. Вместо этого я использовал while(Serial.available()), думая, что это будет работать, но по какой-то причине он не устанавливает свойство value.

Я получаю command, но не получаю value.

Кроме того, я не уверен, является ли вышеприведенный цикл лучшим способом сделать то, что мне нужно, все, что я знаю, это то, что он работает просто так, как есть. :)

Вот мой новый цикл, который возвращает только command, а не value по некоторым причинам:

void loop() {

  // if there are bytes waiting on the serial port
  if (Serial.available()) { 
    boolean start_data = false;
    boolean next = false;

    char command[32];
    char value[32];
    int index = 0;

    while (Serial.available()) {
      char c = Serial.read();
      Serial.print(c);

      if (c == '}') {
        break;
      }

      if(start_data == true) {
        if(c != ',') {

          if(next)
            value[index] = c;
          else
            command[index] = c;

          index++;
        } else {
          next = true;
          command[index] = '\0';
          index = 0;
        }

      }

      if (c == '{') {
        start_data = true;
      }

    }

    value[index] = '\0';

    sendCommand(command,value);

  }

}

Если следующее работает с новым циклом, я буду очень счастлив!

void sendCommand(char *command, char *value) {
 // do something wonderful with command and value!
}

Ответы [ 2 ]

1 голос
/ 14 января 2012

Получил работу, используя следующий код:

#define SOP '{'
#define EOP '}'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(9600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet
    char *cmd = strtok(inData, ",");
    if(cmd)
    {
       char *val = strtok(NULL, ",");
       if(val)
       {
          sendCommand(cmd, val);
       }
    } 

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}
0 голосов
/ 13 января 2012

Я бы изменил структуру, подобную:

while( c != '}') {
     if (Serial.available()) { 
          .
          .
          .
     }
}

Серийные символы принимаются значительно медленнее, чем цикл.

...