Arduino Custom Communication Protocol resolution

Source: Internet
Author: User
Tags strlen

The design of communication protocol is given in the previous article. The format of the communication protocol is as follows:

Protocol Header

Instruction length

Control instructions

Calibration and

The control directives are designed in the following format:

Device type

Equipment number

Port number


For example, the host computer sent the following format data: AA0305020106, meaning that the first of the Protocol is AA, the instruction length is 03, the control instruction is 050201: the practical meaning is the device type is 05, the equipment number is 02, the port is 01, The checksum for these three data is 06. Now you need to write a class library, called Protocolparser, to parse the data in this format. The idea is very simple, that is, the serial port sent to save the data, and then resolve the meaning of each field of the data. Class Library is written in C + +, object-oriented style. ProtocolParser.h source code is as follows:
#ifndef protocolparser_h #define PROTOCOLPARSER_H/* Custom library function Protocol parser V1.0 parsed data format: protocol header-Instruction length-control instruction-checksum "control instruction" format: Device Type-device number- Port number */#include <stdlib.h> #include <string.h>//#include <string>//#pragma warning (disable:4996) #
	Define Buffer_size 128//assumes that the maximum length of the received data is 128 class Protocolparser {Public:protocolparser (char *header);
	~protocolparser ();
	void Append (char *data);  void Appendchar (char ch);//will receive the word from the serial port Fu Cun to the buffer size_t getdevicetype ();//Get device Type size_t getdevicenumber ();//Get device number size_t 
	Getport ()//Get the port number that the device is connected to private:bool the m_bincmd;//flag bit to identify if a control instruction has been received. Char *m_pheader;//protocol header size_t m_ncmdlength;//instruction length The data received by Char *m_pctrlcmd;//control instruction size_t m_nchecksum;//checksum char buffer[buffer_size];//temporarily exists in buffer size_t M_nrecvdataindex; Records the index that receives the data Char GetHeader (size_t index);//Gets the character size_t Getcmdlength () for the specified index of the protocol header, or the length of the control instruction size_t getrecvdatalength ();

Gets the length of the received control instruction size_t getchecksum ();//Gets the actual received checksum}; constructor initialized, header is protocol header protocolparser::P rotocolparser (char *header) {
	M_bincmd = false;
	strcpy (M_pheader, header);
	M_pheader = header;
	m_ncmdlength = 0;
	m_nchecksum = 0;
	M_nrecvdataindex = 0;

	M_pctrlcmd = NULL;
