LinkedIn YouTube Facebook
Szukaj

Wstecz
SoM / SBC

[PROJEKT] Romi Chassis – obsługa enkoderów

W pierwszym programie podwozie Romi Chassis przejedzie 22 cm (jeden obrót koła). Następnie zatrzyma się na 3 sekundy (3000 ms), a następnie wróci na miejsce startu (czyli przejdzie 22 cm do tyłu). To zadanie realizuje to poniższy program (kod programu 1 znajduje się w sekcji do pobrania na końcu artykułu):

// Romi Chassis – obsługa enkoderów
// Program 1
// Autor: Patryk Mądry 
// Mikrokontroler 2017 r.

#define PinA 2 
#define PinB 3 

long licznik = 0;
int kierunek = 1;

void Jedz_do_przodu(int i)
{
 kierunek = 1;
 
 // Lewy silnik
 digitalWrite(6,LOW);
 analogWrite(10,i);
 // Prawy silnik 
 digitalWrite(7,LOW);
 analogWrite(11,i);
}

void Jedz_do_tylu(int i)
{
 kierunek = 0;
 
 // Lewy silnik
 digitalWrite(6,HIGH);
 analogWrite(10,i);
 
 // Prawy silnik 
 digitalWrite(7,HIGH);
 analogWrite(11,i);
}

void Stop()
{
 // Lewy silnik
 digitalWrite(6,LOW);
 analogWrite(10,0);
 
 // Prawy silnik 
 digitalWrite(7,LOW);
 analogWrite(11,0);
}


void setup() {

 Serial.begin(9600);
 pinMode(PinA,INPUT); 
 pinMode(PinB,INPUT); 

 attachInterrupt(0, Kanal_A, CHANGE); 
 attachInterrupt(1, Kanal_B, CHANGE);
 
 pinMode(10,OUTPUT);
 pinMode(11,OUTPUT);

 pinMode(6,OUTPUT);
 pinMode(7,OUTPUT);
}

void loop() {
 
 delay(3000);
 
 while(1)
 {
   //Jedz do przodu przez 1440 impulsów (jeden obrot koła, około 22 cm) 
   while(licznik <=1440)
   {
     Jedz_do_przodu(20);
     Serial.print("Licznik: "); 
     Serial.println(licznik);
   }

   // Zatrzymanie 
   Stop();
   delay(3000);

   //Jedz do tylu przez 1440 impulsów (jeden obrot koła, około 22 cm) 
   while(licznik>0)
   {
     Serial.print("Licznik: "); 
     Serial.println(licznik);
     Jedz_do_tylu(20);
   }

   // Zatrzymanie 
   Stop();
   delay(3000);
  }
}

void Kanal_A()
{
 if (kierunek==1)
 {
   licznik++; 
 }
 else if (kierunek==0)
 {
   licznik--; 
 }
}

void Kanal_B()
{
 if (kierunek==1)
 {
   licznik++; 
 }
 else if (kierunek==0)
 {
   licznik--; 
 }
}

W powyższym kodzie wykorzystamy funkcje (Jedz_do_przodu(int i) oraz Jedz_do_tyłu(int i)), które napisaliśmy podczas realizacji pierwszego projektu z podwoziem Romi Chassis.

Pierwszym krokiem będzie zadeklarowanie, do których wyprowadzeń będą podłączone kanały A i B enkodera (piny 2 oraz 3):

#define PinA 2
#define PinB 3

Następnie deklarujemy zmienne potrzebne do pracy enkodera:

long licznik = 0;
int kierunek = 1;

Następnie trzy funkcje: Jedz_do_przodu(int i), Jedz_do_tylu(int i) oraz Stop() do poruszania się podwozia oraz jego zatrzymywania.

void Jedz_do_przodu(int i)
{
 kierunek = 1;
 // Lewy silnik
 digitalWrite(6,LOW);
 analogWrite(10,i);
 // Prawy silnik 
 digitalWrite(7,LOW);
 analogWrite(11,i);
}

void Jedz_do_tylu(int i)
{
 kierunek = 0;
 // Lewy silnik
 digitalWrite(6,HIGH);
 analogWrite(10,i);
 
 // Prawy silnik 
 digitalWrite(7,HIGH);
 analogWrite(11,i);
}

void Stop()
{
 // Lewy silnik
 digitalWrite(6,LOW);
 analogWrite(10,0);
 
 // Prawy silnik 
 digitalWrite(7,LOW);
 analogWrite(11,0); 
}

W stosunku do funkcji użytych w pierwszej części projektu, dodano zmienną kierunek, która określa czy podwozie porusza się do przodu (wartość 1) czy do tyłu (wartość 0). Taka informacja będzie potrzebna do zliczania impulsów z enkodera (o czym w dalszej części artykułu).

Następnie ustawiamy prędkość transmisji portu szeregowego, deklarujemy wyzwalanie przerwań na pinach 2 i 3 oraz ustawiamy linie wyjściowe do sterowania silnikami.

void setup() {

 Serial.begin(9600);
 pinMode(PinA,INPUT); 
 pinMode(PinB,INPUT); 

 attachInterrupt(0, Kanal_A, CHANGE); 
 attachInterrupt(1, Kanal_B, CHANGE);
 
 pinMode(10,OUTPUT);
 pinMode(11,OUTPUT);

 pinMode(6,OUTPUT);
 pinMode(7,OUTPUT);
}

Następnie przechodzimy do pętli głównej programu:

void loop() {
 
 delay(3000);
 
 while(1)
 {

   //Jedz do przodu przez 1440 impulsów (jeden obrot koła, około 22 cm) 
   while(licznik <=1440)
   {
     Jedz_do_przodu(20);
     Serial.print("Licznik: "); 
     Serial.println(licznik);
   }

   // Zatrzymanie 
   Stop();
   delay(3000);

   //Jedz do tylu przez 1440 impulsów (jeden obrot koła, około 22 cm) 
   while(licznik>0)
   {
     Serial.print("Licznik: "); 
     Serial.println(licznik);
     Jedz_do_tylu(20);
   }

   // Zatrzymanie 
   Stop();
   delay(3000);
  }
}

Mamy tutaj dwie pętle while(). W pierwszej z nich podwozie będzie poruszało się do przodu z wartością PWM równą 20, gdy wartość licznika będzie mniejsza niż 1440. Gdy warunek ten nie jest spełniony (wartość licznika będzie większa niż 1440), następuje zatrzymanie konstrukcji na 3 sekundy. W następnej pętli while(), podwozie porusza się do tyłu do momentu, gdy licznik będzie mniejszy niż 0.

Na końcu programu mamy dwie funkcje Kanal_A() oraz Kanal_B(). Są one wywoływanie, gdy wystąpi przerwanie od kanału A lub B enkodera. Gdy kierunek jest równy 1 (konstrukcja porusza się do przodu), wartość licznika jest zwiększana. Natomiast gdy kierunek jest 0 (czyli konstrukcja porusza się do tyłu), wartość licznika jest zmniejszana.

void Kanal_A()
{
  if (kierunek==1)
  {
    licznik++; 
  }
  else if (kierunek==0)
    {
      licznik--; 
    }
}

void Kanal_B()
{
   if (kierunek==1)
  {
    licznik++; 
  }
  else if (kierunek==0)
    {
      licznik--; 
    }
}

Działanie programu pierwszego zostało pokazane na poniższym materiale wideo:

Autor: Patryk Mądry