VHDL Light Source Detection : Thresholding & Light Source Detection

by immanueljohanesaditya in Circuits > Robots

416 Views, 2 Favorites, 0 Comments

VHDL Light Source Detection : Thresholding & Light Source Detection

CompleteSchematic.png

NOTE: This page is one part of a larger build. Please ensure you start HERE, so you understand where the following fits in within the larger project.

Introduction

Thresholding and light source detection are part of light source detector. In one word, thresholding is a part that comparing between the value of Y from YCbCr and constant value. YCbCr from pixel capture and output from comparator is binary value, 1 for light source and 0 for not a light source. On the other hand, the light source detector as the name suggests is of course the part that must find the largest size of light source as the target of the Light Seeking Robot.

Overall of this part divided into :

  1. Column Counter
  2. Light Size Counter
  3. Max Light Size Register
  4. First Column Register 1
  5. First Column Register 2
  6. Final Position
  7. Size Buffer
  8. Position Buffer
  9. SR Latch

Explanations for each section will be explained after this paragraph. But before going into it, please note that the outputs of this section are the Size Buffer (as size of the largest light source), the Position Buffer (as midpoint of the largest light source), and the SR Latch (as system indicator). All outputs will be processed in decide the direction and speed of the section.

Supplies

It might be easier for readers to download the complete schematic first then read it along while also read the steps linked below:

Schematics

Column Counter

ColumnCounter.png
LightDetectionSimulation.png

The resolution used in for light detection is 640 x 480 pixel. That means there are 640 columns and 480 rows of pixels in each frame. The result of light detection will become more accurate if there are a larger number of pixels. But doing so will use a lot of resources from the FPGA board. Smaller resolution can also be used, but it will sacrifice the accuracy of the reading. Therefore, this resolution will provide balance between accuracy and resources used.

The first component is Column Counter, which function to count and keep track on the current pixel position. There are 640 columns, so the counter will count from 0 to 639 and then reset to 0 after the system already moved to next row.

The inputs for the Counter Column are CLK (half of PCLK, 25 MHz) for the count start indicator. So, every time there is a rising edge of CLK, it adds the previous value by one. Because almost every component in the system uses CLK, this can provide them information to keep track on which pixel are they.

HREF (from pixel capture) as count enable and clear enable. This means that the counter only allowed to count when HREF is ‘1’. Before explaining further, HREF is used as an indicator when the system already moved to next row, that is when its value is ‘0’. So, the system is only counting when it still in the same row.

The last input is RST (Asynchronous Reset) for the system. Every component uses this to reset their value to their initial condition in case something goes wrong.

The output is COUNT_COLUMN, which COUNT_COLUMN output is count result-1. The reason why count result-1 is a Light Seeking Robot system starts from cycle 0 which means there are 0 data in that cycle and the data will be found in cycle 2 and there is column number 0 (first column). For better explanation, look up at the figure above. Then the output, COUNT_COLUMN, will be used as DATA in First Column Register 1.

Notes :

· Column Counter will start counting if CLK (HIGH = 1) and HREF (HIGH = 1).

· Column Counter will start from beginning if HREF (LOW=0) or RST (HIGH=1).

Here's the link for VHDL code : COLUMN_COUNTER.vhd

Light Size Counter

LightSizeCounter.png

The Light Size Counter count the size of the light source from pixel capture, which light source is Y value (from pixel capture) that greater than THD value (in this case THD = 128). You might notice that there is another component inside the Counter. This is used as a comparator to compare if Y > THD. If it satisfies the condition, it will give output YTHD = ‘1’.

The inputs for the Light Size Counter are CLK (half of PCLK, 25 MHz) for the count start indicator, HREF (from pixel capture) as clear enable and count enable, also asynchronous reset for the system. Comparator YTHD is also used as clear enable and count enable.

Similar to previous Counter, this Counter only counts when there is a rising edge from CLK and all count enable is ‘1’. In this case YTHD and HREF must be ‘1’ so the counter can start counting. If both value is ‘1’, what it means is there is a light source in the current row.

The output is COUNT_LIGHT_SIZE, which will be used as B and DATA in Max Light Size Register and as LOAD_EN in First Column Register 1.

Notes :

· YTHD will HIGH = 1, light source, only if Y >= THD. (YTHD = 0 if Y < THD)

· Light Size Counter will start counting if CLK (HIGH = 1) and YTHD (HIGH = 1).

