samedi 17 novembre 2012

Odometry


When we are dealing with an autonomous mobile robot, the first thing comes to our mind is how this robot will locate it self while moving.

There are several methods to do that, But in this article I'm going to talk about Odometry ,or sometimes known by "Dead reckoning", for a two wheeled robot.

The main idea about Odometry is to use a foreknown distance unit in a cumulative way.
Let's get to this example, let's suppose that an adult step is about 1 meter. If this adult walks five steps then he walked 5 meters.
In an orthonormal reference (x,y) if this guy starts at (0,0) moves 5 steps in the direction of Y then he's new position is updated and it's (0,5).
If later he moves 5 steps in the direction of X he new position will be updated compared to he's last position so he's new position is  (5,5).
Let's suppose that the adult turn him self while walking and instead of walking 5 steps towards Y then 5 towards X.
He starts with an angel Theta =45° and goes 7 steps ( Distance=~ sqrt(50))
In this case we can tell his X and Y position with simple trigonometry.

X=Distance*Cos(Theta) =~ 5
Y= Distance*Sin(Theta) =~ 5
(X,Y) = (5,5)










Back to robotics Now :p
If we suppose that these guy is a two wheeled robot the measurement of the foreknown distance would be extracted from sensors like quadrature encoders IMU or something else.

We need to know the position of the robot in real time, that means every small sampling time (10 ms is good) we need to recalculate the distance the robot traveled and the angel it did to calculate it's new position. After that we add this position to last calculated position and so on. just like we did with the guy.

The next diagram will explain how to deal with an Odometry in real time with a two wheeled robot using quadrature encoders.

The next code explaining how to implement Odometry in real time in an arduino.
In this code I used a software interrupt of 120ms (toooo much) get more assured that arduino is not for real time application

  l=0.5*(positionRight+positionLeft);
  Theta=positionRight-positionLeft;
  vitesse=l-lastL;
  lastL=l;
  Theta%=2292; //2292 is the number that corresponds to 2*pi
  double Theta_r=(double)Theta*0.002734;//Theta in radian
  deltaX=-vitesse*sin(Theta_r);
  deltaY=vitesse*cos(Theta_r);
  x+=deltaX;
  y+=deltaY;


Cheers :)



samedi 13 octobre 2012

Doing multiTask application using an STM32 using CoOS and stm32 discovery board

Have you ever wanted to do the same thing at the same time to win more time?! Cleaning the house while doing your homework :D that would be very helpful.
Working with embedded systems made crucial to deal with different tasks at the same time while having (most of the time) only one CPU that can handle only one task at a time.
To schedule between different tasks, embedded systems use RTOS (real time operating systems) which is in same how a little software is responsible to manage all the different tasks that want to use the CPU.

I found lately a wonderful tool to programme STM32 microcontrollers which is CoIDE from Coocox. It's based on the eclipse which makes programming the STM32 a lovely journey you don't want to miss.
 You can download Cocenter from here which contains all the other great software that come with CoIDE like CoOS which is a free RTOS that we will use it in this Tutorial.


So... Our mission is to blink a led in an infinite task and to watch for the value of the button in an other task.
I used the STM32 discovery board that contains an STM32F100RB.


After creating a project in your CoIDE, make sure to add the GPIO, RCC and CoOS libraries from the repository.

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include <CoOs.h>

#define STACK_SIZE_DEFAULT 512

OS_STK task1_stk[STACK_SIZE_DEFAULT];
OS_STK task2_stk[STACK_SIZE_DEFAULT];

void initializeBoard(){

        GPIO_InitTypeDef GPIO_InitStructure_Led;
        GPIO_InitTypeDef GPIO_InitStructure_Button;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//for LEds
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//for buttons

        GPIO_InitStructure_Led.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
        GPIO_InitStructure_Led.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure_Led.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_InitStructure_Button.GPIO_Pin = GPIO_Pin_0;
        GPIO_InitStructure_Button.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_InitStructure_Button.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_Init(GPIOC,&GPIO_InitStructure_Led);
        GPIO_Init(GPIOA,&GPIO_InitStructure_Button);

}

