diff --git a/.gitignore b/.gitignore
index 1fc2c47..a749124 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,7 @@ cmake-build-debug/
.vscode/
# Sphinx build dir
-docs/_build/
\ No newline at end of file
+docs/_build/
+
+# Build artifacts
+a.out
\ No newline at end of file
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index 0ee9eae..81ce4af 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -60,7 +60,8 @@
},
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
- "cppStandard": "c++17"
+ "cppStandard": "c++17",
+ "configurationProvider": "ms-vscode.cmake-tools"
},
{
"name": "Win32",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8b85fa4..8902279 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
+## [v2.1.0] - 2020-11-08
+
+### Added
+- Support for custom baud rates.
+- Support for all standard UNIX baud rates.
+- Improved Doxygen documentation.
+- Improved README.md documentation.
+
+### Removed
+- Dependencies from the README, they weren't that useful and were not accurate anyway.
+
## [v2.0.3] - 2020-10-13
### Added
diff --git a/README.md b/README.md
index 75f4a19..caea473 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# CppLinuxSerial
-Serial port library written in C++
+Linux serial port library written in C++.
[](https://travis-ci.org/gbmhunter/CppLinuxSerial)
@@ -8,7 +8,9 @@ Serial port library written in C++
Library for communicating with COM ports on a Linux system.
-Uses fstream to the file I/O.
+* Simple API
+* Supports custom baud rates
+* cmake based build system
## Installation
@@ -66,18 +68,20 @@ using namespace mn::CppLinuxSerial;
int main() {
// Create serial port object and open serial port
- SerialPort serialPort0("/dev/ttyUSB0", BaudRate::B_57600);
- serialPort0.Open();
+ SerialPort serialPort("/dev/ttyUSB0", BaudRate::B_57600);
+ // Use SerialPort serialPort("/dev/ttyACM0", 13000); instead if you want to provide a custom baud rate
+ serialPort.SetTimeout(-1); // Block when reading until any data is received
+ serialPort.Open();
// Write some ASCII datae
- serialPort0.Write("Hello");
+ serialPort.Write("Hello");
- // Read some data back
+ // Read some data back (will block until at least 1 byte is received due to the SetTimeout(-1) call above)
std::string readData;
- serialPort0.Read(readData);
+ serialPort.Read(readData);
// Close the serial port
- serialPort0.Close();
+ serialPort.Close();
}
```
@@ -87,34 +91,7 @@ If the above code was in a file called `main.cpp` and you had installed `CppLinu
g++ main.cpp -lCppLinuxSerial
```
-For more examples, see the `.cpp` files in `test/unit/`.
-
-## Dependencies
-
-The following table lists all of the libraries dependencies.
-
-
-
-
- | Dependency |
- Comments |
-
-
-
-
- | C++14 |
- C++14 used for strongly typed enums, `std::chrono` and literals. |
-
-
- | stdio.h |
- snprintf() |
-
-
- | stty |
- Used in unit tests to verify the serial port is configured correctly. |
-
-
-
+For more examples, see the files in `test/`.
## Issues
@@ -122,7 +99,7 @@ See GitHub Issues.
## FAQ
-1. My code stalls when calling functions like `SerialPort::Read()`. This is probably because the library is set up to do a blocking read, and not enough characters have been received to allow `SerialPort::Read()` to return. Use `SerialPort::SetNumCharsToWait()` to determine how many characters to wait for before returning (set to 0 for non-blocking mode).
+1. My code stalls when calling functions like `SerialPort::Read()`. This is probably because the library is set up to do a blocking read, and not enough characters have been received to allow `SerialPort::Read()` to return. Call `SerialPort::SetTimeout(0)` before the serial port is open to set a non-blocking mode.
## Changelog
diff --git a/include/CppLinuxSerial/SerialPort.hpp b/include/CppLinuxSerial/SerialPort.hpp
index 1ece112..6739e7a 100644
--- a/include/CppLinuxSerial/SerialPort.hpp
+++ b/include/CppLinuxSerial/SerialPort.hpp
@@ -15,8 +15,11 @@
#include
#include // For file I/O (reading/writing to COM port)
#include
-#include // POSIX terminal control definitions (struct termios)
+// #include // POSIX terminal control definitions (struct termios)
+// #include // Terminal control definitions (struct termios)
#include
+#include
+#include
// User headers
#include "Exception.hpp"
@@ -24,18 +27,44 @@
namespace mn {
namespace CppLinuxSerial {
+ /// \brief Represents the baud rate "types" that can be used with the serial port. STANDARD represents all
+ /// the standard baud rates as provided by UNIX, CUSTOM represents a baud rate defined by an arbitray integer.
+ enum class BaudRateType {
+ STANDARD,
+ CUSTOM,
+ };
+
/// \brief Strongly-typed enumeration of baud rates for use with the SerialPort class
+ /// \details Specifies all the same baud rates as UNIX, as well as B_CUSTOM to specify your
+ /// own. See https://linux.die.net/man/3/cfsetispeed for list of supported UNIX baud rates.
enum class BaudRate {
+ B_0,
+ B_50,
+ B_75,
+ B_110,
+ B_134,
+ B_150,
+ B_200,
+ B_300,
+ B_600,
+ B_1200,
+ B_1800,
+ B_2400,
+ B_4800,
B_9600,
+ B_19200,
B_38400,
B_57600,
B_115200,
- CUSTOM
+ B_230400,
+ B_460800,
+ B_CUSTOM, // Placeholder
};
+ /// \brief Represents the state of the serial port.
enum class State {
CLOSED,
- OPEN
+ OPEN,
};
/// \brief SerialPort object is used to perform rx/tx serial communication.
@@ -48,15 +77,22 @@ namespace mn {
/// \brief Constructor that sets up serial port with the basic (required) parameters.
SerialPort(const std::string &device, BaudRate baudRate);
- //! @brief Destructor. Closes serial port if still open.
+ /// \brief Constructor that sets up serial port with the basic (required) parameters.
+ SerialPort(const std::string &device, speed_t baudRate);
+
+ /// \brief Destructor. Closes serial port if still open.
virtual ~SerialPort();
/// \brief Sets the device to use for serial port communications.
/// \details Method can be called when serial port is in any state.
void SetDevice(const std::string &device);
+ /// \brief Allows the user to set a standard baud rate.
void SetBaudRate(BaudRate baudRate);
+ /// \brief Allows the user to set a custom baud rate.
+ void SetBaudRate(speed_t baudRate);
+
/// \brief Sets the read timeout (in milliseconds)/blocking mode.
/// \details Only call when state != OPEN. This method manupulates VMIN and VTIME.
/// \param timeout_ms Set to -1 to infinite timeout, 0 to return immediately with any data (non
@@ -92,13 +128,19 @@ namespace mn {
private:
/// \brief Returns a populated termios structure for the passed in file descriptor.
- termios GetTermios();
+ // termios GetTermios();
/// \brief Configures the tty device as a serial port.
/// \warning Device must be open (valid file descriptor) when this is called.
void ConfigureTermios();
- void SetTermios(termios myTermios);
+ // void SetTermios(termios myTermios);
+
+ /// \brief Returns a populated termios2 structure for the serial port pointed to by the file descriptor.
+ termios2 GetTermios2();
+
+ /// \brief Assigns the provided tty settings to the serial port pointed to by the file descriptor.
+ void SetTermios2(termios2 tty);
/// \brief Keeps track of the serial port's state.
State state_;
@@ -106,8 +148,14 @@ namespace mn {
/// \brief The file path to the serial port device (e.g. "/dev/ttyUSB0").
std::string device_;
- /// \brief The current baud rate.
- BaudRate baudRate_;
+ /// \brief The type of baud rate that the user has specified.
+ BaudRateType baudRateType_;
+
+ /// \brief The current baud rate if baudRateType_ == STANDARD.
+ BaudRate baudRateStandard_;
+
+ /// \brief The current baud rate if baudRateType_ == CUSTOM.
+ speed_t baudRateCustom_;
/// \brief The file descriptor for the open file. This gets written to when Open() is called.
int fileDesc_;
diff --git a/src/SerialPort.cpp b/src/SerialPort.cpp
index 9bf0aca..d3f09fa 100644
--- a/src/SerialPort.cpp
+++ b/src/SerialPort.cpp
@@ -15,20 +15,28 @@
#include // UNIX standard function definitions
#include // File control definitions
#include // Error number definitions
-#include // POSIX terminal control definitions (struct termios)
+// #include // POSIX terminal control definitions (struct termios)
#include // For throwing std::system_error
+#include // Used for TCGETS2, which is required for custom baud rates
+#include
+// #include // Terminal control definitions (struct termios)
+#include
+#include
// User includes
#include "CppLinuxSerial/Exception.hpp"
#include "CppLinuxSerial/SerialPort.hpp"
+#define BOTHER 0010000
+
namespace mn {
namespace CppLinuxSerial {
SerialPort::SerialPort() {
echo_ = false;
timeout_ms_ = defaultTimeout_ms_;
- baudRate_ = defaultBaudRate_;
+ baudRateType_ = BaudRateType::STANDARD;
+ baudRateStandard_ = defaultBaudRate_;
readBufferSize_B_ = defaultReadBufferSize_B_;
readBuffer_.reserve(readBufferSize_B_);
state_ = State::CLOSED;
@@ -37,7 +45,15 @@ namespace CppLinuxSerial {
SerialPort::SerialPort(const std::string& device, BaudRate baudRate) :
SerialPort() {
device_ = device;
- baudRate_ = baudRate;
+ baudRateType_ = BaudRateType::STANDARD;
+ baudRateStandard_ = baudRate;
+ }
+
+ SerialPort::SerialPort(const std::string& device, speed_t baudRate) :
+ SerialPort() {
+ device_ = device;
+ baudRateType_ = BaudRateType::CUSTOM;
+ baudRateCustom_ = baudRate;
}
SerialPort::~SerialPort() {
@@ -52,13 +68,21 @@ namespace CppLinuxSerial {
void SerialPort::SetDevice(const std::string& device) {
device_ = device;
if(state_ == State::OPEN)
-
-
- ConfigureTermios();
+ ConfigureTermios();
}
void SerialPort::SetBaudRate(BaudRate baudRate) {
- baudRate_ = baudRate;
+ std::cout << "standard called\n";
+ baudRateType_ = BaudRateType::STANDARD;
+ baudRateStandard_ = baudRate;
+ if(state_ == State::OPEN)
+ ConfigureTermios();
+ }
+
+ void SerialPort::SetBaudRate(speed_t baudRate) {
+ std::cout << " custom called\n";
+ baudRateType_ = BaudRateType::CUSTOM;
+ baudRateCustom_ = baudRate;
if(state_ == State::OPEN)
ConfigureTermios();
}
@@ -66,7 +90,7 @@ namespace CppLinuxSerial {
void SerialPort::Open()
{
- std::cout << "Attempting to open COM port \"" << device_ << "\"." << std::endl;
+ // std::cout << "Attempting to open COM port \"" << device_ << "\"." << std::endl;
if(device_.empty()) {
THROW_EXCEPT("Attempted to open file when file path has not been assigned to.");
@@ -86,7 +110,7 @@ namespace CppLinuxSerial {
ConfigureTermios();
- std::cout << "COM port opened successfully." << std::endl;
+ // std::cout << "COM port opened successfully." << std::endl;
state_ = State::OPEN;
}
@@ -97,11 +121,12 @@ namespace CppLinuxSerial {
void SerialPort::ConfigureTermios()
{
- std::cout << "Configuring COM port \"" << device_ << "\"." << std::endl;
+ // std::cout << "Configuring COM port \"" << device_ << "\"." << std::endl;
//================== CONFIGURE ==================//
- termios tty = GetTermios();
+ // termios tty = GetTermios();
+ termios2 tty = GetTermios2();
//================= (.c_cflag) ===============//
@@ -115,29 +140,171 @@ namespace CppLinuxSerial {
//===================== BAUD RATE =================//
- switch(baudRate_) {
- case BaudRate::B_9600:
- cfsetispeed(&tty, B9600);
- cfsetospeed(&tty, B9600);
- break;
- case BaudRate::B_38400:
- cfsetispeed(&tty, B38400);
- cfsetospeed(&tty, B38400);
- break;
- case BaudRate::B_57600:
- cfsetispeed(&tty, B57600);
- cfsetospeed(&tty, B57600);
- break;
- case BaudRate::B_115200:
- cfsetispeed(&tty, B115200);
- cfsetospeed(&tty, B115200);
- break;
- case BaudRate::CUSTOM:
- // See https://gist.github.com/kennethryerson/f7d1abcf2633b7c03cf0
- throw std::runtime_error("Custom baud rate not yet supported.");
- default:
- throw std::runtime_error(std::string() + "baudRate passed to " + __PRETTY_FUNCTION__ + " unrecognized.");
- }
+ // We used to use cfsetispeed() and cfsetospeed() with the B... macros, but this didn't allow
+ // us to set custom baud rates. So now to support both standard and custom baud rates lets
+ // just make everything "custom". This giant switch statement could be replaced with a map/lookup
+ // in the future
+ if (baudRateType_ == BaudRateType::STANDARD) {
+ tty.c_cflag &= ~CBAUD;
+ tty.c_cflag |= CBAUDEX;
+ switch(baudRateStandard_) {
+ case BaudRate::B_0:
+ // cfsetispeed(&tty, B0);
+ // cfsetospeed(&tty, B0);
+ tty.c_ispeed = 0;
+ tty.c_ospeed = 0;
+ break;
+ case BaudRate::B_50:
+ // cfsetispeed(&tty, B50);
+ // cfsetospeed(&tty, B50);
+ tty.c_ispeed = 50;
+ tty.c_ospeed = 50;
+ break;
+ case BaudRate::B_75:
+ // cfsetispeed(&tty, B75);
+ // cfsetospeed(&tty, B75);
+ tty.c_ispeed = 75;
+ tty.c_ospeed = 75;
+ break;
+ case BaudRate::B_110:
+ // cfsetispeed(&tty, B110);
+ // cfsetospeed(&tty, B110);
+ tty.c_ispeed = 110;
+ tty.c_ospeed = 110;
+ break;
+ case BaudRate::B_134:
+ // cfsetispeed(&tty, B134);
+ // cfsetospeed(&tty, B134);
+ tty.c_ispeed = 134;
+ tty.c_ospeed = 134;
+ break;
+ case BaudRate::B_150:
+ // cfsetispeed(&tty, B150);
+ // cfsetospeed(&tty, B150);
+ tty.c_ispeed = 150;
+ tty.c_ospeed = 150;
+ break;
+ case BaudRate::B_200:
+ // cfsetispeed(&tty, B200);
+ // cfsetospeed(&tty, B200);
+ tty.c_ispeed = 200;
+ tty.c_ospeed = 200;
+ break;
+ case BaudRate::B_300:
+ // cfsetispeed(&tty, B300);
+ // cfsetospeed(&tty, B300);
+ tty.c_ispeed = 300;
+ tty.c_ospeed = 300;
+ break;
+ case BaudRate::B_600:
+ // cfsetispeed(&tty, B600);
+ // cfsetospeed(&tty, B600);
+ tty.c_ispeed = 600;
+ tty.c_ospeed = 600;
+ break;
+ case BaudRate::B_1200:
+ // cfsetispeed(&tty, B1200);
+ // cfsetospeed(&tty, B1200);
+ tty.c_ispeed = 1200;
+ tty.c_ospeed = 1200;
+ break;
+ case BaudRate::B_1800:
+ // cfsetispeed(&tty, B1800);
+ // cfsetospeed(&tty, B1800);
+ tty.c_ispeed = 1800;
+ tty.c_ospeed = 1800;
+ break;
+ case BaudRate::B_2400:
+ // cfsetispeed(&tty, B2400);
+ // cfsetospeed(&tty, B2400);
+ tty.c_ispeed = 2400;
+ tty.c_ospeed = 2400;
+ break;
+ case BaudRate::B_4800:
+ // cfsetispeed(&tty, B4800);
+ // cfsetospeed(&tty, B4800);
+ tty.c_ispeed = 4800;
+ tty.c_ospeed = 4800;
+ break;
+ case BaudRate::B_9600:
+ // cfsetispeed(&tty, B9600);
+ // cfsetospeed(&tty, B9600);
+ tty.c_ispeed = 9600;
+ tty.c_ospeed = 9600;
+ break;
+ case BaudRate::B_19200:
+ // cfsetispeed(&tty, B19200);
+ // cfsetospeed(&tty, B19200);
+ tty.c_ispeed = 19200;
+ tty.c_ospeed = 19200;
+ break;
+ case BaudRate::B_38400:
+ // cfsetispeed(&tty, B38400);
+ // cfsetospeed(&tty, B38400);
+ tty.c_ispeed = 38400;
+ tty.c_ospeed = 38400;
+ break;
+ case BaudRate::B_57600:
+ // cfsetispeed(&tty, B57600);
+ // cfsetospeed(&tty, B57600);
+ tty.c_ispeed = 57600;
+ tty.c_ospeed = 57600;
+ break;
+ case BaudRate::B_115200:
+ // cfsetispeed(&tty, B115200);
+ // cfsetospeed(&tty, B115200);
+ tty.c_ispeed = 115200;
+ tty.c_ospeed = 115200;
+ break;
+ case BaudRate::B_230400:
+ // cfsetispeed(&tty, B230400);
+ // cfsetospeed(&tty, B230400);
+ tty.c_ispeed = 230400;
+ tty.c_ospeed = 230400;
+ break;
+ case BaudRate::B_460800:
+ // cfsetispeed(&tty, B460800);
+ // cfsetospeed(&tty, B460800);
+ tty.c_ispeed = 460800;
+ tty.c_ospeed = 460800;
+ break;
+ default:
+ throw std::runtime_error(std::string() + "baudRate passed to " + __PRETTY_FUNCTION__ + " unrecognized.");
+ }
+ }
+ // This does no different than STANDARD atm, but let's keep
+ // them separate for now....
+ else if (baudRateType_ == BaudRateType::CUSTOM)
+ {
+ tty.c_cflag &= ~CBAUD;
+ tty.c_cflag |= CBAUDEX;
+ // tty.c_cflag |= BOTHER;
+ tty.c_ispeed = baudRateCustom_;
+ tty.c_ospeed = baudRateCustom_;
+
+
+ // #include
+ // // configure port to use custom speed instead of 38400
+ // struct serial_struct ss;
+ // ioctl(fileDesc_, TIOCGSERIAL, &ss);
+ // ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
+ // ss.custom_divisor = (ss.baud_base + (baudRateCustom_ / 2)) / baudRateCustom_;
+ // int closestSpeed = ss.baud_base / ss.custom_divisor;
+
+ // if (closestSpeed < baudRateCustom_ * 98 / 100 || closestSpeed > baudRateCustom_ * 102 / 100) {
+ // printf("Cannot set serial port speed to %d. Closest possible is %d\n", baudRateCustom_, closestSpeed);
+ // }
+
+ // ioctl(fileDesc_, TIOCSSERIAL, &ss);
+
+ // cfsetispeed(&tty, B38400);
+ // cfsetospeed(&tty, B38400);
+ }
+ else
+ {
+ // Should never get here, bug in this libraries code!
+ assert(false);
+ }
//===================== (.c_oflag) =================//
@@ -170,14 +337,11 @@ namespace CppLinuxSerial {
tty.c_cc[VMIN] = 0;
}
-
//======================== (.c_iflag) ====================//
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);
-
-
//=========================== LOCAL MODES (c_lflag) =======================//
// Canonical input is when read waits for EOL or EOF characters before returning. In non-canonical mode, the rate at which
@@ -189,11 +353,11 @@ namespace CppLinuxSerial {
tty.c_lflag &= ~ISIG; // Disables recognition of INTR (interrupt), QUIT and SUSP (suspend) characters
-
// Try and use raw function call
//cfmakeraw(&tty);
- this->SetTermios(tty);
+ // this->SetTermios(tty);
+ this->SetTermios2(tty);
/*
// Flush port, then apply attributes
@@ -262,39 +426,60 @@ namespace CppLinuxSerial {
// If code reaches here, read must of been successful
}
- termios SerialPort::GetTermios() {
- if(fileDesc_ == -1)
- throw std::runtime_error("GetTermios() called but file descriptor was not valid.");
+ // termios SerialPort::GetTermios() {
+ // if(fileDesc_ == -1)
+ // throw std::runtime_error("GetTermios() called but file descriptor was not valid.");
- struct termios tty;
- memset(&tty, 0, sizeof(tty));
+ // struct termios tty;
+ // memset(&tty, 0, sizeof(tty));
- // Get current settings (will be stored in termios structure)
- if(tcgetattr(fileDesc_, &tty) != 0)
- {
- // Error occurred
- std::cout << "Could not get terminal attributes for \"" << device_ << "\" - " << strerror(errno) << std::endl;
- throw std::system_error(EFAULT, std::system_category());
- //return false;
- }
+ // // Get current settings (will be stored in termios structure)
+ // if(tcgetattr(fileDesc_, &tty) != 0)
+ // {
+ // // Error occurred
+ // std::cout << "Could not get terminal attributes for \"" << device_ << "\" - " << strerror(errno) << std::endl;
+ // throw std::system_error(EFAULT, std::system_category());
+ // //return false;
+ // }
- return tty;
- }
+ // return tty;
+ // }
- void SerialPort::SetTermios(termios myTermios)
- {
- // Flush port, then apply attributes
- tcflush(fileDesc_, TCIFLUSH);
+ // void SerialPort::SetTermios(termios myTermios)
+ // {
+ // // Flush port, then apply attributes
+ // tcflush(fileDesc_, TCIFLUSH);
- if(tcsetattr(fileDesc_, TCSANOW, &myTermios) != 0)
- {
- // Error occurred
- std::cout << "Could not apply terminal attributes for \"" << device_ << "\" - " << strerror(errno) << std::endl;
- throw std::system_error(EFAULT, std::system_category());
+ // if(tcsetattr(fileDesc_, TCSANOW, &myTermios) != 0)
+ // {
+ // // Error occurred
+ // std::cout << "Could not apply terminal attributes for \"" << device_ << "\" - " << strerror(errno) << std::endl;
+ // throw std::system_error(EFAULT, std::system_category());
- }
+ // }
+
+ // // Successful!
+ // }
- // Successful!
+ termios2 SerialPort::GetTermios2()
+ {
+ struct termios2 term2;
+
+ ioctl(fileDesc_, TCGETS2, &term2);
+
+ return term2;
+
+ // term2.c_cflag &= ~CBAUD; /* Remove current BAUD rate */
+ // term2.c_cflag |= BOTHER; /* Allow custom BAUD rate using int input */
+ // term2.c_ispeed = speed; /* Set the input BAUD rate */
+ // term2.c_ospeed = speed; /* Set the output BAUD rate */
+
+ // ioctl(fd, TCSETS2, &term2);
+ }
+
+ void SerialPort::SetTermios2(termios2 tty)
+ {
+ ioctl(fileDesc_, TCSETS2, &tty);
}
void SerialPort::Close() {
diff --git a/test/arduino/Basic/Basic.ino b/test/arduino/Basic/Basic.ino
new file mode 100644
index 0000000..10fa637
--- /dev/null
+++ b/test/arduino/Basic/Basic.ino
@@ -0,0 +1,24 @@
+/*
+ AnalogReadSerial
+
+ Reads an analog input on pin 0, prints the result to the Serial Monitor.
+ Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
+ Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
+
+ This example code is in the public domain.
+
+ http://www.arduino.cc/en/Tutorial/AnalogReadSerial
+*/
+
+// the setup routine runs once when you press reset:
+void setup() {
+ // initialize serial communication at 9600 bits per second:
+ Serial.begin(9600);
+// Serial.begin(81234); // Used to test custom baud rates
+}
+
+// the loop routine runs over and over again forever:
+void loop() {
+ Serial.println("Hello");
+ delay(100); // delay in between reads for stability
+}
diff --git a/test/arduino/main.cpp b/test/arduino/main.cpp
new file mode 100644
index 0000000..0cf1248
--- /dev/null
+++ b/test/arduino/main.cpp
@@ -0,0 +1,24 @@
+#include
+
+using namespace mn::CppLinuxSerial;
+
+int main() {
+ // Create serial port object and open serial port
+ SerialPort serialPort("/dev/ttyACM0", BaudRate::B_9600);
+ // SerialPort serialPort("/dev/ttyACM0", 13000);
+ serialPort.SetTimeout(-1); // Block when reading until any data is received
+ serialPort.Open();
+
+ // Write some ASCII datae
+ // serialPort0.Write("Hello");
+
+ // Read some data back
+ while(1) {
+ std::string readData;
+ serialPort.Read(readData);
+ std::cout << "Received data: " << readData;
+ }
+
+ // Close the serial port
+ serialPort.Close();
+}
\ No newline at end of file