Τέχνη και Τεχνολογία

Έλεγχος κινητήρα DC

Έλεγχος κινητήρα DC

Σε αυτή την κατασκευή θα δώσουμε κίνηση στον κινητήρα με τη χρήση ενός κοντρόλερ και θα μετράμε την ταχύτητά του, όπως κάναμε στην εφαρμογή “Κινητήρας DC – Encoder”. Για να το κάνουμε αυτό θα προσθέσουμε ένα ακόμη κύκλωμα, αυτό της τροφοδοσίας του κινητήρα, και λίγες γραμμές κώδικα στο πρόγραμμα που γράψαμε για την προηγούμενη κατασκευή μας με τον τίτλο “Κινητήρας DC – Encoder”.
Δευτερευόντως θα χρησιμοποιήσουμε ένα infrared τηλεκοντρόλ για να δίνουμε εντολές κίνησης στον κινητήρα. Εμπρός – πίσω – γρήγορα – αργά κλπ.

Τα υλικά για την κατασκευή είναι τα ίδια. Εδώ θα εστιάσουμε περισσότερο στον κοντρόλερ για την οδήγηση του κινητήρα, και θα πούμε λίγα λόγια για την PWM διαμόρφωση (Pulse Width Modulation) και πως αυτή θα την υλοποιήσουμε στο Arduino UNO.

PWM (Pulse Width Modulation)

Η διαμόρφωση PWM είναι μια περιοδική τετραγωνική κυματομορφή που διαφοροποιείται από το ποσοστό του χρόνου που είναι σε κατάσταση ΟΝ ή αλλιώς Hight σε μία περίοδο. Αυτή την κατάσταση ΟΝ την ονομάζουμε Duty Cycle και τη μετράμε σαν ποσοστό της συνολικής διάρκειας μιας περιόδου.
Στο σχήμα που ακολουθεί βλέπουμε έξι διαφορετικές μορφές μιας PWM. Οι πράσινες κάθετες γραμμές καθορίζουν τη διάρκεια ενός κύκλου ή αλλιώς το πλήθος των κύκλων στη μονάδα του χρόνου.
Στην πρώτη γραμμή διακρίνουμε ότι η κατάσταση των παλμών είναι 0 για όλη τη διάρκεια της περιόδου τους. Τότε λέμε οτι το Duty Cycle είναι 0%. Σε αυτή την περίπτωση η ισχύς που παρέχει ο παλμός είναι μηδενική.
Στη δεύτερη γραμμή ένα μικρό τμήμα της περιόδου, το 25% είναι ΟΝ. Στην περίπτωση αυτή η ισχύς που παρέχει ο παλμός είναι 25% της δυνατότητας του.
Τέλος στην τελευταία γραμμή ο παλμός είναι ΟΝ καθ όλη τη διάρκεια του και η ισχύς που παρέχει είναι το 100% της δυνατότητας του.

Το Arduino UNO με πολύ απλό τρόπο μπορεί να παρέχει PWM διαμόρφωση στα pin 3, 9, 10, 11 με συχνότητα 490 Hz ενώ στα pins 5 και 6 με συχνότητα 980 Hz. Στην εφαρμογή αυτή δεν μας ενδιαφέρει η συχνότητα του παλμού, μας ενδιαφέρει μόνο το Duty Cycle.
Με την εντολή analogWrite(pin, value) , που δεν έχει καμία σχέση με αναλογική έξοδο, δημιουργείται PWM παλμός στο pin που έχουμε ορίσει. Η μεταβλητή value παίρνει τιμές από 0 έως 255. Για την τιμή 0 δημιουργεί παλμό με Duty Cycle 0% και για την τιμή 255 δημιουργεί παλμό με Duty Cycle 100%. Έτσι η τιμή που θα έχει η μεταβλητή καθορίζεται από τη σχέση value = Duty Cycle * 255.
Για παράδειγμα για να φτιάξουμε παλμό με Duty Cycle 20% η τιμή της μεταβλητής είναι value = 0,2 * 255 = 51.

Διαμόρφωση PWM

Κοντρόλερ

Ο κοντρόλερ που χρησιμοποιούμε εδώ είναι ο  7A/160W. Μπορεί να οδηγήσει δύο κινητήρες με τάση από 7 έως 24V. Στην παρακάτω εικόνα  φαίνονται τα σημεία διασύνδεσης του κοντρόλερ  και στον πίνακα που ακολουθεί  φαίνονται οι λειτουργίες που έχουν αυτά τα σημεία διασύνδεσης.

Κοντρόλερ, σημεία διασύνδεσης
Λειτουργίες των σημείων σύνδεσης

Εμείς χρησιμοποιούμε τα σημεία με Label 1,2 για να συνδέσουμε μία μπαταρία 12V.
Τα σημεία 3 και 4 για να συνδέσουμε την τροφοδοσία του κινητήρα (άσπρο και κόκκινο καλώδιο)
Το σημείο 7 για να συνδέσουμε τον παλμό PWM από το pin του Arduino UNO
Τα σημεία 8 και 9 για να συνδέσουμε την επιλογή της φοράς της κίνησης ΙΝ1 και ΙΝ2 όπως φαίνεται στην εικόνα με τις σημειώσει μου.
Και τα σημεία +5V και GND που βρίσκονται πριν το 7 και μετά το 9 όπως φαίνονται στην εικόνα του κοντρόλερ για να συνδέσουμε την τροφοδοσία στο ψηφιακό κύκλωμα του κοντρόλερ.

