Всем привет! Возникла небольшая сложность в получении данных по RS-485. Использую библиотеку QtSerialPort.
Есть протокол в котором взаимодействуют компьютер с неким устройством по сети RS-485. Размер запросных сообщений от устройства 16 байт. Первые два байта описывают тип сообщения.
Размер ответных сообщений от компьютера различный, как и в запросном сообщении первые два байта описывают тип сообщения.
Вот примерный класс для обработки полученных сообщений.
#include "opuConnectionRS485.h"
#include <QDebug>
#include "opuRequestMessage.h"
#include <unistd.h>
ConnectionRS485::ConnectionRS485(QString com_portName, int com_baudrate, QObject *parent) :
QObject(parent), portName_(com_portName), baudrate_(com_baudrate)
{
initSettings();
port_->setReadBufferSize(messageLength);
int portState = port_->open(QIODevice::ReadWrite);
if(portState)
{
qDebug()<< "[ConnectionRS485]. Good open port:" << portName_ << "baudrate:" << baudrate_;
connect(port_, SIGNAL(readyRead()), SLOT(getMessage()));
}else{
qDebug()<< "[ConnectionRS485]. Error open port:" << portName_ << "baudrate:" << baudrate_;
}
}
void ConnectionRS485::initSettings()
{
port_ = new QSerialPort;
port_->setPortName(portName_);
port_->setBaudRate(baudrate_);
port_->setDataBits(QSerialPort::Data8);
port_->setParity(QSerialPort::NoParity);
port_->setStopBits(QSerialPort::OneStop);
port_->setFlowControl(QSerialPort::NoFlowControl);
}
void ConnectionRS485::getMessage()
{
QByteArray message;
if(port_->bytesAvailable() >= messageLength)
{
message = port_->read(messageLength);
emit sendMessage(message);
}
}
void ConnectionRS485::changePortSettings(QString port, int baud)
{
qDebug() << "[ConnectionRS485]. Change port setting port:" << port << " baudrate:" << baud;
port_->setPortName(port);
port_->setBaudRate(baud);
port_->setDataBits(QSerialPort::Data8);
port_->setParity(QSerialPort::NoParity);
port_->setStopBits(QSerialPort::OneStop);
port_->setFlowControl(QSerialPort::NoFlowControl);
}
void ConnectionRS485::writeMessage(QByteArray message)
{
port_->write(message);
port_->flush();
}
А может кто-нибудь знает как вытаскивать из "потока" нужное сообщение? Например есть сеть rs-485 в виде общей шины, в которой гуляют различные сообщения с различной длинной.
Есть так же определенные(необходимые нам) запросные сообщения с заданной длинной, в которых первые два байта обозначают тип сообщения. Как я могу из всех входящих сообщений,
вытащить нужное мне сообщение? Спасибо за ответ=).
На такой шине, где гуляют сообщения с разной длинной должен быть контролер, который инициирует передачу и следит чтобы в каждый момент передавалось только одно сообщение.
Почитайте например про MODBUS
http://www.csimn.com/CSI_pages/Modbus101.html
Для него есть готовая библиотека
http://libmodbus.org
чем длиннее провод - тем ниже должна быть скорость передачи.
и на проводе должны быть терминаторы. если их нет, то скорее всего в сигнале будут отражённые паразитные данные.
да, если в непосредственной близости присутствуют двигатели, трансформаторы или любые девайсы с мощными токами в обмотках, то возможны помехи на линии и данные также могут искажаться.
в целом от подобных вещей спасает только вычисление CRC на каждый пакет и нумерация пакетов плюс система перезапроса пакета, в случае его потери или испорченных данных.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)