I2C Verilog Code Explanation II









In my previous post, I explained working of I2C Verilog code. Same is continued here.

else if(left_bits == 10)begin
  if(sda == 0)begin
   left_bits <= 1;
   direction <= 1;
   temp <= temp_reserved;
  end
  else begin
   direction <= 1;
   alpha <= 0;
   left_bits <= left_bits + 1;
  end
end


When the ACK/NACK is received at 9 then at 10 it is compared with 1 and 0. If the acknowledgment received is 0 then left_bits is reset to its initial valule that is 1. Direction is again set to 1 to make the Master ready to send data to Slave. The register TEMP which is now XXXXXXX gets renewed or say reset with a copy that we stored earlier i.e. in TEMP_RESERVED. If the received acknowledgement is 1 then direction will be changed to 1 because now the Master will have to send the address of register which stores data in the Slave. Setting ALPHA = 0 is not necessay here though. LEFT_BITS is again incremented.

else if(left_bits >=11 && left_bits <=17)begin
  alpha <= register[6];
  register <= register<<1;
  left_bits <= left_bits + 1;
end


From 11 to 17 i.e. 7 counts the Master will send the address of the register of the Slave from where data has to be retrived. The process is same as I explained earlier to send Slave address hence I am not gonna repeat the same.

else if (left_bits >= 18 && left_bits <= 28)begin
  direction <=0;
  left_bits <= left_bits + 1;
end


From 18 to 28 the slave will send an ACK bit to tell the master that if the register address is mathed or not. This happens on 19th cycle. However, there is a clockcycle delay here in Slave at this position. The SDA line is continuous from Master to Slave. Since we cannot do any operation on wires therefore we have to store data from wire to a register in the Slave inorder to use it. However, storing this data results in an extra clock cycle, since values get updated after the clock cycle and not along with clock cycle for a non blocking assignment (<=). For blocking assignment (=) the task is done first having the blocking assignment and then rest of the tasks are completed. 

Example
initial begin
a = 0;
c = 0;
end
always @(posedge clk)begin
  a <= a + 1;
  a <= a + 2;
  c <= c + 1;
  a <= a + 3;
  c <= c + 2;
end

After executing the above command if you are thinking that the result will be a = 6 and c = 3, then you are wrong !!.
The right answer is a = 3 and c = 2;

However, if you code like this snippet below using blocking assignments
always @(posedge clk)begin
  a = a + 1;
  a = a + 2;
  c = c + 1;
  a = a + 3;
  c = c + 2;
end
 The output will be a = 6 and c = 2;

Whenever we use non blocking assignments each line of code does not depend on previous line. They will occur simultaneously with the past data. Data is changed after the clock cycle ends and not immediately. In case of blocking assignment, the first line will be given first priority. After it's execution second line is executed. Data is changed immediately. 
Thus 
a <= a + 1; mean a = 0 + 1 = 1
a <= a + 2 means a = 0 + 2 = 2 . It won't depend on the previous calculation. 
a <= a + 3 means a = 0 + 3 = 3   It won't depend on the previous calculation
At the end of clock cycle a = 3

However,
a = a + 1 means a = 0 + 1 = 1. This will be executed immediately.
a = a + 2 means a = 1 + 2 = 3 This will be executed after the previous execution
a = a + 3 means a = 3 + 3 = 6.

Non blocking assignments are used only when sequential conditions are present i.e. flip flops. Blocking assignments are used for combinational blocks. I hope it is clear the difference between blocking and non blocking assignments. 

To manage this bit delay in slave I had to use a blocking assignment. The Slave sends the 8-bit data stored in its register to Master by setting direction = 0 on the SDA line. 

else if(left_bits == 29)begin
  direction <= 1;
  alpha <= 1;
  left_bits <= left_bits + 1;
end


For the 29th count the Master will set the direction 1 and the Slave will set the direction as 0 as it is the turn of Master to send the acknowledgement bit now informaing the Slave that it has received the 8-bit data. The acknowledgement is sent by assigning ALPHA = 1 i.e. SDA is pulled high. 

else if(left_bits == 30)begin
  alpha <= 0;
  left_bits <= left_bits + 1;
