So I have a program that is supposed to be connected to my PC and allow controlling a couple of Adafruit_NeoPixel strips.
I am using Serial for communication between the Arduino Mega 2560 and my PC.
There is a problem with one of the Serial.readBytes() where only one of the commands wont work at all.
PS. I am using 500'000 baudrate. But I tested with 115'200 baudrate aswell as 9'600. With the same results so there isn't packet loss.
Arduino Command Recieve Code:
else if (opCode == (unsigned char)ControlCodes::CREATE_LED_AREA) // Does not work
{
unsigned char* buffer = (unsigned char*)malloc(5); // Create a 5 byte size buffer
unsigned int bytesRead = GetData(buffer, 5); // Get the data from the Serial port
if (bytesRead == 5) // Check if bytes read is equal to the buffer size
{
unsigned short startLed = buffer[0] << 8 | buffer[1]; // Construct a short (2 byte) value from the first 2 bytes recieved
unsigned short endLed = buffer[2] << 8 | buffer[3]; // Construct a short (2 byte) value from the next 2 bytes recieved
unsigned char mode = buffer[4];
CreateLEDArea(startLed, endLed, mode); // Create LED Area using the newly constructed values
WriteData((unsigned char)ControlResults::OK); // Send back a OK result
}
else
{
WriteData((unsigned char)ControlResults::NOT_OK); // Send back a NOT_OK result
}
}
else if (opCode == (unsigned char)ControlCodes::DELETE_LED_AREA) // Works
{
unsigned char* buffer = (unsigned char*)malloc(2); // Create a 2 byte size buffer
unsigned int bytesRead = GetData(buffer, 2); // Get the data from the Serial port
if (bytesRead == 2) // Check if bytes read is equal to the buffer size
{
unsigned short index = buffer[0] << 8 | buffer[1]; // Construct a short (2 byte) value from the bytes recieved
RemoveLEDArea(index); // Remove LED Area using the newly constructed short
WriteData((unsigned char)ControlResults::OK); // Send back a OK result
}
else
{
WriteData((unsigned char)ControlResults::NOT_OK); // Send back a NOT_OK result
}
}
Arduino GetData function:
unsigned int ArduinoLEDController::GetData(unsigned char* buffer, unsigned int length)
{
return (unsigned int)Serial.readBytes(buffer, length); // Read %length% bytes into the buffer and return the number of bytes actually read.
}
C++17 with Common Language Runtime enabled in Visual Studio 2017.
Code for ControlCodes::CREATE_LED_AREA command:
unsigned char CreateLEDArea(SerialPort^ port, unsigned short startLed, unsigned short endLed, unsigned char mode)
{
port->DiscardInBuffer(); // Clear read buffer so we only read for this command
array<unsigned char>^ data = gcnew array<unsigned char>(6); // Create a new 'managed' unsigned char array with 6 elements
data[0] = (unsigned char)RGBAll::ControlCodes::CREATE_LED_AREA; // Set '0' to the command CREATE_LED_AREA
data[1] = (unsigned char)(startLed >> 8 & 0xFF); // Set '1' to the upper 8 bits of startLed
data[2] = (unsigned char)(startLed & 0xFF); // Set '2' to the lower 8 bits of startLed
data[3] = (unsigned char)(endLed >> 8 & 0xFF); // Set '3' to the upper 8 bits of endLed
data[4] = (unsigned char)(endLed & 0xFF); // Set '4' to the lower 8 bits of endLed
data[5] = mode; // Set '5' to mode
port->Write(data, 0, 6); // Send the array to the Arduino
unsigned char result = (unsigned char)RGBAll::ControlResults::NOT_OK; // Initialize a result as NOT_OK
try
{
result = port->ReadByte(); // Try to read the result
}
catch (System::TimeoutException^)
{
std::wcout << "ReadByte() timed out" << std::endl; // Read byte timed out
}
return result; // Return result
}
Code for ControlCodes::DELETE_LED_AREA command:
unsigned char DeleteLEDArea(SerialPort^ port, unsigned short index)
{
port->DiscardInBuffer(); // Clear read buffer so we only read ffor this command
array<unsigned char>^ data = gcnew array<unsigned char>(3); // Create a new 'managed' unsigned char array with 3 elements
data[0] = (unsigned char)RGBAll::ControlCodes::DELETE_LED_AREA; // Set '0' to the command DELETE_LED_AREA
data[1] = (unsigned char)(index >> 8 & 0xFF); // Set '1' to the upper 8 bits of index
data[2] = (unsigned char)(index & 0xFF); // Set '2' to the lower 8 bits of index
port->Write(data, 0, 3); // Send the array to the Arduino
unsigned char result = (unsigned char)RGBAll::ControlResults::NOT_OK; // Initialize a result as NOT_OK
try
{
result = (unsigned char)port->ReadByte(); // Try to read the result
}
catch (System::TimeoutException^)
{
std::wcout << "ReadByte() timed out" << std::endl; // Read byte timed out
}
return result; // Return result
}
When i run the code and try to use the function like this "CreateLEDArea(port, 0, 50, 0)"
it returns 'NOT_OK'.
When i run the other function like this "DeleteLEDArea(port, 0)"
it returns 'OK'.
So there seems to be a weird thing about that one case.