Skocz do zawartości

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


Cargo1906

Pomocna odpowiedź

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

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.