Hello all,
I am building an application that allows for serial communication between a GUI interface on a PC and an arduino uno. The sending of data from the pc to the arduino seems to be working, but I cannot seem to be able to receive any data.
The basic methodology of my program is as follows:
- After a certain action by the user, the GUI program will send a string to the arduino through the serial port (Right now the only "command" string set up is OUTPUT, which sets an output pins value)
- The arduino will then process that string and implement it, and afterwards send a confirmation string that the command has succeeded
I can tell that the data is getting to the arduino because the TX light blinks whenever a command is sent. However the RX light rarely, if ever, turns on. I do not have LEDs or any other such indicator with me to actually see if the command is being implemented, but right now my only concern is getting data back into the GUI program on the PC.
My code implements the following class to allow for serial communication:
Header:
#ifndef SERIALPORT_H
#define SERIALPORT_H
#define ARDUINO_WAIT_TIME 2000
#define MAX_DATA_LENGTH 255
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
class SerialPort
{
private:
HANDLE handler;
bool connected;
COMSTAT status;
DWORD errors;
public:
SerialPort(char *portName);
~SerialPort();
int readSerialPort(char *buffer, unsigned int buf_size);
bool writeSerialPort(char *buffer, unsigned int buf_size);
bool isConnected();
};
#endif // SERIALPORT_H
[/quote]
SerialPort CPP:
[quote]#include "SerialPort.h"
SerialPort::SerialPort(char *portName)
{
this->connected = false;
this->handler = CreateFileA(static_cast<LPCSTR>(portName),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (this->handler == INVALID_HANDLE_VALUE){
if (GetLastError() == ERROR_FILE_NOT_FOUND){
printf("ERROR: Handle was not attached. Reason: %s not available\n", portName);
}
else
{
printf("ERROR!!!");
}
}
else {
DCB dcbSerialParameters = {0};
if (!GetCommState(this->handler, &dcbSerialParameters)) {
printf("failed to get current serial parameters");
}
else {
dcbSerialParameters.BaudRate = CBR_9600;
dcbSerialParameters.ByteSize = 8;
dcbSerialParameters.StopBits = ONESTOPBIT;
dcbSerialParameters.Parity = NOPARITY;
dcbSerialParameters.fDtrControl = DTR_CONTROL_ENABLE;
if (!SetCommState(handler, &dcbSerialParameters))
{
printf("ALERT: could not set Serial port parameters\n");
}
else {
this->connected = true;
PurgeComm(this->handler, PURGE_RXCLEAR | PURGE_TXCLEAR);
Sleep(ARDUINO_WAIT_TIME);
}
}
}
}
SerialPort::~SerialPort()
{
if (this->connected){
this->connected = false;
CloseHandle(this->handler);
}
}
int SerialPort::readSerialPort(char *buffer, unsigned int buf_size)
{
DWORD bytesRead;
unsigned int toRead;
ClearCommError(this->handler, &this->errors, &this->status);
if (this->status.cbInQue > 0){
if (this->status.cbInQue > buf_size){
toRead = buf_size;
}
else toRead = this->status.cbInQue;
}
if (ReadFile(this->handler, buffer, toRead, &bytesRead, NULL)) return bytesRead;
return 0;
}
bool SerialPort::writeSerialPort(char *buffer, unsigned int buf_size)
{
DWORD bytesSend;
if (!WriteFile(this->handler, (void*) buffer, buf_size, &bytesSend, 0)){
ClearCommError(this->handler, &this->errors, &this->status);
return false;
}
else return true;
}
bool SerialPort::isConnected()
{
return this->connected;
}
My arduino Code:
String incomingByte;
char command[6];
int param1 = 0;
int param2 = 0;
void setup() {
Serial.begin(9600);
}
void loop(){
if(Serial.available() > 0)
incomingByte = Serial.readStringUntil('\n');
// Convert from String Object to string (char)
char buf[15];
incomingByte.toCharArray(buf, 15);
//parse string command
char* token = strtok(buf, " ");
strcpy(command, token);
token = strtok(NULL, " ");
param1 = atoi(token);
token = strtok(NULL, " ");
param2 = atoi(token);
if(*command == 'O' && *(command + 5) == 'T'){ //Look for command OUTPUT
pinMode(param1, 1);
digitalWrite(param1, param2);
incomingByte = "";
Serial.flush();
Serial.println("SUCCESS");
}
}
I will not upload the entirity of my GUI program for simplicity sake, but this is my implementation of reading the arduino, done through a timer on a 500ms interval. Again, this implementation might be my problem.
arduino->readSerialPort(output,MAX_DATA_LENGTH);
if(output[0] = 'S'){
std::string sTemp = std::string(output);
UnicodeString st = UnicodeString(AnsiString(sTemp.c_str()));
consoleEdit->Lines->Add(commandEdit->Text);
Timer1->Enabled = false;
"output" is a char array with size of 255
the jumble in the middle is converting the char array to a wchar UnicodeString so VCL can be happy.
Any help is appreciated