void task1 (void* pdata){
        while(1){
                GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET);
                CoTickDelay (10);
                GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_RESET);
                CoTickDelay (10);
        }
}

void task2 (void* pdata){
        int i;
        while(1){
                i = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);
                GPIO_WriteBit(GPIOC,GPIO_Pin_9,i);
        }
}

int main(void)
{
        initializeBoard();
        CoInitOS();
        CoCreateTask(task1,0,0,&task1_stk[STACK_SIZE_DEFAULT-1],STACK_SIZE_DEFAULT);
        CoCreateTask(task2,0,1,&task2_stk[STACK_SIZE_DEFAULT-1],STACK_SIZE_DEFAULT);
        CoStartOS();
    while(1);
}




mardi 25 septembre 2012

vendredi 24 août 2012

Week 5-1 Point Rotation



In this class we learned the final type of rotations : the point rotation
We need this kind of rotation when the robot must change its angle without changing its position in other words the robot rotate itself.
To make a robot turn a point rotation the wheels must rotate with the same speed but with different directions
This kind of rotation is very helpful in sharp angles <30°
To illustrate this kind of rotation we made a circuit which look like the heart beat:
The center of the robot must follow the circuit with no tolerance.

To apply a point rotation with the nxt-g just drag the steering to the extreme right or left then set the desired duration.

Week 4-2 Parallel rotation


The second type of rotation that we will handle is parallel rotation:

This is the most common way of rotation for four wheels vehicles like cars.
The main idea is to turn the two wheels with different speed, so for a period of time the distance traveled by the faster wheel is more than the slower wheel as a result we don’t have straight movement but curve movement.
To apply this kind of rotation in a bidirectional robot like we have we used this circuit.

The circuit is very similar to a circle.
Ls will try to apply the swing rotation in this circuit but they will find it very painful, the great surprise I had that ls find by themselves the solution which lays in the Steering parameter we already see in the move block which is responsible for turning a bidirectional robot like a bicycle (well this is the example I used may be you will find better examples :=))

You can try other circuit like a snake body circuit for example.

Week 4-1 Swing rotation


Turning your robot is a crucial and standard task while commanding your robot to move, it is very rare to find a circuit with no turns.)
For bidirectional robot like the taskbot we made there are three possible ways of rotations;
Swing rotation
Parallel rotation
Point rotation
In this class we will talk about the swing rotation:
This kind of rotation is the simplest the main idea is when you want to turn left or right just stop a wheel and let the other wheel keep running.

For example, if we want to turn right, all what we have to do is to stop the right  and command the left wheel to move so the robot will turn right.
If we want to turn left,.. I guess you got it J
This kind of rotation is mainly used for turns like 90° or less in a straight circuit (a circuit with no curves)
To illustrate this example you should made a circuit like bellow and then ls will create the algorithm needed to follow this circuit.

First ls should create their first flowchart so you will help them:

To create a swing rotation using nxt-g put 2 move blocks.
In the first move block you select one portàthe motor witch you want to block or stop
Next of it in the second move block select one port -> the motor witch you want to run

dimanche 19 août 2012

Week 3-2 Move the robot to an exact position

In this class we discussed one of the major problems in the mobile robots field witch is as the title says how to move your robot to an exact distance nothing more and nothing less.

Moving the robot to a known position is crucial in some cases, so in this class ls will learn how to convert wanted distance measured with a measuring tool to an order in the move block.

Every group take a wheel and move the wheel from a start point one rotation. Then move the wheel from the exact start point twice.
ls will know that the number of rotation traveled by the wheel is one responsible for how much the robot will move.
Now try with smaller wheel do one rotation then 2, ls will notice that even the wheel traveled the same unit it doesn't travel the same distance as the bigger wheel so here you introduce to them the principal of calculating the circumference.

