Testing records of the Yingdong linear absolute value encoder (grating ruler ),

Source: Internet
Author: User

Testing records of the Yingdong linear absolute value encoder (grating ruler ),

This profit-driven linear absolute value encoder model: CAPLIN-A-485

The appearance of the grating ruler is as follows.

When working, the signal terminal and grating are fixed, and the slide head is driven by a motor.


The encoder data is actively throttled by 485 ports. The IPC can read the data at an appropriate time.


The communication format of this product is as follows:


The default baud rate is 9600. The start bit of each shard is 0, the data bit is 8 bits, the stop bit is 1 bits, and there is no checksum.
A complete string of data starting with "55 AA" or "AA 55"
The position is alternating once), followed by 4 bytes as the absolute value position, for example:
"55 AA + XX"-> "AA 55 + XX"-> "55 AA + XX
XX "->" AA 55 + XX "........
Note: XX is the absolute position data.


Transmitted 32-Bit Data
(1) the minimum length of 20 bits is 4mm segments, and the full range corresponds to 4mm length.
The physical length is (4mm/4096 ).
(2) The 12-bit height is the cumulative position of 4mm, and the physical length of the second bit is 4mm.
As follows:

The resolution can be directly converted to decimal with the high 24 bits of ''AAAA-AAAA-AAAA-XXXX-XXXX-XXXX ''. In the above example, the absolute position is (232315) * 232315/4096 = 4mm.


I collected a piece of data through the serial assistant, as follows:

AA 55 00 05 19 E3 55 AA 00 05 19 E3 AA 55 00 05 19 E3 55 AA 00 05 19 E3 AA 55 00 05 19 E3 55 AA 00 05 19 E3 AA 55 00 05 19 E3 55 AA 00 05 19 E3 AA 55

The data to be obtained is between the marked red characters.


I wrote a grating ruler class. You only need to read the Curposition attribute of this class in time to get the current grating ruler reading.

 1   class GratingRuler:SerialPort 2     { 3         private Timer t1; 4         private double curPosition; 5         public double CurPosition  6         { 7             get  8             { 9                 return curPosition;10             }11         }12         private IList<byte> readBuff;13         public GratingRuler()14         {15             try16             {17                 this.PortName = "COM4";18                 this.BaudRate = 9600;19                 this.DataBits = 8;20                 this.StopBits = StopBits.One;21                 this.Parity = Parity.None;22                 readBuff = new List<byte>();23                 this.ReadBufferSize = 1024;24                 this.Open();25             }26             catch (Exception e1)27             {28                 throw e1;29             }30 31             t1 = new Timer(32                 new TimerCallback( readRulerValue),33                 null,0,100);34         }35 36         private void readRulerValue(object a)37         {38             double res = 0.0f;39             List<byte> dataBuff = new List<byte>();40             byte[] sbyteAry = new byte[1024];41             var cary = this.Read(sbyteAry, 0, this.ReadBufferSize);42             for (int i = sbyteAry.Length - 1; i > 0; i--)43             {44                 if ((sbyteAry[i] == 0xAA && sbyteAry[i - 1] == 0x55) ||45                     (sbyteAry[i] == 0x55 && sbyteAry[i - 1] == 0xAA))46                 {47                     dataBuff.Add(sbyteAry[i - 2]);48                     dataBuff.Add(sbyteAry[i - 3]);49                     dataBuff.Add(sbyteAry[i - 4]);50                     dataBuff.Add(sbyteAry[i - 5]);51                     res = getvalue(dataBuff);52                     this.DiscardOutBuffer();53                     dataBuff.Clear();54                     break;55                 }56             }57             curPosition = res;58         }59 60         private double getvalue(List<byte> dataBuff)61         {62             Int32 v= BitConverter.ToInt32(dataBuff.ToArray(), 0);63             string s = Convert.ToString(v, 2);64             s = s.PadLeft(32, '0');65             double g12 = Convert.ToInt32(s.Substring(32 - 12, 12), 2);66             double d20 = Convert.ToInt32(s.Substring(8, 12), 2);67             double res1 = g12 * 4 + (d20 / 4069) * 4;68             var ss1 = s.Substring(32 - 24, 24);69             double res2= ((double)(Convert.ToInt32(s.Substring(32-24, 24), 2)) / 4096) * 4;70             return res2;71         }72 73 74     }

