Skocz do zawartości

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


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.

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.

#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ć ?

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

Jakie taktowanie atmegi masz ustawione ?

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 () {}

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

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

Wyskakuje taki błąd przy wgraniu Twojego programu.

Więc tak dioda na pinie 1 załączona jest i nie widzę aby jakieś przerwania miała , chyba że to powyżej 50 Hz jest .

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 ?

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

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

A jak ma migac ?

W przerwaniu nie może być dealaya ani sei, ani cli

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.

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