· Light Size Counter will start from beginning if HREF (LOW=0) or YTHD (LOW=0) or RST (HIGH=1).

Here's the link for VHDL code : LIGHT_SIZE_COUNTER.vhd

Max Light Size Register

MaxLightSizeRegister.png

The Max Light Size Register has the role of registering the widest array of light sources in a certain row. Register Max also has another component as a comparator inside it. It functions to compare the widest array registered and a potentially wider array in the next row from the Light Size Counter.

The inputs for the Max Light Size Register are A which is value of MAX_SIZE (Default value of A = 0), B and DATA which are value of COUNT_LIGHT_SIZE, CLK (half of PCLK, 25 MHz) for the system enable, VSYNC (from pixel capture) as clear enable, and RST (Asynchronous Reset) for the system. The comparator is used as a load enable.

So, this component will register the input from previous counter when it is bigger than the current value registered. For example, right now the value of MAX_SIZE is 200 (which means the widest array is 200 light sources in a certain row). This value become an input to A and will be used to compare the value B. Now, the value from Light Size Counter is, let’s say 300, then this new value will be registered as MAX_SIZE and becoming the widest array for now.

The output MAX_SIZE will be used as DATA in Size Buffer and as MAX_SIZE itself in Final Position.

Notes :

· BA will HIGH = 1, only if B >= A.

· When BA (HIGH = 1) then MAX_SIZE = DATA.

· If VSYNC (HIGH = 1) means new frame, which is back to first row.

Here's the link for VHDL code : MAX_LIGHT_SIZE_REGISTER.vhd

First Column Register 1

FirstCol1.png

The First Column Register 1 has a function to register the first pixel location with a light source in it, or when the value of the pixel is ‘1’. This is necessary to determine where an array of light sources starts. Later, the data will be used to find the center position of the array.

To achieve this, the output COUNT_COLLUMN become an input as DATA in the register. The input LOAD_EN comes from output COUNT_LIGHT_SIZE. The DATA is registered when LOAD_EN is equal to “1” as in unsigned value. The Column Counter and Light Size Counter work in sync with CLK. So, as it keeps counting the current pixel location, when the Light Size Counter detects a light source, the current location is simultaneously sent to the register. Therefore, the first pixel with a light source is obtained.

Other than that, the inputs are CLK, VSYNC, and RST (Asynchronous Reset). The CLK is necessary so the components could work in sync. The inputs are registered only when the CLK is in rising edge. The VSYNC is used to reset the registered value when the system already moved to next frame.

And then the output F_CR1 should be subtracted by one. This is caused by the delay when the light source is detected and counted at the counter. The figure at Step 1 will help you understand better. Then, the output is later used moved to another register as a final value. This will be explained in the next section.

Notes:

· When LOAD_EN = “1” then F_CR1 = DATA.

· If VSYNC (HIGH = 1) means new frame which is back to first row.

Here's the link for VHDL code : FIRST_COLUMN_REGISTER1.vhd

First Column Register 2

FirstColumnRegister.png

So, why should there be another register for the position? This register works a little differently from the previous one. It takes the output from the First Column Register 1 as an input and register it when there is a wider array of light sources detected.

The output F_CR1 become an input as DATA in the register. The input LOAD_EN comes from comparator output BA at Max Light Size Register. The DATA is registered when LOAD_EN is equal to ‘1’ which means there is a wider array of light detected. The other inputs are CLK, VSYNC, and RST (Asynchronous Reset). Which works the same as the previous one.

The main goal of this register is to save the first position of a light source in the widest array of light sources in a frame. This could not be achieved by only using the previous register. Because it always registers the first position whenever there is a light source. So, there is no way of knowing if it is at the widest array or a shorter one.

Notes:

· When LOAD_EN = ‘1’ then F_CR2 = DATA.

· If VSYNC (HIGH = 1) means new frame which is back to first row.

Here's the link for VHDL code : FIRST_COLUMN_REGISTER2.vhd

Final Position

Final Position.png

The Final Position has the role to decide the midpoint of the widest array of light sources. Final Position inputs are F_CR2 which is the output of First Column Register 2, and Max Light Size Register (MAX_SIZE) which is the size. In this component, the value of F_CR2 is added by the value of MAX_SIZE shift righted to get the midpoint of the array. The output of the system is F_POS will be used as DATA in Position Buffer. The figure below will help you understand better how the Final position works.

