-
Notifications
You must be signed in to change notification settings - Fork 190
Encoder
Encoder consists of two main parts: encoder disc and optical sensor
I have taken this disc from old ball mouse.
This disc have 65 slits, one of them is closed (but it is counted too: 64 opened + 1 closed) - it is zero angle reference mark.
See this drawing:
Number of slits is defined in "config.h" file: "ENCODER_HOLES_CNT".
Diameter of the disc is 15.5 mm.
I have taken mine sensor from old printer so I can't give exact name of it. It is conventional opto-interrupter, with one LED and one NPN photo-transistor.
Closed opto-interrupter (no current through opto-transistor) is need to produce high level at the sensor output.
Notice that if you are using disc with a small diameter, you need to use sensor with small diameter of the optical beam - usually such sensors have smaller packages.
It is recommended to make sensor fixing adjustable - to change position of the light beam in relation to disc.
Sensor is connected to the PCB using 3 wires: +3.3V (ENC PWR), GND, Signal (connect it to P6 pad).
See "PCB_3D_view_up.png": https://github.com/iliasam/OpenTOFLidar/blob/develop/PCB/PCB_project_v4/PCB_3D_view_up.png
You can use R34 as a pulp-up for opto-interrupter photo-transistor.
This is how signal from the sensor should look at the oscilloscope when motor is running:
Zero mark "pulse" is shown at the center of this image.
Signal from the sensor goes to comparator integrated to the MCU. Comparator reference voltage is 1.2V.
See: "encoder_processing.c" and "config.h":
#define ENCODER_COMP_NEG_SRC COMP_InvertingInput_1_2VREFINT
If you are having problems with your encoder, you can try to simulate it with Arduino compatible board. Use this sketch:
#include <Arduino.h>
#define SEC_TO_US 1000000
//Rotations per second
#define SIM_ENC_SPEED 15
// Number of slits in encoder, including manually closed zero slit
#define ENC_TOTAL_PAIRS 65
//Open-closed pair duration (~1000 for 65 pairs and 15PRS)
#define ENC_PAIR_DURATION_US (SEC_TO_US / SIM_ENC_SPEED / ENC_TOTAL_PAIRS)
//MCU pin
#define SIM_PIN 23
void encoder_closed()
{
//Closed slit -> no light -> no current -> pull-up to 1
digitalWrite(SIM_PIN, 1);
}
void encoder_opened()
{
digitalWrite(SIM_PIN, 0);
}
void encoder_simulate_pair()
{
encoder_opened();
delayMicroseconds(ENC_PAIR_DURATION_US / 2);
encoder_closed();
delayMicroseconds(ENC_PAIR_DURATION_US / 2);
}
//Simulate manually closed zero pair
void encoder_simulate_closed()
{
//encoder_opened(); //This slit is manally closed
encoder_closed();
delayMicroseconds(ENC_PAIR_DURATION_US / 2);
encoder_closed();
delayMicroseconds(ENC_PAIR_DURATION_US / 2);
}
void setup()
{
pinMode(SIM_PIN, OUTPUT);
}
void loop()
{
encoder_simulate_closed();//zero
for (int i = 0; i < (ENC_TOTAL_PAIRS - 1); i++)
{
encoder_simulate_pair();
}
}
You need to set number of slits (holes) of your encoder - ENC_TOTAL_PAIRS .
You need to set suitable GPIO pin - SIM_PIN .
You can use any Arduino compatible board - I tested this sketch at ESP32 board with Arduino FW.
Just disconnect motor and encoder from your LIDAR board and connect GND and SIM_PIN of the Arduino to the LIDAR encoder input P6. This input not 5V tolerant. Use variable potentiometer to make 3.3V output if our Arduino has 5V GPIO!
Add patch to you "scanning_fw" Firmware
In file "dist_measurement.c" in function dist_measurement_recalculate_ref_distance()
add line corr_ref_dist_bins = 50.0f;
before the last
dist_meas_zero_offset_bin = corr_ref_dist_bins - true_dist_bin;
line.
This is needed to disable Reference Plate distance corrections. You will not get accurate distance measurements in a such way,
but you can test that FW is detecting encoder pulses ad laser is controlled OK.
Resulting image: Diameter of the circle is depending on distance to the object.