i am not getting the distance value in LCD for ultrasonic distance sensor

yash_01

Newbie level 4
Joined
Dec 26, 2024
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
55
Missing CODE or SYNTAX Tags: ADDED BY MODERATOR
i wanted to create a project using at89s52 for distance of an object measurement using ultrasonic sensor. so i wrote a code using keil and tried the simulation using proteus, i am getting "distance" as the output but the distance value isnt shown. what is wrong in the code?? my code is:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <reg51.h>
#define lcd_data P2
sbit rs=P1^0; //reg select
sbit rw=P1^1; //rewrite
sbit en=P1^2;  //enable
sbit trig=P1^3;
sbit echo=P1^4;
char distance;
char time;
int i=0,j=0;
char str[4];
 
void lcd_init();
void cmd(unsigned char a);
void dat(unsigned char b);
void show(unsigned char *s);
void lcd_delay();
 
void lcd_init()
{
    cmd(0x38);   //defining is first, the peripherals and the line
    cmd(0x0e);  
    cmd(0x01);
    cmd(0x06);  //entry mode - after refreshing we're ready to use it
    cmd(0x0c);  //defining cursor
    cmd(0x80);    // start from the first row first column
}
 
void cmd(unsigned char a)
{
    lcd_data=a;
    rs=0;   //registers select
    rw=0; // write mode
    en=1; //enabling writing to the registers, power should be on when in use
    lcd_delay();
    en=0;
}
 
void dat(unsigned char b)
{
    lcd_data=b;
    rs=1;
    rw=0;
    en=1;
      lcd_delay();
    en=0;
}
 
void show(unsigned char *s)
{
    while(*s) {
        dat(*s++);
    }
}
 
void lcd_delay(){
    int i;
    for (i=0;i<10000;i++){
    }
}
 
void send_pulse(){
    trig=1;
    TMOD = 0x01;
    TH0 = 0xff;
    TL0 = 0xf6;
    TR0 = 1;       
  while (TF0 == 0);
  TR0 = 0;      
    TF0 = 0;          
    trig=0;
}
 
unsigned char ultrasonic(){  //11.3m
    TMOD = 0x01;          
  TH0 = 0x00;           
  TL0 = 0x00;
    TR0=1;
    send_pulse();
    while (!echo);
    while (echo);
    TR0=0;
    time=(TH0 << 8) | TL0;
    return time/58;
}
 
void int_to_string(unsigned int num, unsigned char *buf) {
    int i = 0, j;
    unsigned char temp[4];
   
    // Convert each digit to a character
    if (num == 0) {
        buf[i++] = '0';
    } else {
        while (num > 0) {
            temp[i++] = (num % 10) + '0';
            num /= 10;
        }
    }
 
    // Reverse the order
    for (j = 0; j < i; j++) {
        buf[j] = temp[i - j - 1];
    }
    buf[I] = '\0'; // Null-terminate the string
}
 
void main(){
    lcd_init();
    cmd(0x80);
    show("Distance");
    while(1){
                    distance=ultrasonic();
              int_to_string(distance, str);
                    cmd(0xc0);
                    show (str);
                    lcd_delay();
                    cmd(0x01);
                    lcd_delay();
            
    }
}[/I]

 
Last edited by a moderator:

the distance value isnt shown
Means what exactly? Empty second line, value of 0 displayed?
Many possible problems. I stopped reading the code when found that time is using an 8-bit (char) variable type, so most of the distance information is discarded.
 

Means what exactly? Empty second line, value of 0 displayed?
Many possible problems. I stopped reading the code when found that time is using an 8-bit (char) variable type, so most of the distance information is discarded.
empty second line, thats the problem . abt the 8 bit char value, since im focusing on nearby distances,i expect my value to be lesser, within 8 bits. is int type required??
 

As time is divided by 58, 8 bit value for time is restricting distance to 0..4. Hardly what you want.
--- Updated ---

Also this is surely wrong:
Code:
buf = '\0'; // Null-terminate the string

Looks like you have written the whole code from the scratch. That's instructive, but you should have a simulator or debugger that allows to execute the code interactively and find all errors.
 
Last edited:

i set my distance as 3cm in that case, but still am not getting the distance value in the second line

 