Συνδεσμολογία πλακέτας

Ο πίνακας που ακολουθεί (Control Logic Table) για τον κινητήρα που έχουμε συνδέσει, μας δείχνει τις κινήσεις που θα εκτελεί ο κινητήρας ανάλογα με τις τιμές που θα έχουν οι είσοδοι ΙΝ1 και ΙΝ2. Τη χρήση τους τη βλέπετε στο πρόγραμμα στις συναρτήσεις goForword() και goBackword().

Προγραμματισμός

Ερχόμαστε τώρα στο πρόγραμμα που θα κινήσει την κατασκευή μας.

// Author Manolis Aristovoulidis
// Το πρόγραμμα αυτό κινεί ένα κινητήρα 12V DC με τη χρήση ενός κοντρόλερ
// χρησημοποιεί ένα Infrared τηλεκοντρόλ για να δίνει οδηγίες για την κίνηση
// μετρά και "τυπώνει" την ταχύτητα και την κατεύθυνση της κίνησης.


#include <IRremote.h>

const int RECV_PIN = 12;
IRrecv irrecv(RECV_PIN);
decode_results results;

// Motor A connections
const int enA = 6;
const int in1 = 5;
const int in2 = 4;

//motor A encoder
const byte encoder_pinA = 2;    //A pin -> the interrupt pin 2
const byte encoder_pinB = 10;    //B pin -> the digital pin 10

int pulses;                   //the number of the pulses
boolean Direction;              //the rotation direction

// Set the speed (0 = off and 255 = max speed)
int motorSpeed = 0;


void setup() {
     // Motor control pins are outputs

      Serial.begin(57600);          //Initialize the serial port
      EncoderInit();                //Initialize the module
      
      pinMode(enA, OUTPUT);
      pinMode(in1, OUTPUT);
      pinMode(in2, OUTPUT);
      irrecv.enableIRIn();
}

void loop() {
    if (irrecv.decode(&results)){
        //Serial.println(results.value, HEX);
        irrecv.resume();
        
        switch (results.value) {
          case 0xFF18E7:  //key UP
              if(motorSpeed <= 200){
                motorSpeed +=50;                  
              }
              if(motorSpeed >=0){
                // move forword
                goForword();
              }else{
                //move backword
                goBackword();
              }
          analogWrite(enA, abs(motorSpeed)); 
          break;
          
          case 0xFF4AB5:  //key DOWN
              if(motorSpeed > -250){
                motorSpeed -=50;                   
              }
              if(motorSpeed >=0){
                // move forword
                goForword();
              }else{
                //move backword
                goBackword();
              }
          analogWrite(enA, abs(motorSpeed)); 
          break;
          case 0xFF38C7:  //key OK
              //stop moving
              stopMove();
              
          break;
          default:
          // statements
          break;
       }
  }

    Serial.print("Direction:");
      if(Direction){
        Serial.print("Forword   ");
      }else{
        Serial.print("Backword  ");
      }
    Serial.print("Pulses:");
    Serial.println(pulses);
    pulses = 0;
    delay(100);
}

void EncoderInit()
{
  Direction = true;         //default -> Forward
  pinMode(encoder_pinB,INPUT);
  attachInterrupt(digitalPinToInterrupt(encoder_pinA), wheelSpeed, RISING );
}

void wheelSpeed()
{
  int val = digitalRead(encoder_pinB);
  if(val == LOW ){
      Direction = false; //Reverse
      pulses--;
    }else{
      Direction = true;  //Forward
      pulses++;
    }
  }

void goForword(){
    digitalWrite(in1, HIGH);    //1,0 ->Forward 
    digitalWrite(in2, LOW);
}

void goBackword(){
    digitalWrite(in1, LOW);    //0,1 ->Backword 
    digitalWrite(in2, HIGH);
}

void stopMove(){
    digitalWrite(in1, LOW);    //1,0 ->Forward 
    digitalWrite(in2, LOW);
    motorSpeed = 0;
    analogWrite(enA, abs(motorSpeed)); 
}

Στο βρόχο Loop() του προγράμματος υπάρχει ένα switch – case το οποίο οδηγεί το πρόγραμμα σύμφωνα με την εντολή που δώσαμε από το τηλεκοντρολ. Από το τηλεκοντρόλ δίνουμε τρεις εντολές, άνω βέλος για αύξηση ταχύτητας προ τα εμπρός, κάτω βέλος για μείωση ταχύτητας και εν τέλει αναστροφή της κίνησης και τέλος “ΟΚ” για μηδενισμό της ταχύτητας του μοτέρ.

Η κίνηση προς τα εμπρός γίνεται με τη συνάρτηση goForword()

Η κίνηση προς τα πίσω γίνεται με τη συνάρτηση goBackword()

Το σταμάτημα του μοτέρ γίνεται με τη συνάρτηση stoMove()

Τέλος η ταχύτητα ορίζεται από την εντολή analogWrite(enA, abs(motorSpeed)) που παράγει τον PWM παλμό στο pin enA με Duty Cycle σύμφωνα με την τιμή της μεταβλητής motorSpeed.

Το πρόγραμμα μπορείτε να το κατεβάστε από εδώ.

Στο βίντεο που ακολουθεί βλέπετε την κατασκευή σε λειτουργία. https://youtu.be/4HFExAJxDxY

Αφήστε μια απάντηση

Η ηλ. διεύθυνση σας δεν δημοσιεύεται. Τα υποχρεωτικά πεδία σημειώνονται με *