Tuesday, March 21, 2017

යකඩයා - 3D Printed Tracked Robot

With the collaboration of 5 members, we developed this tracked robot which called as "Yakadaya" for the competition of Uva Wellassa University robotic competition. How ever we were not able to get the trophy. But I think it is worthy to tell you how we built it.

The idea was came from one of our team members to build a tracked vehicle instead of using wheels in order to get more traction with the ground. Here is the link which we got the basic knowledge on how to build the track. Special thanks goes to "http://www.rctankcombat.com" for sharing the knowledge.

Making the Track

Among various types of track system, we selected hinge track system for Yakadaya. There were several reasons for the selection. According to the game rules, the robot should not exceed the dimensions of 30cm*30cm and 5kg of weight. So the cheapest and best method was to use door hinges for the track. 

Parts List 

1. Door hinges
2. M3 X 300 nuts and bolts
3. M3 X 80 nuts and bolts
4. Rubber sheets with texture on one face
5. Adhesive

Connect each hinge using rivets. We connect each hinge to other by using two rivets as you can see from figure 1.
Figure 1
Door hinges
The middle screw should be about 8mm long. Otherwise it will jam with the engage pins at the drive wheel. Due to the short size of the middle screw, it tends to derail from the drive wheel. You must calculate the distance between engage pins at the drive wheel. As per our calculations, we add ed 9 engage pins at the drive wheel. Figure 2 and 3 shows the solidowkrs design and 3D printed drive wheels.


Figure - 2
Drive wheel ( Solidworks Design )
Figure - 3
3D printed wheel with engage pins

We added four supporting wheels. Those wheels carry out the total weight of the robot. It is better if the number of supporting wheels can be increased which will add more traction with the ground floor. We decide the size of the supporting wheels arbitrary to fit within 30cm width according to the game rules. figure 4 shows the supporting wheel.

Figure - 4
Supporting wheel

To reduce the rotational friction and to support axial load, it used bearings between the supporting wheel and the axle. As in many tanks a 3D printed T shaped bar was used to mount supporting wheel axles.

After assembling the setup, there was a considerable amount of slack between the track and the driving wheels. To reduce the slack we had to add additional two supporting wheels to the other side as well. figure 5,6 and 7 shows upper side supporting wheel and the T shaped bars.

Figure - 5
Upper side supporting wheel


Figure - 6
Figure - 7
Figure 8 shows the assembly view of the all parts together.

Figure - 8


Figure - 9
Yakadaya






Team Members 

Supun Tharanga



Friday, December 5, 2014

Reading MMA7660 Accelerometer Data With nRF51822 BLE SOC

In this post I will describe you how to connect MMA7660 accelerometer to nRF51822 ,how to use the interrupts and gestures and how to read accelerometer data via UART module in  NRF51822.

I'm using nRF Development Kit which includes two nRF51822 chips which are mounted on PCB with a matched antenna.The kit also includes a compact nRF51822 USB dongle that can act as a Bluetooth low energy master emulator when developing Bluetooth low energy applications. Unfortunately we couldn't buy a nRFgo Starter kit. So I will describe how to program the nRF chip without a nRFgo Starter Kit.

Connect pin2 and pin3 together and connect them to 3.3V in K1 header. Then find a ground signal from the board  (see P5 header) and connect it to the GND of the power source.

Initializing UART

To read the data via UART module I used USB to Serial converter module which can be easily buy from ebay. But in my next post, I will describe how to read data via BLE module in the chip. Before using the uart module you must configure the baud rate , hardware flow control and pins.

I did not use any hardware flow control. So I set HDFC to false.

     #define RX_PIN_NUMBER  11
     #define TX_PIN_NUMBER  9
     #define CTS_PIN_NUMBER 10
     #define RTS_PIN_NUMBER 8
     #define HWFC           false

Set the baud rate to 9600.

Initializing I2C


