Разбор входящей строки (команда из двух параметров), парсинг Serial

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Добавляю возможность изменять параметры программы из консоли Serial, путем ввода двух команд, по примеру: набрали "FAN 48" - вентилятор сменил обороты, набрали "BAUD 9600" - скорость обмена по RS-485 изменилась на 9600 и т.п.

void serialEvent()  // функция с таким именем системная, вызывается автоматически как только в Serial приходят данные, т.е. в loop() ее прописывать не нужно. Не работает в Esplora, Leonardo, Micro
{
#define DELIMITER " ,.-"              // символы, возможные в качестве разделителя
  const byte bufLen = 32;             // ограничение длины входящего сообщения
  char buffer[bufLen];
  byte i = 0;                         // длина введенной строки
  delay(32);                          // ожидаем приема всей строки
  if (Serial.available() < 5) return; // отсеивает короткие сообщения
  while (Serial.available() && i < bufLen - 1) buffer[i++] = Serial.read();  //загоняем прочитанное в буфер
  buffer[i] = '\0';                                                          //закрываем массив
// разбиваем строку на подстроки по разделителю
    char *p = buffer;
    char *cmd = strtok_r(p, DELIMITER, &p);           // первая подстрока - команда
    unsigned long value = strtok_r(p, DELIMITER, &p); // первая подстрока - значение
// Входящая строка корректно разделяется на команду и значение, для проверки:
    Serial.printf("cmd: |%s|\n", cmd);
    Serial.printf("value: %s\n", value);
    if (*cmd == "FAN") // <-- это не работает
    {

Почему не выполняется сравнение if (cmd == "FAN")?

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Tomasina пишет:

Почему не выполняется сравнение if (cmd == "FAN")?

Я правильно понял, что, по крайней мере, с даты регистрации 09.03.2013 Вы, так или иначе, изучаете програмирование на С?

То есть более 4-х лет? Круто, чё!

----

Ответ на Ваш вопрос - пототому, что и не должно работать. Вот совсем никак. Для сравнения строк существуют функции.

strcmp() и strncmp(), для примера.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

ну, потому, что

13     char *cmd = strtok_r(p, DELIMITER, &p);           // первая подстрока - команда
14     unsigned long value = strtok_r(p, DELIMITER, &p); // первая подстрока - значение

char // это символ, а не строка

unsigned long // это число, а не строка

здесь #76 посмотри, как я собирал приходящие символы в строку и сравнивал ея с чем-то.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

wdrakula пишет:
То есть более 4-х лет? Круто, чё!

Ага, но я не изучаю C++ целенаправленно. Возникла потребность что-то сделать - сел и сделал. А потом несколько месяцев бездействия. И так сложилось, что за эти годы ни разу не приходилось плотно работать с указателями и ссылками ;) Я тут больше читатель, а не программист.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Tomasina пишет:

И так сложилось, что за эти годы ни разу не приходилось плотно работать с указателями и ссылками ;)

а, зачем ты их тут используешь?

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

надо же когда-то начинать, чтобы понять как оно работает.

Вчера разобрался как это сделать через String.subString и через sscanf_P, но они по отзывам довольно ресурсоемкие, поэтому погружаюсь глубже.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Tomasina, вот вы и добрались до строчных переменных. О них надо знать главное. Без них просто нельзя обойтись. Но в отличии от обычных переменных у них своя специфика. Но эта специфика еще различается до и после появления классов в Си. После появления классов появился класс String(), методы которые позволяют работать как с обычными переменными людям далеких от программирования.http://scrutator.me/post/2014/09/02/cpp_strings_basics.aspx

Ну чистых Си http://younglinux.info/c/strings

ПС: И еще в ардуино есть это dyn_string_t , но с этим я еще не работал

/* An abstract string datatype.
   Copyright (C) 1998-2015 Free Software Foundation, Inc.
   Contributed by Mark Mitchell (mark@markmitchell.com).

This file is part of GCC.
   
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA.  */

#ifndef DYN_STRING_H
#define DYN_STRING_H

#ifdef __cplusplus
extern "C" {
#endif

typedef struct dyn_string
{
  int allocated;	/* The amount of space allocated for the string.  */
  int length;		/* The actual length of the string.  */
  char *s;		/* The string itself, NUL-terminated.  */
}* dyn_string_t;

/* The length STR, in bytes, not including the terminating NUL.  */
#define dyn_string_length(STR)                                          \
  ((STR)->length)

/* The NTBS in which the contents of STR are stored.  */
#define dyn_string_buf(STR)                                             \
  ((STR)->s)

/* Compare DS1 to DS2 with strcmp.  */
#define dyn_string_compare(DS1, DS2)                                    \
  (strcmp ((DS1)->s, (DS2)->s))


extern int dyn_string_init (struct dyn_string *, int);
extern dyn_string_t dyn_string_new (int);
extern void dyn_string_delete (dyn_string_t);
extern char *dyn_string_release (dyn_string_t);
extern dyn_string_t dyn_string_resize (dyn_string_t, int);
extern void dyn_string_clear (dyn_string_t);
extern int dyn_string_copy (dyn_string_t, dyn_string_t);
extern int dyn_string_copy_cstr (dyn_string_t, const char *);
extern int dyn_string_prepend (dyn_string_t, dyn_string_t);
extern int dyn_string_prepend_cstr (dyn_string_t, const char *);
extern int dyn_string_insert (dyn_string_t, int, dyn_string_t);
extern int dyn_string_insert_cstr (dyn_string_t, int, const char *);
extern int dyn_string_insert_char (dyn_string_t, int, int);
extern int dyn_string_append (dyn_string_t, dyn_string_t);
extern int dyn_string_append_cstr (dyn_string_t, const char *);
extern int dyn_string_append_char (dyn_string_t, int);
extern int dyn_string_substring (dyn_string_t,  dyn_string_t, int, int);
extern int dyn_string_eq (dyn_string_t, dyn_string_t);

#ifdef __cplusplus
}
#endif

#endif /* !defined (DYN_STRING_H) */