Sunday, 26 February 2017

Ultrasonic Distance Sensor with PIC microcontroller

Ultrasonic Distance Sensor with
PIC microcontroller







Ultrasonic distance sensor uses to measure the object distance without physically contact. This type of sensor can be use in robots, machines, vehicles, distance measuring tools and etc.

Now we will know that how to work ultrasonic sensor and what will the hardware/circuit required. Ultrasonic sensor has four pins 2 are supply voltage pins, one digital signal output pin and forth pin uses for trigger the sensor to get distance. From microcontroller side only single digital input and single digital output pin would be need to communicate with sensor. You can use any of the controller I/O port pins for this purpose.  








Ultrasonic sensor works by transmitting an ultrasonic burst and providing an output pulse that corresponds to the time required for the burst echo to return to the sensor. By measuring the echo pulse width, the distance to target can easily be calculated. For more information see sensor manufacturer’s datasheet.


Software working procedure

  1. First set the “trigger” pin for 10us to start ranging.
  2. Wait until “echo” pin not goes to high.
  3. Start timer and incensement until “echo” pin not goes to low.
  4. When “echo” pin goes to low, stop timer.
  5. Calculate time to distance by given formula.




                  Tm = time (us) per increment of timer register
                 Count = total increased register value
                 Distance (centimeter) = (Tm * Count) / 58.82







Codes:-

#include <p18f2520.h>

#define Echo_pin PORTBbits.RB5
unsigned int rawDist, b;
int get_sensor_data(void);
void delay_10us(void);
int check_TM(void);


void main()
{
          TRISB = 0xF1;
          PORTB = 0x00;

          T1CON = 0x10;
          T3CON = 0x00;

          while(1)
          {
                   get_sensor_data();      // Use this function where you need.
                   for(b=0;b<5;b++) for(b=0;b<65000;b++);   // Delay between next                                                                                                      measurement.             
          }
}

int get_sensor_data()
{
          int data;

          // Active sensor
          PORTBbits.RB6 = 0;
          PORTBbits.RB6 = 1;
          delay_10us();
          PORTBbits.RB6 = 0;

          // Get data from sensor
          while(Echo_pin != 1);
          data = check_TM();    
          return (data < 400) ? data : 0;
}

void delay_10us()
{
          TMR3H = 0xFF;           // 10us delay according to 20Mhz crystal
          TMR3L = 0xCE;
          T3CONbits.TMR3ON = 1;
          while(PIR2bits.TMR3IF == 0);
          T3CONbits.TMR3ON = 0;
          PIR2bits.TMR3IF = 0;
}

int check_TM()
{
          int a;
          if(Echo_pin == 1)                   // Check ECHO pin for high.
          {
                   TMR1H = 0x00;
                   TMR1L = 0x00;
                   PIR1bits.TMR1IF = 0;
                   T1CONbits.TMR1ON = 1;
                   T0CONbits.TMR0ON = 0;     // Timer register value increse in                                                                                         every 400ns         
                   while(Echo_pin != 0);            // Timer register value will increase                                                                                       unilt ECHO pin is high.
                   T1CONbits.TMR1ON = 0;
                   T0CONbits.TMR0ON = 1;
                   a = (TMR1L + (TMR1H * 256));
                   a = (a / 2.5)/58.82;       // 400ns time per increment of timer register.
                   a += 1;
                   return a;              
          }
          else return 0;

}







Friday, 24 February 2017

Serial Port (USART) - PIC18F2420/2520/4420/4520

Universal Synchronous Asynchronous Receiver Transmitter (USART)




USART module is a serially data transmitting and receiving hardware or software implemented protocol. USART also known as a serial communication interface (SCI). We can communicate two devices such as computers (Please note that a driver is required to interface to RS-232 voltage levels and the PIC MCU should not be directly connected to RS-232 signals.), peripheral devices and can send/receive data thru USART module. Basically USART module can be found on all of microcontroller and microprocessor devices.


USART send/receive protocol and hardware structure on PIC controller.

PIC controllers provided USART can be configured as a full-duplex (Both transmission and reception can occur at the same time) asynchronous system that can communicate with peripheral devices, such as CRT terminals and personal computers. It can also be configured as a halfduplex, synchronous system that can communicate with peripheral devices, such as A/D or D/A integrated circuits, serial EEPROMs, etc.

In the hardware circuit 2 or 3 wires would be use to communicate 2 devices each other. First is TX (Transmit) line, second is RX(Receive) and third is GND( if both devices have different supply sources when the ground should be common for both devices).

In the data sending and receiving process, bit by bit (serial wise) data transfers or receives. Mostly microcontrollers use TTL level supply voltage, it’s means if the voltage are in range of 0 to 0.8 volt with respect to ground supply will be consider as “LOW” and voltage are in range of 2.0 to 5 volt will be consider as “HIGH”.





