Reverse Engineering Laser Distance Sensor
Once I got a non-working Keyence LK-G407 laser distance sensor . Not only was it non-working, it also could not be used without a special control unit. But the sensor has such interesting characteristics: a distance measurement accurate to units of microns, and a work speed of 50 kilograms / s. So, to start it, you will have to dig deeper into the sensor itself, at the same time gain valuable experience.
What is inside the sensor?
The optical part of the sensor is shown in the photo below: On the left in the photo is a laser module, behind it is a photosensitive ruler, on the right is a lens and a mirror. From the design it becomes clear that this sensor can be attributed to the class of laser rangefinders with a triangulation method of distance measurement. The principle of operation of such rangefinders is well described here . In principle, it is quite simple - when you change the distance to the object that the laser shines on, the angle between the range finder lens and the laser spot changes. If you install a photosensitive ruler or matrix in the focal plane of the lens, you can determine this angle by the position of the maximum output signal. Knowing the angle and distance between the laser and the lens, you can determine the distance to the object.
The advantages of this method are very high accuracy at short distances - under certain conditions, it can be better than 0.1 microns!
It is also not a problem to measure distance at high speed - you just need to use a high-speed photosensitive ruler.
The circuitry of such a rangefinder is also quite simple - due to the fact that the device does not have high frequencies, and the primary signal amplification is in the line itself.
But there is a drawback - the accuracy of the method drops sharply with increasing distance.
This sensor uses a telephoto lens (focal length of about 150 mm), therefore, to reduce the size of the sensor, a mirror is included in its composition.
And now it’s worth moving on to the sensor electronics.
Here is the second part of the sensor:
And the board itself: And on the other hand: The printed circuit board seems to be four-layer - most of the signal conductors are on the outer layers, the power lines are on the inner ones. As I already mentioned, there was no control unit for the sensor, and without it it did not start working. It is clear that there were no circuits for the sensor either, the pinout of the cable and the supply voltage of the sensor were not even known. Conclusion - you need to do reverse engineering schemes. The result was such a circuit: Of course, I did not draw the entire sensor circuit, and figured out only in that part that is associated with FPGA. The numbers of elements on the circuit do not correspond to the numbers on the board. Thus, the structural diagram of the sensor:
From it it is clear that the operation of the entire sensor is controlled by two microcircuits - the FPGA Xilinx Spartan-3A and a certain custom microcircuit. However, I was very lucky - it can be seen from the diagram that the custom microcircuit is connected only with FPGA. Thus, the FPGA itself is able to control all the signals in the sensor.
A key element of the entire design is the photosensitive ruler. This line is clearly custom-made. Under the microscope, on one of its edges the inscription is visible:
25-512
LI004-02
I assumed that 512 is the number of pixels in the ruler, and 25 is the pixel width in microns. As it turned out later, I was right.
A small board is soldered to the back of the line:
It has an operational amplifier that increases the signal from the line by 2 times and several resistors and capacitors. This board connects to connector P1. As can be seen from the diagram, only 3 signal lines go to the line. One of them is clearly an analog signal from its output (it is transmitted via a separate coaxial wire). The remaining two lines are digital, and are used to control the ruler. When analyzing the circuit, I was lucky again - when applying voltage to the circuit, a frequency of 10 MHz appears on one of these lines (4). It immediately became clear that this line is responsible for clocking the line. Obviously, all control of the ruler goes along the remaining line (3). I connected the line to the STM32F4 microcontroller, and began to send various signals to lines (3) and (4). As it turned out, the line works quite simply - while there is a high level on line (3), There is an exposure - the ruler receives light. After setting a low level on line (3), you need to apply 14 clock pulses to the line, after which it will produce an analog signal for the next 512 clock pulses. The line operates on a voltage of 5V, and the FPGA - on 3.3V, and therefore, a DD2 chip is used to match the levels.
The analog signal from the line is transmitted through the low-pass filter to the repeater assembled on the DA1 chip. Next, the signal is fed to a PGA - amplifier with programmable gain AD8369 . The maximum gain of this chip is 40 dB, and it can be adjusted programmatically by setting the desired code on its inputs BIT0-3. This microcircuit is designed to amplify a differential signal, and its output is also differential, so then both of its outputs are connected to an operational amplifier DA4, which amplifies the signal by 2 times, and forms a single signal.
Next, the analog signal is fed to the input of a 10-bit AD9200 ADC . This chip was already familiar to me from the SDR receiver. In this case, it is connected so that the range of voltages it digitizes is (0.5-2.5) V. The digitized signal from the ADC output is transmitted to the FPGA.
It is worth paying attention to the CLAMP input of this ADC. This input is also controlled by FPGA. It is designed to bring the constant component of the input signal to a certain level.
Here is the circuit of the ADC input stage from the datasheet:
When a high level is applied to the CLAMP input, the voltage at the output of the amplifier and AIN appears, equal to the voltage at the input “CLAMP IN”.
In this case, the CIN capacitor will be charged until the voltage on it becomes equal (Uin - Uclamp_in). After that, the CLAMP input is set to low, and the amplifier ceases to affect the operation of the ADC in any way. In this sensor, the input “CLAMP IN” is connected to the lower reference voltage of the ADC + 0.5V. Thus, if a certain constant component is present at the output of DA4, then through the use of the CLAMP function it is possible to eliminate its influence on the result of the ADC operation.
After the first test configurations for FPGA were written, it turned out that you really need to control the CLAMP signal, otherwise the signal from the ADC has a very large DC component. In my implementation, I simply applied 1 to it at a time until the data was captured using the ADC.
The circuit shows that it uses a large number of supply voltages. I did not draw diagrams of the various power sources included in the sensor and various smoothing capacitors. As it turned out, the power pins (they are output to a separate connector with 2 pins) are connected to the TPS62050 DC-DC converter. The maximum voltage for it is 10V, from 6V the electronics have not yet started, so I decided that the working voltage of the sensor is 8V.
The laser diode used in this module is controlled by electronics mounted on a separate board:
I did not draw a diagram of this board. It connects to the main board through the P3 connector. As you can see, the laser is controlled along two lines. One of them (3) is connected to the FPGA through an inverter, and is responsible for turning on the laser - it is turned on by a low level at the FPGA output. Another line (4) is needed to control the laser power. This is an analog line, and to change the voltage on it, the circuit includes a DAC assembled on DA5-7 microcircuits (I still did not understand why the developers piled up such a confused circuit rather than taking the finished DAC microcircuit).
As you know, most FPGAs do not contain non-volatile memory, respectively, the FPGA configuration must be stored in an external chip. In this case, it is DD3 XCF01 - a specialized Flash memory chip. When turned on, the FPGA automatically reads the configuration from it into its memory. The FPGA itself and the XCF01 are connected in a JTAG circuit that is connected to the P2 connector. As a result, through this connector, you can program XCF01 in-circuit, configure FPGA and debug.
Thus, I figured out how the sensor electronics work, and I got a part of its circuitry. Now you can begin to experiment, i.e. FPGA programming. It is worth noting that before that I did not deal with FPGAs made by Xilinx. I also did not have the necessary programmer, so I had to do it myself, by combining several OpenSource projects.
The programmer worked fine, and I managed to run simple projects on the FPGA - just switching the FPGA outputs. However, in the future I needed a connection to the computer. I didn’t want to communicate with the LVDS interface (at the port where the LVDS lines are connected to 2.5V), so I just cut the two tracks connecting the FPGA and ASIC. There was a connector on the board, apparently intended for setting up or testing ASICs, I could not use it, so I also cut the two tracks going to it and connected the connector pins to the FPGA pins. Now you can connect a USB-UART adapter to this connector.
Type of board after revision:
After that, I wrote a simple program to test the operation of UART. It worked - the computer correctly accepted single bytes transmitted via UART from the FPGA. The next step is the transfer of data from the photosensitive line to a computer. I used the following block diagram of the FPGA program: View of the circuit in ISE:
The top-level of the project is drawn in the circuit editor, and all the modules included in it are written in Veriolg. The principle of the project is quite simple - the data from the line, digitized by the ADC, is captured by the FPGA and stored in RAM. After all 512 signal elements are captured, they are transmitted via UART to the computer. After all the data has been transmitted, the cycle repeats. The sensor_reader module in this project controls the ruler, laser and CLAMP signal. The control is implemented in the simplest way - all signals are controlled by a clock counter. The tx_controller module includes a UART transmitter module. It is designed to transfer data that the module receives from external memory.
In the process, the level of the useful signal on the line can vary greatly - due to changes in the distance to the object and changes in its reflection coefficient. If the signal is too small, the measurements become impossible, and if the signal is too large, the accuracy of the measurement decreases. Because of this, the gain of the analog signal needs to be adjusted. Initially, the project included the UART receiver module, which allowed you to manually change the gain, later I removed it and made automatic gain control - AGC.
It includes a signal maximum search module ("max_finder") and the AGC module itself ("agc_module"). This module is also quite simple - if the signal level is less than 170, then the gain increases, if more than 250 - decreases.
All modules, the ruler and the ADC are clocked at a frequency of 10 MHz. I set the exposure time to 5 μs. Thus, the entire exposure process and signal capture in the FPGA occupy (5 + 51) μs. The data transfer time is much longer - at a clock frequency of 500,000 bps, transmitting 512 bytes takes 10 ms, which gives 100 measurements per second.
To view the transmitted data in real time, a simple program was written in C #: When moving an object along the laser beam, the position of the peak maximum changes. Simple calculation of the maximum position gives a low measurement accuracy, since the ruler contains only 512 pixels. Therefore, to more accurately measure the position of the signal maximum, one has to use the center of gravity search algorithms, which allow determining the coordinates of the signal maximum with subpixel accuracy.
I used this formula to find the center of gravity of the peak:
where n is the total number of pixels, Int [i] is the intensity of the i pixel.
In order to ensure that the various noise present in the signal does not impair the accuracy, it is useful to process only samples that exceed a certain threshold and are close to the peak maximum. This is especially important when the gain is not enough, and the useful signal does not exceed half the ADC scale. Moreover, with increasing gain, the noise level increases, which worsens the situation. In the above program, this is taken into account.
In the picture above, MAX POS is the value calculated using this formula, MAX POS F is the average value of the last 50 measurements.
As I already said, the resulting measurement frequency is 100 Hz, and it is limited by the data transfer rate via UART. However, it is not necessary to process the signal on a computer; this can also be done on the FPGA, due to which it is possible to repeatedly increase the measurement speed.
As a result, a program was developed for FPGAs with such a structural scheme: Type of circuit in ISE: As you can see, some of the modules are taken from a previous project. In this case, the centroid_finder module is responsible for calculating the position of the center of gravity (centroid) of the signal. In order to limit the area of data analysis, a rough value of the maximum position and its amplitude is transmitted to the module.
Since these values can be calculated only by analyzing the entire signal (that is, they appear with a delay of 512 clock pulses), it turns out that the digitized data must be fed to the input "centroid_finder" with the same delay. In order to delay data by 512 clock cycles, the FIFO buffer is used. The fifo_logic module is used for initial FIFO filling - it prohibits reading from FIFO if it is not filled.
The tx_controller_3bytes module sequentially transfers 3 bytes, the first of them is zero, the remaining two contain the calculated position of the center of gravity. At a speed of 50,000 bit / s, transmitting 3 bytes takes 60 μs - almost as much as signal capture. Zero byte is used to synchronize data - after it is always the highest byte.
UART data transfer and data capture are triggered simultaneously by the start_capture signal. This signal is generated if the previous transmission has ended at the same time and the new position of the center of gravity has been calculated. As a result, the time of distance measurement and data transmission is close to 60 μs, which gives a coordinate measurement speed of 16.6 KSPS. This is less than what is stated by the sensor manufacturer. It indicates the minimum measurement time - 20 μs (this corresponds to 50 KSPS), although it is not clear how this time was obtained, because even with the maximum speed of the AD9200 - 20 MSPS, the signal capture time from 512 pixels will be - 25.6 μs. And this is even without taking into account the exposure time.
As I said earlier, this sensor did not work. As far as I know, the problem was that it was installed on a highly vibrating industrial installation, and due to vibration, the sensor laser failed (the sensor stopped responding to dark surfaces).
Unfortunately, there was no marking on the native diode. I tried to replace the laser diode in the laser module with a purchased 5 mW laser diode, but after a while its intensity decreased. Most likely, the laser module electronics was designed for a more powerful diode (although it operates in a pulsed mode, due to which the average radiation level is quite low).
In order to somehow start the sensor, I made my laser diode driver, working in constant radiation mode:
The native laser diode of the sensor was rolled into the metal housing of the laser module, so the new laser diode had to be simply glued to the module. At the same time, the overall dimensions of the diode used were slightly different from the dimensions of the native diode, because of which I was not able to focus the laser module qualitatively.
This is how the assembled sensor looks:
In order to be able to measure the distance using the sensor, it is necessary to calibrate it, i.e. determine the law linking the result returned by the sensor and the real distance. The calibration process itself is a series of measurements, as a result of which a set of distances from the sensor to a certain object is formed, and the corresponding results.
The distance between the sensor and the object must be measured very accurately. For calibration, I made a stand, which includes a linear encoder and the laser sensor itself: The distance is measured to the plate mounted on the end of the encoder. After all the data is collected, you can conduct a regression analysis in Mathcad. As a result, I got the following expression: value_mm = 70.0 / Tan (-0.000277757 * max_pos + 0.28355) - 366.23554 Obviously, the values of the constants in the expression depend on the position of the sensor parts. The slightest shift in details will result in the calculated distance being incorrect. Therefore, all parts must be very firmly fixed. The video below shows how you can process sensor data:
The first part of the video shows how the signal from the photosensitive line looks. It is clearly seen that if the object is dark, then the amplitude does not change (due to the operation of the AGC), but the noise level increases significantly.
In the second part of the video, the program receives the center of gravity from the sensor, and recounts it to the distance. Also, the program receives the value of the distance to the object received from the encoder. Under the encoder distance, the difference between these distances is displayed. You can see that in motion the difference becomes more than 1 mm (this is due to delays in the transmission of distances and their display), but during stops at any distance, the difference does not exceed 0.03 mm.
In order to make the data received from the sensor easier to analyze, I wrote a program that stores the data received from the sensor in wav format. Such files can be opened in sound editors, and apply various filters to them.
Here's an example of what the signal from the sensor looks like, which was sent to the wall of the transformer power supply:
It can be seen how the power supply started to vibrate when it was turned on.
I tried to direct the sensor to the speaker cone on which the music is playing - and after processing it was really audible in the sound editor.
In this way, I managed to give a non-working sensor a new life (I may need it in future projects), and at the same time gain experience working with Xilinx FPGAs.
Projects for FPGA