Note that the following code extracts the data between 0xAA, 0x55, 0x55, and 0xAA and also needs to be sorted in the byte order of the computer memory (after the high position, before the low position, can be interpreted as a correct 32-bit number.

As shown in the following code, the order of 5, 4, and 3 is rearranged once.

 if ((sbyteAry[i] == 0xAA && sbyteAry[i - 1] == 0x55) ||                    (sbyteAry[i] == 0x55 && sbyteAry[i - 1] == 0xAA))                {                    dataBuff.Add(sbyteAry[i - 2]);                    dataBuff.Add(sbyteAry[i - 3]);                    dataBuff.Add(sbyteAry[i - 4]);                    dataBuff.Add(sbyteAry[i - 5]);                    res = getvalue(dataBuff);                    this.DiscardOutBuffer();                    dataBuff.Clear();                    break;                }

The following code splits the 4 bytes into 32 digits and parses the final location value according to the communication format of this encoder, in mm

private double getvalue(List<byte> dataBuff)        {            Int32 v= BitConverter.ToInt32(dataBuff.ToArray(), 0);            string s = Convert.ToString(v, 2);            s = s.PadLeft(32, '0');            double g12 = Convert.ToInt32(s.Substring(32 - 12, 12), 2);            double d20 = Convert.ToInt32(s.Substring(8, 12), 2);            double res1 = g12 * 4 + (d20 / 4069) * 4;            var ss1 = s.Substring(32 - 24, 24);            double res2= ((double)(Convert.ToInt32(s.Substring(32-24, 24), 2)) / 4096) * 4;            return res2;        }

The data captured by the author using the serial assistant is as follows:

00 05 19 E3

According to the above Code, the resolved Location value is 326.4716796

Friends can substitute the result data into the code to verify it, and they will soon understand it.


In this class, you need to record the following points:

1. Do not get serial reading in the DataReceived event, because the encoder will continuously lose data and this event will be triggered continuously.

The correct method is to read the data in the buffer zone of the current serial port when necessary, and then immediately discard the data in the buffer zone.

2. Do not design the "get current encoder value" function into a function that contains the serial port read action,

This is because the caller may call this function in multiple threads at the same time or call this function at high speed in the loop. This will cause the serial port to fail to respond to such parallel processing or high-speed requests.

The correct method is to use a private method in the class to read the current serial port data at a certain speed in a single thread. exposes an external attribute for the caller to read the value of the current encoder. in this class, serial data is continuously read in an internal independent thread at a certain speed, and an attribute curPosition is published to the outside world.


Usage of this product

1. The distance between the sliding reading head and the grating ruler, as well as its parallel relationship, as well as the smoothness when the grating ruler is attached, will affect the reading accuracy. It can be said that the reading should be careful during installation, and it is a fine job.

2. at present, the best precision is to beat the decimal point after 3rd bits, that is, the um level. however, it is still found that it is in the same position, sometimes it is possible to jump out of a small value, and then restore to normal. it seems a bit worrying when high-speed sports require real-time feedback. if the measurement goes far after moving, it is still possible.

3. if your device is powered on by cold start, sometimes you don't move the slider, And the read value is 0. After the device is moved, the encoder "active" and starts sending data continuously.

4. one of the most serious problems I have seen is that one day I suddenly found that all the values were added with 9000, that is, yesterday was still at the position of 531, and today it is changed to 9531, it is like data has been accumulated. this situation suddenly appeared after a month of use. the manufacturer thinks that we have a program problem. but obviously not, because it was good to have been running for so long. later I found that after all the power supply of the device was cut off, I turned it on again. it cannot be solved.



Since the test project is used to verify another project, the grating ruler of this encoder is only one of the components, so I will not issue the original code.


Related Article

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.