PIC MCUs enhanced USART module implements additional features, including automatic baud rate detection and calibration, automatic wake-up on Sync Break reception and 12-bit Break character transmit. These make it ideally suited for use in Local Interconnect Network bus (LIN bus) systems.



The EUSART can be configured in the following modes:

  • Asynchronous (full duplex) with:

              -  Auto-wake-up on character reception.
              -  Auto-baud calibration.
              - 12-bit Break character transmission.
  • Synchronous – Master (half duplex) with selectable clock polarity
  • Synchronous – Slave (half duplex) with selectable clock polarity





USART receive and transmit pins should be configure as input pins.


The operation of the Enhanced USART module is controlled through these registers:
  • ·        Transmit Status and Control (TXSTA).
  • ·        Receive Status and Control (RCSTA).
  • ·        Baud Rate Control (BAUDCON)
  • ·        Transmit Register (TXREG)
  • ·        Receive Register (RCREG)
  • ·        Baud rate value (SPBRG)



TXSTA: TRANSMIT STATUS AND CONTROL REGISTER

Bit7   :- Clock source selection bit

  • ·        If you are using asynchronous mode, not to be use. In the synchronous mode we would configure this bit for set master or slave mode.

   TXSTAbits.CSRC = 1;           // Master mode.
   TXSTAbits.CSRC = 0;           // Slave mode.


Bit6   :- Bits transmission mede.

             TXSTAbits.TX9 = 1;              // 9 bit transmission.
   TXSTAbits.TX9 = 0;              // 8 bit transmission.


Bit5   :- Transmission enable/disable bit

             TXSTAbits.TXEN = 1; // Transmission enable.
   TXSTAbits.TXEN = 1; // Transmission disable.


Bit4   :- Synchronous/Asynchronous mode selection

             TXSTAbits.SYNC = 1; // Synchronous mode.
   TXSTAbits.SYNC = 0; // Asynchronous mode.


Bit3   :- Send Break Character bit

  • ·        The EUSART module has the capability of sending the special Break character sequences that are required by the LIN bus standard. The Break character transmit consists of a Start bit, followed by twelve ‘0’ bits and a Stop bit.


           TXSTAbits.SENDB = 1;        // Send Sync Break on next transmission.
           TXSTAbits.SENDB = 0;        // Sync Break transmission completed.


Bit2   :- High or low baud rate selection

             TXSTAbits.BRGH = 1;          // High baud rate.
   TXSTAbits.BRGH = 0;          // Low baud rate.


Bit1   :- Transmission status bit

             TXSTAbits.TRMT = 1; // Transmission shift register is empty.
   TXSTAbits.TRMT = 0; // Transmission shift register is full.


Bit0   :- 9th bit of transmit data

  • ·        If 9-bit transmission is selected, the ninth bit should be loaded in bit, TX9D.



USART TRANSMIT BLOCK DIAGRAM



RCSTA: RECEIVE STATUS AND CONTROL REGISTER


Bit7   :- Serial port enable/disable bit 

             RCSTAbits.SPEN = 1;          // Serial port enable
             RCSTAbits.SPEN = 0;          // Serial port disable


Bit6   :- 9-Bit Receive Enable bit

             RCSTAbits.RX9 = 1;   // Selects 9-bit reception
             RCSTAbits.RX9 = 8;   // Selects 8-bit reception


Bit5   :- Not in use with asynchronous mode


Bit4   :- Continuous Receive Enable bit

          RCSTAbits.CREN = 1;         // Enable receiving
RCSTAbits.CREN = 0;         // Disable receiving


Bit3   :- Address Detect Enable bit

  • ·        This bit uses when your receiving data format is 9bit, otherwise not in use.

          RCSTAbits.ADDEN = 1;       // Enable address detection
          RCSTAbits.ADDEN = 0;       // Disable address detection


Bit2   :- Framing Error bit

  • ·        When received data format will not match with configured setting and any other unsuitable condition, this error will generate. Error can be cleared by reading RCREG register and receiving next valid byte.


Bit1   :- Overrun Error bit

  • ·        Error can be cleared by clearing bit, CREN.



Bit0   :- 9th Bit of Received Data

  • ·        This can be address/data bit or a parity bit.


USART RECEIVE BLOCK DIAGRAM








BAUDCON: BAUD RATE CONTROL REGISTER

When you are going to use asynchronous mode serial interfacing, you would not need to configure BAUDCON register. You can leave it or set all byte as 0. If you need to know as many as, take a look on controller datasheet.


Codes:-

Now the time is to make a program which will send “Hello World” string when the specific character ‘A’ will received. In this example we are not using interrupt on receiving. This will just a single task program and will check RCREG (receiving register) in infinite loop.


#include <p18f2520.h>

void Open_USART(void);
void USART_string( char *buffer);

char data[] = "Hello World\r\n";
char received_bit;

