Проблема сравнения строк
У меня есть эта функция обратного вызова в моем скетче 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!
@Starter, 👍1
Обсуждение1 ответ
Лучший ответ:
Как заявил @timemage, strcmp
возвращает 0
для равенства. С уважением, в предоставленном коде, когда вы отправляете сообщение, содержимое которого не является КОМАНДОЙ
, светодиод будет гореть.
Чтобы получить то, что нам нужно, мы должны сравнить возвращаемое значение strcmp с
0
! Если он равен, то строки совпадают, и ваш предложенный код выполняется:
void stringCallback(char *myString)
{
if (strcmp(myString, "COMMAND") == 0) {
digitalWrite(13, HIGH);
}
Firmata.sendString(myString);
}
функции strcmp уже 50 лет, и она задокументирована во многих местах. исправление вашего кода не является полезным ресурсом на сайте вопросов и ответов, @Juraj
- Как разделить входящую строку?
- Как вывести несколько переменных в строке?
- форматирование строк в Arduino для вывода
- Очень простая операция Arduino Uno Serial.readString()
- DateTime в строку
- Как преобразовать строку в массив байтов
- Как отправить строку на мастер с помощью i2c
- Создание форматированной строки (включая числа с плавающей запятой) в Arduino-совместимом C++
Комментарии не предназначены для расширенного обсуждения; этот разговор был [перенесен в chat](https://chat.stackexchange.com/rooms/119633/discussion-on-question-by-starter-string-comparison-problem)., @Majenko