I have this callback function in my Firmata sketch. It receives a string as a character array and does something with it. The problem is, that the string is being sent to the Arduino in T0円h0円i0円s0円
form - after each character there is a 0円
terminator. As you can see, my function is switching the d13 LED on if the string incoming is COMMAND
. I had tried to use several comparison methods:
strcmp(myString, "COMMAND") == 1
;myString == "COMMAND"
;strcmp(myString, "COMMAND0円") == 1
;myString == "COMMAND0円"
;strcmp(myString, "C0円O0円M0円 M0円A0円N0円D0円") == 1
;myString == "C0円O0円M0円 M0円A0円N0円D0円"
;==
with saving theCOMMAND
to a char array variable;strcmp
with saving theCOMMAND
to a char array variable;- last two things with converting both the incoming and the needed to a String instance;
- comparing a String instance with a directly stated
"COMMAND"
...
Nothing works. How can I compare the strings workably?
Full Arduino sketch:
#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();
}
}
Full code of the desktop program:
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)
Strange detail: my Arduino is on the COM6
COM-port. If I connect it via my program and send com6
to the arduino, the D13 LED turns on!
-
Comments are not for extended discussion; this conversation has been moved to chat.Majenko– Majenko2021年02月11日 15:46:30 +00:00Commented Feb 11, 2021 at 15:46
1 Answer 1
As @timemage stated, strcmp
returns 0
for equal. Sincerely in the provided code, while you send a message, which contents are not COMMAND
, the LED will be turned on.
To get what we need, we must compare strcmp
return value with 0
! If it equals, then the strings match, and your suggested code is being executed:
void stringCallback(char *myString)
{
if (strcmp(myString, "COMMAND") == 0) {
digitalWrite(13, HIGH);
}
Firmata.sendString(myString);
}
-
the strcmp function is 50 years old and documented in many places. a fix of your code is not a useful resource on a Q&A site2021年02月12日 18:05:45 +00:00Commented Feb 12, 2021 at 18:05