Skip to content

Commit

Permalink
Tiding up the flow control functionality.
Browse files Browse the repository at this point in the history
  • Loading branch information
gbmhunter committed Nov 11, 2022
1 parent dbedac7 commit 7186684
Show file tree
Hide file tree
Showing 5 changed files with 533 additions and 511 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [vX.X.X]

- Replaced all tabs in code with spaces, which should fix the ugly code rendering in GitHub.
- Added ability to set/change the flow control (hardware, software or none).
- Added some ready-to-run examples in the new `example/` directory.

## [v2.4.0] - 2022-02-12

- Added `Available()` method to return number of bytes ready to be read from the receive buffer (thanks lotricekCZ).
Expand Down
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ Library for communicating with COM ports on a Linux system.
using namespace mn::CppLinuxSerial;

int main() {
// Create serial port object and open serial port at 57600 buad, 8 data bits, no parity bit, and one stop bit (8n1)
// Create serial port object and open serial port at 57600 buad, 8 data bits, no parity bit, one stop bit (8n1),
// and no flow control
SerialPort serialPort("/dev/ttyUSB0", BaudRate::B_57600, NumDataBits::EIGHT, Parity::NONE, NumStopBits::ONE);
// 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
Expand All @@ -91,6 +92,19 @@ If the above code was in a file called `main.cpp` and you had installed `CppLinu
g++ main.cpp -lCppLinuxSerial
```

If you wanted to also set flow control (e.g. hardware), you can add it onto the end of the constructor as shown below. If you don't set it, it defaults to no flow control.

```c++
SerialPort serialPort("/dev/ttyUSB0", BaudRate::B_57600, NumDataBits::EIGHT, Parity::NONE, NumStopBits::ONE, FlowControl::HARDWARE);
```
If you want to read and write binary rather than strings, you can use `WriteBinary()` and `ReadBinary()` which take vectors of bytes rather than `std::string`:
```c++
serialPort.WriteBinary(const std::vector<uint8_t>& data);
serialPort.ReadBinary(std::vector<uint8_t>& data);
```

For more examples, see the files in `test/`.

## Issues
Expand Down
15 changes: 15 additions & 0 deletions examples/FlowControl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "CppLinuxSerial/SerialPort.hpp"

using namespace mn::CppLinuxSerial;

int main() {
SerialPort serialPort("/dev/ttyUSB0", BaudRate::B_9600, NumDataBits::EIGHT, Parity::NONE, NumStopBits::ONE, FlowControl::NONE);
serialPort.SetTimeout(-1); // Block when reading until any data is received
serialPort.Open();
serialPort.Write("Hello");
std::string readData;
serialPort.Read(readData);
std::cout << "readData: " << readData << std::endl;
serialPort.Close();
return 0;
}
66 changes: 34 additions & 32 deletions include/CppLinuxSerial/SerialPort.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace mn {
CUSTOM,
};

/// \brief Strongly-typed enumeration of baud rates for use with the SerialPort class
/// \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 {
Expand Down Expand Up @@ -81,7 +81,7 @@ namespace mn {
TWO,
};

/// \brief Adding the ability to choose a flow control strategy on instantiation
/// \brief All the possible options for setting the flow control.
enum class FlowControl {
NONE,
HARDWARE,
Expand All @@ -94,29 +94,29 @@ namespace mn {
OPEN,
};

/// \brief SerialPort object is used to perform rx/tx serial communication.
/// \brief SerialPort object is used to perform rx/tx serial communication.
class SerialPort {

public:
/// \brief Default constructor. You must specify at least the device before calling Open().
/// \brief Default constructor. You must specify at least the device before calling Open().
SerialPort();

/// \brief Constructor that sets up serial port with the basic (required) parameters.
/// \brief Constructor that sets up serial port with the basic (required) parameters.
SerialPort(const std::string &device, BaudRate baudRate);

/// \brief Constructor that sets up serial port and allows the user to specify all the common parameters.
/// \brief Constructor that sets up serial port and allows the user to specify all the common parameters.
SerialPort(const std::string &device, BaudRate baudRate, NumDataBits numDataBits, Parity parity, NumStopBits numStopBits);

/// \brief Constructor that sets up serial port and allows the user to specify all the common parameters + Flow control.
/// \brief Constructor that sets up serial port and allows the user to specify all the common parameters and flow control.
SerialPort(const std::string &device, BaudRate baudRate, NumDataBits numDataBits, Parity parity, NumStopBits numStopBits, FlowControl flow);

/// \brief Constructor that sets up serial port with the basic parameters, and a custom baud rate.
/// \brief Constructor that sets up serial port with the basic parameters, and a custom baud rate.
SerialPort(const std::string &device, speed_t baudRate);

/// \brief Destructor. Closes serial port if still open.
/// \brief Destructor. Closes serial port if still open.
virtual ~SerialPort();

/// \brief Sets the device to use for serial port communications.
/// \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);

Expand All @@ -132,6 +132,7 @@ namespace mn {
/// \brief Call this to set the parity.
void SetParity(Parity parity);

/// \brief Call this to set the number of stop bits.
void SetNumStopBits(NumStopBits numStopBits);

/// \brief Sets the read timeout (in milliseconds)/blocking mode.
Expand All @@ -142,43 +143,43 @@ namespace mn {
/// 25500ms (another Linux API restriction).
void SetTimeout(int32_t timeout_ms);

/// \brief Enables/disables echo.
/// \param value Pass in true to enable echo, false to disable echo.
/// \brief Enables/disables echo.
/// \param value Pass in true to enable echo, false to disable echo.
void SetEcho(bool value);

/// \brief Opens the COM port for use.
/// \throws CppLinuxSerial::Exception if device cannot be opened.
/// \note Must call this before you can configure the COM port.
/// \brief Opens the COM port for use.
/// \throws CppLinuxSerial::Exception if device cannot be opened.
/// \note Must call this before you can configure the COM port.
void Open();

/// \brief Closes the COM port.
/// \brief Closes the COM port.
void Close();

/// \brief Sends a text message over the com port.
/// \param data The data that will be written to the COM port.
/// \throws CppLinuxSerial::Exception if state != OPEN.
/// \brief Sends a text message over the com port.
/// \param data The data that will be written to the COM port.
/// \throws CppLinuxSerial::Exception if state != OPEN.
void Write(const std::string& data);

/// \brief Sends a binary message over the com port.
/// \param data The data that will be written to the COM port.
/// \throws CppLinuxSerial::Exception if state != OPEN.
/// \brief Sends a binary message over the com port.
/// \param data The data that will be written to the COM port.
/// \throws CppLinuxSerial::Exception if state != OPEN.
void WriteBinary(const std::vector<uint8_t>& data);

/// \brief Use to read text from the COM port.
/// \param data The object the read characters from the COM port will be saved to.
/// \brief Use to read text from the COM port.
/// \param data The object the read characters from the COM port will be saved to.
/// \param wait_ms The amount of time to wait for data. Set to 0 for non-blocking mode. Set to -1
/// to wait indefinitely for new data.
/// \throws CppLinuxSerial::Exception if state != OPEN.
/// \throws CppLinuxSerial::Exception if state != OPEN.
void Read(std::string& data);

/// \brief Use to read binary data from the COM port.
/// \param data The object the read uint8_t bytes from the COM port will be saved to.
/// \brief Use to read binary data from the COM port.
/// \param data The object the read uint8_t bytes from the COM port will be saved to.
/// \param wait_ms The amount of time to wait for data. Set to 0 for non-blocking mode. Set to -1
/// to wait indefinitely for new data.
/// \throws CppLinuxSerial::Exception if state != OPEN.
/// \throws CppLinuxSerial::Exception if state != OPEN.
void ReadBinary(std::vector<uint8_t>& data);

/// \brief Use to get number of bytes available in receive buffer.
/// \brief Use to get number of bytes available in receive buffer.
/// \returns The number of bytes available in the receive buffer (ready to be read).
/// \throws CppLinuxSerial::Exception if state != OPEN.
int32_t Available();
Expand All @@ -189,13 +190,13 @@ namespace mn {

private:

/// \brief Configures the tty device as a serial port.
/// \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);

/// \brief Returns a populated termios2 structure for the serial port pointed to by the file descriptor.
/// \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.
Expand Down Expand Up @@ -227,7 +228,8 @@ namespace mn {

/// \brief The flow control of the system. Defaults to None (most common).
FlowControl flowControl_ = FlowControl::NONE;
/// \brief The file descriptor for the open file. This gets written to when Open() is called.

/// \brief The file descriptor for the open file. This gets written to when Open() is called.
int fileDesc_;

bool echo_;
Expand Down
Loading

0 comments on commit 7186684

Please sign in to comment.