Skocz do zawartości

Robocik jeżdżący - kręci się w koło - brak reakcji na czujnik


daniel89

Pomocna odpowiedź

ma tym timerem załączać pilota i usprawnić program.

#include <Servo.h>
#include <interrupts.h>


Servo dservo;
#define trig 2
#define echo 3
int pwmMotorA=6;
int InMotorA1=5;
int InMotorA2=4;
int pwmMotorB=11;
int InMotorB1=10;
int InMotorB2=9;
volatile int IRpin=7;
volatile int stan=0;
int pos = 0;
volatile int imp=50;
volatile boolean x=0;
volatile boolean pil=0;



void setup () {

   TCCR1A |= (1<<WGM12); //tryb CTC
   TCCR1B |= (1<<CS12) | (1<<CS10);  //prescaler 1024
   TIMSK1 |= (1<<OCIE1A) | (1<<OCIE1B);
   OCR1A = 65530;
   OCR1B = 65530;

 dservo.attach(13);
 pinMode(pwmMotorA, OUTPUT);
 pinMode(pwmMotorB, OUTPUT);
 pinMode(InMotorA1, OUTPUT);
 pinMode(InMotorA2, OUTPUT);  
 pinMode(InMotorB1, OUTPUT);
 pinMode(InMotorB2, OUTPUT);  
 pinMode (trig, OUTPUT);
 pinMode (echo, INPUT);
 sei(); 
};


ISR(TIMER1_COMPB_vect){
if(imp>50){
   pil=1;
}
imp++;
if(imp>60){imp=51;}

}


void loop () {
x=!x;
digitalWrite(1, x);
delay(300);
 if(stan==1){
   int duration, distance;
   digitalWrite( trig, LOW);
   delayMicroseconds (2);
   digitalWrite (trig, HIGH);
   delayMicroseconds(10);
   digitalWrite (trig, LOW);
   duration = pulseIn(echo, HIGH);
   distance = (duration/2) / 29.1;

   if (distance<=30 && distance >=10 ) {
     analogWrite(pwmMotorA,255);
     analogWrite(pwmMotorB,0);
     digitalWrite(InMotorA1, LOW);
     digitalWrite(InMotorA2, HIGH);
     digitalWrite(InMotorB1, LOW);
     digitalWrite(InMotorB2, LOW);
     //Ustawienie prędkości obrotowej na 50% (zakres PWM: 8bitów czyli 0-255)
   }

   if (distance <10) {
     analogWrite(pwmMotorA,255);
     analogWrite(pwmMotorB,255);
     digitalWrite(InMotorA1, HIGH);
     digitalWrite(InMotorA2, LOW);
     digitalWrite(InMotorB1, HIGH);
     digitalWrite(InMotorB2, LOW);
//      for(pos = 0; pos < 180; pos +=1)
//      {
//        dservo.write(pos);
//        delay(20);
//      }
//      for (pos = 180; pos>=1; pos-=1)
//      {
//        dservo.write(pos);
//        delay(20); 
//      }
//      for (pos = 1; pos < 90; pos +=1)
//      {
//        dservo.write(pos);
//        delay(20);
//      }

   }

   if(distance>30){
     analogWrite(pwmMotorA,255);
     analogWrite(pwmMotorB,255);
     digitalWrite(InMotorA1, LOW);
     digitalWrite(InMotorA2, HIGH);
     digitalWrite(InMotorB1, LOW);
     digitalWrite(InMotorB2, HIGH);
   }
 }
 if(stan==0){
     analogWrite(pwmMotorA,0);
     analogWrite(pwmMotorB,0);
     digitalWrite(InMotorA1, LOW);
     digitalWrite(InMotorA2, LOW);
     digitalWrite(InMotorB1, LOW);
     digitalWrite(InMotorB2, LOW);
 } 
}




void pilot() {
 if (digitalRead(IRpin) ==LOW && pil==1){
   switch(stan){
     case 0:
       stan=1;
       break;
     case 1:
       stan=0;
       break;
   }
   imp=0;
   pil=0;
 }
}

