DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Loading...
Searching...
No Matches
HardwareAdapterSerialPort.cpp
Go to the documentation of this file.
1// This file is part of DynExp.
2
3#include "stdafx.h"
4#include "moc_HardwareAdapterSerialPort.cpp"
6
7namespace DynExp
8{
10 {
11 auto SerialPortInfos = QSerialPortInfo::availablePorts();
12 std::vector<std::string> SerialPortNames;
13
14 for (int i = 0; i < Util::NumToT<int>(SerialPortInfos.length()); ++i)
15 SerialPortNames.emplace_back(SerialPortInfos[i].portName().toStdString());
16
17 return SerialPortNames;
18 }
19
38
40 {
41 auto SerialPorts = HardwareAdapterSerialPort::Enumerate();
42 if (SerialPorts.empty())
43 throw Util::EmptyException("There is not any available serial port.");
44 PortName.SetTextList(std::move(SerialPorts));
45
47 }
48
50 : Port(this)
51 {
52 QObject::connect(&Port, &QSerialPort::readyRead, this, &HardwareAdapterSerialPortWorker::OnDataAvailable);
53 }
54
55 void HardwareAdapterSerialPortWorker::Init(QString PortName, HardwareAdapterSerialPortParams::BaudRateType BaudRate, QSerialPort::DataBits DataBits,
56 QSerialPort::StopBits StopBits, QSerialPort::Parity Parity)
57 {
59 Port.setPort(QSerialPortInfo(PortName));
60 Port.setBaudRate(BaudRate);
61 Port.setDataBits(DataBits);
62 Port.setStopBits(StopBits);
63 Port.setParity(Parity);
64 }
65
70
71 bool HardwareAdapterSerialPortWorker::CheckError(const std::source_location Location) const
72 {
73 if (Port.error() != QSerialPort::NoError)
74 {
75 SetException(SerialPortException(Util::ToStr(Port.errorString()), Port.error(), Location));
76
77 return false;
78 }
79
80 return true;
81 }
82
84 {
85 if (!Port.isOpen())
86 {
87 Port.open(QIODevice::ReadWrite);
88 if (CheckError())
90 }
91 }
92
94 {
95 if (Port.isOpen())
96 {
97 Port.clear();
98 Port.close();
99
101 }
102 }
103
105 {
106 Close();
107
108 Port.clearError();
109 }
110
112 {
113 if (Port.isOpen())
114 Port.clear();
115 }
116
118 {
119 if (Port.isOpen())
120 Port.flush();
121 }
122
124 {
125 QByteArray BytesRead(Port.readAll());
126 CheckError();
127
128 if (BytesRead.size())
129 DataRead(BytesRead.constData());
130 }
131
133 {
134 auto StdString(String.toStdString());
135
136 auto BytesWritten = Port.write(StdString.c_str(), StdString.size()); // crop terminating '\0'
137 if (BytesWritten != Util::NumToT<decltype(BytesWritten)>(StdString.size()))
138 SetException(SerialPortException("It was not possible to write the desired amount of data to a serial port.", Port.error()));
139 CheckError();
140 }
141
143 {
144 auto Owner = std::dynamic_pointer_cast<const HardwareAdapterSerialPort>(GetOwner());
145 if (!Owner)
146 return;
147
148 const auto LineEnding = Owner->GetLineEnding();
149
150 auto BytesWritten = Port.write(Owner->LineEndingToChar(LineEnding).data(), Owner->GetLineEndingLength(LineEnding));
151 if (BytesWritten != Owner->GetLineEndingLength(LineEnding))
152 SetException(SerialPortException("It was not possible to write the desired amount of data to a serial port.", Port.error()));
153 else
154 Port.flush();
155 CheckError();
156 }
157
158 HardwareAdapterSerialPort::HardwareAdapterSerialPort(const std::thread::id OwnerThreadID, ParamsBasePtrType&& Params)
159 : QSerialCommunicationHardwareAdapter(OwnerThreadID, std::move(Params))
160 {
162 }
163
165 {
166 auto Worker = std::make_unique<HardwareAdapterSerialPortWorker>();
167
169
170 return Worker;
171 }
172
174 {
175 static bool AlreadyRegistered = false;
176
177 if (!AlreadyRegistered)
178 {
179 qRegisterMetaType<QSerialPort::BaudRate>();
180 qRegisterMetaType<QSerialPort::DataBits>();
181 qRegisterMetaType<QSerialPort::StopBits>();
182 qRegisterMetaType<QSerialPort::Parity>();
183
184 AlreadyRegistered = true;
185 }
186 }
187
189 {
190 auto DerivedParams = dynamic_Params_cast<HardwareAdapterSerialPort>(GetParams());
191
192 emit InitSig(QString::fromStdString(DerivedParams->PortName), DerivedParams->BaudRate,
193 DerivedParams->DataBits, DerivedParams->StopBits, DerivedParams->Parity);
194 }
195
203}
Implementation of a hardware adapter to communicate text-based commands over COM ports.
static Util::TextValueListType< BaudRateType > BaudRateTypeStrList()
Assigns labels to the entries of BaudRateType.
BaudRateType
Extends QSerialPort::BaudRate enumeration with further Baud rates.
void ConfigureParamsImpl(dispatch_tag< QSerialCommunicationHardwareAdapterParams >) override final
Called by DynExp::ParamsBase::ConfigureParams() as a starting point for the tag dispatch mechanism to...
void Init(QString PortName, HardwareAdapterSerialPortParams::BaudRateType BaudRate, QSerialPort::DataBits DataBits, QSerialPort::StopBits StopBits, QSerialPort::Parity Parity)
Initializes HardwareAdapterSerialPortWorker::Port for serial communication with the given settings.
bool CheckError(const std::source_location Location=std::source_location::current()) const
Checks whether Port is in an error state. If this is the case, sets an exception using QSerialCommuni...
virtual void ResetChild() override
Resets the worker and the communication connection.
virtual void Write_endl_Child() override
Writes end of the line character(s) to the communication connection's hardware interface.
virtual void FlushChild() override
Flushes the communication connection's buffers.
virtual void ClearChild() override
Clears the communication connection's buffers and state.
QSerialPort Port
COM port for serial communication.
virtual void CloseChild() override
Closes the communication connection.
virtual void ReadChild() override
Reads from the communication connection's hardware interface.
virtual void WriteChild(const QString &String) override
Writes String to the communication connection's hardware interface.
virtual void OpenChild() override
Opens the communication connection.
void OnDataAvailable()
Qt slot called when Port has received data which can be read.
void Init()
Initializes the instance at construction or in case Object::Reset() is called.
QWorkerPtrType MakeWorker() override
Abstract factory function for a worker instance derived from QSerialCommunicationHardwareAdapterWorke...
static auto Enumerate()
Enumerates all serial ports available on the system.
void RegisterQTypesAsMetaTypes()
Registers QSerialPort enumerations as Qt meta types using qRegisterMetaType() (refer to Qt documentat...
void InitSig(QString PortName, HardwareAdapterSerialPortParams::BaudRateType BaudRate, QSerialPort::DataBits DataBits, QSerialPort::StopBits StopBits, QSerialPort::Parity Parity)
Initializes HardwareAdapterSerialPortWorker::Port for serial communication with the given settings.
HardwareAdapterSerialPort(const std::thread::id OwnerThreadID, ParamsBasePtrType &&Params)
Constructs a hardware adapter instance.
void ResetImpl(dispatch_tag< QSerialCommunicationHardwareAdapter >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
ParamsConstTypeSyncPtrType GetParams(const std::chrono::milliseconds Timeout=GetParamsTimeoutDefault) const
Locks the mutex of the parameter class instance Params assigned to this Object instance and returns a...
Definition Object.cpp:436
Refer to ParamsBase::dispatch_tag.
Definition Object.h:2018
Tag for function dispatching mechanism within this class used when derived classes are not intended t...
Definition Object.h:349
void SetException(const ExceptionType &Exception) const
Calls QSerialCommunicationHardwareAdapter::SetException on QWorker::Owner. Does nothing if QWorker::O...
void DataRead(const std::string &String) const
Calls QSerialCommunicationHardwareAdapter::DataRead on QWorker::Owner. Does nothing if QWorker::Owner...
void Read()
Reads from the communication connection's hardware interface.
void Close()
Closes the communication connection.
void SetCommunicationChannelClosed() const noexcept
Calls QSerialCommunicationHardwareAdapter::SetCommunicationChannelClosed on QWorker::Owner....
void SetCommunicationChannelOpened() const noexcept
Calls QSerialCommunicationHardwareAdapter::SetCommunicationChannelOpened on QWorker::Owner....
SerialCommunicationHardwareAdapter is based on a Qt communication object (wrapped by QSerialCommunica...
void ResetSig()
Resets the worker and the communication connection.
QSerialCommunicationHardwareAdapterWorker * Worker
Worker instance running in its own thread to handle the actual communication there.
std::unique_ptr< QSerialCommunicationHardwareAdapterWorker > QWorkerPtrType
Pointer-type owning the related QSerialCommunicationHardwareAdapterWorker instance.
static constexpr auto GetMaxBufferSize() noexcept
Defines the maximal size of the hardware adapter's (read) buffer.
Defines an exception caused by a hardware operation on a COM port (e.g. reading/writing data to a COM...
Thrown when a list is expected to contain entries and when a query results in an empty answer or an e...
Definition Exception.h:225
auto GetOwner() const noexcept
Returns this worker instance's owner.
Definition QtUtil.h:349
OwnerPtrType Owner
Pointer to the hardware adapter owning this instance.
Definition QtUtil.h:371
DynExp's main namespace contains the implementation of DynExp including classes to manage resources (...
std::unique_ptr< ParamsBase > ParamsBasePtrType
Alias for a pointer to the parameter system base class ParamsBase.
Definition Object.h:1807
std::string ToStr(const T &Value, int Precision=-1)
Converts a (numeric) value of type T to a std::string using operator<< of std::stringstream.
Definition Util.h:688
ToT NumToT(const FromT Value)
Converts a value of a numeric type to a value of another numeric type checking the conversion for its...
Definition Util.h:750
std::vector< std::pair< TextType, ValueType > > TextValueListType
Type of a list containing key-value pairs where key is a text of type Util::TextType.
Definition QtUtil.h:37
Accumulates include statements to provide a precompiled header.