Skocz do zawartości

Problem z programowaniem serwa - Proszę o poradę


Pomocna odpowiedź

Napisano

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]

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

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.

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

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

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

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