Measuring circumference of the taskbot wheel:
Start by measure the circumference of the robot practically using standard measuring tools.
Then write the result for each group.
ls will notice that the results are not the same so there are an incertitude factor during the measuring.
The solution is to calculate the circumference using already knowing informations:

We used the famous formula : ( D = 2.25 inche/5.751 centimeters , Pi = 3.14)
C = Pi * D
C= 17.49 cm

A mission to 59.5 cm:
This is an example to demonstrate this new way for using the move block. 
So our objective is that the robot go exactly 59.5 cm 
We have to calculate the number of rotations needed to put in the move block.
The operation is simple: we divide the desired distance on the circumference of the wheel.
number of rotations needed = 59.5/17.49 = 3.4
So the number of rotations needed is 3.4


samedi 18 août 2012

Week 3-1 The Move block


After you make sure that the ls teams finished their taskbot, you could ask this question to your ls:
Now what should this robot do?
you will definitely hear that robot should MOVE.
Yes !! the robot has two wheels so it has to move.
To start the ls must guess that there is something missing in there robot witch is a program to command this robot--> So we open the NXT-G program (that comes with the lego mindstorm kit)
*ls create a project with there group name
*save the project in a descent place in the hard drive
 The front view
NXT-G is a wonderful environment for developing software and to discover programming. it uses a graphical language witch based on the flowchart concept.
*Ls localize and drag and drop the move blok into the programming area.
After That it's time to configure the move block.

Move block general configuration:

*ls click on the move block a configuration panel opens in the bottom of the windows.
Ports: are the ports where we connected our motor
Direction: a robot can move forward, backward or stop
Steering : give the example of the bicycle , how can a cyclist control the rotation of its bicycle. We will discuss this function later.
Power : explain the direct relation between POWER ENERGY and SPEED.
Duration: this parameter specify how long the robot will execute this block before going to the next block in the flowchart.
Next action: witch is a field that tells what to do after finishing this block. The robot will stop immediately execute breaks plus stopping power or will take it's time while stopping with just stop its power.

Application:
Make the robot move :))))




Week 2-2 The task bot


Hello,
In this class I have strongly insisted on the power of TEAM WORK!
TEAM WORK are not just  a couple of beautiful words. They have a big and a crucial meaning in the robotics engineering because simply no one can progress while working only with him self no helps no suggestions that's totally a big failure in the robotic world and this person simply wont  progress in his technical and social experience.
Robotics engineering must be done in groups of 2 or more even that I have enough kits for each student I chose to divide them into 5 groups of 3. every group has its table, desktop and it's lego mindstorm kit.

There are another essential factor  in robotics witch is competitions. So this groups or teams they will be always competing to each other to create a stressed work climate so the ls will be used to work and find solutions under pressure witch is the usual state of an engineer.

In this class ls teams must build there first robot with the mindstorm kits. The first robot is the fairly famous taskbot.
Taskbot is a 2 wheel drive robot with one guide wheel  an NXT brick and we can easily add sensors to its structure.

This pdf describe the building instructions:
http://www.education.rec.ri.cmu.edu/content/lego/building/build_shows/taskbot.pdf

make sure that all the groups finish there robot on time so you can move to the next course. 

Week 2-1 Parts identifications


In this class we opened for the first time our lego mindstorm kits that you can buy from here and discovered what's in there.
For this session I used this html page : http://www.education.rec.ri.cmu.edu/previews/robot_c_products/teaching_rc_tetrix_preview/fundamentals/nxt_hardware/parts/parts.html
It contains all the parts within a lego mindstorm kit and clearly devised them into sections.
During the class ls with the help of their teacher must identify each part and have a scratch on the surface idea about its functions.
For example in the electronics section start to identify first each of the parts and let the ls guess what can this part do.
At the end of this class
*ls must differ between the two main components of a robot (the mechanical structure and the electronics )
*ls must identify the main electronic component (the NXT) as it's the mind of their future robots?
*ls must know what's a sensor and what's an actuator witch one is an input and witch one is an output (whitch one is for collecting informations and witch one is for executing orders) for the nxt brick.

