From: Thomas Pietrzak Date: Wed, 15 Feb 2012 13:41:58 +0000 (+0000) Subject: Arduino serial library X-Git-Url: https://git.thomaspietrzak.com/?a=commitdiff_plain;h=412231aa715d1a36e1f3233f51715e5ee0e5a6b8;p=arduinoserial.git Arduino serial library git-svn-id: svn+ssh://thomaspietrzak.com/var/svn/rep@46 47cf9a05-e0a8-4ed5-9e9b-101a649bc004 --- 412231aa715d1a36e1f3233f51715e5ee0e5a6b8 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 0000000..71bf454 Binary files /dev/null and b/ArduinoSerial/ArduinoSerial.suo differ diff --git a/ArduinoSerial/ArduinoSerial/ArduinoSerial.vcxproj b/ArduinoSerial/ArduinoSerial/ArduinoSerial.vcxproj new file mode 100644 index 0000000..588b847 --- /dev/null +++ b/ArduinoSerial/ArduinoSerial/ArduinoSerial.vcxproj @@ -0,0 +1,87 @@ + + + + + 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