源码地址:
源码包含三个传感器例子
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;//
}
源码地址:
源码包含三个传感器例子