Skocz do zawartości

Błędnie działający moduł czujników linii TCRT5000


Pomocna odpowiedź

Napisano

Witam,
jestem w trakcie budowy robota działaniem przypominającego Elebota

Będzie to połączenie line follower'a z robotem, którego zadaniem będzie omijanie przeszkód. Jako czujniki linii zastosowałem TCRT5000, a moduł odpowiedzialny za wykrywanie przeszkód to dwie diody IR oraz odbiornik TSOP. Częstotliwość dla diód generowana jest przez ATTiny13A. Która wysyła sygnał na piny PD2 i PD3 ATmegi, wraz z nadejściem odpowiedniego stanu generowane jest przerwanie.

Całość składa się z trzech płytek uniwersalnych (całość już polutowana). Na pierwszej z nich 3 czujniki linii, na drugiej ATmega8 i mostek H (l293d), a na trzeciej właśnie ATTiny oraz diody i odbiornik IR.

Mam jednak problem z czujnikami linii. Gdy robot nie był jeszcze złożony, a wszystkie płytki zasilane były z płytki stykowej przez zasilacz, moduł z TCRT działał jak należy. Teraz, po złożeniu robot praktycznie nie reaguje na zmianę koloru podłoża pod czujnikami, a gdy już tak się stanie to dzieje się to z dużym opóźnieniem, czego wcześniej nie zauważyłem, gdyż robot od razu reagował na zmianę koloru linii.

Prosiłbym o sprawdzenie algorytmu i dodanie ewentualnych uwag:

Fragmenty kodu:

Inicjalizacja ADC:

ADCSRA = (1<<ADEN)                 // ADC Enable (uruchomienie przetwornika)
            |(1<<ADFR)               //tryb Free run
            |(1<<ADSC)               //rozpoczęcie konwersji
            |(1<<ADPS2)|(1<<ADPS1)   //preskaler 64
            |(1<<ADIE);              //uruchomienie zgłaszania przerwań

   ADMUX  =  (1<<ADLAR)               //wynik 8-bit
            |(1<<REFS0)              //AVCC jako napięcie referencyjne
            |wejscie;                //Wybór wejścia początkowego czyli PC4

  DDRC &=~ (1<<wej_3);        //Ustawienie pinów wejściowych ADC
  DDRC &=~ (1<<wej_4);        //Ustawienie pinów wejściowych ADC
  DDRC &=~ (1<<wej_5);        //Ustawienie pinów wejściowych ADC

PWM:

	TCCR1A |= (1<<COM1A1)|(1<<COM1B1);          // set OC1A i OC1B at BOTTOM, clear at CompareMatch
TCCR1A |= (1<<WGM11);                       // Fast PWM
TCCR1B |= (1<<WGM12)|(1<<WGM13);
TCCR1B |= (1<<CS11);                       //preskaler 8
ICR1 = 20000;                              //wartosc top
DDRB |= (1<<PB1)|(1<<PB2);                 //OC1A i OC1B

Obsługa przerwania od ADC:

ISR(ADC_vect)    //obsługa przerwania od ADC
{
      switch(wejscie)
      {

        case 3://gdy PC3
          adc3=ADCH;     //odczytaj tylko starszy bajt pomiaru
          break;


         case 4://gdy PC4
           adc4=ADCH;     //odczytaj tylko starszy bajt pomiaru
           break;

         case 5://gdy PC5
           adc5=ADCH;     //odczytaj tylko starszy bajt pomiaru
           break;
      }

      if(wejscie<5)
           wejscie++;
      else
           wejscie=3;

      ADMUX = 0;  //kasowanie rejestru

      ADMUX  |= (1<<ADLAR)|(1<<REFS0)| wejscie; //Ustawianie nowych wartości

}

Na poniższym obrazku prezentuję odczyty z poszczególnych czujników, gdy znajdują się na czarną, lub białą linią w danej chwili.

Wartości napięć przeliczyłem na wartości według wzoru (Vin*5)/256.

Kod, który odpowiada za zachowanie robota w danej sytuacji:

while(1)
{

	   if(jazda2)  //jesli jazda2==1
	   {
		   //stan początkowy serw
		   PORTB |= (1<<PB4); PORTB &= (~(1<<PB5))&(~(1<<PB3)); //cała naprzód
		   PORTC |= (1<<PC0);
		   OCR1A = 15000;
		   OCR1B = 15000;
	   }

	   else if(jazda1)
	   {


       PORTB |= (1<<PB4); PORTB &= (~(1<<PB5))&(~(1<<PB3));
       PORTC |= (1<<PC0);

       //dobrze jedzie
       if((adc3<20)&&((adc4<230)&&(adc4>=150))&&((adc5<70)&&(adc5>=20)))  //dobrze - oba silniki w przód
       {
	       OCR1A = 10000;
	       OCR1B = 10000;
       }

       //zjezdza na prawo
       else if((adc3>150)&&(adc4<30)&&(adc5<70))
       {

	       OCR1A = 3000;
	       OCR1B = 8000;
       }

       //zjezdza ma lewo
       else if((adc3<30)&&(adc4<30)&&(adc5>150))
       {
	       OCR1A = 8000;
	       OCR1B = 3000;
       }

       else {} //wyskok z if(jazda)
   }

	   else  //jesli jazda =/= 1
	   {
		   PORTB &= (~(1<<PB5))&(~(1<<PB3))&(~(1<<PB4));
		   PORTC &= (~(1<<PC0));
		   PORTB &= ~(1<<PB7);
		   PORTD &= ~(1<<PD0);
	   }

}

Jak pisałem wcześniej robot nie zachowuje się niestety jak powinien.

Wydaje się nie wchodzić w odpowiednie warunki if, choć pomiary robiłem kilka razy i przy różnym oświetleniu wyniki były podobne.

Nie wiem czy błąd jest w samym algorytmie, ale być może w ogóle źle zrozumiałem sposób jego realizacji.

Będę wdzięczny za każdą uwagę i każdą pomoc,

Pozdrawiam

__________

Komentarz dodany przez: Sabre

Pomoże ktokolwiek?

Chodzi mi tylko o sprawdzenie algorytmu, chciałbym dojść w czym jest problem - czy niewłaściwie go ułożyłem, czy też źle dobrałem wartości, czy jeszcze coś innego?

Jestem naprawdę wdzięczny za każdą pomoc.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...