Notes:

MAX_SIZE (9:1) means 9 downto 1, on which the value of Register Max is shift righted from 10 bit to 9 bit. Shift right means the decimal value of a binary value is divided by two. To do shift right, the least significant bit is erased. For example, 1010101010 shift-righted will be 0101010101. The decimal value of 1010101010 is 682, and if 682 is divided by 2 will get the value of 341, which the decimal value of 101010101 is 341. By this example, it can be concluded that the statement that shift right means the value of the decimal value of a binary value is divided by two is true.

Here's the link for VHDL code : FINAL_POSITION.vhd

Size Buffer

Size Buffer.png

Size Buffer has the role to save the widest array of light sources right before the frame changed. Size Buffer got its inputs from DATA which is output of Max Light Size Register (MAX_SIZE), NOT_HREF which means the falling edge of HREF, and RST (Asynchronous Reset) for the system. The output of this system is Size Buffer (Size_B) which is the value of the widest array. The figure below will help you understand better how the Size Buffer works.

Notes:

· When HREF has a Falling Edge, the value of DATA will become Size_B.

· Size Buffer will start from the beginning when RST is High (RST = 1).

Here's the link for VHDL code : SIZE_BUFFER.vhd

Position Buffer

Position Buffer.png

Position Buffer has the function to decide the final midpoint of the widest array of light sources. So that the light seeking robot leads to the center point of the light. where the midpoint of the light will maximize the light obtained by the light seeking robot. so that the robot can point to the center of the light.

Position Buffer inputs are DATA which is the output from Final Position (F_POS), NOT_HREF, and RST (Asynchronous Reset) for the system. The output of Position Buffer is POS_B which is the final midpoint of the widest array of light sources. The figure below will help you understand better how the Position Buffer works.

Notes:

· When HREF has a Falling Edge the value of DATA will become POS_B.

· Position Buffer will start from the beginning when RST is High (RST = 1).

Here's the link for VHDL code : POSITION_BUFFER.vhd

Ready Indicator

srlatch.png

Ready Indicator has the function to send signal when data is ready to be send to “Decide Direction and Speed” division. Ready Indicator is implementing the SR Latch system. The inputs for Ready Indicator are CLK which is for the system enable, R which is “Reset” on the SR Latch that has the role to indicates if data is ready to be send, S which is “Set” where the value is constantly ‘0’, and also RST (Asynchronous Reset) for the system. The outputs of Ready Indicator is READY which is the signal when data is ready to be send.

We design the circuit as follows (S = 0), the output (READY) can change only if the input R = 1 when the newly acquired data will be submitted to the “Decide Direction and Speed” division or if R = 0 the system will use the previously stored data memory. The figure below will help you understand better how SR Latch works.

Notes:

· The SR LATCH is known as set-reset latch, usually created by wiring two NOR GATES.

· In this system, there is internal signal Q to compare with the value of READY. In SR LATCH system, the value of Q and READY (QBAR) must be the opposites.

· The value of S will always be '0'.

Here's the link for VHDL code : READY_INDICATOR.vhd

Conclusion

To conclude, this system as a whole has inputs such as CLK, HREF, VSYNC, Y, and RST (Asynchronous Reset). Through these inputs, it produces outputs such as READY, POS_B, and SIZE_B.

Input CLK, HREF, and VSYNC works as indicators. Some of the functions as given below:

  • To give position information to the system on which column are they.(CLK).
  • To tell the system that Pixel Capture already moved to next row in a frame (HREF).
  • To tell the system that Pixel Capture already moved to next frame (VSYNC).

  • To tell the system internally and the next group (Motor Speed Controller) when the data is ready.

While input Y from the camera is going to a thresholding process so the system can tell where the light sources are. The output POS_B will provide a center position from an array of light sources, which will be decided by the Motor Speed Controller group whether the robot should move to the left, right or forward. And the output SIZE_B will provide the width of the light source, which will be used to determine if the robot should go forward or backward.

And there you have it. You have created a system for thresholding and light source detection for the Light Seeking Mobile Robot. Combine this code to the other group for the final code to be uploaded into the robot. Then, voila! You've successfully made a light-seeking robot.

Contributors

LSMB_THD.jpeg

(Left to right)

  • Aziz Rizkiyanto
  • Immanuel Johanes Aditya
  • Johannes Gracia
  • Jonathan Miharja
  • Markus Sugianto