Saturday 8 November 2014

Obstacles avoiding buggy

Another project I used to work on lately. Three-wheel buggy that uses PID controller to avoid obstacles on its way. I will update this post with more details whenever I have some more time. It uses Arduino board for controlling motors and ultrasonic sensors to measure the distance between the buggy and anything in front of it.

This is how the buggy looks like



Software
I made the C++ library which you can use to assign pins of the Arduino to outputs of the sensors and motors. 
buggy.h
buggy.c

There are three important functions there:


//sends a 10ms signal to Trig pin of ultrasonic sensors then waits for 8 signals from the echo pin of sensor and returns the distance
long Buggy::CountDistance(int pin_trigger, int pin_echo)
{
    digitalWrite(pin_trigger, HIGH);
    delayMicroseconds(10);
    digitalWrite(pin_trigger, LOW);
    //sending 8 pulses
    long distance=pulseIn(pin_echo, HIGH)/58;
    return distance;
}

//measures the distance from three sensors
void Buggy::AssignDistance(void)
{
    distance_left=CountDistance(sonar_pin_trigg_left, sonar_pin_echo_left);
    distance_center=CountDistance(sonar_pin_trigg_center, sonar_pin_echo_center);
    distance_right=CountDistance(sonar_pin_trigg_right, sonar_pin_echo_right);
}

//returns the distance from sensors
//for n=1 -> left sensor, n=2 ->central sensor, n=3->right sensor
long Buggy::GetDistance(int n)
{
    switch(n)
    {
        case 1:
            return distance_left;
            break;
        case 2:
            return distance_center;
            break;
        case 3:
            return distance_right;
            break;
        default:
            break;
    }
}

The Arduino code is included in the following source file:

Arduino code

Main function:
void loop()
{
  //-------------------READING SENSORS---------------------
  ReadSensors();
  L_distance=robot->GetDistance(1);//distance on left sensor
  //robot->GetDistance(2));//distance on center sensor
  R_distance=robot->GetDistance(3);//distance on right sensor
  //--------------------------------------------------------
  
  if(L_distance>50)
        L_distance=50;
  if(R_distance>50)
        R_distance=50;
   L=50-L_distance;
   R=50-R_distance;
   
   PID=PID_value(L,R);
   Motor_control(PID);
   
}//end of loop()

It reads the distance between the buggy and anything around from all three sensors. 
This part of code 'saturates' the distance so that it is only in range of 0-50 cm

//-----------------------
 if(L_distance>50)
        L_distance=50;
  if(R_distance>50)
        R_distance=50;
   L=50-L_distance;
   R=50-R_distance;
//-----------------------

After that PID controller sends the value to the motors according to the distance read from sensors.
Motor control(double) function is the motor controlling function and it sends values to both left and right motors.

Lets take a look at the function which operates right motor:
//-------------------------------------------------------
void Right_Motor(double PID)
{
  if(av_PWM+PID>max_PWM)
    analogWrite(right_forward, max_PWM);
  else if(av_PWM+PID<0)
    analogWrite(right_forward, 0);
  else
    analogWrite(right_forward, av_PWM+PID);
}
//--------------------------------------------------------
First of all PID values is calculated in 'double PID_value(int L, int R)'. When Right_Motor(double) receives the value it checks if PWM value is in range of 0-255, which is minimum-maximum range for Arduino's analogWrite(double) function. If it exceed it then Right_motor function saturates it either to 0 or 255. Otherwise it uses PID value to move the motor.

Here is the youtube link with the buggy avoiding obstacles. It only uses proportional part at the moment. I will make another video with the upgraded version of the controller in the future.

P controller

Later on I will update it with the circuit diagram, hardware and upgraded version of controller...


Tuesday 12 August 2014

1d electronic ping pong game

I have had this idea to build a 3D ping-pong game for two players, consisting of many LEDs making a cube, and that is how I came up with this much easier and straight-forward 1D game. The project can be built and programmed in even one day if someone has all the required components. The outcome looks like that:



The aim of the game is to press each of the push-buttons once far left/right LED is on. Once a player presses it the 'ball' bounces off and LEDs are being illuminated sequentially in the opposite direction. One player wins when the other one presses the push-button if any other LED is on or does not press it when supposed to. If a player wins the yellow LED, above his push-button, lights up and the other one has to press the push-button in order to start the game over again. When one player wins 3 times the red LED, above the microcontroller, lights up indicating the end of the game. Each time the player successfully presses the button the 'ball' moves faster.

Here is the list of all required electronic components:
  • 1 x toogle switch(I did not have this one so I just used a 2-wire terminal block connector)
  • 2 x push-button
  • 4 x 10k resistor
  • 11 x 560R resistor
  • 11 x LED
  • microcontroller PIC16F628 or any similar(PIC16F628 datasheet)
  • power supply 3-5.5V
  • 1 x 100nF capacitor
  • 1 x 100pF capacitor
  • 6 pins to connect the microcontroller with PICkit 3 In-Circuit Debugger(PICkit 3)
You can also supply the board with 3-5.5V using the PICkit 3. In order to do that you have to use MPLAB X IDE and right click on a project you are working on. Then choose Properties->PICkit 3->Power in Option categories and check the 'Power target circuit from PICkit 3' box. After that you can adjust any supply power in range from 3 to 5.5V.

The following diagram shows the circuit and the wiring:


Above diagram along with the TinyCad design file can also be download from following link:

The only parts which are missing in the diagram are pins 5 and 14, which are to be connected to the ground and power supply, respectively. 

You can download the software from the following link:

The software consists of 3 files:
  • main.c - the main program
  • functions.h - description of all the functions
  • conf.h - configuration bits file
Keep in mind that I am using internal clock instead of the external RC circuit which you can see on the circuit diagram. Thus, the frequency, according to the PIC datasheet, is equal to 4Mhz. If you want to use a different clock input you must go to conf.h and change the following line of code:

#pragma config FOSC = INTOSCCLK 

As you change the frequency all the delays described in my code will be different due the change of clock cycle. The base delay is included in <delays.h>, library of xc8 compiler(you choose it when creating the project in MPLAB). In the functions.h file I have the following function:



void delay_10ms(void)


{
    int i,j;
    for(i=1;i<=10;i++)
    {
        for(j=1;j<=100;j++)
            _delay(10);
    }
}

It correspond to a delay of 10ms. It is based on _delay(10) corresponding to 10 instruction cycles, each of which takes 4 clock cycles. You can calculate the required delay using this formula:

DELAY=N*4/FREQUENCY


Have fun building your own ping-pong game and message me if you have any problems!









Monday 14 July 2014

Start off!

Hi there, I just started this blog and I hope it will be successful as a blog about sharing my projects with the other people. I will not post here any news from electronic or robotic field, although if there is something quite interesting going on in these areas I will probably give it a shout here. So check my posts, comment and enjoy! :)