mercredi 15 août 2012

Week 1-2 The flowchart


Hello,
In our second class this week, we talked about a strong concept in programming nxt based robots witch is the flowchart. So what's the flowchart and why we need to learn it ? And how could this thing help us?

Try to start with an activity and a simple question:
The activity was to stand from one place and go drink a glass of water witch placed on a table three steps away.
The question then was what actions would a person do for making this specific task?

At first kids will try to guess (with the instructor help ) the motions needed to be done by a person and give a general idea about it.
something like this: stand -->walk --> drink the water.
After they all convinced of this task dividing ask this questions:
Can we walk before we stand?
Is it possible for us to drink water while we still walking?
So kids will realize that to get to our goal witch is drinking water we need to follow the exact order of this tasks.
We have already divided our general task to three sub tasks. from go drink water to stand -->walk --> drink the water.
No The second question:
Imagine that this person is a robot what are the other sub tasks needed to be done to "stand" to "walk"  and to "drink water".
Now every ls should start to guess all the little tiny tasks that needed to be done in order to achieve the bigger tasks.
Let them test and think for 30 minutes, then take their trials and evaluate every trial.
examples of trials you could find:
stand : move both legs together
walk: move first leg-->move second leg-->move first leg --> move second leg
drink: put forward right arm--> catch the glass --> move right arm to mouth --> DRINK WATER

some trials would be a little deeper than others, but the deeper the better.
There is no course about flowchart for now, they have to get the idea about ordering and dividing tasks to smaller tasks to achieve their goals.
The design of the flowchart will be studied in parallel with other stuff in the future.

dimanche 12 août 2012

Week 1-1 Introducing the world of robotics


Hello,
In the first week start to talk about robotics in general.
Try to start by asking some questions:

what's a robot?

{The robot is a structure that do something (this is very general) .
You could try this: robots are mechanical and electrical structures that moves.
Or you can just show some robots pictures and/or videos (iRobot, big dog, nao, )
In this specific question the little students (that I will call them "ls" from now) must know that robots are not just humanoids.

what can a robot do ?

Here ls will try to guess how can the robot be useful. The general answer would be helping mom in the kitchen due to Hollywood stuff.
Show some videos, and help them guessing the functions of a robot.
A robot can move, can transport things.
A robot can walk,  can detect obstacles etc...

What they shouldn't do?

Here you must insist that robots can not replace humans in emotional situations.
Ls must realize that robots only do what we order them to do nothing more and nothing less.
Give some examples; can robot replace your mom or dad?
Can robot be happy for you ?
Can we motivate a robot to improve his abilities ?etc...

Where can we find robots?

Home, industry, medicine, military, space, games, etc....

Are we really need robots?

This is the most important questions:
try to listen to your students guessing the answer while giving them some hints.
Robots are made to replace human in dangerous spots (give the example of curiosity robot) , to do a boring work all day. Robots are used to make precise measurements where error is not tolerated and many other stuff.
So the main idea is : Robots exist to help humans and not replace them!

mardi 31 juillet 2012

Integrating a SQLite database in your c# application

Hello all,
I needed in one of my project to store data in a database, So as I only know Mysql I directly jump on it.
But my big problem was that I have to put all of the files in one package the thing that Mysql won't allow me to do, cause Mysql is a server database witch means that we can only connect to it and not integrate it in our application like this example . (correct me if I'm wrong please)
So I searched more and I found this little piece of jewellery System.data.sql.dll witch is a SQL based database direct link library that could be simply integrated in your C# application.
These are some tools I used to create and manage my database:
Some useful tutoriels:
using the sqlite function and send SQL queries. 
Gives a very useful class to manage data with dataGridView, inserting , updating and all those stuff
I added a method that can create data table:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Windows.Forms;

