Thursday, December 28, 2023

PIC16F887 HC-SR04 Distance Sensor LCD Using XC8

Overview

HC-SR04 is an ultrasonic range finder. It uses sound wave traveling to find detected object distance. Its working range is between 4cm and 4m. To control and get distance data from this sensor we can use a digital circuit, or a microprocessor, or even manually by hand. Its echo output is a logic high level TTL signal with a specific period. A microprocessor's timer is used for calculating the timing signal associated with distance. For more details about using this sensor with a simple PIC16F84A micro-controller you can see this post.

PIC16F887 HC-SR04 Distance Sensor LCD Using XC8
PIC16F887 Prototyping Board

PIC16F887 HC-SR04 Distance Sensor LCD Using XC8
PIC16F887 Prototyping Board
 
PIC16F887 HC-SR04 Distance Sensor LCD Using XC8
HC-SR04 Module Front

PIC16F887 HC-SR04 Distance Sensor LCD Using XC8
HC-SR04 Module Back

MPLABX IDE and XC8 C Programming

In this XC8 programming example, I use a PIC16F887 8-bit micro-controller to read distance data, and displaying its timing value with calculated distance on a 16x4 character LCD. I use Timer0 timer/counter to measure the sensor's TTL high pulse period.







PIC16F887 HC-SR04 Distance Sensor LCD Using XC8
Schematic and Program Simulation

An 8MHz internal RC oscillator is used for the system. Timer0 prescaler is set to 1:2 to get a 1µs timing ticks. Since this timer module is an 8-bit timer/counter I use TIMER0 interrupt to expand its timing period. Hence it becomes a 16-bit timer with the aid of timing interrupt. 

An 8-bit micro-controller is easy to program using C in MPLABX IDE and XC8 embedded C compiler from Microchip Technology. An HD44780 character LCD is very simple to interface and program. This character LCD is common operate in 4-bit data transfer mode.

  1. /*
  2.  * File: main.c
  3.  * Author: Admin
  4.  *
  5.  * Created on December 28, 2023, 9:51 PM
  6.  */
  7.  
  8. #include <xc.h>
  9. #include "config.h"
  10. #include "lcd.h"
  11.  
  12. #include <stdio.h>
  13.  
  14. #define _XTAL_FREQ 8000000UL
  15.  
  16. #define TRIGGER RD6
  17. #define ECHO RD7
  18.  
  19. volatile uint8_t T0OV=0;
  20. volatile uint16_t myCounter=0;
  21. volatile uint16_t getDistance=0, temp=0;
  22.  
  23. void __interrupt() T0_ISR(){
  24. if(T0IF==1){
  25. T0OV+=1;
  26. myCounter++;
  27. T0IF=0;
  28. }
  29. }
  30.  
  31. void readDistance(void){
  32. char msg[8];
  33. TRIGGER=1;
  34. __delay_us(10);
  35. TRIGGER=0;
  36. __delay_us(30);
  37. while(ECHO==0){
  38. /*Waiting For High Pulse Response, Or Sensor Present*/
  39. temp++;
  40. __delay_us(10);
  41. if(temp>=20) break;
  42. }
  43. TMR0=0;
  44. T0OV=0;
  45. while(ECHO==1);
  46. temp=(T0OV<<8)+TMR0+14;
  47. getDistance=temp/58;
  48.  
  49. lcdXY(5,4);
  50. sprintf(msg,"%4d %cS ",temp,228);
  51. lcdString(msg);
  52. lcdXY(5,2);
  53. if(temp>=116&&getDistance<=400){
  54. sprintf(msg,"%3d",getDistance);
  55. lcdString(msg);
  56.  
  57. temp%=58;
  58. temp=(temp*100)/58;
  59. sprintf(msg,".%d%dcm",temp/10,temp%10);
  60. lcdString(msg);
  61. }else lcdString("Invalid");
  62. temp=0;
  63. T0OV=0;
  64. TMR0=0;
  65. }
  66.  
  67. void main(void) {
  68. /*8MHz internal oscillator*/
  69. OSCCONbits.IRCF=7;
  70. lcdInit();
  71. /*RD7 as input*/
  72. PORTD=0;
  73. TRISD=0x80;
  74. /*Select system clock*/
  75. T0CS=0;
  76. /*Timer0 Prescaler*/
  77. PSA=0;
  78. /*Select 1:2 Prescaler*/
  79. OPTION_REGbits.PS=0;
  80. /*Enable Timer0 Interrupt*/
  81. T0IE=1;
  82. GIE=1;
  83. T0IF=0;
  84.  
  85. lcdXY(5,1);
  86. lcdString("PIC16F887 ");
  87. lcdXY(1,2);
  88. lcdString("HC-SR04 Distance");
  89. lcdXY(2,3); lcdString("Sensor Example");
  90. lcdXY(2,4); lcdString("MPLABX IDE XC8");
  91. __delay_ms(2000);
  92. lcdCommand(0x0C);
  93. lcdCommand(0x01);
  94. __delay_ms(5);
  95. lcdXY(5,1);
  96. lcdString("Distance: ");
  97. lcdXY(1,3);
  98. lcdString("TIMER0 Duration:");
  99. TMR0=0;
  100. while(1){
  101. if(myCounter>=5000){
  102. readDistance();
  103. myCounter=0;
  104. }
  105. }
  106. return;
  107. }
  108.  
  109.  
  110.  

The Interrupt Service Routine (ISR) for PIC micro-controller in XC8 programming is differ depends on the version of the compiler. Some time the source codes can generate error in other version. In some case, it can be build but the ISR does not work during run-time. So we will need to read its compiler user manual. 

PIC16F887 HC-SR04 Distance Sensor LCD Using XC8
MPLABX IDE Dashboard

Click here to download its source file.




No comments:

Post a Comment

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (54) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (46) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (66) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (2) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (30) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)