Ten timer niby działa ale nie do końca. Świeci dioda jak ją ustwię na wyjście ale już nie miga dopiero jak w pętlę loop wrzucę to miga z delayem a tego nie chce tylko z timera sterować.

Dalej jest problem taki że vector w nim ustwiłem na COMPB ,gdyż na COMPA wyskakiwał błąd że VECT___17 jest w błędzie z dservo . Nie wiem czy to nie ma problemu z pwm od silnika czy to nie zajmuje w procku vectora i przez to się gubi ?

Dalej problem jak wgram bez timerów to jakiej funkcji bym nie wykonał to działa ale tylko na jednym czujniku lub serwie bądź pilocie a połączyć tego się nie dało gdyż program złe komendy dawał . Było if if else i odnośnik do pilota void pilot na końcu loop, ale to nie dawało rady. Potem postanowiłem dodać serwo i już całkowicie zgłupiał. No i ten pilot jakoś nie chce normalnie działać na załączeniu ze stanu LOW a na odbiorniku IR jest ciągle 5v czyli HIGH a jak pilotem załącze to 4,5 czyli powinno LOW złapać , a się gubi i nie chce.

W programie jest pokazane jak co się ma dziać i tak bym chciał aby to działało tylko nie chce.

Link do komentarza
Share on other sites

No ok, ale aby to przerwanie ruszyło to timer musi odliczyć ileś tam impulsów, a u ciebie nie jest on skonfigurowany poprawnie.

Jak ilość impulsów zliczonych przez timer zrówna się z tym co podałeś w rejestrze w tym przypadku OCR wtedy nastąpi wywołanie przerwania. Samo sei() tylko zezwala na akcję wywołania przerwania.

Link do komentarza
Share on other sites

#include <Servo.h>
#include <interrupts.h>



Servo dservo;
#define trig 2
#define echo 3
int pwmMotorA=6;
int InMotorA1=5;
int InMotorA2=4;
int pwmMotorB=11;
int InMotorB1=10;
int InMotorB2=9;
volatile int IRpin=7;
volatile int stan=0;
int pos = 0;
volatile int imp=50;
volatile boolean x=0;
volatile boolean pil=0;



void setup () {

   TCCR3B |= 0;
   TCCR3B |= (1<<CS32) | (1<<CS30);  //prescaler 256
   TIMSK3 |= (1<<TOIE3);


 dservo.attach(13);
 pinMode(pwmMotorA, OUTPUT);
 pinMode(pwmMotorB, OUTPUT);
 pinMode(InMotorA1, OUTPUT);
 pinMode(InMotorA2, OUTPUT);  
 pinMode(InMotorB1, OUTPUT);
 pinMode(InMotorB2, OUTPUT);  
 pinMode (trig, OUTPUT);
 pinMode (echo, INPUT);
 sei(); 
};


ISR(TIMER3_OVF_vect){
if(imp>50){
   pil=1;
}
imp++;
if(imp>60){imp=51;}

x=!x;
digitalWrite(1, x);


}


