Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# libabbaurora changelog

## v0.2.2 - 2023-11-23
* add serial read timeout + character read delay
## v0.2.1 - 2022-01-02
* improve debug logging

Expand Down
8 changes: 6 additions & 2 deletions include/ABBAurora.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#ifndef ABBAurora_h
#define ABBAurora_h

#include <stdint.h>
#include "ABBAuroraEnums.h"
#include "ABBAuroraSerial.h"

Expand Down Expand Up @@ -79,9 +81,11 @@ class ABBAurora

@param device Serial device, i.e. /dev/ttyUSB0
@param baudrate Optional baud rate
@param max_read_iterations Max serial read iterations
@param character_delay Max delay between character reads in microseconds
*/
bool Setup(const std::string &device, const speed_t baudrate = B19200);
/** @brief Set serial device address
bool Setup(const std::string &device, const speed_t baudrate, const int &max_read_iterations, const int &character_delay);
/** @brief Set zerial device address

Sets a new RS485 serial device address

Expand Down
9 changes: 7 additions & 2 deletions include/ABBAuroraSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,17 @@ class ABBAuroraSerial

@param device The serial device, i.e. /dev/ttyUSB0
@param baudrate The serial baud rate
@param max_read_iterations Max read iterations to wait for data arrival
@param character_delay Inter character read delay
*/
bool Begin(const std::string &device, const speed_t &baudrate);
bool Begin(const std::string &device, const speed_t &baudrate, const int &max_read_iterations, const int &character_delay);
/** @brief Read bytes

Read bytes available in the input buffer

@param buffer Buffer to store the bytes
@param length Number of bytes to read
@param length Number of bytes to read

*/
int ReadBytes(uint8_t *buffer, const int &length);
/** @brief Write bytes
Expand Down Expand Up @@ -94,6 +97,8 @@ class ABBAuroraSerial

private:
int SerialPort; ///< Serial port number
int MaxReadIterations = 1000; ///< Max number of read iterations
int CharacterDelay = 52; ///< Delay between reading characters
std::string ErrorMessage; ///< Error message string
unsigned char Log; ///< Log level
};
Expand Down
4 changes: 2 additions & 2 deletions src/ABBAurora.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ void ABBAurora::SetLogLevel(const unsigned char &log_level)
Log = log_level;
}

bool ABBAurora::Setup(const std::string &device, const speed_t baudrate)
bool ABBAurora::Setup(const std::string &device, const speed_t baudrate, const int &max_read_iterations, const int &character_delay)
{
ReceiveData = new uint8_t[ABBAurora::ReceiveBufferSize] ();
Serial = new ABBAuroraSerial(Log);
if (!Serial->Begin(device, baudrate))
if (!Serial->Begin(device, baudrate, max_read_iterations, character_delay))
{
ErrorMessage = Serial->GetErrorMessage();
return false;
Expand Down
14 changes: 8 additions & 6 deletions src/ABBAuroraSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ ABBAuroraSerial::~ABBAuroraSerial(void)
}
}

bool ABBAuroraSerial::Begin(const std::string &device, const speed_t &baudrate)
bool ABBAuroraSerial::Begin(const std::string &device, const speed_t &baudrate, const int &max_read_iterations, const int &character_delay)
{
if (device.empty()) {
ErrorMessage = "Serial device argument empty";
return false;
}
MaxReadIterations = max_read_iterations;
CharacterDelay = character_delay;

SerialPort = open(device.c_str(), O_RDWR | O_NOCTTY);

if (SerialPort < 0) {
ErrorMessage = std::string("Error opening device ") + device + ": "
+ strerror(errno) + " (" + std::to_string(errno) + ")";
Expand Down Expand Up @@ -77,18 +80,17 @@ bool ABBAuroraSerial::Begin(const std::string &device, const speed_t &baudrate)
int ABBAuroraSerial::ReadBytes(uint8_t *buffer, const int &length)
{
int bytes_received, retval, iterations = 0;
const int max_iterations = 1000;
//std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
//std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();

while (iterations < max_iterations) {
while (iterations < MaxReadIterations) {
int bytes_available;
retval = ioctl(SerialPort, FIONREAD, &bytes_available);
if (retval < 0) {
ErrorMessage = "Serial FIONREAD ioctl failed";
return -1;
}
// intercharacter delay: 1 / baud rate * 1e6 = 52 µs
std::this_thread::sleep_for(std::chrono::microseconds(50));
std::this_thread::sleep_for(std::chrono::microseconds(CharacterDelay));
if (bytes_available >= length)
break;
iterations++;
Expand All @@ -97,7 +99,7 @@ int ABBAuroraSerial::ReadBytes(uint8_t *buffer, const int &length)
//std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << "[µs]" << std::endl;
//std::cout << "Iterations: " << iterations << std::endl;

if (iterations == max_iterations)
if (iterations == MaxReadIterations)
{
ErrorMessage = "Timeout, inverter could not be reached";
return -1;
Expand Down