Project 6 – Analog Sensor: Range using Ultrasonic Range Finder

There are many sensor to measure a range such as using Ultrasonic, Infrared and more. In here, we are going to experience how to measure a range using Maxbotic Maxsonar-EZ1 ultrasonic range finder which it will give the output value in inch.



Back to Project 5                                                                                                            Go to Project 7

There are many sensor to measure a range such as using Ultrasonic, Infrared and more. In here, we are going to experience how to measure a range using Maxbotic Maxsonar-EZ1 ultrasonic range finder which it will give the output value in inch.




16 x 2 LCD Display





Maxsonar-EZ1 ultrasonic sensor are operate in +5V and draw on 2mA of current. For this sensor, it have 3 modes of output which is UART, analog and pwm.

Maxsonar-EZ1 will send the output if in ASCII format. For this sensor, the output are in RS232 format which mean that the HIGH(1) bit are at 0V while the LOW(0) bit are 5V. We need to connect the TX of sensor connect to NPN while RX of sensor to TX of microcontroller just like figure below.

Connect the analog output of the ultrasonic sensor to the RA0 of microcontroller.

Connect this pin to the RB2 of microcontroller.



The Maxsonar-EZ1 sensor offer a very short to long range detection which is from 0-inches to 254-inches plus with a very low power consumption. It has provided sonar range information from 6-inches out to 254-inches with 1-inches resolution. Object from 0-inches to 6-inches are range as 6-inches. It has 3 modes selection for the output range which is:
~ Serial, 0V – 5V, 9600 Baud
~ Analog, 10mV/inch
~ Pulse Width, 147us/inch
For detail information, please refer the Maxsonar-EZ1 datasheet.

EUART of PIC16F887
The Enhanced Universal Synchronous Asynchronous Receiver Transmitter (EUSART) module is a serial I/O communication peripheral. It is also known as Serial Communications Interface (SCI). It contains all clock generators, shift registers and data buffers necessary to perform an input or output serial data transfer independently of the device program execution. As its name states, apart from the usage of clock for synchronization, this module can also establish asynchronous connection, which makes it irreplaceable in some applications.

EUSART Asynchronous Mode

EUSART Asynchronous Transmitter


EUSART Asynchronous Receiver




unsigned int T0=0, T=0, TH=0;
unsigned char data[6] = {0};
In this global variable, we have already declare that To, T, TH are 0. Same as data[0] to data[6] are 0.


static void interrupt isr(void)
For every interrupt subroutine, void interrupt isr(void) MUST be added in the program. In here, we extra added a static is because we need to return the result of the program that executed in the interrupt subroutine back to the main program. On the other hand, there was 2 interrupt that have been set in main program which is timer 0 and also PORTB change interrupt.

If (T0IF)
T0IF = 0;
To +=0x100;
Check if the timer 0 is interrupt . If interrupt flog is HIGH(1), the timer 0 is interrupt. Clear the timer flag to LOW(0) and add the increase To and make it 16-bit.

RBIF = 0;
if (PWM_IN)
TMR0 = 0;
To = 0;
else TH = TMR0 + To;
If PORTB interrupt-on-change flag is set, we reset the flag bit by giving a value 0 to RBIF. After that we check whether if the input from PWM is in HIGH(1) or LOW(0). If HIGH(1), reset timer and To to 0. if LOW(0), the TMR0 value is added with To value.


IOCB<7:0> = 00000100
For enabled interrupt-on-change pins, the present value is compared with the old value latched on the last read of PORTB to determine which bits have changed or mismatched the old value. The ‘mismatch’ outputs of the last read are OR’d together to set the PORTB. Change Interrupt flag bit (RBIF) in the INTCON register. In here, we make the PORTB.2 as interrupt on change. Please refer PIC16F887 for detail.

RBIE = 1;
PORTB Change Interrupt Enable Bit. HIGH(1) to enable while LOW(0) to disable. If detected the change on PORTB.2.


T0CS = 0;
TMR0 Clock Source Select Bit. We choose LOW(0) for selecting the Internal instruction cycle clock.
Let’s say our default used crystal is 20MHz. The clock cycle is 20MHz/4 = 5MHz.

PSA = 0;
Prescaler Assignment Bit. We choose LOW(0) to assign the precaler to the timer 0 module.

PS<2:0> = 111;
Choose the TMR0 prescaler rate to 256.

T0IE = 1;
Timer 0 Interrupt enable bit. HIGH(1) to ON the timer 0 interrupt.