void loop () {
pilot();
 if(stan==1){
   int duration, distance;
   digitalWrite( trig, LOW);
   delayMicroseconds (2);
   digitalWrite (trig, HIGH);
   delayMicroseconds(10);
   digitalWrite (trig, LOW);
   duration = pulseIn(echo, HIGH);
   distance = (duration/2) / 29.1;

   if (distance<=30 && distance >=10 ) {
     analogWrite(pwmMotorA,255);
     analogWrite(pwmMotorB,0);
     digitalWrite(InMotorA1, LOW);
     digitalWrite(InMotorA2, HIGH);
     digitalWrite(InMotorB1, LOW);
     digitalWrite(InMotorB2, LOW);
     //Ustawienie prędkości obrotowej na 50% (zakres PWM: 8bitów czyli 0-255)
   }

   if (distance <10) {
     analogWrite(pwmMotorA,255);
     analogWrite(pwmMotorB,255);
     digitalWrite(InMotorA1, HIGH);
     digitalWrite(InMotorA2, LOW);
     digitalWrite(InMotorB1, HIGH);
     digitalWrite(InMotorB2, LOW);
//      for(pos = 0; pos < 180; pos +=1)
//      {
//        dservo.write(pos);
//        delay(20);
//      }
//      for (pos = 180; pos>=1; pos-=1)
//      {
//        dservo.write(pos);
//        delay(20); 
//      }
//      for (pos = 1; pos < 90; pos +=1)
//      {
//        dservo.write(pos);
//        delay(20);
//      }

   }

   if(distance>30){
     analogWrite(pwmMotorA,255);
     analogWrite(pwmMotorB,255);
     digitalWrite(InMotorA1, LOW);
     digitalWrite(InMotorA2, HIGH);
     digitalWrite(InMotorB1, LOW);
     digitalWrite(InMotorB2, HIGH);
   }
 }
 if(stan==0){
     analogWrite(pwmMotorA,0);
     analogWrite(pwmMotorB,0);
     digitalWrite(InMotorA1, LOW);
     digitalWrite(InMotorA2, LOW);
     digitalWrite(InMotorB1, LOW);
     digitalWrite(InMotorB2, LOW);
 } 
}




void pilot() {
 if (digitalRead(IRpin) ==LOW && pil==1){
   switch(stan){
     case 0:
       stan=1;
       break;
     case 1:
       stan=0;
       break;
   }
   imp=0;
   pil=0;
 }
}

Jeszcze timer 3 próbowałem tak skonfigurować .

Też ten sam problem . Czyli co źle dalej skonfigurowany ? Gdzie mam to sei dać ?

Link do komentarza
Share on other sites

Jaka jest instrukcja zmieniająca stan diody na przeciwny w tym arduino - pisze program testowy ?

Jakie taktowanie atmegi masz ustawione ?

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

Dioda powinna migać co sekundę - program testowy

Wzór na OCR:

OCR = (F_CPU/PRESKALER/CZESTOTLIWOSC) -1

15624 = (16000000/1024/1Hz) - 1

    #include <Servo.h>
   #include <interrupts.h>

volatile boolean x=0;

   void setup () {

       TCCR1A |= (1<<WGM12); //tryb CTC
       TCCR1B |= (1<<CS12) | (1<<CS10);  //prescaler 1024
       TIMSK1 |= (1<<OCIE1B);
       OCR1B = 15624; //1 Hz przy 16Mhz (zegar)

     sei();

pinMode(1, OUTPUT); 

   };

   ISR(TIMER1_COMPB_vect){
   x=!x;
digitalwrite(1,x) ;
   }

   void loop () {}
Link do komentarza
Share on other sites

sketch_may14a.ino: In function 'void __vector_18()':