I don't know the Keil compiler but I'm pretty sure that your 'lcd_delay()' function will not do anything. Most of the compilers that I know of (even in the lowest level of optimisation) will replace this whole function with nothing. You are probably getting away with this in the simulator because (I assume) it doesn't care about actual delays in the simulated LCD.
Instead you should be using a delay function provided by the compiler or use a hardware timer (or use assembler that will not be optimised away).
I don't know the LCD you will actually be using, but I suggest that you look at the data sheet for it - many will require long(ish) delays during the initialisation that youy are not providing.
Does the code as you have shown it actually compile? The reason I ask is that line 105 uses an uppercase 'I' as the index which is not declared. (Elsewhere you use a lower case 'i' that is correct. I think this may be due to the forum thinking that this is the start of an italic block, going by the '[/I]' at the end of the code block.)
Susan
 


See post #4.
got it, i rectified the code. but now the problem is im getting my distance as 0:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <reg51.h>
#define lcd_data P2
sbit rs=P1^0; //reg select
sbit rw=P1^1; //rewrite
sbit en=P1^2;  //enable
sbit trig=P1^3;
sbit echo=P1^4;
int distance;
int time;
int i=0,j=0;
char str[4];
 
void lcd_init();
void cmd(unsigned char a);
void dat(unsigned char b);
void show(unsigned char *s);
void lcd_delay();
 
void lcd_init()
{
    cmd(0x38);   //defining is first, the peripherals and the line
    cmd(0x0e);  
    cmd(0x01);
    cmd(0x06);  //entry mode - after refreshing we're ready to use it
    cmd(0x0c);  //defining cursor
    cmd(0x80);    // start from the first row first column
}
 
void cmd(unsigned char a)
{
    lcd_data=a;
    rs=0;   //registers select
    rw=0; // write mode
    en=1; //enabling writing to the registers, power should be on when in use
    lcd_delay();
    en=0;
}
 
void dat(unsigned char b)
{
    lcd_data=b;
    rs=1;
    rw=0;
    en=1;
      lcd_delay();
    en=0;
}
 
void show(unsigned char *s)
{
    while(*s) {
        dat(*s++);
    }
}
 
void lcd_delay(){
    int i;
    for (i=0;i<10000;i++){
    }
}
       
void send_pulse(){
    trig=1;
    TMOD = 0x01;
    TH0 = 0xff;
    TL0 = 0xf6;
    TR0 = 1;       
  while (TF0 == 0);
  TR0 = 0;      
    TF0 = 0;          
    trig=0;
}
 
unsigned int ultrasonic(){ 
    TMOD = 0x01;          
  TH0 = 0x00;           
  TL0 = 0x00;
    TR0=1;
    send_pulse();
    while (!echo);
    while (echo);
    TR0=0;
    time=(TH0 << 8) | TL0;
    return time/58;
}
 
void intToString(unsigned int num, char *str) {
    int i = 0,k=0,j=0; 
    do {
        str[i++] = (num % 10) + '0'; 
        num /= 10;
    } while (num != 0);
    str[I] = '\0';
    for ( j = 0, k = i - 1; j < k; j++, k--) {
        char temp = str[j];
        str[j] = str[k];
        str[k] = temp;
    }
}
 
void main(){
    lcd_init();
    while(1){
              cmd(0x80);
            show("Distance");
                    distance=ultrasonic();
              intToString(distance, str);
                    cmd(0xc0);
                    show (str);
                    lcd_delay();
                    cmd(0x01);
                    lcd_delay();
    }
}

[/I]
 
Last edited by a moderator:

yes it is, in my code i've written only small i, so it compiles with no errors. and for the lcd_delay, yes i agree it is not recommeded to use for loops, just for now im using it because proteus accepts it. but while flashing ill make sure to include hardware timers
 

Usage of Timer0 for pulse generation and measurement causes problems. Presently the timer isn't running when you intendend to measure echo time. Revise respective code, ultrasonic() and send_pulse().
As stated before, if you write code from the scratch, consider that everly line might have errors.
 

    yash_01

    Points: 2
    got the answer ! thank u!
and for the lcd_delay, yes i agree it is not recommeded to use for loops, just for now im using it because proteus accepts it. but while flashing ill make sure to include hardware timers
I don´t understand your idea with this.

The delay() (non accurate) ... as well as the timer (accurate) is responsible for the overall measurement accuracy.

Now you encounter accuracy problems ... and you worry about these accuracy problems. ..but still rely on non accurate delay().
This makes no sense for me.

In my opinion:
If you want to test your "prototoype" according accuracy ... then you need to design EVERYTHING for the test, that affects accuracy, like you want it in your finished product.

You may change the power supply (which should not significantly affect accuracy), you may change the display, you may change the size of your PCB, you may change the user interface..
BUT you need to set up your application "accuracy wise" like the expected end product.

Otherwise any accuracy test will not give meaningful informations for the end product.


Klaus
 

got the output! thanks !
 

Cookies are required to use this site. You must accept them to continue using the site. Learn more…