end
else if(left_bits == 31)begin
  #2 alpha <= 1;
  left_bits <= left_bits + 1;
end
else if(left_bits == 32)
  a <= 0;
end

At the count 30 ALPHA is set to 0 as ACK is only of 1 bit. For the count 31 ALPHA is set to 1 i.e SDA is pulled high. No negative edge is present afterwards here. For the count 32 "a" is set to 0 thus switching SCL line to 1. Since there is not negedge of SDA there SCL won't start clocking again which I have already explained earlier. #2 is time delay to 2 ns to introduce the STOP condition. 

Fig - STOP Condition

Although #1 should be present there as in the above image I mistakenly added an extra clock cycle. You are free to experiment.

I'll explain the SLAVE code later.

So Long

I2C Verilog Code Explanation I


In this post, I am going to explain my previous post regarding I2C. You can visit the post by clicking here.



INOUT  SDA: The SDA line is the inout port because Master will send data, address along this line as well as the Slave will send ACK/ NACK along the same SDA line hence it has to be inout type.

OUTPUT REG SCL: The SCL line will be the output from Master to other Slaves. SCL is controlled by Master here by the register "a" in the code.

REG DIRECTION: This register will decide whether the direction of flow of data on the SDA line. The line assign sda = direction?alpha:1'bz. using the direction keyword.

Its equivalent code will be
 if(direction==1)
   sda = alpha;
 else if(direction==0)
  sda = 1'bz;

If Master sets the direction as 1 then sda = alpha. At the same moment, Slave must also have the direction set to 0 in order to allow data from Master. When the Slave wants to send the data then the Slave will set the direction as 1 and Master will set it as 0.

REG ALPHA: This register holds the bit that has to be sent on the SDA line. Since SDA is a wire, therefore it is not possible to use it inside always@ block.

REG [6:0] ADDRESS: This 7-bit register holds the 7bit register holds the address of the slave.

REG[7:0] TEMP: This 8-bit register holds the address of the slave along with RW bit that has to be sent on the SDA line.

REG[7:0] TEMP_RESERVED: This 8-bit register just holds a copy of TEMP register for future use.

TEMP = {ADDRESS,RW}: This concatenates the 7-bit address and 1 bit RW into an 8-bit register and stores the final data back in TEMP.
always @(posedge clk)begin
  if(a==0)
    scl <= 1;
  else if(a==1)
    scl <= !scl;
end


Here "a" is a switch. When "ON"  it will clock the SCL line. When OFF it will pull up the SCL line HIGH. It is just a manual control for Master to control SCL.
always @(negedge sda)
  a <= 1;

As soon as the SDA line is pulled down, "a" is triggered to start SCL clock. This is the START condition. Although SDA has many negative edges it won't affect SCL because of above code. When we want a STOP condition then SDA is pulled HIGH first. Thus no negative edge occurs after that point and then "a" is triggered low which pulls SCL HIGH and STOP condition is achieved.
always @(negedge scl)begin
  #1 forever #2 scl2 <= !scl2;

SCL2 is an internal clock which starts as soon as SCL is triggered. This is done because we cannot use SCL for our operation. SDA only changes when SCL is LOW (See the LAST image in my post) and not on positive edge or negative edge. #1 is the delay of 1ns. SCL2 starts ticking after 1ns start of SCL. Using the posedge of SCL2 we achieve our required condition to change SDA when SCL is LOW.


Look at this image above. SDA changes when SCL is low (in middle). It neither changes at positive edge nor at the negative edge.

SDA changes at positive edge / negative edge of SCL2 which itself changes at LOW SCL.
Thus SCL and SCL2 are 1ns apart.
integer left_bits = 1;
LEFT_BITS is just a counter for proper operation that I used. It would create a havoc working without it.
always @(negedge scl2)begin
All the SDA operations are operated on a clocked edge of SCL2 not SCL to maintain I2C standard.
if(left_bits <= 8) begin
  alpha <= temp[7];
  temp <= temp<<1;
  left_bits <= left_bits + 1;
end

The above code above is pretty simple. It loops for 8 times in order to send 8 bits which include 7-bit Slave address and 1-bit RW.
 temp[7] is the MSB which has to be sent first on SDA. (bit by bit)
However, after sending the MSB we have to send the next bit i.e temp[6] therefore, I left shifted the temp bit which shifts 1 bit towards left.

Example:
If temp[7:0] = 10101010;
temp = temp<<1;  Here temp will be 0101010X

if I had used temp = temp<<<1; then temp would be 01010100.

If I had used temp = temp<<2; then temp would be 101010XX

I hope I have cleared the difference between << and <<<. Similarly, we can use >> and >>> although it is of no use here.

NOTE: Initially, the direction is set to 1 in Master and 0 in slave i.e. Master is sending data on SDA line which SLAVE has to accept.
else if(left_bits == 9)begin
direction <= 0;
ack <= sda;
left_bits <= left_bits + 1;
end

After sending 8 bits direction is changed to 0 in Master and 1 in Slave. It is the turn of Master to accept from Slave. At this moment Slave, if the address is matched it will send 0 NACK or 1 if the address is not matched. ACK is opposite of NACK.

.....................
To be continued in next post.



ESP8266 WebSockets

I worked on web sockets on a Wemos D1 mini using an ESP8266 chip and it worked fabulously. I have designed an "HTML" file which can initiate a connection with my D1 mini to control the onboard LED.

Any board with ESP will work here. In my application, I can switch on and switch off the onboard LED of the board. A continuous connection was also made to see the real-time calculation going on the ESP board with my browser.

However, I faced some problems like socket timeout which I haven't solved yet. The problem is that when the ESP is connected to the browser, it shows the real-time data for some minutes after which the connection is stopped. I still have to figure out the reason to solve this issue.

WebSockets have helped me to a great extent. I can use the serial monitor over wifi now. I can even update the values over wifi and get back the current readings.

I began with the web socket library by "Ipnica" at GitHub. Click here to download the library. After installing ESP board on Arduino IDE and the above-downloaded library I was good to go.

The code for a simple WebSocket connection is here

I am assuming readers know most of the commands here.

WebSocketsServer webSocket = WebSocketsServer(81);

This will create an instance of WebSocket server at port 81. Your address will be like ws://192.168.5.2:81/
Do remember that "ws" here represents WebSockets. Its the representation of a web socket url. Similarly "wss" is for WebSocket Secure just like HTTPS.

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)

This void method is very important. The payload will contain the data that has to be sent or is being received. The length is the length of the payload. "type" indicates the type of data i.e TEXT of Binary. Num contains the data about the IP address of the connected client.

case WStype_DISCONNECTED:
  • When the socket is disconnected this condition is fired up.

case WStype_CONNECTED:
  • When the socket is connected successfully this condition is fired up.

case WStype_TEXT:
  • When the data received is of type TEXT
case WStype_BIN:
  • When the data received is of type Binary !!

webSocket.sendTXT(num, x, strlen(x));
  • When the user wants to send a data to the browser of type TEXT. The first argument is the details about the ip address of the connected client. The second argument is a const char * type data. The third argument is the length of const char *x.