class SQLiteDatabase
{
    String dbConnection;

    /// <summary>
    ///     Default Constructor for SQLiteDatabase Class.
    /// </summary>
    public SQLiteDatabase()
    {
        dbConnection = "Data Source=REMOTES.s3db";
    }

    /// <summary>
    ///     Single Param Constructor for specifying the DB file.
    /// </summary>
    /// <param name="inputFile">The File containing the DB</param>
    public SQLiteDatabase(String inputFile)
    {
        dbConnection = String.Format("Data Source={0}", inputFile);
    }

    /// <summary>
    ///     Single Param Constructor for specifying advanced connection options.
    /// </summary>
    /// <param name="connectionOpts">A dictionary containing all desired options and their values</param>
    public SQLiteDatabase(Dictionary<String, String> connectionOpts)
    {
        String str = "";
        foreach (KeyValuePair<String, String> row in connectionOpts)
        {
            str += String.Format("{0}={1}; ", row.Key, row.Value);
        }
        str = str.Trim().Substring(0, str.Length - 1);
        dbConnection = str;
    }

    /// <summary>
    ///     Allows the programmer to run a query against the Database.
    /// </summary>
    /// <param name="sql">The SQL to run</param>
    /// <returns>A DataTable containing the result set.</returns>
    public DataTable GetDataTable(string sql)
    {
        DataTable dt = new DataTable();
        try
        {
            SQLiteConnection cnn = new SQLiteConnection(dbConnection);
            cnn.Open();
            SQLiteCommand mycommand = new SQLiteCommand(cnn);
            mycommand.CommandText = sql;
            SQLiteDataReader reader = mycommand.ExecuteReader();
            dt.Load(reader);
            reader.Close();
            cnn.Close();
        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
        }
        return dt;
    }

    /// <summary>
    ///     Allows the programmer to interact with the database for purposes other than a query.
    /// </summary>
    /// <param name="sql">The SQL to be run.</param>
    /// <returns>An Integer containing the number of rows updated.</returns>
    public int ExecuteNonQuery(string sql)
    {
        SQLiteConnection cnn = new SQLiteConnection(dbConnection);
        cnn.Open();
        SQLiteCommand mycommand = new SQLiteCommand(cnn);
        mycommand.CommandText = sql;
        int rowsUpdated = mycommand.ExecuteNonQuery();
        cnn.Close();
        return rowsUpdated;
    }

    /// <summary>
    ///     Allows the programmer to retrieve single items from the DB.
    /// </summary>
    /// <param name="sql">The query to run.</param>
    /// <returns>A string.</returns>
    public string ExecuteScalar(string sql)
    {
        SQLiteConnection cnn = new SQLiteConnection(dbConnection);
        cnn.Open();
        SQLiteCommand mycommand = new SQLiteCommand(cnn);
        mycommand.CommandText = sql;
        object value = mycommand.ExecuteScalar();
        cnn.Close();
        if (value != null)
        {
            return value.ToString();
        }
        return "";
    }

    /// <summary>
    ///     Allows the programmer to easily update rows in the DB.
    /// </summary>
    /// <param name="tableName">The table to update.</param>
    /// <param name="data">A dictionary containing Column names and their new values.</param>
    /// <param name="where">The where clause for the update statement.</param>
    /// <returns>A boolean true or false to signify success or failure.</returns>
    public bool Update(String tableName, Dictionary<String, String> data, String where)
    {
        String vals = "";
        Boolean returnCode = true;
        if (data.Count >= 1)
        {
            foreach (KeyValuePair<String, String> val in data)
            {
                vals += String.Format(" {0} = '{1}',", val.Key.ToString(), val.Value.ToString());
            }
            vals = vals.Substring(0, vals.Length - 1);
        }
        try
        {
            this.ExecuteNonQuery(String.Format("update {0} set {1} where {2};", tableName, vals, where));
        }
        catch
        {
            returnCode = false;
        }
        return returnCode;
    }

