Linux libserial库使用3-----定时读取易航通OBD数据

源码地址:
源码包含三个传感器例子
1.初始化
初始化串口,启动接收线程和一个发送线程。该传感器需要定时喂数据才能正常输出数据。

void OBD_manager::start()
{
std::string p = “/dev/ttyUSB0”;
TYYS_INFO(“open OBD port”);
try
{
// Open the Serial Port at the desired hardware port.
serial_port.Open§ ;
}
catch (const OpenFailed&)
{

//    std::cerr << "The serial port did not open correctly." << std::endl ;
  //  return EXIT_FAILURE ;
}

// Set the baud rate of the serial port.
serial_port.SetBaudRate(BaudRate::BAUD_19200) ;

// Set the number of data bits.
serial_port.SetCharacterSize(CharacterSize::CHAR_SIZE_8) ;

// Turn off hardware flow control.
serial_port.SetFlowControl(FlowControl::FLOW_CONTROL_NONE) ;

// Disable parity.
serial_port.SetParity(Parity::PARITY_NONE) ;

// Set the number of stop bits.
serial_port.SetStopBits(StopBits::STOP_BITS_1) ;
serial_port.FlushIOBuffers();
serial_port.Write("obd\n");

// Wait for data to be available at the serial port.
//ile(!serial_port.IsDataAvailable())
{
    usleep(1000) ;
}

pthread_t nRet = pthread_create(&_nPid, 0, run2, this);
if(nRet != 0){
    perror("SerialPortManager pthread_create failed!\n");
}

nRet = pthread_create(&_nPid1, 0, run1, this);
if(nRet != 0){
    perror("SerialPortManager pthread_create failed!\n");
}

}
2.喂数据部分
void OBD_manager::obdfool()
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); //允许退出线程
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); //设置立即取消
sleep(3);
while(1)
{
sleep(1) ;
serial_port.Write(“tyys\n”);

}

}
3.包头和容错部分
void OBD_manager::obd_process()
{
unsigned char m_checksum=0;
size_t m_pos;

//check size
datalength=read_buffer.size();
if(datalength<10)
return;

// boost::algorithm.starts_with(obdhex,“55aaf8f0”)
//check header
//https://thispointer.com/c-check-if-a-string-starts-with-an-another-given-string/
if(!boost::algorithm::starts_with(obdhex,“55aaf8f0”))
//INFO(“OBD header false”);
return;

//checksum校验和
for(int i=2;i<datalength-1;i++)
m_checksum=(unsigned char)m_checksum^read_buffer.at(i);
//INFO(“m_checksum: “<< m_checksum <<”___”<<read_buffer.at(datalength-1)<<" checksum: ");

if(m_checksum!=read_buffer.at(datalength-1))
{
    //cout<<"obd_checksum is false"<<endl;
    return;
}
decodeobd();

}
4.解码
void OBD_manager::decodeobd()
{

//TYYS_INFO(“decodeobd”);
//stc_Acc.a[0] = ((unsigned short)read_buffer.at(3)<<8)|read_buffer.at(2);
unsigned short totalItems =0;
std::map<std::string, std::string>::iterator it;

std::string total_Items =obdhex.substr(18,4);
totalItems=stoi(total_Items);
//cout <<“totalItems:”<<totalItems<<endl;
int offset = 22;
string itemId;
string itemValue;
string itemdescribe;
int i=0;
if(((totalItems-1)*12)>obdhex.size())
return;

for( i=0;i<totalItems;i++)
{
int startIndex = offset + i * 12;
itemId=obdhex.substr(startIndex,4);
boost::to_upper(itemId);

itemId="0x"+itemId;
  itemValue=obdhex.substr(startIndex+4,8);
 //cout <<"itemId:"<<itemId<<" itemValue:"<<itemValue<<endl;
//check for items

it = items.find(itemId);
if (it != items.end())
{
//itemdescribe=it->second;
//cout <first<<"___"<second<<endl;
}
//yihangIdToField
it = yihangIdToField.find(itemId);

if (it != yihangIdToField.end())
{
    //itemdescribe=it->second;
    //cout <<it->first<<"___"<<it->second<<endl;

    m_obddata.itemid=itemId;
    //rpm

    m_obddata.itemname=it->second;
    m_obddata.value=stold(itemValue);
     if((itemId.compare("0x0300")==0)&&(m_obddata.value>6000))
     break;
    obd_event(m_obddata);


}

// else
// continue;
/* */

}
5.接收线程
void OBD_manager::run()
{
std::string accrbuff;
int ret;
size_t m_timeout = 1000 ;***//超时设置 ***
search_header();

/*优化方案:此处将串口每一句作为一个节点保存到链表中,另一个线程去以此取节点解析*/

pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); //允许退出线程
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); //设置立即取消
    while(1){

        try
        {
            // Read as many bytes as are available during the timeout period.
            **serial_port.Read(read_buffer, 0, m_timeout) ;**
        }
        catch (const ReadTimeout&)
        {
            hexprintdata();

            // TYYS_INFO("buffer size is "<<read_buffer.size() );
            obd_process();
        }

       // usleep(100*1000);

	}

}

6.辅助函数:接收到的数据转HEX打印。
std::string hexStr(unsigned char* data, int len)
{
std::stringstream ss;
ss << std::hex;
for(int i=0;i<len;++i)
ss << std::setw(2) << std::setfill(‘0’) << (int)data[i];
return ss.str();
}

void OBD_manager::hexprintdata()
{

std::string m_obdheader(read_buffer.begin(),read_buffer.end());
obdhex = hexStr((unsigned char*)m_obdheader.c_str(), m_obdheader.length());
cout <<obdhex <<"******"<<endl;

//cout <<hex <<"****"<<endl;//
}

源码地址:
源码包含三个传感器例子

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值