void main()
{
            TRISCbits.TRISC6 = 1;   // Sets transmit pin
            TRISCbits.TRISC7 = 1;   // Sets recieve pin
           
            Open_USART();

            while(1)
            {
                        received_bit = RCREG;
                        if(received_bit == 'A')
                        {
                                    USART_string(data);
                                    RCREG = 0;
                        }
            }          
}


void Open_USART(void)
{
            // Settings of resisters according to PIC18F2520
            TXSTA = 0x24;                                 // 8 bit mode, Transmit enable,                                                                                            Asynchronous mode, High speed 
                                                                         mode
            RCSTA = 0x90;                                // Serial enable, Receiving enable,
            BAUDCON = 0x00;                        // 8-bit Baud Rate Generator,
            SPBRG = 129;                                   // 9600 baud rate at 20Mhz oscillator.                                                                              0.16% error.
}

void USART_string( char *buffer)
{
            int a = 0;
            do
            {           // Transmit a byte
                        while(!TXSTAbits.TRMT);
                        TXREG = buffer[a];
                        a++;
            } while( buffer[a] != 0 );
}







Tuesday, 21 February 2017

Pulse width modulation (PWM) - PIC microcontroller

Generate PWM with Pic controller




Pulse width modulation (PWM) is a technique to controls the pulse signals for power transmission applications like motor controlling, LED dimming and many more. Pulse modulation technique has some little calculations and some parameters.

  • ·         Duty cycle: - Duty cycle describe On time of a pulse.
  • ·         Period: - Total time of a pulse On time + Off time
  • ·         Frequency: - How many periods come in a second is frequency.


Example :-
                                Frequency = 2Khz
                                Period = 1 / frequency   =  1 / 2000   =    0.0005s
                                = 5ms
        Duty Cycle = (OnTime / Period) * 100%


Pic18f series controllers have standard CCP module with Enhanced PWM capabilities. These include the provision for 2 or 4 output channels, user-selectable polarity and automatic shutdown and restart. PWM module uses timer2 in free running clock mode to derive a reference clock. We will discuss only on a single PWM.



Block Diagram




Control registers of PWM
  • ·         CCPxCON
  • ·         PR2
  • ·         CCPRxL
  • ·         CCPRxH
  • ·         T2CON



CCPxCON: CCPx CONTROL REGISTER (28-PIN DEVICES)

Bit7-6   :- Not in use

Bit5-4   :- PWM Duty Cycle bit 1 and bit 0 for CCPx Module

  •  PWM duty cycle can be use as 10 bit resolution mode. These bits are LSB bits 0 & 1. Other 8 MSb are containing with CCPRxL register.  The following formula uses to calculate the PWM duty cycle in time.


                       PWM Duty Cycle = (CCPRxL:CCPxCON) • TOSC • (TMR2 Prescale Value)


In PWM mode, CCPRxH is a read-only register.


Bit3-0   :- CCP mode selection

  • CCP module can be configured as variant types of modes that are given in datasheet CCPxCON register. Now we are talking about PWM only so we will chose only last mode.

CCP1CONbits.CCP1M3 = 1;          //Selecting PWM mode
CCP1CONbits.CCP1M2 = 1;   


Other 2 bits can be set or not.




PWM Output







See the Timer2 register: -  http://embeddedooo.blogspot.in/2017/02/timer1-timer2-timer3.html





Codes:-

#include <p18f2520.h>

void config_timer2(void);
void config_PWM_ccp1(void);

void main()
{
            TRISC=0x00;                        // Set PORTC as output.
            PORTC=0x00;

            config_PWM_ccp1();
            config_timer2();
           
            while(1)
            {          
                        CCPR1L=127;                      // PWM duty cycle % = PR2/CCPR1L
            }
}

void config_timer2()
{
            // Timer2 Registers:
            // Prescaler=1:1; TMR2 PostScaler=1:11; PR2=227 - Freq = 2,002.40288Hz -                  Period = 0.4994 ms

            T2CONbits.T2OUTPS3 = 1;          // Postscaler selection bits
            T2CONbits.T2OUTPS2 = 0;
            T2CONbits.T2OUTPS1 = 1;
            T2CONbits.T2OUTPS0 = 0;
            T2CONbits.TMR2ON  = 1;            // Timer2 on bit: 1=Timer2 is on;
            T2CONbits.T2CKPS1 = 0;             // bits 1-0  Prescaler Rate Select bits
            T2CONbits.T2CKPS0 = 0;
            PR2 = 227;                                      // PR2 (Timer2 Match value)
}

void config_PWM_ccp1()
{
            CCPR1L=0;                                    // Set duty cycle register value to 0.   
            CCP1CONbits.CCP1M3 = 1;         //Selecting PWM mode
            CCP1CONbits.CCP1M2 = 1;
            CCP1CONbits.CCP1M1 = 0;
            CCP1CONbits.CCP1M0 = 0;

}