TMR0 = 0;
Timer 0 module register from 0x00 to 0xFF. The timer 0 will start counting from the value given until the next 0x00 and trigger the overflow flag.

GIE = 1;
PEIE = 1;
GIE,Global Interrupt Enable Bit. HIGH(1) to enable all unmasked interrupt. LOW(0) disable all interrupt.
PEIE,Peripheral Interrupt Enable Bit. HIGH(1) to enable all unmasked peripheral interrupt. LOW(0) to disable all peripheral interrupt.


BRG16 = 0;
BRG16, 16-bit Baud Rate Generator bit. HIGH(1) to set it to 16 bit baud rate generator. LOW(1) to 8-bit baud rate generator.

SYNC = 0;
EUSART Mode Select bit. HIGH(1) to synchronous mode. LOW(0) to asynchronous mode.

TX9 =0;
RX9 = 0;
8-Bits transmit enable bit and 8-Bits reception.

BRGH = 1;
High Baud rate select bit are set to High Speed.

SPBRG = 129;
SPBRG is in decimal value which is use to select the baud rate of 9600 with condition of SYNC = 0, BRGH = 1, BRG16 = 0, Fosc = 20MHz. Please refer PIC16F887 datasheet for detail.

SPEN = 1;
SPEN is serial port enable bit which will configure RX/DT and TX/CK pins as serial port pins.

CREN = 1;
Continuously receive the data enable bit.

TXEN = 1;
Transmit enable to send data out through serial communication port TX pin.

dummy = RCREG;
Store the data in the dummy to clear the buffer of RCREG.


In analog reading, by including the adc.c & adc.h module, the adc result will be save in adc_value after been added by 10 times and divided by 10 to get the average result. By referring to the Maxsonar-EZ1 datasheet. The output are 10mV/Inch and the maximum range are given 2.55V. By applying formula:
adc_value = 2.55/5*1024 = 522(decimal)
522 / 256-inch = ~2


range_pwm = TH;
We have already declare that TH is the timer value of the PWM reading. The TH value are insert to range_pwm.

range_pwm = (range_pwm*100)/288;
~ each value = 256*4/20mhz = 51.2us
~ 1 inch = 147us
~ 147us/51.2us = 2.88


Maxsonar-EZ1 in UART mode are directly given an ASCII value to the microcontroller which start with an “R”, then follow by 3 value of range such as 255-inch in “2”, “5”, “5” and then lastly is the carriage return which is totally of 5 data to be received.

If (RCREG == ‘R‘) data[k=0] = RCREG;
Check if the RCREG are ASCII value ‘R’. if yes then save the data at data[0] by reset the k = 0.

if (data[0] == ‘R‘) data[k++] = RCREG;
After make sure the data[0] is ‘R’. Then next step is to save the next RCREG value in data[1], data[2], data[3] by increasing k by 1 at the time.

By referring to LCD library, by sending a 1 will toggle ON the RS of the LCD which is read as an character for LCD. Then send the ASCII data that given by the Maxsonar-EZ1 to the LCD.


while (SW1 == 0 );
Check if switch 1 is still holding. If yes then keep looping until switch 1 is release.

If (++mode > 3)
mode = 1;
Check if mode is increase until 3 or more. If yes then reset back to mode 1.

Back to Project 5                                                                                                           Go to Project 7



1. P6 User Manual.pdf


4 thoughts on “Project 6 – Analog Sensor: Range using Ultrasonic Range Finder”

  1. You will need to show your code, we cannot produce whole code for you as the hardware is not the same. Anyway please do discuss in our technical forum.

  2. how i want to modified this coding to create my project…when ultrasonic get 1 meter range, the motor that connect to the output will run….i use ultrasonic SN-LV-EZ1 and connect to SK40C and connect to Enhanced 30 Amp DC Motor Driver, that control the motor. IC that i use is 18F4550

Leave a Comment

Your email address will not be published.

Share this Tutorial

Share on facebook
Share on whatsapp
Share on email
Share on print
Share on twitter
Share on pinterest
Share on facebook
Share on whatsapp
Share on email
Share on print
Share on twitter
Share on pinterest

Latest Tutorial

DIY Interactive Robot Using REKA:BIT With Micro:bit
BLTouch Installation for Ender 3 with 32-bit V4.2.2 Board
Pick and Send Random Meal’s Option and Locations through Telegram Bot Using Grove WiFi 8266 on micro:bit
DIY Automated Vacuum Cleaner Using REKA:BIT With Micro:bit
Rainbow Spark in Mini House using Maker Uno.
Tutorials of Cytron Technologies Scroll to Top