    /// <summary>
    ///     Allows the programmer to easily delete rows from the DB.
    /// </summary>
    /// <param name="tableName">The table from which to delete.</param>
    /// <param name="where">The where clause for the delete.</param>
    /// <returns>A boolean true or false to signify success or failure.</returns>
    public bool Delete(String tableName, String where)
    {
        Boolean returnCode = true;
        try
        {
            this.ExecuteNonQuery(String.Format("delete from {0} where {1};", tableName, where));
        }
        catch (Exception fail)
        {
            MessageBox.Show(fail.Message);
            returnCode = false;
        }
        return returnCode;
    }

    /// <summary>
    ///     Allows the programmer to easily insert into the DB
    /// </summary>
    /// <param name="tableName">The table into which we insert the data.</param>
    /// <param name="data">A dictionary containing the column names and data for the insert.</param>
    /// <returns>A boolean true or false to signify success or failure.</returns>
    public bool Insert(String tableName, Dictionary<String, String> data)
    {
        String columns = "";
        String values = "";
        Boolean returnCode = true;
        foreach (KeyValuePair<String, String> val in data)
        {
            columns += String.Format(" {0},", val.Key.ToString());
            values += String.Format(" '{0}',", val.Value);
        }
        columns = columns.Substring(0, columns.Length - 1);
        values = values.Substring(0, values.Length - 1);
        try
        {
            this.ExecuteNonQuery(String.Format("insert into {0}({1}) values({2});", tableName, columns, values));
        }
        catch (Exception fail)
        {
            MessageBox.Show(fail.Message);
            returnCode = false;
        }
        return returnCode;
    }

