GÖRÜNÜŞ

Önceki yazımızda şase üzerine yerleştirdiğimiz sensörleri ve bazı donanımları paylaşmıştık. Sonrasında yaptığımız testlerde ön tarafında tam ortaya koyduğumuz sensör  tüm engelleri tanımlayamıyordu.

Ortaya değilde sağ köşeye ve sol köşeye yerleştirelim dedik. Fakat bu sefer de tam ortadaki egelleri düzgün tanımlayamadık. Peki ortaya, sağa ve sola olmak üzere 3 adet koysak diye düşünürken aracı yan taraflarını da kontrol edip, dönüşlerde bir yere toslamamamız gerektiğini farkettik.

Sonunda da bu yazıda anlatacağımız hem ön tarafı hemde yan tarafı belirli bir mantık çerçevesinde kontrol edeceğimiz sistem tasarlandı.  Tasarımın ayrıntıları şu şekildedir:

 

 

ENGEL TARAMA

 

 

Üst tarafta gördüğümüz gibi sistem iki adet ır sensör ve bir adet de servo motordan oluşmaktadır.

*Yandaki resime baktığımızda, sensörler aralarında 60° açı bulunacak şekilde servo motora sabitlenmiş ve aracın ön tarafında merkeze yerleştirilmiştir.

*Sensörlerden biri a noktası doğrultusunda iken diğeri b noktasınınkindedir.

*Servomuz hareket etmeye başladığında a doğrultusu a’ ne; b ise b’ ne doğru 4 kademede ilerleyecektir.

*Her kademe tamamlandığında adc işlemi uygulanacak, çıktı değerleri ve sensörlerin açılarına göre beagleboard ve mcu muz yorum yapıp karar verecektir.

 

move değişkenimiz sadece ileri fonksiyonu aktif iken 1 seviyesinde olacaktır. Diğer durumlarda aracın ön tarafını taramaya ihtiyaç yoktur.

 

while (move){
	    	for(i=0;i<=4;i++){
		    	 PWMGenDisable(PWM_BASE, PWM_GEN_2);
		    	 PWMOutputState(PWM_BASE, PWM_OUT_4_BIT, false);
		    	 PWMPulseWidthSet(PWM_BASE, PWM_OUT_4, ulPeriod2 * (93-(10* i))/ 1000);
		   		 PWMGenEnable(PWM_BASE, PWM_GEN_2);
		    	 PWMOutputState(PWM_BASE, PWM_OUT_4_BIT, true);
		    	 SysCtlDelay(SysCtlClockGet()/20 );
		    	 Ir_Check();
	    	}
 
	    	for(i=0;i<=2;i++){
		    	 PWMGenDisable(PWM_BASE, PWM_GEN_2);
		    	 PWMOutputState(PWM_BASE, PWM_OUT_4_BIT, false);
		    	 PWMPulseWidthSet(PWM_BASE, PWM_OUT_4, ulPeriod2 * (63+(10*i))/ 1000);
		   		 PWMGenEnable(PWM_BASE, PWM_GEN_2);
		    	 PWMOutputState(PWM_BASE, PWM_OUT_4_BIT, true);
		    	 SysCtlDelay(SysCtlClockGet()/20);
		    	 Ir_Check();
	    	}
    	}

 

 

Ir_Check() ise servo motor bir adım ilerledikten sonra, sensörlerin değerlerini ölçmek üzere adc kanallarını ayarlayan ve ölçüm işlemini gerçekleştiren fonksiyondur.ADC sonuçlarını beagleboarda bırakmadan en başta belirlediğimiz değere göre kıyaslar ve engel durumunda da aracı durdurur.

void Ir_Check()
{
 
		ADCSequenceDisable(ADC0_BASE,3);
		ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH1 | ADC_CTL_IE | ADC_CTL_END);
		ADCSequenceEnable(ADC0_BASE,3);
 
		ADCProcessorTrigger(ADC0_BASE, 3);// adc modülünü tetikleriz
        while(!ADCIntStatus(ADC0_BASE, 3, false)) {}// adc dönüşümünün tamamlanmasını bekleriz
        ADCSequenceDataGet(ADC0_BASE, 3, &adc_temp1);// adc_temp1 e IR sensörümüzün datasını atarız	
 
		if ((adc_temp1 > 700)  ){
			Display96x16x1StringDraw("engel VAR111!!", 6, 0);
			stop();
		}
 
		else {
			Display96x16x1StringDraw("engel yok      ", 6, 0);
		}	
 
		ADCSequenceDisable(ADC0_BASE,3);
		ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH2 | ADC_CTL_IE | ADC_CTL_END);
		ADCSequenceEnable(ADC0_BASE,3);
 
		ADCProcessorTrigger(ADC0_BASE, 3);// adc modülünü tetikleriz
        while(!ADCIntStatus(ADC0_BASE, 3, false)) {}// adc dönüşümünün tamamlanmasını bekleriz
        ADCSequenceDataGet(ADC0_BASE, 3, &adc_temp2);// adc_temp1 e IR sensörümüzün datasını atarız	
 
		if ((adc_temp2 > 700) ){
			Display96x16x1StringDraw("engel VAR222!!", 6, 1);
			stop();
		}
		else {
			Display96x16x1StringDraw("engel yok      ", 6, 1);
		}
}

 

