Проблема сравнения строк

У меня есть эта функция обратного вызова в моем скетче Firmata. Он получает строку в виде массива символов и что-то с ней делает. Проблема в том, что строка отправляется на Arduino в форме T\0h\0i\0s\0 - после каждого символа стоит терминатор \0. Как вы можете видеть, моя функция включает светодиод d13, если входящая строка является КОМАНДОЙ. Я попытался использовать несколько методов сравнения:

  • strcmp(myString, "КОМАНДА") == 1;
  • myString == "КОМАНДА";
  • strcmp(myString, "COMMAND\0") == 1;
  • myString == "КОМАНДА\0";
  • strcmp(myString, "C\0O\0M\0 M\0A\0N\0D\0") == 1;
  • myString == "C\0O\0M\0 M\0A \ 0N\0D\0";
  • == с сохранением КОМАНДЫ в переменной массива char;
  • strcmp с сохранением КОМАНДЫ в переменной массива char;
  • последние две вещи с преобразованием как входящего, так и необходимого в строковый экземпляр;
  • сравнение строкового экземпляра с прямо указанной "КОМАНДОЙ"...

Ничего не работает. Как я могу сравнить строки работоспособно?

Полный скетч Arduino:

#include <Firmata.h>

void stringCallback(char *myString)
{
  if (strcmp(myString, "COMMAND") == 1) {
    digitalWrite(13, HIGH);
  }
  Firmata.sendString(myString);
}


void sysexCallback(byte command, byte argc, byte *argv)
{
  Firmata.sendSysex(command, argc, argv);
}

void setup()
{
  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
  Firmata.attach(STRING_DATA, stringCallback);
  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.begin(57600);
  pinMode(13, INPUT);
}

void loop()
{
  while (Firmata.available()) {
    Firmata.processInput();
  }
}

Полный код настольной программы:

import pyfirmata, time

class CustomArduino(pyfirmata.Arduino):
    def __init__(self, port: str):
        pyfirmata.Arduino.__init__(self, port)
        self.iterator = pyfirmata.util.Iterator(self)
        self.iterator.start()

        self.add_cmd_handler(0x71, self.receiveString)


    def receiveString(self, *args, **kwargs):
        print(f'Raw: {args}\n'
              f'Received: {pyfirmata.util.two_byte_iter_to_str(args)}')


    def sendString(self, data):
        self.send_sysex(0x71, pyfirmata.util.str_to_two_byte_iter(data))


    def send_sysex(self, sysex_cmd, data=[]):
        """
        Sends a SysEx msg.
        :arg sysex_cmd: A sysex command byte
        : arg data: a bytearray of 7-bit bytes of arbitrary data
        """
        msg = bytearray([pyfirmata.pyfirmata.START_SYSEX, sysex_cmd])
        msg.extend(data)
        msg.append(pyfirmata.pyfirmata.END_SYSEX)
        self.sp.write(msg)


print('STRING TESTER\nPlease input your COM port: ', end = '')
myCom = str(input())
device = CustomArduino(myCom)

while True: 
    device.sendString(input('Send: '))
    time.sleep(1)

Странная деталь: мой Arduino находится на COM-порту COM6. Если я подключу его через свою программу и отправлю com6 на arduino, загорится светодиод D13!

, 👍1

Обсуждение

Комментарии не предназначены для расширенного обсуждения; этот разговор был [перенесен в chat](https://chat.stackexchange.com/rooms/119633/discussion-on-question-by-starter-string-comparison-problem)., @Majenko


1 ответ


Лучший ответ:

0

Как заявил @timemage, strcmp возвращает 0 для равенства. С уважением, в предоставленном коде, когда вы отправляете сообщение, содержимое которого не является КОМАНДОЙ, светодиод будет гореть.

Чтобы получить то, что нам нужно, мы должны сравнить возвращаемое значение strcmp с 0! Если он равен, то строки совпадают, и ваш предложенный код выполняется:

void stringCallback(char *myString)
{
  if (strcmp(myString, "COMMAND") == 0) {
    digitalWrite(13, HIGH);
  }
  Firmata.sendString(myString);
}
,

функции strcmp уже 50 лет, и она задокументирована во многих местах. исправление вашего кода не является полезным ресурсом на сайте вопросов и ответов, @Juraj