    /// <summary>
    ///     Allows the programmer to easily delete all data from the DB.
    /// </summary>
    /// <returns>A boolean true or false to signify success or failure.</returns>
    public bool ClearDB()
    {
        DataTable tables;
        try
        {
            tables = this.GetDataTable("select NAME from SQLITE_MASTER where type='table' order by NAME;");
            foreach (DataRow table in tables.Rows)
            {
                this.ClearTable(table["NAME"].ToString());
            }
            return true;
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    ///     Allows the user to easily clear all data from a specific table.
    /// </summary>
    /// <param name="table">The name of the table to clear.</param>
    /// <returns>A boolean true or false to signify success or failure.</returns>
    public bool ClearTable(String table)
    {
        try
        {

            this.ExecuteNonQuery(String.Format("delete from {0};", table));
            return true;
        }
        catch
        {
            return false;
        }
    }
    public bool CreateTable(String TableName)
    {
        try
        {
            this.ExecuteNonQuery("CREATE TABLE IF NOT EXISTS " + TableName + " ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR(100) NOT NULL);");
            return true;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
            return false;
        }
    }
}






vendredi 6 juillet 2012

Talking to an external EEPROM via I2C protocol

Hello,
you may want sometimes to save data that are too much to handle by your poor little pic, well you may thought of using an external eeprom to save all your data their,
In this tutoriel, I'm going to tell how to interface the 24LC256 eeprom with a 16F887 pic microcontroller.

I2C is a protocol that can allow multiple slaves and multiple masters to be connected in the same network, and that's pretty awsom ^^, most of the time there is only one master and many slaves, but in our case there will be one master (our PIC 16F887) and one slave our (24LC256 eeprom).
The master can communicate with only one slave at a time so how can he make a difference between his slaves?
well that's easy every slave has its unique address in the network for example our 24LC256 address has a 7 bit address that's equal to in binary 0B1010A1A2A3,
A master in a I2C network can read xor write it can't do both of them at the same time, so you may wonder how the slave would know if the master need to right or read from it,
well that's simple if the master want to write in the eeprom it sends 0XA0 and if it want to read it sends 0XA1, in other terms the LSB is the bit responsible for reading or writing.

wiring The 24LC256 EEPROM

A1 A2 and A3 are wired to the ground so our eeprom address is 0B1010000
Wp it's a bit for writing protection or read only, I'm not sur just wired to the ground.
SDA is the pin responsible for sending and receiving data,
SCK is the serial clock
We must use 2 pull up resistor for SDA and SCL (in proteus isis use the pull up resistor model)

Writing and reading from the EEPROM

we will store a data in a specific address then we are going to read data from that address.
unsigned char i = 0;
char txt[4];
void rc(){
     uart1_write(10);
     uarT1_write(13);
}
void main(){
  uart1_init(9600);
  I2C1_Init(100000);
  uart1_write_text("initialize I2C communication");rc();
  I2C1_Start();
  uart1_write_text("Start I2C communication");rc();
  I2C1_Wr(0xA0);
  delay_ms(10);
  uart1_write_text("write eeprom address");rc();
  I2C1_Wr(0x00);
  delay_ms(10);
  uart1_write_text("write low address");rc();
  I2C1_Wr(0x00);
   delay_ms(10);
   uart1_write_text("write high address");rc();
  I2C1_Wr(26); //donnée à écrire
  delay_ms(10);
  uart1_write_text("send to be stored");rc();
  I2C1_Stop();
  uart1_write_text("Stop I2C communication");rc();
  Delay_100ms();
  I2C1_Start();
  uart1_write_text("Start I2C communication");rc();
  I2C1_Wr(0xA0);
    delay_ms(10);
    uart1_write_text("write eeprom address");rc();
  I2C1_Wr(0x00);
     delay_ms(10);
     uart1_write_text("Start I2C communication");rc();
  I2C1_Wr(0X00);
  delay_ms(10);
  uart1_write_text("write low address");rc();
  I2C1_Repeated_Start();
  uart1_write_text("write high address");rc();
  I2C1_Wr(0xA1);
  delay_ms(10);
  uart1_write_text("read eeprom address");rc();
  i=I2C1_Rd(0);
  uart1_write_text("read stored data");rc();
  I2C1_Stop();
  uart1_write_text("Stop I2C communication");rc();
  bytetostr(i,txt);
  uart1_write_text(txt);rc();
}

I hope that was clear, don't stop sharing!!



vendredi 1 juin 2012

Building NXT robots

So here I am founding my self learning the NXT lego mindstorm kit for robotics to teach some robotic lessons to some kids with my friend Helmi.

I didn't play with lego when I was young and I didn't make any robot neither but I found that learning such things in early age is just great cause robotics include many disciplines like mathematics physics algorithms mechanics and even chemistry in some cases so for a child this is a great opportunity to boost his way of thinking perception searching for information and finding solutions without mentioning increasing his self confidence and sense of innovation and creation with such a simple tool simple tasks but with amazing results.
Sure I will post some of NXT robotics experience. Till that day keep sharing :)

mardi 15 mai 2012

PID control: algorithm and implementation


Meet,



Mr Proportional
a fat guy that eat too much his one and only issue is his stomach :pp





Mr Integrator