Sistemin bütün halinin blok şeması ise aşağıdaki gibidir.

 

 

BLOK YAPISI

 

 

Beagleboarddan gelecek hareket komutlarını uygulayarak motorları sürecek, engel yakalmak için servo motoru ve IR sensörleri kontrol edecek  ayrıca engel gördüğünde aracı durdurup beagleboardı bilgilendirecek Stellaris in kodlarının tamamı aşağıdaki gibidir.

 

#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/pwm.h"
#include "drivers/display96x16x1.h"
#include "driverlib/adc.h"
 
volatile int move=0;
volatile unsigned long adc_temp1, adc_temp2;
/////////////////////////////////////////////
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif
 
/////// hareket fonksiyonları  ///////
 
void forward(void)
{
	move=1;
	Display96x16x1Init(false);
    Display96x16x1StringDraw("ileri", 6, 0);
 
    PWMOutputState(PWM_BASE, PWM_OUT_0_BIT | PWM_OUT_2_BIT, true);
    PWMOutputState(PWM_BASE, PWM_OUT_1_BIT | PWM_OUT_3_BIT, false);
}
void rear (void)
{
	move=0;
	Display96x16x1Init(false);
    Display96x16x1StringDraw("geri", 6, 0);
 
    PWMOutputState(PWM_BASE, PWM_OUT_1_BIT | PWM_OUT_3_BIT, true);
    PWMOutputState(PWM_BASE, PWM_OUT_0_BIT | PWM_OUT_2_BIT, false);
}
void left(void)
{
	move=0;
	Display96x16x1Init(false);
    Display96x16x1StringDraw("sol", 6, 0);
 
    PWMOutputState(PWM_BASE, PWM_OUT_1_BIT | PWM_OUT_2_BIT, true);
    PWMOutputState(PWM_BASE, PWM_OUT_0_BIT | PWM_OUT_3_BIT, false);
}
void right (void)
{
	move=0;
	Display96x16x1Init(false);
    Display96x16x1StringDraw("sag", 6, 0);
 
    PWMOutputState(PWM_BASE, PWM_OUT_0_BIT | PWM_OUT_3_BIT, true);
    PWMOutputState(PWM_BASE, PWM_OUT_1_BIT | PWM_OUT_2_BIT, false);
}
void stop (void)
{
	move=0;
	Display96x16x1Init(false);
    Display96x16x1StringDraw("dur", 6, 0);
 
    PWMOutputState(PWM_BASE, PWM_OUT_0_BIT | PWM_OUT_1_BIT|PWM_OUT_2_BIT | PWM_OUT_3_BIT, false);
}
////////////////////////////////////////
 
void UARTIntHandler(void)
{
	Display96x16x1Init(false);
	Display96x16x1StringDraw("asdasd", 6, 0);
 
    unsigned long ulStatus;
	char  temp[1]; 
 
    ulStatus = UARTIntStatus(UART0_BASE, true);   
 
    temp[0] = UARTCharGet(UART0_BASE);
 
		if (temp[0] == 'w')
		{
 
   			forward();
		}
		if (temp[0] == 's')
		{
 
			rear();
		}
		if (temp[0] == 'd')
		{
 
			right();
		}
		if (temp[0] == 'a')
		{
 
			left();
		}
		if (temp[0] == ' ')
		{
 
			stop();
		}
 
	UARTIntClear(UART0_BASE, ulStatus);		// seri port interrupt bayrağını temizler
}
 
void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount)
{
    while(ulCount--)
    {
        UARTCharPutNonBlocking(UART0_BASE, *pucBuffer++);
    }
}
 
void Ir_Check()
{
 
		ADCSequenceDisable(ADC0_BASE,3);
		ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH1 | ADC_CTL_IE | ADC_CTL_END);
		ADCSequenceEnable(ADC0_BASE,3);
 
		ADCProcessorTrigger(ADC0_BASE, 3);// adc modülünü tetikleriz
        while(!ADCIntStatus(ADC0_BASE, 3, false)) {}// adc dönüşümünün tamamlanmasını bekleriz
        ADCSequenceDataGet(ADC0_BASE, 3, &adc_temp1);// adc_temp1 e IR sensörümüzün datasını atarız	
 
		if ((adc_temp1 > 700)  ){
			Display96x16x1StringDraw("engel VAR111!!", 6, 0);
			stop();
		}
 
		else {
			Display96x16x1StringDraw("engel yok      ", 6, 0);
		}	
 
		ADCSequenceDisable(ADC0_BASE,3);
		ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH2 | ADC_CTL_IE | ADC_CTL_END);
		ADCSequenceEnable(ADC0_BASE,3);
 
		ADCProcessorTrigger(ADC0_BASE, 3);// adc modülünü tetikleriz
        while(!ADCIntStatus(ADC0_BASE, 3, false)) {}// adc dönüşümünün tamamlanmasını bekleriz
        ADCSequenceDataGet(ADC0_BASE, 3, &adc_temp2);// adc_temp1 e IR sensörümüzün datasını atarız	
 
		if ((adc_temp2 > 700) ){
			Display96x16x1StringDraw("engel VAR222!!", 6, 1);
			stop();
		}
		else {
			Display96x16x1StringDraw("engel yok      ", 6, 1);
		}
}
 
