From 412231aa715d1a36e1f3233f51715e5ee0e5a6b8 Mon Sep 17 00:00:00 2001 From: Thomas Pietrzak Date: Wed, 15 Feb 2012 13:41:58 +0000 Subject: [PATCH] Arduino serial library git-svn-id: svn+ssh://thomaspietrzak.com/var/svn/rep@46 47cf9a05-e0a8-4ed5-9e9b-101a649bc004 --- ArduinoSerial/ArduinoSerial.sln | 20 +++ ArduinoSerial/ArduinoSerial.suo | Bin 0 -> 19456 bytes .../ArduinoSerial/ArduinoSerial.vcxproj | 87 +++++++++++ .../ArduinoSerial.vcxproj.filters | 33 ++++ Serial.cpp | 10 ++ Serial.hpp | 35 +++++ SerialWindows.cpp | 142 ++++++++++++++++++ SerialWindows.hpp | 35 +++++ 8 files changed, 362 insertions(+) create mode 100644 ArduinoSerial/ArduinoSerial.sln create mode 100644 ArduinoSerial/ArduinoSerial.suo create mode 100644 ArduinoSerial/ArduinoSerial/ArduinoSerial.vcxproj create mode 100644 ArduinoSerial/ArduinoSerial/ArduinoSerial.vcxproj.filters create mode 100644 Serial.cpp create mode 100644 Serial.hpp create mode 100644 SerialWindows.cpp create mode 100644 SerialWindows.hpp diff --git a/ArduinoSerial/ArduinoSerial.sln b/ArduinoSerial/ArduinoSerial.sln new file mode 100644 index 0000000..3c947c0 --- /dev/null +++ b/ArduinoSerial/ArduinoSerial.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArduinoSerial", "ArduinoSerial\ArduinoSerial.vcxproj", "{CEF57CED-C17A-4E1C-998B-56B13896738B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CEF57CED-C17A-4E1C-998B-56B13896738B}.Debug|Win32.ActiveCfg = Debug|Win32 + {CEF57CED-C17A-4E1C-998B-56B13896738B}.Debug|Win32.Build.0 = Debug|Win32 + {CEF57CED-C17A-4E1C-998B-56B13896738B}.Release|Win32.ActiveCfg = Release|Win32 + {CEF57CED-C17A-4E1C-998B-56B13896738B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ArduinoSerial/ArduinoSerial.suo b/ArduinoSerial/ArduinoSerial.suo new file mode 100644 index 0000000000000000000000000000000000000000..71bf454febfb3450f098cc089d8c35c012e10bb3 GIT binary patch literal 19456 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 + + + + Debug + Win32 + + + Release + Win32 + + + + {CEF57CED-C17A-4E1C-998B-56B13896738B} + Win32Proj + ArduinoSerial + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;ARDUINOSERIAL_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;ARDUINOSERIAL_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ArduinoSerial/ArduinoSerial/ArduinoSerial.vcxproj.filters b/ArduinoSerial/ArduinoSerial/ArduinoSerial.vcxproj.filters new file mode 100644 index 0000000..c4a1bfe --- /dev/null +++ b/ArduinoSerial/ArduinoSerial/ArduinoSerial.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/Serial.cpp b/Serial.cpp new file mode 100644 index 0000000..6474450 --- /dev/null +++ b/Serial.cpp @@ -0,0 +1,10 @@ +#include "Serial.hpp" + +Serial::Serial(const char *) +:_connected(false) +{ +} + +Serial::~Serial() +{ +} diff --git a/Serial.hpp b/Serial.hpp new file mode 100644 index 0000000..da69a33 --- /dev/null +++ b/Serial.hpp @@ -0,0 +1,35 @@ +#ifndef _SERIAL_ +#define _SERIAL_ + +#define ARDUINO_WAIT_TIME 500 + +class Serial +{ + public: + //Initialize Serial communication with the given COM port + __declspec(dllexport) Serial(const char *portName); + + //Close the connection + //NOTA: for some reason you can't connect again before exiting + //the program and running it again + __declspec(dllexport) virtual ~Serial(); + + //Read data in a buffer, if nbChar is greater than the + //maximum number of bytes available, it will return only the + //bytes available. The function return -1 when nothing could + //be read, the number of bytes actually read. + __declspec(dllexport) virtual int ReadData(void *buffer, unsigned int nbChar)=0; + + //Writes data from a buffer through the Serial connection + //return true on success. + __declspec(dllexport) virtual bool WriteData(void *buffer, unsigned int nbChar)=0; + + //Check if we are actually connected + __declspec(dllexport) bool IsConnected() { return _connected; } + + protected: + //Connection status + bool _connected; +}; + +#endif diff --git a/SerialWindows.cpp b/SerialWindows.cpp new file mode 100644 index 0000000..04a27ad --- /dev/null +++ b/SerialWindows.cpp @@ -0,0 +1,142 @@ +#include "SerialWindows.hpp" + +#include +using namespace std; + +#ifdef WIN32 +#include +#endif + +SerialWindows::SerialWindows(const char *portName) +:Serial(portName) +{ + //Try to connect to the given port throuh CreateFile + _hSerial = CreateFileA(portName, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, //FILE_ATTRIBUTE_NORMAL, + NULL); + + //Check if the connection was successfull + if(_hSerial == INVALID_HANDLE_VALUE) + { + //If not success full display an Error + if(GetLastError() == ERROR_FILE_NOT_FOUND) + cerr << "ERROR: Handle was not attached. Reason: " << portName << " not available." << endl; + else + cerr << "ERROR unknown" << endl; + char buffer[256]; + sprintf(buffer, "Port %s does not exist or not reachable", portName); + throw buffer; + } + else + { + /* + COMMTIMEOUTS commTimeouts; + commTimeouts.ReadIntervalTimeout = 1; + commTimeouts.ReadTotalTimeoutMultiplier = 10; + commTimeouts.ReadTotalTimeoutConstant = 100; + commTimeouts.WriteTotalTimeoutMultiplier = 10; + commTimeouts.WriteTotalTimeoutConstant = 100; + if (SetCommTimeouts(_comport, &commTimeouts) == 0) + throw "Cannot set COM port timeouts";*/ + + + //If connected we try to set the comm parameters + DCB dcbSerialParams = {0}; + + //Try to get the current + if (!GetCommState(_hSerial, &dcbSerialParams)) + //If impossible, show an error + cerr << "ERROR: failed to get current serial parameters!" << endl; + else + { + //Define serial connection parameters for the arduino board + dcbSerialParams.BaudRate=CBR_57600; + dcbSerialParams.ByteSize=8; + dcbSerialParams.StopBits=ONESTOPBIT; + dcbSerialParams.Parity=NOPARITY; + + //Set the parameters and check for their proper application + if(!SetCommState(_hSerial, &dcbSerialParams)) + cerr << "ERROR: Could not set Serial Port parameters" << endl; + else + { + //If everything went fine we're connected + _connected = true; + //We wait 2s as the arduino board will be reseting + //Sleep(2000); + //SDL_Delay(ARDUINO_WAIT_TIME); + } + } + } +} + +SerialWindows::~SerialWindows() +{ + //Check if we are connected before trying to disconnect + if(_connected) + { + //We're no longer connected + _connected = false; + //Close the serial handler + CloseHandle(_hSerial); + } +} + +int SerialWindows::ReadData(void *buffer, unsigned int nbChar) +{ + //Number of bytes we'll have read + DWORD bytesRead = 0; + //Number of bytes we'll really ask to read + unsigned int toRead = 0; + + //Use the ClearCommError function to get status info on the Serial port + ClearCommError(_hSerial, &_errors, &_status); + + //Check if there is something to read + if(_status.cbInQue > 0) + { + //If there is we check if there is enough data to read the required number + //of characters, if not we'll read only the available characters to prevent + //locking of the application. + if(_status.cbInQue > nbChar) + toRead = nbChar; + else + toRead = _status.cbInQue; + + //Try to read the require number of chars, and return the number of read bytes on success + if(ReadFile(_hSerial, buffer, toRead, &bytesRead, NULL) && bytesRead != 0) + return bytesRead; + } + + //If nothing has been read, or that an error was detected return -1 + return -1; +} + + +bool SerialWindows::WriteData(void *buffer, unsigned int nbChar) +{ + DWORD bytesSend; + + //Try to write the buffer on the Serial port + if(!WriteFile(_hSerial, buffer, nbChar, &bytesSend, 0)) + { + //In case it don't work get comm error and return false + ClearCommError(_hSerial, &_errors, &_status); + + return false; + } + else + { + ClearCommError(_hSerial, &_errors, &_status); +/* if(!FlushFileBuffers(_hSerial)) + cout << "ERROR while flushing" << endl;*/ +/* stringstream s; + s << bytesSend << " SENT" << endl; + OutputDebugString(s.str().c_str());*/ + return true; + } +} diff --git a/SerialWindows.hpp b/SerialWindows.hpp new file mode 100644 index 0000000..0d2b112 --- /dev/null +++ b/SerialWindows.hpp @@ -0,0 +1,35 @@ +#ifndef _SERIALWINDOWS_ +#define _SERIALWINDOWS_ + +#include "Serial.hpp" + +#include + +class SerialWindows : public Serial +{ + public: + //Initialize Serial communication with the given COM port + __declspec(dllexport) SerialWindows(const char *portName); + //Close the connection + //NOTA: for some reason you can't connect again before exiting + //the program and running it again + __declspec(dllexport) ~SerialWindows(); + //Read data in a buffer, if nbChar is greater than the + //maximum number of bytes available, it will return only the + //bytes available. The function return -1 when nothing could + //be read, the number of bytes actually read. + __declspec(dllexport) int ReadData(void *buffer, unsigned int nbChar); + //Writes data from a buffer through the Serial connection + //return true on success. + __declspec(dllexport) bool WriteData(void *buffer, unsigned int nbChar); + + + private: + //Serial comm handler + HANDLE _hSerial; + //Get various information about the connection + COMSTAT _status; + //Keep track of last error + DWORD _errors; +}; +#endif -- 2.30.2