Ссылка на протокол:
Протокол ASTM
Основные моменты протокола:
Вот мой код на прием и отправку данных в устройство:
//Запуск чтения serial порт соединения с устройством
FurunoCA270 *CA270;
CA270=new FurunoCA270();
CA270->serialPort=sPort5->serialPort;
CA270->terminal=ui->terminal;
CA270->Start(data);
void FurunoCA270::Start(QString msg){
//записываем шаг итерации при принятий и отправке данных;
QByteArray ACK="\x06";
QByteArray ENQ="\x05";
QByteArray EOT="\x04";
QByteArray STX="\x02";
QByteArray ETX="\x03";
QByteArray byte;
static QByteArray IpuByte;
/*Схема запросов с IPU->HOST Порядок тестов Q [ALL или barcode];
* IPU |-> ENQ -> HOST
* <- ACK -|
* |-> H ->
* <- ACK -|
* |-> Q ->
* <- ACK -|
* |-> L ->
* <- ACK -|
* |->EOT ->
* */
byte+=msg;
//Если от устройства идет прием данных:
if(!byte.contains(ACK)){
IpuByte+=byte;
if(byte.contains(ENQ)){
serialPort->write(ACK);
}
if(!byte.contains(EOT)){
if(byte.contains(LF)){
serialPort->write(ACK);
terminal->append("HOST=====>ACK");
}
}else{
terminal->append("IPU=====>EOT");
//определяю по записи Q в строке, это передача данных от устройства или запрос данных, если запрос данных то
отправляю сигнал ENQ.
if(IpuByte.contains("Q")){
serialPort->write(ENQ);
terminal->append("HOST=====>ENQ");
}else{
//если это прием данных от устройства то отправляю на парсинг.
Parser(IpuByte); //
IpuByte.clear();
}
}
}else{
if(IpuByte.length()>0){
//если приходят запросы от оборудования то передаю сообщения в устройство
//условие на получение первого ACK;
this->SendMsg(IpuByte);
IpuByte.clear();
}
}
}
void FurunoCA270::SendMsg(QByteArray byteArray){
if(byteArray.contains("ALL")){
this->ALL();
}else{
//код на по штучную вставку данных.
}
}
void FurunoCA270::ALL(){
QHash<int,QMap<QString,QStringList>> data=QsqlQueryData::WorkList("FurunoCA270");
static QByteArray msg;
QDateTime dt = QDateTime::currentDateTime();
// H+=STX+h+CR+ETX+CheckSum(h)+CR+LF;
// msg+=H;
int N=1;
QString h="H|\\^&|||HOST|||||||||"+dt.toString("yyyyMMddhhmmss");
sendSerialMsg(h);
for(int i=0; i<data.size(); i++){
QString p;
QString o;
QString c;
QString l;
QMap<QString,QStringList>::iterator it = data[i].begin();
for(;it != data[i].end(); ++it){
QString SID=QString::number(N);
if(SID.length()==2){SID="0"+SID;}
if(SID.length()==1){SID="00"+SID;}
//+QsqlQueryData::InfoPacient(it.key())[0].toUtf8()+" "+QsqlQueryData::InfoPacient(it.key())[1][0].toUtf8()+" "+QsqlQueryData::InfoPacient(it.key())[2][0]+
p="P|"+QString::number(N)+"|"+it.key()+"|||PACIENT UNK||"+QsqlQueryData::InfoPacient(it.key())[3]+"||Race1|||||"+QsqlQueryData::InfoPacient(it.key())[4]+"|1||||||||||";
QString tests;
for(int j=0; j<it.value().size(); j++){
if(IDTest(it.value()[j]).length()>0){
tests+="^^^"+IDTest(it.value()[j])+"\\";
}
}
tests.chop(1);
o="O|1|"+SID+"||"+tests+"||||||||||||01";
c="C|1|I|TestOrder1|G";
}
sendSerialMsg(p);
sendSerialMsg(o);
sendSerialMsg(c);
N++;
}
QString l="L|1";
sendSerialMsg(l);
QByteArray EOT="\x04";
serialPort->write(EOT+LF);
}
int FurunoCA270::sendSerialMsg(QString msg){
static int j=0;
QByteArray Msg;
if(msg.contains("H")){
j=j+1;
}
Msg+=STX+QString::number(j)+msg+CR+ETX+CheckSum(QString::number(j)+msg)+CR+LF;
serialPort->write(Msg);
terminal->append(Msg);
j=j+1;
if(j==8){
j=0;
}
if(msg.contains("L")){
j=0;
}
return j;
}
Проблема:
Код работает не совсем корректно, хотелось бы сделать его отдельным классом, чтобы не формировать сообщения для устройства как в данном коде. Может быть у кого есть пример кода или кто нибуть занимался данной тематикой и может подсказать правильное решение?
Потому как в данном коде я не учитываю таймауты, не учитываю длину сообщении. Да код рабочий с устройством идет обмен данными, и передача и прием, но хотелось бы чтобы было логично и правильно а главное удобно.
PS: я мало программировал на С++, поэтому не надо осуждать.