sketch_may14a:19: error: expected `;' before 'digitalwrite'

Wyskakuje taki błąd przy wgraniu Twojego programu.

Link do komentarza
Share on other sites

Zamiast

x=!x

daj

x=^x

albo tak

x^=x
chyba że to powyżej 50 Hz jest .

A wzór na OCR podany kilka postów wcześniej to co ?

Link do komentarza
Share on other sites

teraz dioda zaczęła chodzić jeszcze na tym 1 programie

miga co 5 sekund na 1 sekunde.

Czy normalne jest to, że jak podepnę zasilacz 12 v pod to arduino to powinno takie niskie dźwięki wydawać takie piszczenie ? Pytam bo tak mam. W Instrukcji było że od 6 v - 20 v można zasilić.

Te xor ^= nie działają. Tylko to =! działa ale jak mówię miga co 5 sekund na 1 sekunde

Link do komentarza
Share on other sites

 #include <Servo.h>
#include <interrupts.h>


Servo dservo;
#define trig 2
#define echo 3
int pwmMotorA=6;
int InMotorA1=5;
int InMotorA2=4;
int pwmMotorB=11;
int InMotorB1=10;
int InMotorB2=9;
volatile int IRpin=7;
volatile int stan=0;
int pos = 0;
volatile int imp=50;
volatile boolean x=0;
volatile boolean pil=0;



void setup () {

   TCCR1A |= (1<<WGM12); //tryb CTC
   TCCR1B |= (1<<CS12) | (1<<CS10);  //prescaler 1024
   TIMSK1 |= (1<<OCIE1A) | (1<<OCIE1B);
   OCR1A = 65530;
   OCR1B = 65530;

 dservo.attach(13);
 pinMode(pwmMotorA, OUTPUT);
 pinMode(pwmMotorB, OUTPUT);
 pinMode(InMotorA1, OUTPUT);
 pinMode(InMotorA2, OUTPUT); 
 pinMode(InMotorB1, OUTPUT);
 pinMode(InMotorB2, OUTPUT); 
 pinMode (trig, OUTPUT);
 pinMode (echo, INPUT);
 sei();
 pinMode(1, OUTPUT);

};


ISR(TIMER1_COMPB_vect){
//if(imp>50){
//    pil=1;
//}
//imp++;
//if(imp>60){imp=51;}

x=!x;
digitalWrite(1, x);



}


void loop () {

 if(stan==1){
   int duration, distance;
   digitalWrite( trig, LOW);
   delayMicroseconds (2);
   digitalWrite (trig, HIGH);
   delayMicroseconds(10);
   digitalWrite (trig, LOW);
   duration = pulseIn(echo, HIGH);
   distance = (duration/2) / 29.1;

   if (distance<=30 && distance >=10 ) {
     analogWrite(pwmMotorA,255);
     analogWrite(pwmMotorB,0);
     digitalWrite(InMotorA1, LOW);
     digitalWrite(InMotorA2, HIGH);
     digitalWrite(InMotorB1, LOW);
     digitalWrite(InMotorB2, LOW);
     //Ustawienie prędkości obrotowej na 50% (zakres PWM: 8bitów czyli 0-255)
   }

   if (distance <10) {
     analogWrite(pwmMotorA,255);
     analogWrite(pwmMotorB,255);
     digitalWrite(InMotorA1, HIGH);
     digitalWrite(InMotorA2, LOW);
     digitalWrite(InMotorB1, HIGH);
     digitalWrite(InMotorB2, LOW);
//      for(pos = 0; pos < 180; pos +=1)
//      {
//        dservo.write(pos);
//        delay(20);
//      }
//      for (pos = 180; pos>=1; pos-=1)
//      {
//        dservo.write(pos);
//        delay(20);
//      }
//      for (pos = 1; pos < 90; pos +=1)
//      {
//        dservo.write(pos);
//        delay(20);
//      }

   }

   if(distance>30){
     analogWrite(pwmMotorA,255);
     analogWrite(pwmMotorB,255);
     digitalWrite(InMotorA1, LOW);
     digitalWrite(InMotorA2, HIGH);
     digitalWrite(InMotorB1, LOW);
     digitalWrite(InMotorB2, HIGH);
   }
 }
 if(stan==0){
     analogWrite(pwmMotorA,0);
     analogWrite(pwmMotorB,0);
     digitalWrite(InMotorA1, LOW);
     digitalWrite(InMotorA2, LOW);
     digitalWrite(InMotorB1, LOW);
     digitalWrite(InMotorB2, LOW);
 }
}




void pilot() {
 if (digitalRead(IRpin) ==LOW && pil==1){
   switch(stan){
     case 0:
       stan=1;
       break;
     case 1:
       stan=0;
       break;
   }
   imp=0;
   pil=0;
 }
}
Link do komentarza
Share on other sites

Poprawiłem. Czy tak jak teraz jest dobrze ?

I czy obsługa pilota jest poprawna ?

Po wgraniu tego programu dioda ciągle się pali nie wiedzę aby przerywała. Ustawiłem OCR1B = 15624; czyli powinna co sekundę migać ale nie miga w tym głównym programie. Nawet co 5 sekund nie miga tak jak to bez pozostałych parametrów kodu robiło.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

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