int main(void)
{
 
    unsigned long ulPeriod;
    unsigned long ulPeriod2;
     int i;
 
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_6MHZ);
    SysCtlPWMClockSet(SYSCTL_PWMDIV_1);
 
    Display96x16x1Init(false);	// ekranı temizleme
    Display96x16x1StringDraw("   oto-pilot ", 6, 0);
    Display96x16x1StringDraw("bitirme projesi", 6, 1);
	SysCtlDelay(SysCtlClockGet() /2);
	///////////////////////////////////////////////////////////////////
	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
     SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
	/////////////////seri port ayarlama///////////////////////////////
 
    IntMasterEnable();
 
	GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
 
	UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600,
                        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                         UART_CONFIG_PAR_NONE));
 
	IntEnable(INT_UART0);
    UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
 
	Display96x16x1Init(false);
	Display96x16x1StringDraw("seri port hazir", 6, 0);
    UARTSend((unsigned char *)"seri port hazir", 16);
    SysCtlDelay(SysCtlClockGet() /2);
    ////////////////////  PWM AYARLAMASI  ///////////////////////////
 
    GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    GPIOPinTypePWM(GPIO_PORTE_BASE, GPIO_PIN_0);
 
    ulPeriod = SysCtlClockGet() /5000;
    ulPeriod2 = SysCtlClockGet() /50;
 
    PWMGenConfigure(PWM_BASE, PWM_GEN_0,
                    PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
	PWMGenConfigure(PWM_BASE, PWM_GEN_1,
                    PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    PWMGenConfigure(PWM_BASE, PWM_GEN_2,
                   PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
 
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_0, ulPeriod);
	PWMGenPeriodSet(PWM_BASE, PWM_GEN_1, ulPeriod);
	PWMGenPeriodSet(PWM_BASE, PWM_GEN_2, ulPeriod2);
 
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_0, ulPeriod * 9 / 10);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_1, ulPeriod * 9 / 10);
	PWMPulseWidthSet(PWM_BASE, PWM_OUT_2, ulPeriod * 9 / 10);
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_3, ulPeriod * 9 / 10);
 
    PWMGenEnable(PWM_BASE, PWM_GEN_0);
	PWMGenEnable(PWM_BASE, PWM_GEN_1);
 
    Display96x16x1Init(false);
	Display96x16x1StringDraw("pwm hazir", 6, 0);
	SysCtlDelay(SysCtlClockGet() /2);
 
	//////////////////////   ADC BİRİMLERİ AYARLANMASI   //////////
 
	ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
	ADCSequenceEnable(ADC0_BASE, 3);
    ADCIntClear(ADC0_BASE, 3);    
 
    Display96x16x1Init(false);
	Display96x16x1StringDraw("adc hazir", 6, 0);
	SysCtlDelay(SysCtlClockGet() /2);
    ///////////////////////////////////////////////////////////////
 
    while(1)
    {
    	while (move){
	    	for(i=0;i<=4;i++){
		    	 PWMGenDisable(PWM_BASE, PWM_GEN_2);
		    	 PWMOutputState(PWM_BASE, PWM_OUT_4_BIT, false);
		    	 PWMPulseWidthSet(PWM_BASE, PWM_OUT_4, ulPeriod2 * (93-(10* i))/ 1000);
		   		 PWMGenEnable(PWM_BASE, PWM_GEN_2);
		    	 PWMOutputState(PWM_BASE, PWM_OUT_4_BIT, true);
		    	 SysCtlDelay(SysCtlClockGet()/20 );
		    	 Ir_Check();
	    	}
 
	    	for(i=0;i<=2;i++){
		    	 PWMGenDisable(PWM_BASE, PWM_GEN_2);
		    	 PWMOutputState(PWM_BASE, PWM_OUT_4_BIT, false);
		    	 PWMPulseWidthSet(PWM_BASE, PWM_OUT_4, ulPeriod2 * (63+(10*i))/ 1000);
		   		 PWMGenEnable(PWM_BASE, PWM_GEN_2);
		    	 PWMOutputState(PWM_BASE, PWM_OUT_4_BIT, true);
		    	 SysCtlDelay(SysCtlClockGet()/20);
		    	 Ir_Check();
	    	}
    	}
    }
}

 

 

 

 

 

 

 

BATARYALAR

 

 

GÖRÜNÜŞ

GÖRÜNÜŞ