Pic 16f877 ve HCSR04 ile mesafe ölçümü

Katılım
11 May 2024
Mesajlar
11
Puanları
1
Yaş
21
iyi günler ,mıkroişlemciler dersi için proje yapmamız istendi ve bızde hcsr04 sensörüyle mesafe ölçüp lcd ye yazdırmak istiyoruz. kodumuz da ekrana mesafe(distance) yazısı geliyor ve alt satırda 0 cm yazıyor ama 0 cm de takılı kalıyor başka değer göstermiyor.bunu nasıl çözebilirm yardımcı olur musunuz? ayrıca diyelim 10 cm den küçük değerlerde buzzer kodu da eklemek istiyorum nereye eklemeliyim teşekkürler. kod şu şekilde:


//LCD module connections
#define LCD_RS_PIN PIN_D0
#define LCD_RW_PIN PIN_D1
#define LCD_ENABLE_PIN PIN_D2
#define LCD_DATA4 PIN_D3
#define LCD_DATA5 PIN_D4
#define LCD_DATA6 PIN_D5
#define LCD_DATA7 PIN_D6
//End LCD module connections

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 8000000)
#include <lcd.c>
#use fast_io(B)

int8 check;
unsigned int16 i, distance;
void main(){
output_b(0);
set_tris_b(2); // Configure RB1 as input
lcd_init(); // Initialize LCD module
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_2); // Configure Timer1 module
set_timer1(0); // Reset Timer1
lcd_putc('\f'); // LCD Clear
lcd_gotoxy(4, 1); // Go to column 4 row 1
lcd_putc("Distance:");
while(TRUE){
check = 0;
i = 0;
output_high(PIN_B0);
delay_us(10);
output_low(PIN_B0);
set_timer1(0); // Reset Timer1
while(!input(PIN_B1) && (get_timer1() < 1000));
if(get_timer1() > 990)
check = 1; // Timeout error
set_timer1(0); // Reset Timer1
while(input(PIN_B1) && (i < 25000))
i = get_timer1(); // Store Timer1 value in i
if(i > 24990) // Out of range error
check = 2;
if(check == 1){
lcd_gotoxy(3, 2); // Go to column 3 row 2
lcd_putc(" Time Out ");
}
if(check == 2){
lcd_gotoxy(3, 2); // Go to column 3 row 2
lcd_putc("Out Of Range");
}
else{
distance = i/58; // Calculate the distance
lcd_gotoxy(3, 2); // Go to column 3 row 2
lcd_putc(" cm ");
lcd_gotoxy(6, 2); // Go to column 6 row 2
printf(lcd_putc,"%3Lu",distance);
}
delay_ms(100);
}
}
 
Kodunuzda bazı hatalar ve eksiklikler var gibi görünüyor.
İlk olarak, kodunuzda 'check' değerini kontrol ediyorsunuz, ancak 'else' bloğunu sadece 'check == 2' için kullanıyorsunuz.
'check == 1' durumunda 'Out of Range' mesajı yazılmıyor.
Bu nedenle, 'check == 1' durumunda da bir mesaj yazmanız gerekiyor.

Ayrıca, buzzer kodunu eklemek istierseniz, belirli bir mesafe limiti altında buzzer çalmak istediğinizde kontrol yapmanız gerekiyor.
Mesela, 10 cm'den daha küçük bir mesafede buzzer çalmasını istiyorsanız, 'distance' değerini kontrol edebilirsiniz.
Bu kodda, 'BUZZER_PIN' tanımlayarak ve buzzer kodunu 'distance' değerini kontrol ederek ekledim.
Eğer 'distance' 10 cm'den küçükse, buzzer aktive edilecek, değilse devre dışı bırakılacak.
Bu şekilde, LCD ekranınızda mesafe görüntülenirken, aynı zamanda belirli bir mesafenin altında olduğunda bir alarm verecektir
Kodu test edin:
.
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 8000000)
#include <lcd.c>
#use fast_io(B)

#define BUZZER_PIN PIN_C0 // Buzzer pin

int8 check;
unsigned int16 i, distance;

void main(){
output_b(0);
set_tris_b(0b00000010); // Configure RB1 as input, others as output
output_low(BUZZER_PIN); // Initialize buzzer pin
lcd_init(); // Initialize LCD module
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_2); // Configure Timer1 module
set_timer1(0); // Reset Timer1
lcd_putc('\f'); // LCD Clear
lcd_gotoxy(4, 1); // Go to column 4 row 1
lcd_putc("Distance:");

while(TRUE){
check = 0;
i = 0;
output_high(PIN_B0);
delay_us(10);
output_low(PIN_B0);
set_timer1(0); // Reset Timer1
while(!input(PIN_B1) && (get_timer1() < 1000));
if(get_timer1() > 990)
check = 1; // Timeout error
set_timer1(0); // Reset Timer1
while(input(PIN_B1) && (i < 25000))
i = get_timer1(); // Store Timer1 value in i
if(i > 24990) // Out of range error
check = 2;

if(check == 1){
lcd_gotoxy(3, 2); // Go to column 3 row 2
lcd_putc(" Time Out ");
}
else if(check == 2){
lcd_gotoxy(3, 2); // Go to column 3 row 2
lcd_putc("Out Of Range");
}
else{
distance = i/58; // Calculate the distance
lcd_gotoxy(3, 2); // Go to column 3 row 2
lcd_putc(" cm ");
lcd_gotoxy(6, 2); // Go to column 6 row 2
printf(lcd_putc,"%3Lu",distance);

// Check if distance is less than 10 cm and activate buzzer
if(distance < 10){
output_high(BUZZER_PIN);
}
else{
output_low(BUZZER_PIN);
}
}
delay_ms(100);
}
}
 
cevabınız için teşekkür ederim bu seferde compile ediliyor ama ekrana hiç yazı gelmiyor .proteusta eklediğiniz buzzerıda çizimime ekledim. ne ayrıca diğer sorum buzer pinin yada lcd pinlerini fast_io diye tanımlamaya gerk var mı? gerek yok mu?
 

Ekli dosyalar

  • Ekran görüntüsü 2024-05-12 140221.png
    61.2 KB · Görüntüleme: 7
Ekrana hiç yazı gelmemesi ve buzzerın çalışmaması, birkaç olası neden olabilir. İlk olarak, kodunuzda LCD'ye veri göndermek için printf(lcd_putc,"%3Lu",distance); kullanıyorsunuz. Ancak bu ifade doğru bir şekilde LCD'ye mesafe değerini yazdırmıyor olabilir.

Bunun yerine, mesafe değerini doğrudan yazdırmak için lcd_putc(distance/100 + '0'); lcd_putc((distance/10)%10 + '0'); lcd_putc(distance%10 + '0'); gibi bir ifade kullanabilirsiniz. Bu şekilde, mesafe değerini üç basamak olarak doğrudan LCD'ye yazdırabilirsiniz.

Ayrıca, buzzerın simülatördeki tanımlanma değerlerine, voltajına bakın. (Led takarak deneyebilirsiniz)

Bu kodu deneyin:

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 8000000)
#include <lcd.c>

#define BUZZER_PIN PIN_C0 // Buzzer pin

int8 check;
unsigned int16 i, distance;

void main(){
output_b(0);
set_tris_b(0b00000010); // Configure RB1 as input, others as output
output_low(BUZZER_PIN); // Initialize buzzer pin
lcd_init(); // Initialize LCD module
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_2); // Configure Timer1 module
set_timer1(0); // Reset Timer1
lcd_putc('\f'); // LCD Clear
lcd_gotoxy(4, 1); // Go to column 4 row 1
lcd_putc("Distance:");

while(TRUE){
check = 0;
i = 0;
output_high(PIN_B0);
delay_us(10);
output_low(PIN_B0);
set_timer1(0); // Reset Timer1
while(!input(PIN_B1) && (get_timer1() < 1000));
if(get_timer1() > 990)
check = 1; // Timeout error
set_timer1(0); // Reset Timer1
while(input(PIN_B1) && (i < 25000))
i = get_timer1(); // Store Timer1 value in i
if(i > 24990) // Out of range error
check = 2;

if(check == 1){
lcd_gotoxy(3, 2); // Go to column 3 row 2
lcd_putc(" Time Out ");
}
else if(check == 2){
lcd_gotoxy(3, 2); // Go to column 3 row 2
lcd_putc("Out Of Range");
}
else{
distance = i/58; // Calculate the distance
lcd_gotoxy(3, 2); // Go to column 3 row 2
lcd_putc(" cm ");
lcd_gotoxy(6, 2); // Go to column 6 row 2
lcd_putc(distance/100 + '0');
lcd_putc((distance/10)%10 + '0');
lcd_putc(distance%10 + '0');

// Check if distance is less than 10 cm and activate buzzer
if(distance < 10){
output_high(BUZZER_PIN);
}
else{
output_low(BUZZER_PIN);
}
}
delay_ms(100);
}
}


Bu kod, mesafe değerini üç basamak olarak doğrudan LCD'ye yazdırır ve buzzerın doğru çalışması için BUZZER_PIN'i doğru olarak ayarlar.
Bu düzeltmelerin ardından kodunuzun düzgün çalışması gerekir.

Fast_IO kullanımı, bazı durumlarda performans artışı sağlayabilir, ancak bu durumda gerekli değildir. Ancak, kodunuzda verilen pinleri fast_io olarak tanımlamanızın herhangi bir olumsuz etkisi yoktur.
Bu, genellikle daha genel bir programlama uygulamasıdır.

Kolay gelsin
 
teşekkürler .ama yine bi değişiklik olmadı .Neden bu kadar zorlandığımı anlayamıyorum herşey doğru geliyor hatayı bi türlü anlayamadım. attığınız kodda da bi değişiklik olmadı malesef .ilk attığım şematikte vdd vs pinleri proteusta gözükmüyor onları otomatik olarak bağlıyor diye biliyorum değil mi onlardan kaynkalı bi sorun olamaz sanırım.zira ilk attığım kodda distance 0 cm yazıyor çünkü
 
Tamam, siz Proteus çizimi gönderin, ben Multisim kullanıyorum ama bir bakalım.
Component tanımlamalarında Vdd Vs gibi pinlerin görünmesi lazım.
Terdeddüdünüz varsa dışardan bağlayın.
 
Küçük bir hata buldum,
Osilatör kısmındaki kondansatörler 22uF konulmuş,
Bu kondansatör değerleri ile osilatör kısmı çalışamaz, 22pF olmalı.
Bu şekilde deneyin
Ben Proteus'u yükledim ancak kod karakter hataları alıyorum, siz source kodu pic'e yükleyip gönderirseniz bakmaya devam edebilirim.
Siz hata mesajları alıyorsanız onları fotoğraflayın
 
Son düzenleme:
https://drive.google.com/file/d/1wF65Len-A9FMo5MdovIUdCLb7aWkDDL7/view?usp=drive_link
https://drive.google.com/file/d/19GhftMjHkRpPh1JOf0aHuSjz1vaXFLh_/view?usp=drive_link

proteusa yükldiğimde paylaştığımda tekrar açınca hex yüklenmemiş gözüküyor hex ve c dosyalarını linkten indirebilirsiniz.
 
Son düzenleme:
düzeldi sanırım ekte bulabilrsiniz
 

Ekli dosyalar

  • MIKRO PORJEA (1)zzz.pdsprj
    18.4 KB · Görüntüleme: 4
Bu siteyi kullanmak için çerezler gereklidir. Siteyi kullanmaya devam etmek için onları kabul etmelisiniz. Daha fazla bilgi edin…