Home
  • CommManager
  • CommManager Class

    通讯管理器,传递查询语句和结果管理串口子线程的作用,封装了多线程,向外部提供统一的 接口,起到类似中介的作用,将 AbstractProtocol 和实际执行串口/网络访问的类(子线程中)聚合起来,方便迭代更新 More...

    Public Functions

    CommManager(QObject *parent = 0)
    ~CommManager()
    AbstractComm *abstractComm() const
    void addProtocol(AbstractProtocol *p)
    const CommInfo &currentCommInfo()
    void delProtocol(AbstractProtocol *p)
    T getProtocol(const QString &objectName)
    AbstractProtocol *protocol(const QString &objectName)
    const QList<AbstractProtocol *> &protocolList()
    void removeAllProtocol()
    void resetMode(const QString &type, const bool halfDuplex)
    void resetMode(const QString &className)
    const CommState &state()

    Public Slots

    virtual void close()
    virtual void openDevice(const QString &name = "")
    virtual void startNextQuery()
    virtual void startQuery()
    virtual void stopAllQuery()

    Signals

    void cmdCountChanged(const int remain, const int all)
    void codeMayMessed()
    void commInfoChanged(const CommInfo &ci)
    void recvLineData(const QByteArray &data, const int count = 0)
    void recvRawData(const QByteArray &data)
    void sendData(const QByteArray &data)
    void setCommProperty(const QString &key, const QVariant &value)
    void stateChanged(const CommState &state)

    Protected Functions

    void init(const QString &name)

    Protected Slots

    void onRecvLineData(const QByteArray &data)
    void onStateChanged(const CommState &state)
    void onTimeout()
    void onWriteFinish()
    void write()

    Detailed Description

    \authorBriFuture

    通讯管理器,传递查询语句和结果管理串口子线程的作用,封装了多线程,向外部提供统一的 接口,起到类似中介的作用,将 AbstractProtocol 和实际执行串口/网络访问的类(子线程中)聚合起来,方便迭代更新

    \date2018.07.19 This is a new Communicator Class which doesn't exactly query and process data, because the real serialPort/socket is moved into a subThread which wont block UI-thread, it is a manager class that handle the sub thread, notify serial to query, receive data from serial port / network, and transfer it into BaseComm's implementation.

    Warning: \date 2018.04.25

    此前串口通讯无法正确识别下位机的发送时间间隔(数据每隔 16 ms 才被接收到)。最终在 FT232R 的驱动设置中找到了延时的根本原因 (参考http://projectgus.com/2011/10/notes-on-ftdi-latency-with-arduino/), 因此解决了串口通讯无法识别下位机发送时间间隙的问题。

    Because of the delay of data coming into serial port (it is after almost 16ms that the data can be received from serial port), Finally, we found the root cause of the delay is made by the driver settings of FT232R with the help of this article: http://projectgus.com/2011/10/notes-on-ftdi-latency-with-arduino/ At last, we solved the problem of the data delay and successfully found the gap between tow sentences from slave computer.

    example:

    CommManager *cm = Comm::manager;
    cm.resetMode("Network", true);  // 设为网络通讯半双工模式
    connect(cm, &CommManager::recvLineData, this, &SomeClass::recvLine);  // 接收数据

    Member Function Documentation

    CommManager::CommManager(QObject *parent = 0)

    Default constructs an instance of CommManager.

    CommManager::~CommManager()

    关闭串口/网路,结束子线程

    AbstractComm *CommManager::abstractComm() const

    返回当前所用的通讯器

    void CommManager::addProtocol(AbstractProtocol *p)

    CommManager 管理器中添加协议,以便处理相应协议的数据

    example:

    CommManager *manager = Comm::manager;
    ...
    qDebug() << "List Size: " << manager.protocolList().size();  // assume the size now is N = 10, then output is "List Size: 10"
    AbstractProtocol *p  = new ImplProtocol;  // ImplProtocol must be implement subclass of AbstractProtocol
    manager->addProtocol(p);  // now ImplProtocol is added, the data will be transmitted to this protocol if it is enabled.
    qDebug() << "List Size: " << manager.protocolList().size();  // output is "List Size: 11"

    See also CommManager::onRecvLineData and CommManager::delProtocol.

    [virtual slot] void CommManager::close()

    关闭串口并清空指令队列

    example:

    CommManager *m = Comm::manager;
    m->openDevice("COM1");  // 打开 COM1 串口
    ...
    m->close();  // 关闭打开的 COM1 串口

    [signal] void CommManager::cmdCountChanged(const int remain, const int all)

    通知其他组件指令数目有变化

    [signal] void CommManager::codeMayMessed()

    [signal] void CommManager::commInfoChanged(const CommInfo &ci)

    const CommInfo &CommManager::currentCommInfo()

    返回当前通讯器的 CommInfo \return

    void CommManager::delProtocol(AbstractProtocol *p)

    删除管理器中的协议

    example:

    CommManager *manager = Comm::manager;
    ...
    qDebug() << "List Size: " << manager.protocolList().size();  // assume the size now is N = 10, then output is "List Size: 10"
    manager->delProtocol(p);  // p points to an instance of ImplProtocol
    qDebug() << "List Size: " << manager.protocolList().size();  // output is "List Size: 9"

    See also CommManager::addProtocol.

    T CommManager::getProtocol(const QString &objectName)

    [protected] void CommManager::init(const QString &name)

    将 mode 字符串传递给负责构造 AbstractComm 的工厂类。 Pass the mode string into CommFactory::defaultFactory() that responds for construct BaseComm @param mode

    [protected slot] void CommManager::onRecvLineData(const QByteArray &data)

    接收到来自串口的数据后,将其转发给各个协议

    [protected slot] void CommManager::onStateChanged(const CommState &state)

    在设备的状态改变时,将状态转发给其它层

    [protected slot] void CommManager::onTimeout()

    [protected slot] void CommManager::onWriteFinish()

    在实际串口执行完查询后进行相应操作

    @date 2018.06.16 可能存在的bug: 假设查询队列为 Q1, Q2, Q3 回复为 A1, A2 A3, A4 这里的 A2 A3 是在查询完 Q2 之后同时回复 然而此时协议的定时器尚未工作,在接收到 A3 回复时由于定时器发生错误导致查询队列(程序)崩溃, 因此协议在接收指令时务必判断定时器是否工作

    [virtual slot] void CommManager::openDevice(const QString &name = "")

    打开指定设备,若参数 name 为空,则默认打开最后一次使用的设备

    example: 打开串口 COM1

    CommManager *manager = Comm::manager;
    manager->openDevice("COM1");  // if serial port COM1 is free to use, then COM1 will be occupied by the program

    连接服务器 192.168.0.100 / localhost,连接网络前需要设置端口

      manager->setCommProperty("port", 8080);
      manager->openDevice("localhost");  // connect to localhost
    // manager->openDevice("192.168.0.100");  // effects the same as before

    See also CommManager::setCommProperty and CommManager::close.

    AbstractProtocol *CommManager::protocol(const QString &objectName)

    const QList<AbstractProtocol *> &CommManager::protocolList()

    [signal] void CommManager::recvLineData(const QByteArray &data, const int count = 0)

    [signal] void CommManager::recvRawData(const QByteArray &data)

    通知其他组件从串口/网络中接收到的原始数据(即不一定包含 AbstractProtocol::LineSeperator 的数据)

    void CommManager::removeAllProtocol()

    void CommManager::resetMode(const QString &type, const bool halfDuplex)

    CommManager::resetMode

    This is an overloaded function.

    example:

    ...
    manager->resetMode("Network", false);  //设为网络通讯全双工模式s

    void CommManager::resetMode(const QString &className)

    指定的className,重设Comm模式 提供该接口是为了在某些特殊情况下,现有的通讯器无法满足要求,需要扩展通讯器时,通过该方法生成自定义的通讯器类

    This is an overloaded function.

    扩展通讯器示例:

    Comm::factory->addComm(SubComm::staticMetaObject, SubComm::commInfo);  // SubComm is a subclass of Abstract Comm
    Comm::manager->resetMode("SubComm");  // 构建一个新的通讯器

    common example:

    // assume that there is a communicator VirtualCom OTHER THAN ComFullDuplex
    CommManager *manager = Comm::manager;
    ...
    manager->resetMode("VirtualCom");  // Data will be received from VirtualCom

    See also CommFactory and CommManager::resetMode(const QString &type, const bool halfDuplex).

    [signal] void CommManager::sendData(const QByteArray &data)

    表示数据已经由通讯器发送到串口/网络中

    [signal] void CommManager::setCommProperty(const QString &key, const QVariant &value)

    设置串口/网络设备的属性

    See also AbstractComm::setCommProperty.

    [virtual slot] void CommManager::startNextQuery()

    若协议中有指令未执行,接着执行下一条指令

    [virtual slot] void CommManager::startQuery()

    发送的指令可能不会立即被下位机执行,需要等待一定时间接收下位机的反馈。

    example

    ...
    manager->startQuery();  // 从协议列表中找出一个用命令的协议,将该命令写入到串口等设备中进行查询

    const CommState &CommManager::state()

    返回串口状态

    [signal] void CommManager::stateChanged(const CommState &state)

    通知串口/网络设备的状态有变化

    [virtual slot] void CommManager::stopAllQuery()

    停止所有查询,并通知协议管理器也重置查询

    [protected slot] void CommManager::write()