I have two custom devices that I am attempting to control via a USB-to-serial connection. Each device will respond with a unique identifier so that I know which is attached to which port. I have some code that is partially working, but when I attempt to issue commands over the ID’d ports, one of the ports receives no data.
In setup:
// Point at a new serial object
ser_ptr = new ofSerial();
// Get a list of all serial devices
vector <ofSerialDeviceInfo> deviceList = ser_ptr->getDeviceList();
// Something to hold the found port names
vector <string> COMPorts;
// Get each port name
while (numCOMs < deviceList.size())
{
// Setup the port
ser_ptr->setup(deviceList[numCOMs].getDeviceName(), baud);
// Send challenge to device
int retValueOfChallenge = isMyDevice(ser_ptr); // Done this way for debug
// This will return whether it's a left (1) or right (2) device
if (retValueOfChallenge > 0)
{
// If the device answered as expected, add this port to the vector
headlights.push_back(*ser_ptr);
}
// We've added that port, so close it
ser_ptr->close();
// Done with this port
numCOMs++;
}
The helper function:
int ofApp::isMyDevice(ofSerial *port_ptr)
{
uint8_t commandBytes[2] = { 0x01, 0x00 };
uint8_t returnedBytes[10];
const uint8_t expectedBytes[10] = { 0x7F, 'M', 'D', 'M', '-', 'X', '\0' };
bool timedOut = false;
int deviceFound = 0;
port_ptr->writeBytes(commandBytes, 2);
// How long to wait on a read; 200mS is FOREVER
uint64_t timeOut = ofGetElapsedTimeMillis();
// Wait for the bytes to come in or timeout
while (port_ptr->available() < 9)
{
if ((ofGetElapsedTimeMillis() - timeOut) > 200)
{
timedOut = true;
break;
}
}
// If we timed out, return false
if (timedOut)
{
deviceFound = 0;
}
// Otherwise, get the bytes from the buffer
else
{
ser_ptr->readBytes(returnedBytes, 9);
// Compare vs. expected; initial 5 chars
int charsMatch = strncmp((char *)expectedBytes, (char *)returnedBytes, 5); // Done this way for debug
if (charsMatch == 0)
{
// This is left or right?
if (returnedBytes[5] == 'L')
{
deviceFound = 1;
}
else if (returnedBytes[5] == 'R')
{
deviceFound = 2;
}
else
{
deviceFound = 0;
}
}
else
{
deviceFound = 0;
}
}
return(deviceFound);
}
//------------------------------------------------------------------------------------
From there, whenever I want to send a command to both devices, I try something like this:
for (int i = 0; i < headlights.size(); i++)
{
headlights[i].writeBytes(commandBytes, 3);
}
But, the device with the higher “COMx” port number never receives it’s data. Is this the correct way to do this? It seems that when you open an ofSerial instance, it has knowledge of all of the COM ports in the system. So, do I need only a single ofSerial, and then I iterate through the devices under it? Looking for guidance on the best way to approach this.
Note that if hard-code the ports with unique instances, something like this:
serialRight.setup("COM7", baud);
serialLeft.setup("COM9", baud);
And then I use writeBytes on both of those instances, then everything works fine. Any ideas?
Thank you.