Distance Measurement Based on STC89C52RC, LCD1602, and Ultrasonic Module (HC-SR04)

Hello everyone! Today, I am sharing a perfect electronic project for beginners — using the STC89C52RC microcontroller + LCD1602 + HC-SR04 ultrasonic module to create a distance measuring device that can display distance in real-time! The cost is less than 30 yuan, and the difficulty is comparable to building blocks. Once completed, it can also be used as a small toy, providing a great sense of accomplishment!

Why do this? What are the applications?

  • As a reversing radar (alerts when close to obstacles)
  • As a sensing module for an automatic hand sanitizer dispenser
  • It can even serve as a “science toy” for children, measuring the length of a room or the height of a table

The key is! The principle is super simple, and I have written the code for you. Just follow along, and you definitely won’t go wrong!

Working Principle: How does ultrasonic sound “see” distance?

  1. HC-SR04 emits ultrasonic waves: The microcontroller sends a high-level signal of more than 10us to the Trig pin, and the module will emit 8 pulses of 40kHz ultrasonic waves
  2. Wait for reflection: The ultrasonic waves bounce back when they encounter an obstacle and are received by the module’s Echo pin
  3. Calculate time difference: The microcontroller uses a timer to record the time from “transmission to reception” (for example, it took 10ms)
  4. Calculate distance: The speed of sound in air is approximately 340m/s, so distance = (time × speed) ÷ 2 (because it travels back and forth)

For example: If the time is 10ms (0.01 seconds), the distance is (0.01×340)÷2=1.7 meters!

Program Code1.LCD1602.c

  • #include<REGX52.H>
    
    sbit LCD_RS=P2^6;
    sbit LCD_RW=P2^5;
    sbit LCD_EN=P2^7;
    #define LCD_DataPort P0
    
    void LCD_Delay50us(void) // [email protected] {
        unsigned char i;
        i=20;
        while(--i);
    }
    
    void LCD_Delay2ms(void) // [email protected] {
        unsigned char i,j;
        i=4;
        j=146;
        do {
            while(--j);
        } while(--i);
    }
    
    void LCD_WriteCommand(unsigned char Command) {
        LCD_RS=0;
        LCD_RW=0;
        LCD_DataPort=Command;
        LCD_EN=1;
        LCD_Delay50us();
        LCD_EN=0;
        LCD_Delay50us();
    }
    
    void LCD_WriteData(unsigned char Data) {
        LCD_RS=1;
        LCD_RW=0;
        LCD_DataPort=Data;
        LCD_EN=1;
        LCD_Delay50us();
        LCD_EN=0;
        LCD_Delay50us();
    }
    
    void LCD_SetCursor(unsigned char Line,unsigned char Column) {
        if(Line==1) {
            LCD_WriteCommand(0x80|(Column-1));
        } else if(Line==2) {
            LCD_WriteCommand(0x80|(Column-1+0x40));
        }
    }
    
    void LCD_Init() {
        LCD_WriteCommand(0x38); // 8-bit data interface, two lines display, 5*7 dot matrix
        LCD_WriteCommand(0x0C); // Display on, cursor off, blink off
        LCD_WriteCommand(0x06); // After data read/write operation, cursor automatically increments, screen does not move
        LCD_WriteCommand(0x01); // Cursor reset, clear screen
        LCD_Delay2ms(); // Clearing screen command takes longer time, requires longer delay
    }
    
    void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char) {
        LCD_SetCursor(Line,Column);
        LCD_WriteData(Char);
    }
    
    void LCD_ShowString(unsigned char Line,unsigned char Column,char *String) {
        unsigned char i;
        LCD_SetCursor(Line,Column);
        for(i=0;String[i]!='\0';i++) {
            LCD_WriteData(String[i]);
        }
    }
    
    int LCD_Pow(int X,int Y) {
        unsigned char i;
        int Result=1;
        for(i=0;i<Y;i++) {
            Result*=X;
        }
        return Result;
    }
    
    void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length) {
        unsigned char i;
        LCD_SetCursor(Line,Column);
        for(i=Length;i>0;i--) {
            LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
        }
    }
    
    void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length) {
        unsigned char i;
        unsigned int Number1;
        LCD_SetCursor(Line,Column);
        if(Number>=0) {
            LCD_WriteData('+');
            Number1=Number;
        } else {
            LCD_WriteData('-');
            Number1=-Number;
        }
        for(i=Length;i>0;i--) {
            LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
        }
    }
    
    void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length) {
        unsigned char i,SingleNumber;
        LCD_SetCursor(Line,Column);
        for(i=Length;i>0;i--) {
            SingleNumber=Number/LCD_Pow(16,i-1)%16;
            if(SingleNumber<10) {
                LCD_WriteData(SingleNumber+'0');
            } else {
                LCD_WriteData(SingleNumber-10+'A');
            }
        }
    }
    
    void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length) {
        unsigned char i;
        LCD_SetCursor(Line,Column);
        for(i=Length;i>0;i--) {
            LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
        }
    }
    
    void LCD_Clear(void) {
        LCD_WriteCommand(0x01);
        LCD_Delay2ms();
    }
    
    void LCD_IsShowCursor(unsigned char State) {
        if(State) {
            LCD_WriteCommand(0x0E);
        } else {
            LCD_WriteCommand(0x0C);
        }
    }

Pitfall Guide: The 3 Most Common Mistakes for Beginners

  1. LCD not displaying?First, check if VCC and GND are connected incorrectly, then adjust the contrast potentiometer (turn it clockwise a bit). If it still doesn’t work, try replacing the LCD (cheap ones may be faulty).

  2. Inaccurate distance measurement?Ultrasonic waves are easily affected by environmental temperature (the speed varies in winter and summer). You can add temperature compensation in the code; also, avoid measuring objects that are too close (less than 2cm) or too far (more than 4m).

  3. No response from the module?Use a multimeter to check if the HC-SR04’s VCC has 5V voltage, and check if the connections for Trig and Echo are loose; Dupont wires sometimes have poor contact.

Advanced Play: Make Your Distance Meter Cooler!

After completing the basic version, try these upgrade features:

  • Add a buzzer: Alarm when the distance is less than 30cm (modify the condition in the main function)
  • Replace with an OLED screen: Clearer display, can also show distance curves
  • Add a Bluetooth module: Send data to your phone (using the HC-05 module)

Finally: For the complete code, follow the public account “Bear Stealing Honey” and reply with“Ultrasonic Distance Measurement” to get itIf you find this useful, feel free to follow the public account and give a “recommendation” and “like” before you go!

Leave a Comment