MMA7660 accelerometer module is specially designed for identify gestures. It communicates with the micro controller via I2C interface. So we must activate the I2C interface of nrf51822 SoC. In order to do so, twi_hw_master.c file should be imported to your workspace. By calling "twi_master_init(void)" function in the above C file,we can initialize hardware I2C interface of the chip. By default SDA and SCK pins are 24U and 25U. By reading the data sheet of accelerometer module you would get better understand how it communicates with external micro controller via I2C interface. In the data sheet they have mentioned the I2C frequency the accelerometer works with.

There are some issues with I2C interface. Most of the time devices will not communicate properly if the connections between them are loos. Connecting wires should shorter as possible. 

SDA and SCL pins should be connected to pull up resisters. In the breakout board I bought from ebay got those pull up resisters. So I was able to connect the breakout board's SCL and SDA pins directly to the chip.

So we have done the basic setup to communicate with accelerometer and get data out from it.

MMA7660 Register Settings 


XbotiX- 2014 University of Ruhuna Robotics Competition Winners




XbotiX robotics Competition was held by University of Ruhuna. Among more than 40 competitors, We were able to win the Trophy...

Wednesday, April 30, 2014

Reading Serial Port Data & Plotting Gray Image in Matlab

I my previous post I connected a OV7660 camera module to STM32F4 Discovery board. Then I was needed to display the data transmitted by micro controller to PC as an Gray scale image. To do that I use Matlab. Using Matlab reading a serial port is easy, but you must get familiar with matlab.

My micro controller sends data as bytes (0-255) to PC which indicating intensity values of each pixel in image. I pick those bytes by reading the relevant serial port in matlab. I suggest you to get familiar with matlab Serial functions before looking at the below code .

This code containes only few lines, but it does much work to read and display bytes as an image.


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
clear all
s = serial('COM1');
s.BaudRate = 921600;


%get(s);

image = zeros(70,80);
row =1;
col = 1;

fopen(s);
pix = fgetl(s);

while str2double(pix)~= 256
    pix = fgetl(s);
    
end
while str2double(pix)~= 300
    pix = fgetl(s);
    
end

for i = 1:70*80
 pix = fgetl(s);
 
 %class(str2double(pix));
 image(row,col) =str2double(pix);
%image(row,col) = 255;
 if  mod(i,80) == 0
     row=row+1;
     col = 0;
 end
 col=col+1;
end
fclose(s);
%figure()
colormap(gray);
imagesc(image);


    

Following video presents how this code works. Each and every time pressing the Run icon, It will show the image captured by camera.


Comments are warmly welcome!

Monday, April 28, 2014

STM32F4 Discovery Board + OV7660 or OV7670 Working Code

Hello all,

This post is about on how to get data from  OV7660/OV7670 camera module by connecting to STM32F4 Discovery Board. first of all I would like to introduce you following posts on connecting OV7670 camera module to a micro controller which were really helpful for me to become success.

  • http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html
  • http://embeddedprogrammer.blogspot.com/2013/01/demo-stm32f4-ov7670-qserialterm.html
  • forum
I must thankful for the above posts which were really useful. 

Okay, Lets get to work!

Before you are going to do this project I recommend you to read the data sheets and reference manuals of OV7660, STM32F4 data sheet and STM32F4 Reference manual. It is not a good practice for a person who is willing to gain his knowledge on embedded systems to copy and pasting a code in internet and make it to work. What is really valuable is practicing to read data sheets and understanding how they work.

Above mentioned blog posts have clearly mentioned how camera module works. The difference between OV7660 and OV7670 is ,OV7670 has more options like scaling the image as user wanted,register values  etc... . The behavior of working is same for both the camera modules.

I will explain how I became success step by step

STEP 1