Buffer[0] = ' the '; } protocolparser::~protocolparser () {} #endif
ProtocolParser.cpp source code is as follows:
/* Protocolparser the implementation of the functions of the class * * #include "ProtocolParser.h"//#include <iostream> using namespace std; Gets the character of the specified index for the protocol header, where the default header is one byte, for example 0xAA char protocolparser::getheader (size_t index) {int headerlength = strlen (m_
	Pheader);
return M_pheader[index];
	//Gets the length of the control instruction field and gets the size_t protocolparser::getcmdlength () {int len = strlen (buffer) by the value of the 2nd and 3 bits of the received data;
	if (Len >= 2) {m_ncmdlength= (buffer[0]-' 0 ') * + (buffer[1]-' 0 ') * 1;
return m_ncmdlength;
	//Get the actual received checksum size_t Protocolparser::getchecksum () {//int len = strlen (buffer);
	M_nchecksum = (Buffer[getcmdlength () * 2 + 2]-' 0 ') * + (Buffer[getcmdlength () * 2 + 3]-' 0 ') * 1;
return m_nchecksum;
	}//From buffer to resolve the device type size_t protocolparser::getdevicetype () {//int len = strlen (buffer);
Return (buffer[2]-' 0 ') * + (buffer[3]-' 0 ') * 1;
	}//From buffer to resolve the device number size_t Protocolparser::getdevicenumber () {//int len = strlen (buffer);
Return (buffer[4]-' 0 ') * + (buffer[5]-' 0 ') * 1; }//resolves the port number from the buffer size_tProtocolparser::getport () {//int len = strlen (buffer);
Return (buffer[6]-' 0 ') * + (Buffer[7]-' 0 ') * 1;
	//The string received from the serial port is stored in buffer void Protocolparser::appendchar (char ch) {size_t bufferlength = strlen (buffer);
		Switch (m_nrecvdataindex) {case 0:case 1://the index value of the data received is 0 or 1, which indicates that the header M_bincmd = True was received;
		Buffer[0] = 0;
		m_nrecvdataindex++;
		Return
	Break
		Case 2:case 3://The index value of the data received is 2 or 3, which means that the received "Instruction Length" section buffer[m_nrecvdataindex-2] = ch;
		Buffer[m_nrecvdataindex-1] = ' the ';
		m_nrecvdataindex++;
		Return
	Break
	Default:break;
		} if (m_nrecvdataindex== (Getcmdlength () *2+5))//reached the index value {buffer[bufferlength] = ch;
		Buffer[bufferlength + 1] = ';
		size_t chksum = 0;
		Calculates the checksum for the received data (size_t i = 0; i < getcmdlength () *2;++i) {chksum ^= buffer[i + 2];  } if (Chksum==getchecksum ())//Determines whether the actual received checksum is equal to the computed checksum {//parsing the meanings of the various fields of the buffer cout << "DeviceType:" <<
			Getdevicetype () << Endl; cout << "DeviceNumber:" &LT;&LT
			Getdevicenumber () << Endl;
		cout << "Port:" << getport () << Endl;
		{cout << "error" << Endl) else//Unequal description
		} buffer[0] = ';
		M_bincmd = false;
		M_nrecvdataindex = 0;
	m_nchecksum=0;
		else if (m_bincmd)//instruction is not received {buffer[bufferlength] = ch;
		Buffer[bufferlength + 1] = ';
	m_nrecvdataindex++;
	} void Protocolparser::append (char *data) {for (size_t i = 0; i < strlen (data); ++i) {Appendchar (data[i));
	}/*int Main () {freopen ("In.txt", "R", stdin);
	Freopen ("OUT.txt", "w", stdout);
	Protocolparser protocolparser ("AA");
	Char ch;
	while (cin>>ch) {Protocolparser.appendchar (CH);
return 0;
 }
*/
In order to verify the correctness of the code, there are two ways, one is to import it into the Arduino IDE, form a custom class library, directly invoke the relevant interface, the other is to modify the code, paste directly into the Arduino IDE, the compile run. Here in the second way, the source code directly modified in the Arduino IDE is as follows:
/* Custom Library Functions: Protocol parser V1.0 parsed data format: protocol header-Instruction length-control instruction-checksum "control instruction" format: Device Type-device number-port number/#include <stdlib.h> #include <st ring.h>//#pragma warning (disable:4996) #define Buffer_size 128//assumes that the maximum length of the received data is 128 class Protocolparser {Public:proto
  Colparser (char *header);
  ~protocolparser ();
  void Append (char *data); void Appendchar (char ch);//will receive the word from the serial port Fu Cun to the buffer size_t getdevicetype ();//Get device Type size_t getdevicenumber ();//Get Device number Size _t Getport ()//Get the port number that the device is connected to Private:bool m_bincmd;//flag bit to identify whether a control instruction has been received. Char *m_pheader;//protocol Header size_t m_ncmdlength;/ /instruction length char *m_pctrlcmd;//control instruction size_t m_nchecksum;//checksum char buffer[buffer_size];//receive data temporarily in buffer size_t M_NRECVD ataindex;//records receive data index char getheader (size_t index);//Get the character size_t Getcmdlength () for the specified index of the protocol header size_t

Talength ()//Get the length of a control instruction received size_t getchecksum ();//Get the actual received checksum};
  constructor initialized, header is protocol header protocolparser::P rotocolparser (char *header) {m_bincmd = false;
  strcpy (M_pheader, header); M_pheader = header;
  m_ncmdlength = 0;
  m_nchecksum = 0;
  M_nrecvdataindex = 0;

  M_pctrlcmd = NULL;
Buffer[0] = ' the '; } protocolparser::~protocolparser () {} char Protocolparser::getheader (size_t index) {int headerlength = strlen (m_phe
  Ader);
return M_pheader[index];
  //Gets the length of the control instruction field and gets the size_t protocolparser::getcmdlength () {int len = strlen (buffer) by the value of the 2nd and 3 bits of the received data;
  if (Len >= 2) {m_ncmdlength= (buffer[0]-' 0 ') * + (buffer[1]-' 0 ') * 1;
return m_ncmdlength;
  //Get the actual received checksum size_t Protocolparser::getchecksum () {//int len = strlen (buffer);
  M_nchecksum = (Buffer[getcmdlength () * 2 + 2]-' 0 ') * + (Buffer[getcmdlength () * 2 + 3]-' 0 ') * 1;
return m_nchecksum;
  }//From buffer to resolve the device type size_t protocolparser::getdevicetype () {//int len = strlen (buffer);
Return (buffer[2]-' 0 ') * + (buffer[3]-' 0 ') * 1;
  }//From buffer to resolve the device number size_t Protocolparser::getdevicenumber () {//int len = strlen (buffer); Return (buffer[4]-' 0 ') * + (Buffer[5]-' 0 ') * 1;
  }//From buffer to resolve the port number size_t Protocolparser::getport () {//int len = strlen (buffer);
Return (buffer[6]-' 0 ') * + (Buffer[7]-' 0 ') * 1;
  //The string received from the serial port is stored in buffer void Protocolparser::appendchar (char ch) {size_t bufferlength = strlen (buffer);
    Switch (m_nrecvdataindex) {case 0:case 1://the index value of the data received is 0 or 1, which indicates that the header M_bincmd = True was received;
    Buffer[0] = 0;
    m_nrecvdataindex++;
    Return
  Break
    Case 2:case 3://The index value of the data received is 2 or 3, which means that the received "Instruction Length" section buffer[m_nrecvdataindex-2] = ch;
    Buffer[m_nrecvdataindex-1] = ' the ';
    m_nrecvdataindex++;
    Return
  Break
  Default:break;
    } if (m_nrecvdataindex== (Getcmdlength () *2+5))//reached the index value {buffer[bufferlength] = ch;
    Buffer[bufferlength + 1] = ';
    size_t chksum = 0;
    Calculates the checksum for the received data (size_t i = 0; i < getcmdlength () *2;++i) {chksum ^= buffer[i + 2];
  } if (Chksum==getchecksum ())//Determines whether the actual checksum received is equal to the computed checksum {serial.println ("DeviceType:");    Serial.println (Getdevicetype (), DEC);
      Serial.println ("DeviceNumber:");
      Serial.println (Getdevicenumber (), DEC);
      Serial.println ("Port:");
      Serial.println (Getport (), DEC);
      Getdevicenumber ();
      Getport ();
      Parse the meaning of each field of buffer//cout << "DeviceType:" << getdevicetype () << Endl;
      cout << "DeviceNumber:" << getdevicenumber () << Endl;
    cout << "Port:" << getport () << Endl;
      } else//Inequality description error {SERIAL.PRINTLN ("error");
    cout << "Error" << Endl;
    } buffer[0] = ';
    M_bincmd = false;
    M_nrecvdataindex = 0;
  m_nchecksum = 0;
    else if (m_bincmd)//instruction is not received {buffer[bufferlength] = ch;
    Buffer[bufferlength + 1] = ';
  m_nrecvdataindex++;
  } void Protocolparser::append (char *data) {for (size_t i = 0; i < strlen (data); ++i) {Appendchar (data[i));
}}//int led=13;
char value; Protocolparser ProtocolparsER (170);
  void Setup () {//Put your setup code here, to run Once:Serial.begin (9600);
  Serial.println ("Parser:");
Pinmode (Led,output); void Loop () {//Put your main code here, to run Repeatedly:while (serial.available () >0) {Value=serial.read ()
    ;
    Serial.print (value);
    Protocolparser.appendchar (value);
  Serial.println (Protocolparser.getport ()); }
}
Compile the run upload to the board after, in the Serial debugging assistant debugging results as shown below:


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.