 a punctual guy and obsessed with time he can never be satisfied with something unless he finished it all.






Mr Derivator
an athlete that loves to run, sometimes slow and sometimes fast and he can make his colleagues run faster.








Mr P Mr I and Mr D can make a great combination to make any system work at his best withe all the energy that given by Mr P all the punctuality that is given by Mr I and all the speed that it's given by Mr D.


So PID Controller is a command law that controls a system to respond to a specific order.
Our objective to make a specific system respond to our command with the minimum possible error as fast as possible and with maintaining it's stabilité

So let's look to this system:
It can be controlled by two different way.
The first method is an open loop command  it's a very simple command we just put the command manually and the system will react according to that command BUT that means we don't have any idea about what's going on in the end and even that we can observe our system working we don't have an exact idea about his performance.

The second method is a close loop command that means we give a desired goal for example a specific position the system then will calculate the error = desired goal - output and create the command accordingly so in this case the command is generated automatically. 
here we can notice that the desired goal and the output must be with the same unity that means the desired goal must much the unity of the system output.

Where's the PID?

well PID regulator is the first one which meets the error calculated each time.


As we already saw Mr P, I and D are the 3 gentlemen who constitute the PID regulator.

Mr P is simply the error that we already talked about.
Mr I is the sum of all the errors calculated
Mr D present the Dynamic of the errors whether the error value are changed suddenly or smoothly we should consider that in out regulator.

How can I much this gentlemen with my specific system?

well here we need a little magic. You should know the exact amount of food to give to Mr P Let's called Kp. The exact sense of punctuality to Mr I (Ki) and the perfect body to Mr D (Kd).

Implementation:

If you want to implement your PID controller into a microcontroller you need to follow this steps;

1° Create a Timer interrupt (which represent the sampling time)
2° predefine your PID parameters
3° in the Timer routine calculate the 3 Mrs:
   MrP = target-output
-------------------------------
  MrI=MrP+LastMrI
 LastMr+=MrI
------------------------------
MrD=MrP-LastMrD
LastMrD=MrP
------------------------------
4°calculate the correction
 correction = Kp*Mrp+Ki*MrI+ Kd*MrD
5°Saturation:
correction mustn't exceed the maximum value the actuator would take so we need to do a saturation routine

N°: Sometimes "correction" have negative values so if we are dealing with motors that means turning in the other sens if we are dealing with a temperature regulation that means we should stop or cooling our system.

dimanche 6 mai 2012

use the visual assistant

visual assistant is a wonderful tool that allows you to create complex image processing alghorithm with simple cliks

USB communication


In this tutorial I'm using a PIC18F4550 with 48MHz crystal to communicate through usb with PC.
If you are using proteus ISIS I'm happy to tell you that there's a wonderful feature which create a virtual usb driver so you don't need any electronics to test your program.

I'm going to show you how to create a project that includes the usb HID (Human interface devices) library. So after this project you will be able to create your own HID devices with your product and vendor IDs.

First start by creating a new Projects with all the settings mentioned above and copy this code which is by the way the example code given by the Help.

unsigned char readbuff[64] absolute 0x500;   // Buffers should be in USB RAM, please consult datasheet
unsigned char writebuff[64] absolute 0x540;

char cnt;
char kk;

void interrupt(){
   USB_Interrupt_Proc();                   // USB servicing is done inside the interrupt
}

void main(void){
  ADCON1 |= 0x0F;                         // Configure all ports with analog function as digital
  CMCON  |= 7;                            // Disable comparators

  HID_Enable(&readbuff,&writebuff);       // Enable HID communication

  while(1){
    while(!HID_Read())
      ;

    for(cnt=0;cnt<64;cnt++)
      writebuff[cnt]=readbuff[cnt];

    while(!HID_Write(&writebuff,64))
      ;
  }
}
The code simply send back what he received ^^

Now Tools->HID terminal

Set your VID and PID your Vendor Name and Product Name as you want.
Then select the mikroC radio and save your descriptor file with your project files (not an obligation but recommended :p ).

Go to view-->project manager
right click on the "source" folder and choose "add files to project" to add the descriptor file you already created.

before compiling one last step:
go to edit project and set it like in the picture


Finally Compile your project. It should work fine if you are not using the demo version.


mercredi 28 mars 2012

Gesture recognition with Imaq labview

Hi,
I was working the last days on a project of gesture recognition using labview.
Labview is a great program, a simple programmer can easily learn the graphical language it use, because everything in labview is referred as block and the relations between blocks are maintained with wires.
In my projects I used the vision toolkit which is one of the most great toolKit in labview. Now I can control numerique or analogic data only through my hand.

This is an update:
I continued the project with two of my freinds helmi and slim, we can now control actuator with gestur recognition we succeded at controling the speed of a dc motor by just moving our fingurs :))


It was a great experience :)