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 T\0h\0i\0s\0 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, "COMMAND\0") == 1;myString == "COMMAND\0";strcmp(myString, "C\0O\0M\0 M\0A\0N\0D\0") == 1;myString == "C\0O\0M\0 M\0A\0N\0D\0";==with saving theCOMMANDto a char array variable;strcmpwith saving theCOMMANDto 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!