Skocz do zawartości

Problem z programowaniem serwa - Proszę o poradę


matrix760

Pomocna odpowiedź

Witam wszystkich.

Mój problem jest następujący. Chciałbym wysterować serwo w zależności od sygnału z czujnika. Serwo ma być w położeniu środkowym, gdy czujnik wysyła "0" logiczne ,a przypadku "1" logicznej serwo ma przejść w położenie skraje w lewo, a następnie skrajne w prawo i tam się zatrzymać. Taki pełny obrót. Prosiłbym o jakieś porady ewentualnie korektę programu. Program, który jest poniżej działa w ten sposób, że z położenia skrajnego lewego wraca do położenia środkowego... Dodam, że dopiero zaczynam naukę języka C dla AVR. Z góry dziękuje za porady:)🙂

 while(1)

 {
        if(!(PINB & (1<<PB0))) // czujnik

	{
	  {
	    OCR1A = 700;  //położenie środkowe	    

}}		   else 

	 {  

	   p=p+50;

	   if(p>1150)  //położenie skrajne w lewo

           { p=1150;
            OCR1A = p;
		 }

		 else 

		 {

		  if(!(PINB & (1<<PB0)))

                      { 
                         p=p-50; 
                          if(p<250) 
                  p=250;
		 OCR1A = p;  //położenie skrajne w prawo
                       }  }


     }

__________

Komentarz dodany przez: Nawyk

Używaj znaczników [ code][ /code]

Link do komentarza
Share on other sites

Blisko, ale zrób coś takiego

if (pinb ..) //pierwszy warunek
{ 
OCR1A = 700;
zmiennatemp=0;
}
else
{//czujnik daje 1 logiczne
 zmiennatemp++;
 if (zmiennatemp<25)//liczbę dobierz wg. potrzeb
 {
    OCR1A = 400; //przykładowe skrajnie w lewo
  }
  else
  {
    OCR1A = 1000; //skrajne w prawo
    zmiennatemp=25;//zeby jej stale nie dodawać, bo się przepełni
  }
}

czyli teraz na początku jest środek, potem skrajnie w lewo i po 25 pętlach skrajnie w prawo.

Gdybyś chciał zrobić powolne przesuwanie się w lewo/w prawo to mógłbyś zrobić coś w tym stylu:

if (pinb ..) //pierwszy warunek
{ 
OCR1A = 700;
zmiennatemp=0;
}
else
{//czujnik daje 1 logiczne
 zmiennatemp++;
 if (zmiennatemp<25)//liczbę dobierz wg. potrzeb
 {
    OCR1A = 700-zmiennatemp*12; //przykładowe skrajnie w lewo - czym zmienna wieksza tym dalej
  }
  else
  {
    OCR1A = 400+zmiennatemp*12; //skrajne w prawo - czym zmienna wieksza tym dalej
    zmiennatemp=75;//zeby jej stale nie dodawać, bo się przepełni - zwiekszylismy maksymalny stan
  }
}
Link do komentarza
Share on other sites

Wpisałem identycznie i coś nie chce działać. Ustawia się tylko w jedno skrajne położenie i nie chce przejść do drugiego. Mnie chodzi o to żeby od razy po osiągnięciu skrajnego położenia, serwo przeszło na drugie skrajne położenie.

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

 
#define F_CPU 1000000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include <avr/signal.h>


int main(void)
{

 int z;

 DDRB |= (1<<PB3);  // 36Khz IR
  DDRB &= ~(1<<PB0); // TSOP36 wejscie
  PORTB |=(1<<PB0);  
  DDRB |= (1<<PB2);  
  DDRB |= (1<<PB1);  
  DDRD |= (1<<PD6); 


 ICR1  = 10000; 


 TCCR1A |= (1<<COM1A1);   // 50Hz dla serwa
 TCCR1B |= (1<<WGM13)|(1<<CS10);


  TCCR2 |= (1<<WGM21)|(1<<COM20);  //modulacja 36Khz dla IR
  TCCR2 |= (1<<CS20);

  OCR2 = 13; 

sei(); 

 while(1)

 {
        if(!(PINB & (1<<PB0)))

	{

	  {


		z=0;
	    OCR1A = 700;   	


}}		   else 

	 {  z++;

	    if(z<25)

		{

		OCR1A = 1150;
		}

		else

		{

		OCR1A =250;
		z=25;
		}



}}
 } 

[ Dodano: 16-10-2011, 21:02 ]

Dokładniej mówiąc, ma to być głowa dla robota. Czujnik wykrywania przeszkód. Dlatego, potrzebuję 3 położenia, żeby monitorować otoczenie..

Link do komentarza
Share on other sites

Na początek radzę trochę poukładać kod i ujednolicić wcięcia bo znacznie łatwiej będzie się pracować/pomagać.

Według mnie w obecnej sytuacji zmienna 'z' jest bardzo szybko inkrementowana (zakładając, że wartość na PB0 jest cały czas '1') powyżej wartości 25 i serwo ustawia się tylko w pozycji odpowiadającej OCR1A =250. Spróbuj znacznie ją zwiększyć, bądź użyć dla testu (pomiędzy ustawianiem poszczególnych wartości OCR1A) funkcji _delay_ms().

  • Lubię! 1
Link do komentarza
Share on other sites

Tak jak kolega Ownya mówi - w pętli while(1) zaraz na początku dodaj np.

_delay_ms(50);

W ten sposób zanim dojdziesz do wartości 25 i zmienisz kierunek na przeciwny minie 24*50ms=1200ms.

Tak jak masz teraz program przelatuje tą pętlę 25 razy w przeciągu kilku ms i natychmiast zmienia kierunek pracy serwa - zanim jeszcze serwo zacznie się ruszać.

  • Lubię! 1
Link do komentarza
Share on other sites

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.