Before doing all the things you must give a clock to camera module in order to work. Without giving a clock it is a dead module. I was able to connect this camera module to both STM32F103 and STM32f4 Discovery board. I shift to discovery board because it is unable to get data at higher speeds since no DCMI interface is available on that microcontroller.
STM32F4 is more powerful than F103. It is having DCMI and DMA modules. So the speed is really good.
To get a clock out from your microcontroller,just search on microcontroller's data sheet as MCO.
You can see what is the MCO pin in your microcontroller. In discovery board I used PA8 to get clock out. Get the data sheet of STM32F4 Discovery board and search on PA8. You will see what PA8 can do. We must set that pin as MCO in configuration code. Following is the code for it.


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
void MCO1_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;

 RCC_ClockSecuritySystemCmd(ENABLE);

 /* Enable GPIOs clocks */
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
 
 GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_MCO);
  
 /* Configure MCO (PA8) */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  
 GPIO_Init(GPIOA, &GPIO_InitStructure);

 RCC_MCO1Config(RCC_MCO1Source_PLLCLK, RCC_MCO1Div_4);
}


You must check the clock is worming correctly using a logic analyzer or a oscilloscope before move to next step.

STEP 2

Next is to configure the camera as we want. Omnivision has used SCCB interface to configure the camera. Seems like SCCB is almost same as I2C. But I couldn't get to work with I2C. By changing some commands I was able to communicate with the camera. following is the code for SCCB interface, It is worked well for me. If anything need to be changed, please let me know. Your ideas are warmly welcome!


1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
#include "stm32f4xx.h"
#define ONE_BYTE_REG_ADDR 0x01
#define TWO_BYTE_REG_ADDR 0x02

void Hardware_InitI2C(void) 
{
 
 GPIO_InitTypeDef GPIO_InitStructure; // this is for the GPIO pins used as I2C1SDA and I2C1SCL
 I2C_InitTypeDef I2C_InitStructure; // this is for the I2C1 initilization
 
 /* enable APB1 peripheral clock for I2C1*/
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
 
 /* enable the peripheral clock for the pins used by
  PB6 for I2C SCL and PB9 for I2C1_SDL*/
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); 
 
 /* This sequence sets up the I2C1SDA and I2C1SCL pins
  * so they work correctly with the I2C1 peripheral
  */
 GPIO_StructInit(&GPIO_InitStructure);
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; // Pins 10(I2C1_SCL) and 11(I2C1_SDA)
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // the pins are configured as alternate function so the USART peripheral has access to them
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;// this defines the IO speed and has nothing to do with the baudrate!
 GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;// this defines the output type as open drain
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// this activates the pullup resistors on the IO pins
 GPIO_Init(GPIOB, &GPIO_InitStructure);// now all the values are passed to the GPIO_Init() 
 
 
 /* The I2C1_SCL and I2C1_SDA pins are now connected to their AF
  * so that the I2C1 can take over control of the
  * pins
  */
 GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1); //
 GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);
 
  /* Configure I2C1 */
  I2C_StructInit(&I2C_InitStructure);
  I2C_DeInit(I2C1);
 
  /* Enable the I2C peripheral */
  I2C_Cmd(I2C1, ENABLE);
 
  /* Set the I2C structure parameters */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = 0x00;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_ClockSpeed = 100000;
  /* I2C Peripheral Enable */
I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);
  /* Initialize the I2C peripheral w/ selected parameters */
  I2C_Init(I2C1,&I2C_InitStructure);
 I2C_Cmd(I2C1, ENABLE);
     

}

