@AlexSer

Как в QT настроить обмен данными через SerialPort с устройством по протоколу ASTM E1381-95?

Ссылка на протокол:
Протокол ASTM

Основные моменты протокола:
613062002ce8b291241488.png

Вот мой код на прием и отправку данных в устройство:
//Запуск чтения 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: я мало программировал на С++, поэтому не надо осуждать.
  • Вопрос задан
  • 191 просмотр
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы