mikroC ile PIC Programlama #09 : HC-SR04 ile Mesafe Ölçümü
Merhaba, mikroC ile PIC programlama eğitimlerimizin bu adımında HC-SR04 ultrasonic ses sensörünü kullanarak mesafe ölçüm uygulaması yapacağız.
Bölümler
00:00 Proje Dosyalarının Oluşturulması
00:46 Pin Tanımlamaları
02:04 Geriye Değer Döndüren Fonksiyon Tasarımı
02:42 Timer0 Kullanımı ve T0CON Registerinin Düzenlenmesi
03:51 HC-SR04 Çalışma Prensibi ve Uygulaması
06:18 Mesafe Hesaplamaları
09:43 Ölçülen Mesafenin IntToStr() Fonksiyonu ile Ekrana Yazdırılması
12:10 Uygulamanın Test Edilmesi ve GitHub’a Yüklenmesi
Şematik Tasarım
Uygulama Kodları
// Connections
sbit LED at LATA4_bit;
sbit TRIG at LATB0_bit;
sbit ECHO at RB1_bit;
sbit LCD_BACKLIGHT at LATD6_bit;
// Lcd pinout settings
sbit LCD_RS at LATD0_bit;
sbit LCD_EN at LATD1_bit;
sbit LCD_D4 at LATD2_bit;
sbit LCD_D5 at LATD3_bit;
sbit LCD_D6 at LATD4_bit;
sbit LCD_D7 at LATD5_bit;
// Pin direction
sbit LCD_RS_Direction at TRISD0_bit;
sbit LCD_EN_Direction at TRISD1_bit;
sbit LCD_D7_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD2_bit;
// Global Variables
unsigned int distance;
char txt[7];
void wait(unsigned int time){
while(time--)
delay_ms(1);
}
unsigned int getDistance(){
unsigned int temp;
T0CON=0b01000110;
TMR0H=0;
TMR0L=0;
TRIG=1;
delay_us(10);
TRIG=0;
while(!ECHO);
TMR0ON_bit=1;
while(ECHO && TMR0L<250);
temp=1.8303*TMR0L;
return temp;
}
void main() {
TRISA=0b00000000; // [][][][LED][][][][]
TRISB=0b00000010; // [][][][][][][ECHO][TRIG]
TRISC=0b00000000; // [][][][][][][][]
TRISD=0b00000000; // [][LCD_BACKLIGHT][LCD_D7][LCD_D6][LCD_D5][LCD_D4][LCD_EN][LCD_RS]
TRISE=0b00000000; // [][][][][][][][]
LATA=0x00;
LATB=0x00;
LATC=0x00;
LATD=0x00;
LATE=0x00;
//ADCON1=0x0F; // PIC18F4550 için
ANSELA=0x00;
ANSELB=0x00;
ANSELC=0x00;
ANSELD=0x00;
ANSELE=0x00;
Lcd_Init();
LCD_BACKLIGHT=1;
Lcd_Out(1,1,"Mesafe: mm");
Lcd_Cmd(_LCD_CURSOR_OFF);
while(1){
distance=getDistance();
IntToStr(distance,txt);
if(distance>300) Lcd_Out(1,8," MAX");
else Lcd_Out(1,8,txt);
wait(100);
}
}
Uygulama kodlarını GitHub üzerinden incelemek ve indirmek için tıklayın. Merak ettiğiniz ve aklınıza takılan soruları aşağıda 👇 yorum olarak bize iletebilirsiniz. Yeni uygulamalar gerçekleştirirken YouTube kanalımızdaki videolarımızdan yararlanmayı unutmayın. İyi çalışmalar. 🙂 #geliştirmeyebaşla
12 thoughts on “mikroC ile PIC Programlama #09 : HC-SR04 ile Mesafe Ölçümü”
merhaba. Ben trudyo ile uzaktan bluetooth kontrollü araç yapıyorum. Aracın kontrol kodlarını yazdım. Ancak projeme mesafe sensörü koyarak 20 cm de bir cisim algılandığında motorlar eğer çalışıyorsa motorları durdurmak istiyorum. Örnek uygulamanızdan esinlenerek kodlar denedim ama bir sonuç alamadım. Yardımcı olursanız çok sevinirim.
Merhaba, örnek kodlarınızı paylaşabilir misiniz? Ek olarak mesafe okuma işlemini yapabiliyor musunuz? Yani mesafe okuma kısmında mı sorun yaşıyorsunuz, yoksa örnekte bulunan kodları kendi programınıza entegre ederken mi sorun yaşıyorsunuz?
Mesafe sensörü bağlantılarını ve kod denemeleri yaptım Mesafe sensörünün önüne engel koymama rağmen motorlar haraketine devam ediyor. Yazmış olduğum kodu paylaşıyorum.
// Pin Tanımlamaları
sbit motorA1 at LATB5_bit; // L298N IN3
sbit motorA2 at LATB6_bit; // L298N IN1
sbit motorB1 at LATB7_bit; // L298N IN2
sbit motorB2 at LATB4_bit; // L298N IN4
sbit motorA1_Direction at TRISB5_bit;
sbit motorA2_Direction at TRISB6_bit;
sbit motorB1_Direction at TRISB7_bit;
sbit motorB2_Direction at TRISB4_bit;
// Değişkenler
char state; // Bluetooth'tan gelen veri
// Motor Kontrol Fonksiyonu
void setMotor(char motorA1State, char motorA2State, char motorB1State, char motorB2State) {
motorA1 = motorA1State;
motorA2 = motorA2State;
motorB1 = motorB1State;
motorB2 = motorB2State;
}
// Başlangıç Ayarları
void setup() {
// Motor pinlerini çıkış olarak ayarla
motorA1_Direction = 0;
motorA2_Direction = 0;
motorB1_Direction = 0;
motorB2_Direction = 0;
// Motorları başlangıçta kapalı tut
setMotor(0, 0, 0, 0);
// Analog girişleri devre dışı bırak
ANSELA = 0x00;
ANSELB = 0x00;
ANSELC = 0x00;
// UART başlat
UART1_Init(9600); // 9600 baud
Delay_ms(100); // UART kararlılığı için küçük bir gecikme
}
// Komutları İşle
void processCommand() {
switch (state) {
case '\r' :break;
case 'F': setMotor(1, 1, 0, 0); break; // İleri
case 'B': setMotor(0, 0, 1, 1); break; // Geri
case 'L': setMotor(1, 0, 1, 0); break; // Sol
case 'R': setMotor(0, 1, 0, 1); break; // Sağ
case 'S': setMotor(0, 0, 0, 0); break; // Dur
case '\n' :break;
//default: setMotor(0, 0, 0, 0); break; // Geçersiz Komut
}
}
// Ana Döngü
void loop() {
if (UART1_Data_Ready()) {
state = UART1_Read(); // Gelen veriyi oku
processCommand(); // Komutu işle
}
}
// Ana Fonksiyon
void main() {
setup(); // Başlangıç ayarlarını yap
while (1) {
loop(); // Ana döngüyü çalıştır
}
}
Yanlış kodu atmışım sanırım. Denediğim kod bu şekilde:
// Pin Tanımlamaları
sbit motorA1 at LATB5_bit; // L298N IN3
sbit motorA2 at LATB6_bit; // L298N IN1
sbit motorB1 at LATB7_bit; // L298N IN2
sbit motorB2 at LATB4_bit; // L298N IN4
sbit motorA1_Direction at TRISB5_bit;
sbit motorA2_Direction at TRISB6_bit;
sbit motorB1_Direction at TRISB7_bit;
sbit motorB2_Direction at TRISB4_bit;
// Mesafe Sensörü Pin Tanımlamaları
sbit Trigger at LATB0_bit; // Trigger pini RB0
sbit ECHO at RB1_bit; // Echo pini RB1
sbit Trigger_Direction at TRISB0_bit; // Trigger çıkış
sbit Echo_Direction at TRISB1_bit; // Echo giriş
// Değişkenler
char state; // Bluetooth'tan gelen veri
unsigned int time; // Mesafe ölçüm zamanı
float distance; // Mesafe
// Motor Kontrol Fonksiyonu
void setMotor(char motorA1State, char motorA2State, char motorB1State, char motorB2State) {
motorA1 = motorA1State;
motorA2 = motorA2State;
motorB1 = motorB1State;
motorB2 = motorB2State;
}
// Gecikme Fonksiyonu (us)
void Delay_us(unsigned int us_delay) {
while (us_delay--)
asm nop;
}
// Ultrasonik Ölçüm Fonksiyonu
float Measure_Distance() {
Trigger = 0;
Delay_us(2); // Minimum 2us bekleme
Trigger = 1;
Delay_us(10); // 10us tetikleme sinyali
Trigger = 0;
while (!Echo); // Echo yükselmesini bekle
TMR1H = 0; // Timer1 sıfırla
TMR1L = 0;
T1CON.TMR1ON = 1; // Timer1 başlat
while (Echo); // Echo düşmesini bekle
T1CON.TMR1ON = 0; // Timer1 durdur
time = (TMR1H << 8) | TMR1L; // Timer değerini oku
distance = (float)time / 58.0; // Mesafeyi cm'ye dönüştür (HC-SR04 için formül)
return distance;
}
// Komutları İşle
void processCommand() {
switch (state) {
case 'F': setMotor(1, 1, 0, 0); break; // İleri
case 'B': setMotor(0, 0, 1, 1); break; // Geri
case 'L': setMotor(1, 0, 1, 0); break; // Sol
case 'R': setMotor(0, 1, 0, 1); break; // Sağ
case 'S': setMotor(0, 0, 0, 0); break; // Dur
default: setMotor(0, 0, 0, 0); break; // Geçersiz Komut
}
}
// Başlangıç Ayarları
void setup() {
// Motor pinlerini çıkış olarak ayarla
motorA1_Direction = 0;
motorA2_Direction = 0;
motorB1_Direction = 0;
motorB2_Direction = 0;
// Motorları başlangıçta kapalı tut
setMotor(0, 0, 0, 0);
// Mesafe sensörü pin yönleri
Trigger_Direction = 0; // Trigger çıkış
Echo_Direction = 1; // Echo giriş
// Analog girişleri devre dışı bırak
ANSELA = 0x00;
ANSELB = 0x00;
ANSELC = 0x00;
// Timer1 Ayarları
T1CON = 0b00100001; // Prescaler 1:4, Timer1 OSC kapalı
// UART başlat
UART1_Init(9600); // 9600 baud
Delay_ms(100); // UART kararlılığı için küçük bir gecikme
}
// Ana Döngü
void loop() {
// Mesafe ölçümü
distance = Measure_Distance();
if (distance < 10.0) { // Mesafe 10 cm'den azsa
setMotor(0, 0, 0, 0); // Motorları durdur
} else {
if (UART1_Data_Ready()) {
state = UART1_Read(); // Gelen veriyi oku
processCommand(); // Komutu işle
}
}
Delay_ms(100); // Kısa bekleme
}
// Ana Fonksiyon
void main() {
setup(); // Başlangıç ayarlarını yap
while (1) {
loop(); // Ana döngüyü çalıştır
}
}
Senin için entegre etmeye çalıştım. Rica etsem denemenden sonra durumu bildirebilir misin?
// Pin Tanimlamalari
sbit motorA1 at LATB5_bit; // L298N IN3
sbit motorA2 at LATB6_bit; // L298N IN1
sbit motorB1 at LATB7_bit; // L298N IN2
sbit motorB2 at LATB4_bit; // L298N IN4
sbit motorA1_Direction at TRISB5_bit;
sbit motorA2_Direction at TRISB6_bit;
sbit motorB1_Direction at TRISB7_bit;
sbit motorB2_Direction at TRISB4_bit;
// Mesafe Sensörü Pin Tanimlamalari
sbit TRIG at LATB0_bit; // Trigger pini RB0
sbit ECHO at RB1_bit; // Echo pini RB1
sbit Trigger_Direction at TRISB0_bit; // Trigger çikis
sbit Echo_Direction at TRISB1_bit; // Echo giris
// Degiskenler
char state; // Bluetooth’tan gelen veri
unsigned int time; // Mesafe ölçüm zamani
/******************************************************************************/
// Mesafe Olcumu
// Global Variables
unsigned int distance;
unsigned int getDistance(){
unsigned int temp;
T0CON=0b01000110;
TMR0H=0;
TMR0L=0;
TRIG=1;
delay_us(10);
TRIG=0;
while(!ECHO);
TMR0ON_bit=1;
while(ECHO && TMR0L<250);
temp=1.8303*TMR0L;
return temp;
}
/******************************************************************************/
// Motor Kontrol Fonksiyonu
void setMotor(char motorA1State, char motorA2State, char motorB1State, char motorB2State) {
motorA1 = motorA1State;
motorA2 = motorA2State;
motorB1 = motorB1State;
motorB2 = motorB2State;
}
// Komutlari Isle
void processCommand() {
switch (state) {
case 'F': setMotor(1, 1, 0, 0); break; // Ileri
case 'B': setMotor(0, 0, 1, 1); break; // Geri
case 'L': setMotor(1, 0, 1, 0); break; // Sol
case 'R': setMotor(0, 1, 0, 1); break; // Sag
case 'S': setMotor(0, 0, 0, 0); break; // Dur
default: setMotor(0, 0, 0, 0); break; // Geçersiz Komut
}
}
// Baslangiç Ayarlari
void setup() {
// Motor pinlerini çikis olarak ayarla
motorA1_Direction = 0;
motorA2_Direction = 0;
motorB1_Direction = 0;
motorB2_Direction = 0;
// Motorlari baslangiçta kapali tut
setMotor(0, 0, 0, 0);
// Mesafe sensörü pin yönleri
Trigger_Direction = 0; // Trigger çikis
Echo_Direction = 1; // Echo giris
// Analog girisleri devre disi birak
ANSELA = 0x00;
ANSELB = 0x00;
ANSELC = 0x00;
// UART baslat
UART1_Init(9600); // 9600 baud
Delay_ms(100); // UART kararliligi için küçük bir gecikme
}
// Ana Döngü
void loop() {
// Mesafe ölçümü
//distance=getDistance();
if (UART1_Data_Ready()) {
state = UART1_Read(); // Gelen veriyi oku
distance=getDistance();
if(distance>200) // Mesafe 200'den buyuk ise
processCommand(); // Komutu isle
else // Degilse
setMotor(0, 0, 0, 0); // Motoru durdur
delay_ms(100); // Komut isletildikten sonra 100ms bekleme
}
/*
if (distance < 10.0) { // Mesafe 10 cm'den azsa setMotor(0, 0, 0, 0); // Motorlari durdur } else { if (UART1_Data_Ready()) { state = UART1_Read(); // Gelen veriyi oku processCommand(); // Komutu isle } }Delay_ms(100); // Kisa bekleme */ }// Ana Fonksiyon void main() { setup(); // Baslangiç ayarlarini yap while (1) { loop(); // Ana döngüyü çalistir } }
en son kısımda bir hata olabilirmi acaba. Derlerdim ama ana fonksiyon tanımlanmamış hatası veriyor
Tekrar paylaşabilirim.
// Pin Tanimlamalari
sbit motorA1 at LATB5_bit; // L298N IN3
sbit motorA2 at LATB6_bit; // L298N IN1
sbit motorB1 at LATB7_bit; // L298N IN2
sbit motorB2 at LATB4_bit; // L298N IN4
sbit motorA1_Direction at TRISB5_bit;
sbit motorA2_Direction at TRISB6_bit;
sbit motorB1_Direction at TRISB7_bit;
sbit motorB2_Direction at TRISB4_bit;
// Mesafe Sensörü Pin Tanimlamalari
sbit TRIG at LATB0_bit; // Trigger pini RB0
sbit ECHO at RB1_bit; // Echo pini RB1
sbit Trigger_Direction at TRISB0_bit; // Trigger çikis
sbit Echo_Direction at TRISB1_bit; // Echo giris
// Degiskenler
char state; // Bluetooth’tan gelen veri
unsigned int time; // Mesafe ölçüm zamani
// Mesafe Olcumu
// Global Variables
unsigned int distance;
unsigned int getDistance(){
unsigned int temp;
T0CON=0b01000110;
TMR0H=0;
TMR0L=0;
TRIG=1;
delay_us(10);
TRIG=0;
while(!ECHO);
TMR0ON_bit=1;
while(ECHO && TMR0L<250);
temp=1.8303*TMR0L;
return temp;
}
// Motor Kontrol Fonksiyonu
void setMotor(char motorA1State, char motorA2State, char motorB1State, char motorB2State) {
motorA1 = motorA1State;
motorA2 = motorA2State;
motorB1 = motorB1State;
motorB2 = motorB2State;
}
// Komutlari Isle
void processCommand() {
switch (state) {
case 'F': setMotor(1, 1, 0, 0); break; // Ileri
case 'B': setMotor(0, 0, 1, 1); break; // Geri
case 'L': setMotor(1, 0, 1, 0); break; // Sol
case 'R': setMotor(0, 1, 0, 1); break; // Sag
case 'S': setMotor(0, 0, 0, 0); break; // Dur
default: setMotor(0, 0, 0, 0); break; // Geçersiz Komut
}
}
// Baslangiç Ayarlari
void setup() {
// Motor pinlerini çikis olarak ayarla
motorA1_Direction = 0;
motorA2_Direction = 0;
motorB1_Direction = 0;
motorB2_Direction = 0;
// Motorlari baslangiçta kapali tut
setMotor(0, 0, 0, 0);
// Mesafe sensörü pin yönleri
Trigger_Direction = 0; // Trigger çikis
Echo_Direction = 1; // Echo giris
// Analog girisleri devre disi birak
ANSELA = 0x00;
ANSELB = 0x00;
ANSELC = 0x00;
// UART baslat
UART1_Init(9600); // 9600 baud
Delay_ms(100); // UART kararliligi için küçük bir gecikme
}
// Ana Döngü
void loop() {
if (UART1_Data_Ready()) {
state = UART1_Read(); // Gelen veriyi oku
distance=getDistance();
if(distance>200) // Mesafe 200'den buyuk ise
processCommand(); // Komutu isle
else // Degilse
setMotor(0, 0, 0, 0); // Motoru durdur
delay_ms(100); // Komut isletildikten sonra 100ms bekleme
}
}
// Ana Fonksiyon
void main() {
setup(); // Baslangiç ayarlarini yap
while (1) {
loop(); // Ana döngüyü çalistir
}
}
kodu denedim ve çalıştı. İlginiz için çok teşekkür ederim.
Merhaba ben trudyo kullanarak mesafe senörü ile açılan kapı projesi yapıyorum fakat mesafe sensöründen hiç veri alamıyorum ve projemi ilerletemiyorum. bir çok farklı kod denedim fakat bi değişme olmadı. yardımcı olursanız çok sevinirim.
Merhaba, öncelikle yukarıdaki uygulamayı birebir aynı olacak şekilde test ettiğinizi ve sonuç alamadığınızı düşünecek olursak;
1.Bağlantılarınızda problem olma ihtimali (Örneğin sorunlu bir yada daha fazla jumper kablo olması veya yanlış bir bağlantı)
2.Program konfigürasyon ayarlarının doğru yapılmamış olması (Link üzerinden kontrol edebilirsiniz: https://trudyo.com/trudyo-konfigurasyon-ayarlari/)
3.Program kodlarınızda hatalı bir işlem yapılmış olması (Bunun için kodlarınızı paylaşabilirseniz sizin için bir sorun olup olmadığını kontrol edebiliriz)
4.Tüm bunlara rağmen çalışmaması durumunda farklı bir HC-SR04 ile deneme yapmak.
Yukarıda izleyebileceğiniz adımları sizin için paylaştık. Sizden geri dönüş bekliyor olacağız.
Timer ile ilgili bir kodda hata yapmışım tekrardan kodlarınız üzerinden kontrol ettiğim vakit fark ettim. İlginiz için teşekkür ederim.
Rica ederiz.😊
Yorum yapmak için giriş yapmalısınız.