int i2c_send_data(u8 slave_addr, u16 reg_addr, u8* data, u8 addr_len)
{
  int timeout = 0x7FFFFF;
  int ret = 0;
         /* send i2c*/
  I2C_GenerateSTART(I2C1, ENABLE); 
  while( !I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));  
  {
   if ((timeout--) == 0) 
   {
    ret = 1;
    goto exit;
   }
  }
  I2C_Send7bitAddress(I2C1, slave_addr, I2C_Direction_Transmitter);  
  while(!(I2C1->SR1 & (1 << 1))); // check ADDR bit
  {
   if ((timeout--) == 0) 
   {
    ret = 2;
    goto exit;
   }
  }
  while(!(I2C1->SR2 & (1 << 2)));   // check TRA bit
  {
   if ((timeout--) == 0) 
   {
    ret = 3;
    goto exit;
   }
  }
 
  /* 2 byte reg address */
  if(addr_len == TWO_BYTE_REG_ADDR)
  {
   // MSB
   I2C_SendData(I2C1, (0xFF & (reg_addr >> 8)) );   
   while(!(I2C1->SR1 & (1 << 7))); 
   {
   if ((timeout--) == 0) 
   {
    ret = 4;
    goto exit;
   }
   }
     
   // LSB
   I2C_SendData(I2C1, (0xFF & reg_addr));   
   while(!(I2C1->SR1 & (1 << 7)));
   {
   if ((timeout--) == 0) 
   {
    ret = 5;
    goto exit;
   }
   }
  
  }
  /* 1 byte reg address */
  else 
  {
   I2C_SendData(I2C1, (0xFF & reg_addr));   
   while(!(I2C1->SR1 & (1 << 7)));
   {
   if ((timeout--) == 0) 
   {
    ret = 6;
    goto exit;
   }
   } 
  }

  I2C_SendData(I2C1, *data);  
  while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  {
//   if ((timeout--) == 0) 
   {
    ret = 7;
    goto exit;
   }
  } 

                exit:  
  I2C_GenerateSTOP(I2C1, ENABLE);  
  return ret;
}

int i2c_receive_data(u8 slave_addr, u16 reg_addr, u8* data, u8 addr_len)
{
  int timeout = 0x7FFFFF;
  int ret = 0;
   /* send i2c*/
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
  I2C_GenerateSTART(I2C1, ENABLE); 
  while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
  {
   if ((timeout--) == 0) 
   {
    ret = 1;
    goto exit;
   }
  }
  
  I2C_Send7bitAddress(I2C1, slave_addr, I2C_Direction_Transmitter);  
  while(!(I2C1->SR1 & (1 << 1))); // check ADDR bit
  {
   if ((timeout--) == 0)    
   {
    ret = 2;
    goto exit;
   }
  }
  
  while(!(I2C1->SR2 & (1 << 2)));   // check TRA bit
  {
   if ((timeout--) == 0) 
   {
    ret = 3;
    goto exit;
   }
  }
  
  /* 2 byte reg address */
  if(addr_len == TWO_BYTE_REG_ADDR)
  {
   // MSB
   I2C_SendData(I2C1, (0xFF & (reg_addr >> 8)) );   
   while(!(I2C1->SR1 & (1 << 7))); 
   {
   if ((timeout--) == 0) 
   {
    ret = 4;
    goto exit;
   }
  }
     
   // LSB
   I2C_SendData(I2C1, (0xFF & reg_addr));   
   while(!(I2C1->SR1 & (1 << 7)));
   {
   if ((timeout--) == 0) 
   {
    ret = 5;
    goto exit;
   }
  }
  }
  
  /* 1 byte reg address */
  else 
  {
   I2C_SendData(I2C1, (0xFF & reg_addr));
   while(!(I2C1->SR1 & (1 << 7)));
   {
   if ((timeout--) == 0) 
   {
    ret = 6;
    goto exit;
   }
  }
  }

  I2C_GenerateSTOP(I2C1, ENABLE);
  I2C_GenerateSTART(I2C1, ENABLE);
  while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
  {
   if ((timeout--) == 0) 
   {
    ret = 7;
    goto exit;
   }
  }
  I2C_Send7bitAddress(I2C1, slave_addr, I2C_Direction_Receiver);
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); // check ADDR bit
  {
   if ((timeout--) == 0) 
   {
    ret = 8;
    goto exit;
   }
  }
    
  
  I2C_AcknowledgeConfig(I2C1, DISABLE);
                /* Send STOP Condition */
                I2C_GenerateSTOP(I2C1, ENABLE);
  
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
  {
   if ((timeout--) == 0) 
   {
    ret = 10;
    goto exit;
   }
  }
  
  *data = I2C_ReceiveData(I2C1);
  I2C_AcknowledgeConfig(I2C1, ENABLE);
  return ret;
  
exit:
  I2C_GenerateSTOP(I2C1, ENABLE);
  return ret;
}

To write to and read from  the camera i defined two functions...

Monday, April 21, 2014

Accelerometer Data Filtering Using Low Pass filter


      While you are working with accelerometers you may have noticed that the data are too noisy. To use those values to your application, definitely you will have to filter out them. So what is a filter, you may heard of a water filter,which is used to remove germs and unwanted materials in water. Using a filter, we will be able to get more precise data from accelerometer. There are many filters which can do data filtering. In this post I'm going to show you how to filter out accelerometer data using a simple low pass filter.

Following figure (fig.1) shows you the data from  MPU6050 accelerometer without(blue line) and with(white line) filtering. The accelerometer was mounted on the middle of a quadcopter. So when the motors are rotating accelerometer data got more and more noisy(fig.2). I felt how could I deal with these kind of very very noisy data at the first time I saw accelerometer readings come out from the accelerometer.


                                                                             fig.1
                                                                   

                                                                            fig.2


As you can see from above images, blue line is very noisy while white line is low nisy because it has been filter out by a low pass filter.

I used STM32F103RBT6 microcontroller to configure and read data through I2C interface. you can connect two MPU6050 modules to same I2C line. I hope to add a new post on how to configure and read data from MPU6050 in near future.

Some accelerometr modules have its inbuilt low pass filters, They can be configured to out put only the filter out data. MPU6050 is an example for that. If you are combining accelerometer and gyro to get precise angle, you have to use kalman filter or Complimentary filter. But in MPU6050 there is an inbuilt Digital Motion Processor capable of processing 9 axis motion fusion algorithms.

But in this post I use a low pass filter to filter out accelerometer data from accelerometer.

Below is the code for a digital low pass filter.

void accelerometer_Smooth (void)
{
    
    static int element=0;
    static int n,k = 0;
    static double x_Low,y_Low,z_Low,x0,y0,z0,z02 = 0;
    
    /* Low pass filter */
    
  const float dt = (1.0 / 50.0);
  const float RC = 0.35;
  const float alpha = dt / (RC + dt);

    
   
  x_Low = ((alpha * axData[0]) + (1.0 - alpha) * x0);
  y_Low = ((alpha * axData[1]) + (1.0 - alpha) * y0);
  z_Low = ((alpha * axData[2]) + (1.0 - alpha) * z0);  
  x0 = x_Low;
  y0 = y_Low;
  z0 = z_Low;

}

You can change the values of dt and RC according to the rise time you want.

axData[0],axData[1],axData[2] are global variables which contains the new accelerometer data without filtering.

axData[0] = x axis acceleration come out from accelerometer without filtering.
axData[1] = y axis acceleration come out from accelerometer without filtering.
axData[2] = z axis acceleration come out from accelerometer without filtering.

By using a median filter and a kalman predictor we can obtain the same results as low pass filter. I will post about them in near future.

Serial chart was really helpful to examine data coming out from accelerometer. You can download the software from here.



Friday, August 2, 2013

How to Program Arduino Pro Mini With USB to UART Serial Converter Module


How to start with Arduino Pro Mini and USB to UART Serial Converter Module

Arduino is very popular within electronic hobbyist and robotics due to its simplicity.Freely you can download all the data of arduino from http://www.arduino.cc/
Arduino software,The hardware reference designs and all the libraries are free to download from their site.

Arduino Pro Mini is a small version of Arduino. Original Arduino Pro Mini is about $18. Also you could buy one from ebay for lower prices.To program the board you need a USB to UART Serial Converter Module if you are going to program it using your laptop since modern laptops doesn't include any serial port.When you are ordering Arduino Pro Mini remember to order USB to UART Serial Converter Module which you can easily buy from ebay.




Monday, July 15, 2013

Techfest 2012 IIT Bombay


Techfest is the Asia's Largest Science and Technology festival, with more than 92,000 people in attendance and a reach of over 2200 colleges across India and over 500 overseas.

Sri Lankan Robotics Challenge 2012 - 2nd runners up


                                       

Sri Lankan Robotics Challenge (SLRC) ,the Sri Lanka's biggest robotics competition was held in December 2012 at University of Moratuwa,Sri Laka.We won the third place from all the competitors all around the country.Got selected for Techfest 2012 at IIT Bombay,India.

Image zooming with MATLAB Sample Codes


Here I will explain two algorithms of image processing.They are Nearest-neighbor interpolation and Bilinear interpolation.When an image is zoom its' dimensions are larger than the original image.To fill the extra pixels' intensity levels of the zoom image we can use above mentioned algorithms.

Nearest neighbour Interpolation

Following picture shows original image is scaled twice without filling intermediate pixels and after filling intermediate pixels respectively





In Nearest neighbor algorithm intensity value of the v(x,y) is assigned to the nearest intensity value of the original image f(x,y).You can easily understand the logic behind this by referring following image.


You will understand the algorithm furthermore by studying following matlab code.



Original Image before zoom

Zoom Image using Nearest-Neighbor Algorithm


Bilinear Interpolation


If you familiar with linear interpolation, then it is easy to understand what is bilinear interpolation. So lets look what is linear interpolation by going through this link.


Now you are familiar with linear interpolation. It is use to find a point between two points in a two dimensional space. As the word says bilinear interpolation is used to find a point of between two functions on a 2D grid.




Following is the Matlab code for image zooming using Bilinear Interpolation.

clc
clear all
close all
a=imread('Slanka.jpg');      %import image"y.jpg"

[row col d] = size(a);  %3 dimentional array
zoom=3;                 %zooming factor
zr=zoom*row;
zc=zoom*col;

for i=1:zr
    
    x=i/zoom;
    
    x1=floor(x);
    x2=ceil(x);
    if x1==0
        x1=1;
    end
    xint=rem(x,1);
    for j=1:zc
        
        y=j/zoom;
        
        y1=floor(y);
        y2=ceil(y);
        if y1==0
            y1=1;
        end
        yint=rem(y,1);
        
        BL=a(x1,y1,:);
        TL=a(x1,y2,:);
        BR=a(x2,y1,:);
        TR=a(x2,y2,:);
        
        R1=BR*yint+BL*(1-yint);
        R2=TR*yint+TL*(1-yint);
        
        im_zoom(i,j,:)=R1*xint+R2*(1-xint);
    end
end
imshow(im_zoom);

Original Image before zoom

After zooming Bilinear Interpolation





Saturday, June 15, 2013

How to make a simple line following robot





I'll explain how to build a 'Line Following Robot step by step.

                                         
It is better if you have any basic knowledge about electronics,such as reading resister color code,soldiering, familiar with circuit symbols,polarity of capacitors,diodes etc..

If you are not familiar,then use following links to learn about them before read this page

As the first step of line following robot,we have to make the chassis of it.
Following conditions should be considered before making the chassis of the bot.
  1. Weight.
  2. Moment of  inertia.
  3. Center of gravity.
  4. Wheel size.

Since we are planing to make a normal line following robot,we do not need to consider above conditions heavily.
  1. Weight   :-It is better if the robot is light weight.Because it is easy to control when its' weight is low.Also it helps to save energy of battery.
  2. Moment of inertia  :-It is hard to control robot movements when moment of inertia is high.so keep heavy items such as batteries,motors etc as close to robot center as possible.
  3. Center of gravity  :-To accelerate/decelerate robot weight should on its tires.If there is no weight on tires -> no grip.So center of gravity should close to the axle of wheels.C.G. should be low as possible.You can use Lighter or slimmer motors to lower c.g.
  4. Wheel size  :-Bigger wheels higher the c.g.smaller wheels lower the c.g.Keep wheels & shaft as light as possible.Wider wheels are hard to turn.
Lets select motors and wheels,
  • Motor   :-This is a 500rpm geared DC motor.You can use this kind of motor or any kind of 12v DC geared motor.


Thursday, March 28, 2013

Connecting PLC to PC


Hi all,Since I'm new to PLC  world I will not explain about how PLC work in this article.But I'll publish new articles when I get to know about them more and more.

In this article I will show you how to connect PLC to your computer to read its register values.This tutorial will only work for Xinje XC-6TCA .PLC is mainly use in automation industry due to its reliability and good performances in harsh environments.Ladder logic is use to program PLC.It is easy to understand than any other programming language.


I recommend you to read the manual of the PLC before working with any PLC,because it gives us all the information about functions of it.

There are two ways to communicate with PLC and PC.They are Free communication and MODBUS communication.In this article I will only show you how to communicate with Free communication.

Step -1
Connect PLC to the PC through data cable provided.
If your cable is PS2 to serial DB9 cable,it is unable to connect it directly to    the   your laptop.You have to connect it to the laptop using serial DB9 to USB  cable.

Step -2
There are two ports in PLC. Configurations of port 1 cannot be changed.COM 1 (Port1) is the program port, it can be used to download the program and connect with the other devices. The parameters (baud rate, data bit etc.) of this COM port are fixed, can’t be re-set.


COM 2 (Port2) is communication port, it can be used to download program and connect with the other devices. The parameters (baud rate, data bit etc.) of this COM port can be re-set via software.

I'am going to use port1 to download the program and port2 to read the data from PLC.

Open software,go to Configurations select serial port 2.Note that not to change settings of port1.




Step -3
Change serial port2 settings as following image

set communication mode to User Protocol
Baud rate to 9600
and the others as in the image
Then click Write To Plc

Step -4
Download your program to PLC and run it.

Step -5
Disconnect power and remove the cable from port1,connect it to port2 to read data from PLC according to your program.
Re power PLC to read data from PLC.If you don't have any serial port moniter. microc will help you to show the data comming from PLC.


Step -6
Open microc software ,then open USART monitor,set the values as you set into the PLC.Then click connect.you are done!

Tuesday, October 30, 2012

Homemade Pickit2 lite

You may have programmed PIC using microchip pickit-2,It is a easiest way of programming microchip programmable ICs.I will show you how to make your own pickit 2 in a easiest way.Following site helped me to create the pickit 2 lite.Here is the link to the site-http://dlmkerode.tripod.com/PICKIT2_1.htm

I will show you,how I made it in home step by step.

1. Preparing the PCB 

At first time,I made pickit on a vero board.I realized that it can use to programme PIC10F, PIC12F5xx, PIC16F5xx, PIC12F6xx, PIC16F, PIC18F, PIC24.Then I moved to create pickit2 on a PCB.

#schematic of the pickit2 lite is as follows 

Using Proteus,Eagle cad or any cad software you can make the PCB layout of the schematic.I used following technique to get the pcb layout to copper plated plate.

#pcb layout of the pickit2



2.Inserting components and soldering

There is an inductor on the circuit which is hard to find in local market .I ordered them from ebay.It took only a week to receive me.

If you cant find an inductor in local market,don't worry there is an alternative in your old phone charger,radio or in DVD player.Any inductor which having an inductance of more than 330uh, can be used to replace the 680uh indutor in the above schematic.


Use a 28 pin IC base to mount the pic 18F256 to the circuit.Never solder it directly to the circuit board.Heat generated from by the soldering iron can damage the IC. Another important thing is,data cable should not be more than 1m.(sometimes may work).Because I haven't inserted the ferrite bead which is used to suppress high frequency noise in electronic circuits.