It can also be used like this.
webSocket.sendTXT(num, "Yay It works!!", strlen("Yay It works!!));


Incase when we want to send normal string then the command should be

String s = String(a);
char const *x = s.c_str();
char const *x = s.c_str();

Here s can be "Hello" or any integer converted into a String.

String _payload = String((char *) &payload[0]);
  • This will store the incoming character array inform of string into the payload.
The HTML file 
con = new WebSocket('ws://192.168.1.5:81/',['arduino']);
  • A new websocket connection is initiated with the mentioned ws address and the following protocol. The first argument can be variable too. My Wemos has the wsIP ws://192.168.1.5:81/
con.onopen = function(event){ console.log("Opened"); };
Whenever a new Web Socket connection has opened this property "onopen" is initiated. You can put any conditions in the curly braces. If you are using Chrome then press Ctrl + Shift + I and then click console tab above to see the message that will be logged in console, once a connection has been opened.

con.onmessage = function (evt) {
var received_msg = evt.data;
document.getElementById("message").innerHTML = evt.data;};

Whenever a new message arrives on the browser this property is fired up. An event is raised that contains the data received. 

con.onclose = function(){
console.log("Masakaaaa!!!");};


Whenever a WS connection is closed the above function is fired up which may or may not log events depending upon the user choice. I have logged a string on the console here.

function SwitchON() {
var toSend = "ON";
con.send(toSend); };

This is a function named SwitchON. Whenever this function is called, a string is sent to the server.

<input type="button" onclick="SwitchON()"> Turn LED Off

This will create a button which when clicked will call the SwitchON function which in turn will send data.

Here is the working of the WebSocket.



So Long

I2C Verilog Code and working


I had already made a post regarding I2C long ago, however, in this post I am reposting I2C but with various changes. Some changes involve the using of Acknowledgement Bit by the Slave and Master, Same SDA line for slave address, register address as well as data. No extra data line is required to read the data from the slave. Everything can be seen on the SDA line along. This version of I2C in Verilog has the full support of adding *multiple* slaves.
Yes!! You can use multiple slaves at the same time. The only feature lacking that I am working on right now is the RW bit. The RW or better say Read/Write bit is present here but I have focussed only on the read operation here. I am working on the write operation too and will update soon for the latter.

For this I2C I had to grasp myself with the knowledge of the inout signal line in Xilinx. The SDA has to be an inout line or else it won't be a proper I2C model, despite serving the same functionality.

The Master will send 7-bit address along with RW bit on the SDA line and the corresponding slave will respond back with an ACK bit. After that Master will send the register address which will be acknowledged
by the slave with an ACK bit. Then the slave will send the 8-bit data from the received register to the Master. After receiving the data, Master will respond back with ACK bit and after a CC the I2C operation will end with the STOP bit.

The SCL line changes only when SDA is stable. The testbench I have used here only acts as a supervisor which provides a clock signal to Master. The Master is connected to the slave only with SDA and SCL line.

*DISCLAIMER: This Verilog Code only supports "Read" Operation. I'll continue with the "Write" operation later.

I have worked on this code using a different approach. If the Slave address that Master sends doesn't match with the Slave then it will keep on sending the same address. However, this approach is only applicable to 1 Slave. Consider the case where there are two slaves S1 and S2. If S1 address is matched then data exchange takes place between Master and S1. However, S2 will then inflict as the address won't match here. This will lead to an error on the SDA lines inform of X.

Thus to overcome this difficulty I have re-changed the code to NOT to send address, again and again, i.e if the address doesn't match then Master won't resend the address. Although a Master should keep on sending the address in real, my code faces a problem which I'll deal later.

As I have mentioned that I have used inout command in this code. Inout command should only be used using a tri-state buffer.

A tristate buffer is coded somewhat like this:
x <= direction?data:1'bZ;

A tristate buffer has an enable pin. When enabled (here direction == TRUE) then data will be transmitted. On the other case, when disabled (here direction == FALSE) then a high impedance is
sent thereby disconnecting the output from the input circuit. Consider A and B. When A is true then it is at higher potential. When B is false it is at a lower potential. As current flows from High to Low, this signal will blow from A(TRUE - 1) to B (FALSE Z). Similarly, if B is true and A is false then signal will flow from B to A.

While I was coding, I faced tremendous problems with switching between TRUE and FALSE in both Master and Slave. If both A and B are set to TRUE then you will get ZZZZZZZ (in blue color) as output. If both A and B are low you will get XXXXXX (in red color) as output. 

The signal line of type inout can only be a wire. It cannot be registered as reg type so to use it we have to use the "assign" keyword.

RW- 0 ACK = 1 Slave address matched

RW- 0 ACK = 0 Slave address not matched

Get Single Master Single Slave Code from here: Github I2C_Code

Master & Slave


Test Bench

NOTE - To restart the I2C transmission all you have to do is give a fork join condition
fork
#160 alpha <= 0;
#160 direction <= 1;
#162 left_bits <= 1;
join



Place this piece of code in the initial begin of the Master Code. Remember that you have to give sufficient #time condition to avoid conflict. With this you can you can pull SDA line low to restart I2C for a new data. However, data will too remain same. Thus you will have to change the data by using #time syntax like this in Master

fork
#160 alpha <= 0;
#160 direction <= 1;
#162 left_bits <= 1;
#160 register = 7'b00011001; // 00011001 = 25 in decimal
#160 reg_temp = register;
join

In Slave you will have to enter new data in the array at location 25.

Sim View of the code above in Xilinx




For Multi Slave I2C significant changes are required. Consider a case where we have two slaves named A and B. The master will send the address of A. In that case slave A will send acknowledgment bit (1 in this case) on the sda line. However, slave B will also send acknowledgment bit (0 in this case). This creates a problem as Verilog doesn't allow multiple drivers for a single wire. Even if I simulated I got ZZ as the acknowledgment because of that conflict.

It can be represented as follows


Thus to avoid this condition I used the Verilog keyword "wor". wor is logical OR of wires joint together.

In case if Slave A NACK = 0 and Slave B NACK = 1 then wor would output as 1(B) + 0(A) = 1

Similarly

0(A) + 0(B) = 0

0(A) + 1(B) = 0

1(A) + 1(B) = NOT POSSIBLE FOR I2C WITH SAME ADDRESS.


The following piece of code has a single master and 3 slaves. One thing I came to notice that all slaves code can remain same except the module name or else any change made to any slave would result in a change is every slave.


Multi Slave Code (Works Pretty well. Comment or message for any error)
To change slave address one can change it to desired address by changing address at line 22 of Master

To fully understand my code click HERE
So Long

Self Balancing Bot with PID


In my previous project, I dealt with self-balancing robot without PID controller in this version of embedded the PID control on the same boat and the results are a better than the previous version obviously I am using the control systems part where our main objective is to achieve a critically damped robot. It should reach the steady state as it should have fewer oscillations and it should also recover from light to medium push.

In my previous bot without PID, I had to face problems where the robot will run away with a certain angle. Let's said it x and the Motors will move forward to balance the boat, however, the force or better say pseudo force that acts on the bot will be equal to the force that is pulling the robot downloads at a certain time. When these two forces balance the Robot full neither fall down nor it attain its vertical position. In this Mod, the robot will keep moving forward and forward in forward and finally, it will fall down
Obviously controlling this robot without PID has drawbacks, therefore, I worked on PID and the results are pretty good now.

The construction is same as it was in the previous Bot so if you have made the boat using my previous post then, of course, this will also work. All you have to do is to change the code and will be as good as new.

One thing you must remember while tuning the PID is, first of all, you must set everything parameters to zero that means P is equal to zero I is equal to zero and similarly is D is equal to zero. The Proportional part deals with the force part. It describes the force of your robot for any tilt i.e how vigorously it's gonna react.

So, first of all, you have to keep increasing your P-value until your oscillating. It may even oscillate wildly or it may even oscillate like a drowsy lump. All you have to do is to make the boat oscillate. After that increase the Derivative value to reduce these oscillations. Your robot will stand a bit still not exactly still at the center point without oscillating much. Largest the value of D, quicker it will attain the steady state. Now increase the I value. I value will deal with the response to the tilt. It will tell the bot how quickly you want your bot to recover from a tilt.

The circuit for the bot is same as the previous one.

Working 



Working Updated



*Latest Updated* Source_Code
Ping me if you face any problem. PID tuning takes luck and not the time I guess. In my next post, I'll deal with PID automatic tuning for this bot. So Long.

Self-Balancing Bot without PID



Self Balancing robot is one awesome form of the subject Control Systems. It relies on the topic "Feedback Controller".It always feels awesome to work on these projects and to calibrate your bot according to your needs. Although calibration my bot took less time than to work with PIDs which can take ages and ages also. Auto-Tune PID is also available to manipulate your bot but still, hard work deserves more reward and peace.

In this project, I haven't used PID control to control the motion of bot. That doesn't mean that my bot is unstable or it will wobble around here and there. It is indeed stable and can recover from sudden jerks and movements too. I am not using the enable pins of L293D IC which is used to control the motors using PWM signal I am using here a soft coded PWM signal and decoding part of Arduino to determine the speed of the motor with the respect to the angle. Also, I coded a virtual encoder that can help my bot to return to its original place from where it started drifting.

This project is a complete do it yourself project. I've only used foam tape, hot glue gun, some rulers, etc. I've converted the micro servo into continuous rotation Servo since it has high torque but also one should note that it has less speed so better use large wheels in order to cover more distance.

I am using here
Two continuous micro servo 9g
GY-521 Accelerometer + Gyroscope
Arduino Pro Mini
L293d
0.1 uF Ceramic Capacitors
10 uF  Electrolytic Capacitors

Do remember that electrolytic capacitors have polarity and ceramics do not. Ceramic capacitors are being used here to nullify motor noise. Electrolytic capacitors are being used for appropriate filtering of power fed into L293D IC.

Some concepts of GY-521 -  Gyroscope never measure the actual angle of the tilt it actually measures the rate of tilting. Similarly, the accelerometer measures the acceleration in a particular direction basically GY-521 has 3 Axis accelerometer it can measure in X Y and Z-Axis. The gyroscope present on GY-521 can measure and X, Y, and Z gyro rate. We can either use Kalman filter or the complementary filter to nullify the peaks and valleys obtained from GY-521. The complementary filter is easy as it is just a one-line code as compared to Kalman filter. However, I got results that were more or less equal for both more filters.

I named my bot 'Po'. Yes, I love Kung Fu Panda.

Po works within 5 regions on each signed axis i.e 5 on the positive angle tilt and 5 on the negative angle tilt.
Within the first region (0, 0.8) and (-0.8, 0) degree, no power is supplied to the motor since the bot is perfectly stable.
Within the second region (0.8, - 2) and (-2, -0.8) degree, servos run @ 30% duty cycle.
Within the third region (2, 7) and (-7, -2) degrees, servos run @ 60% duty cycle.
Within the third region (7, 15) and (-15, -7) degrees, servos run @ 80% duty cycle.
Within the third region (15, 25) and (-25, -15) degrees, servos run @ 100% duty cycle.


Both the servos were attached using a ruler and foam tape like this.
A vertical section is added to the horizontal servo support. This vertical support will carry the circuit board.

Here is the circuit of the connection.



I am uploading my sketches using HC 05 Bluetooth. Better prefer a bluetooth module with a STATE pin present on it. Serial Monitor also works using bluetooth.


Currently I am working on an another way of controlling the bot using an equation of the damped parabola. I will upload its results soon. To increase smoothness we will have to increase the regions and change motor duty cycle. Then we can map the duty cycle to the angle of Po to get an equation. Sounds a tough job but is far better than trial and error of PID setting if you ask me.

Another approach I am thinking about is using state space. I have used servos here because plastic DC motors have a backlash error that will always make an error of 0.5 degrees which will keep your bot vibrating at the single point.

I have used an approach to change the balance angle in this bot as it moves. Whenever forward() is instantiated, a counter named "f" is incremented. Similarly, a counter "b" is incremented whenever backward() instantiated. A separate counter is run inside the main loop which checks "f" and "b" after every 1200 cycle. If "f" is greater than "b" setpoint is decreased by 0.05 degrees. If "b" is greater than "f" then setpoint is increased by 0.05 degrees. Then it will reset the main loop counter along with "f" and "b" too. Th basic problem of self-balancing bots without encoder is that they don't return back from where it started. Although Po won't return to its exact point of location, it will return to its nearest point as long as both motors rotate at the same rate which rarely happens with L293D IC.

A point of note - Better use L298 or L293 IC as both have the greater amount of current supply than L293D IC. Also, use a 0.1nF ceramic capacitor across the motor terminals in order to nullify the reverse current spikes. Whenever your motor power stops, it will still rotate due to inertia and will act as a generator of better say back EMF. This sudden drop is the spike and will keep resetting your Arduino, Bluetooth or even Gyro. In my case, it always resets the bluetooth module.



Here is the code for Po.

Detecting Objects using Machine Learning I

Detecting Objects using YOLO

This post deals with my small project on YOLO. It is a great project which if linked with an Arduino will certainly make you win Google Science Fair. Pardon 😁

It also enables to localize the object. If you lost your specs then maybe this will certainly work.

So YOLO stands for "You Only Look Once". Yes, YOLO looks at the image only once. It works by dividing the image into K x K cells


A bit like this
Fig 1 - Image divided into cells

Before working on YOLO have a look at its output like this when I ran an edited version of YOLO over the above image.
Fig 2 - YOLO Output using classification.


Each of these yellow boxes is called bounding box in YOLO language. Each cell in Fig 1  will generate bounding boxes. Treat each image cell as an individual cell and a CNN is run over that image to extract out the features from it. If that feature is significant then a bounding box is drawn over that portion of a particular cell with a bounding information or confidence score.

Remember
Higher is the significance, higher is the boundary information or confidence score.


Bounding information is the thickness of the bounding box. More significant items get a thicker boundary box. On the contrary, less significant items get a thinner boundary. When these cells are merged then all boundary boxes with approximately same boundary information gets converted into a bigger boundary box called as boundary box group. However, this boundary box does not classify any object. It just provides the significance score. This process continues and the result is the Fig 2 or it can even be Fig 3 below.



Fig 3 


Back to work now.
If you are imagining the boundary score then prefer the below image.


Fig 4 Confidence Score a.k.a Boundary Information

The boundary boxes with a higher score are used for classification. So first we find out whether there is a boundary box present, second, it predicts the class of the information inside the bounding box. YOLO can detect up to 20 different objects. Some of em are dogs, person, cars, traffic lights etc.

Now YOLO combines the results of image classification and marks the boundary group which contains the complete object. After this, only those boxes are kept whose box information is highest i.e it represents a full object inside or at least more than 80%. Rest other insignificant boxes are removed.



The result is in Fig 2. 
Every bounding box has 5 parameters namely x, y, w, h and its score. x and y is the center of the boundary box within the cell. w and h is the width and height of the boundary within the cell respectively. So if we feed an image in to Tensorflow, we would get 
K * K * (B * 5 + C) tensors. C is the total number of classes. K is the number of cells. 

To begin our own we need
  1. A long nap
  2. Microsoft Visual Studio 2k15 Click here to download or here.
  3. OpenCV 3.0 
  4. CUDA 8.0 Click here to download


If you have the 2nd item then I guess you can move over the 1st item or else put the 2nd item on download and follow the 1st item. 

**Important**
Install Visual Studio in "custom" mode. Then select Visual C++ in programming languages and also Common Tools.
**Important**

Then clone the following repository.

Extract the folder in the default python folder of your OS. My extracted folder name was "Darkflow-masters". Do check yours. It may differ

Now open Command Prompt as admin and cd to your scripts folder. The script folder lies inside Python folder. My python folder's location is E:\PyPy so to cd there I opened CMD as an admin. The below screenshot shows how to reach to your scripts folder.


Now type 
pip install cython
pip install tensorflow

After the above process, locate your darkflow folder you just extracted a few moments ago using cd.

Then type 
python setup.py build_ext --inplace

Since my python.exe was not in the same location as setup.py (lies inside darkflow folder) therefore I typed the following. (Yours will differ)

E:\PyPy\python setup.py build_ext --inplace

Somewhat like this 

Now to run YOLO we have the syntax
A. To run on CPU (Yeah it sucks!)
python flow --imgdir (Sample Image directory) --model (cfg directory) --load (weights directory)
B. To run on GPU (Life is sweet. More sweet if GPU is Nvidia)
python flow --imgdir (Sample Image directory) --model (cfg directory) --load (weights directory) --gpu 1.0

Command I used on my computer. Of course yours will differ
E:\PyPy\python flow --imgdir sample_img/ --model xx/tiny-yolo-voc.cfg --load xx/tiny-yolo-voc.weights --gpu 1.0


Here are my outputs





Error - cl.exe not found
Solution - Re-install Visual Studio

Error - AssertionError: Over-read bin/yolo.weights
Solution - You have used the wrong cfg with wrong weights.

Error - ImportError: No module named 'darkflow.cython_utils.cy_yolo_findboxes'
Solution - Use this command setup.py build_ext --inplace as I have instructed.

Error - No cv2 module found
Solution - pip install opencv-python

ErrorAssertionError: expect xyz bytes, found abc bytes
Solution - You used the wrong cfg with the wrong weights again!