Site icon AranaCorp

Controlar um servomotor com Arduino

5
(1)

Um dos principais objectivos da robótica é fazer objectos se moverem por si sós. Para isso, é muito comum utilizar motores elétricos, e mais especialmente servomotores. Neste artigo, aprenderemos a programar a placa Arduino de modo a poder controlar um servomotor e veremos um pouco mais sobre o uso das bibliotecas, em especial a Servo.h.

Leia antes: Programar com Arduino

Equipamento

Servomotor

Os servomotores são pequenos concentrados de tecnologia que combinam mecânica e eletrônica. Eles são muito utilizados no modelismo e na robótica. Seu nome vem do fato de eles poderem controlar a sua própria posição (ou velocidade).

Eles são compostos por um motor de corrente contínua, uma caixa de redução e de uma placa de circuito interno, que permitem controlar a posição por meio de um sinal de modulação por largura de pulso (em inglês, PWM – Pulse Width Modulation).

Esquema de ligação

O servomotor é alimentado pelo fio terra preto/marrom (GND) e pelo fio vermelho de tensão da bateria (+5V); ele é controlado por um sinal PWM enviado através do fio amarelo/branco (terminal 9). Dependendo da quantidade de servomotores utilizados e da sua potência, é possível alimentá-lo pelo terminal 5V da placa Arduino. A placa Arduino pode ser alimentada pelo computador através de entrada USB.

Código básico para controle do servomotor

Para controlar a posição do servomotor, é preciso enviar um sinal por modulação de largura de pulso.

//Déclaration des constantes
#define UPDATE_TIME 20

//Déclaration des paramètres
int servoPin = 9;
int pulse = 1500;


void setup() {
  // Code d'initialisation
  pinMode(servoPin,OUTPUT);
  Serial.begin(9600); 
}

void loop() {
  // Code principal
  digitalWrite(servoPin,HIGH);
  delayMicroseconds(pulse);
  digitalWrite(servoPin,LOW);
  delay(UPDATE_TIME);
}

Evidentemente, isso não é muito prático. Seria melhor pedir uma posição ao servomotor. Para tanto, podemos criar uma subfunção que permita converter uma posição em largura de pulso. Isso exige uma pequena dose de matemática: Se temos:

Podemos então determinar a regra para conversão da posição angular em largura de pulso.

//Déclaration des constantes
#define UPDATE_TIME 20

//Déclaration des paramètres
int servoPin = 9;
int angle = 50;


void setup() {
  // Code d'initialisation
  pinMode(servoPin,OUTPUT);
  Serial.begin(9600); 
}

void loop() {
  // Code principal
  digitalWrite(servoPin,HIGH);
  delayMicroseconds(convertirAngleEnImpulsion(angle));
  digitalWrite(servoPin,LOW);
  delay(UPDATE_TIME);
}

// Déclaration d'un sous fonction
int convertirAngleEnImpulsion(int ang){
  float a = 2000.0/180.0;
  float b = 500;

  return int(a*ang+b);
}

É possível escrever programas muito mais complexos para o Arduino, mas diversas aplicações já podem ser realizadas com essas informações básicas e o conhecimento de certas bibliotecas. Uma delas é a biblioteca do servomotor, que veremos em seguida.

N.B. Este código nos mostra o princípio de um sinal PWM. Na prática, para aplicar um sinal PWM a um servomotor ou a um LED, utilizaremos a função analogWrite() disponível em certo pino do Arduino. Esta função toma um valor inicial entre 0 e 255.

//Déclaration des constantes
#define UPDATE_TIME 20

//Déclaration des paramètres
int servoPin = 9;


void setup() {
  // Code d'initialisation
  pinMode(servoPin,OUTPUT);
  Serial.begin(9600); // Initialise la communication série PC/Arduino
}

void loop() {
  // Code principal
  for(int i=0;i<180;i++){
    analogWrite(servoPin,convertirAngleEnPWM(i));
    delay(UPDATE_TIME);
  }
delay(200);
  for(int i=180;i>=0;i--){
    analogWrite(servoPin,convertirAngleEnPWM(i));
    delay(UPDATE_TIME);
  }
 delay(200);
}

// Déclaration d'un sous fonction
int convertirAngleEnPWM(int ang){
  float a = 255.0/180.0;
  return (a*ang);
}

Controle do servomotor com a biblioteca Servo.h

Já vimos que é possível criar subfunções com códigos que poderão ser reutilizados sempre que desejarmos. Essas subfunções são armazenadas nas bibliotecas, em ficheiros externos ao programa principal, podendo ser utilizadas em qualquer aplicação. Elas são criadas para organizar o programa com maior clareza e para simplificar o trabalho dos programadores, evitando copiar e colar ou reescrever o código. Para utilizar a biblioteca, adicione-a biblioteca ao código com a palavra-chave #include. Confira a documentação disponível para Arduino para utilizá-la corretamente (por exemplo).

//Librairie
#include <Servo.h>

//Déclaration des constantes
#define UPDATE_TIME 15
#define MAX_POS 180
#define MIN_POS 0

//Déclaration des paramètres
int servoPin = 9;
int pulse = 1500;

//Déclaration des variables
Servo myServo;  // création d'un objet Servo
// Sur la plupart des cartes, on peut créer jusqu'à douze objets

int pos=0;    // variable contenant la position du servomoteur

void setup() {
  myServo.attach(servoPin); 
}

void loop() {
  for (pos = MIN_POS; pos <= MAX_POS; pos += 1) { 
    myServo.write(pos);              
    delay(UPDATE_TIME);                       
  }
  for (pos = MAX_POS; pos >= MIN_POS; pos -= 1) { 
    myServo.write(pos);             
    delay(UPDATE_TIME);                      
  }
}

Crie a sua própria biblioteca ServoLib.h

A criação de uma biblioteca permite reutilizar segmentos de códigos em diversos projectos sem precisar reescrevê-los. Uma biblioteca se compõe de dois ficheiros em linguagem c (um ficheiro .cpp e um ficheiro .h), ambos com o mesmo nome. O ficheiro .h, chamado de header, contém a declaração das variáveis, das funções e das classes utilizadas. O ficheiro .cpp contém o código propriamente dito. Esses ficheiros devem ser salvos numa pasta com o mesmo nome da biblioteca no seguinte diretório: .Documents/Arduino/libraries.

Ficheiro ServoLib.h

#ifndef ServoLib_h
#define ServoLib_h

//Déclaration des constantes
#define UPDATE_TIME 15
#define MAX_POS 180
#define MIN_POS 0
#define MAX_PULSE_WIDTH 2500
#define MIN_PULSE_WIDTH 500

//Déclaration de la classe
class ServoLib
{
 public:
  ServoLib(); //constructeur
  int servoPin; //broche du servomoteur
  void associePin(int pin); 
  void envoiePosition(int value);
  int convertirAngleEnImpulsion(int ang);
  void appliquerImpulsion(int pulse);
};

#endif

Ficheiro ServoLib.cpp

#include <ServoLib.h>

ServoLib::ServoLib(){}

void ServoLib::associePin(int pin){
  servoPin=pin;
  pinMode(servoPin,OUTPUT);
}

void ServoLib::envoiePosition(int value){
  int pulse=0;
  if (value<MIN_POS)
    value=MIN_POS;
  else if (value>MAX_POS)
    value=MAX_POS;

  value=map(value,MIN_POS,MAX_POS,MIN_PULSE_WIDTH,MAX_PULSE_WIDTH);
  pulse=this->convertirAngleEnImpulsion(value);
  this->appliquerImpulsion(pulse);
}

void ServoLib::appliquerImpulsion(int pulse){
  digitalWrite(servoPin,HIGH);
  delayMicroseconds(pulse);
  digitalWrite(servoPin,LOW);
  delay(UPDATE_TIME);
}

int ServoLib::convertirAngleEnImpulsion(int ang){
  float a = 2500/180;
  float b = 500;

  return int(a*ang+b);
}

O ficheiro keyword.txt é opcional. Ele permite modificar a cor dos nomes no programa Arduino.

#######################################
# Syntax Coloring Map ServoLib
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

ServoLib  KEYWORD1  ServoLib

#######################################
# Methods and Functions (KEYWORD2)
#######################################
associePin KEYWORD2
envoiePosition  KEYWORD2
convertirAngleEnImpulsion KEYWORD2
appliquerImpulsion KEYWORDS2

#######################################
# Constants (LITERAL1)
#######################################
UPDATE_TIME LITERAL1
MIN_POS LITERAL1
MAX_POS LITERAL1
MIN_PULSE_WIDTH LITERAL1
MAX_PULSE_WIDTH LITERAL1

Sem o ficheiro keywords.txt

Com o ficheiro keywords.txt

Após recarregar o programa, poderá conferir, no Menu Esboço > Incluir Biblioteca, que a biblioteca que acabou de criar foi adicionada à lista.

Então o código pode ser simplificado da seguinte forma:

//Librairie
#include "ServoLib.h"

//Déclaration des paramètres
int servoPin = 9;

//Déclaration des variables
ServoLib myServo;  // création d'un objet Servo
// Sur la plupart des cartes, on peut créer jusqu'à douze objets

int pos=0;    // variable contenant la position du servomoteur

void setup() {
  myServo.associePin(servoPin);
}

void loop() {
  for (pos = MIN_POS; pos <= MAX_POS; pos += 1) {
    myServo.envoiePosition(pos);
    delay(UPDATE_TIME);
  }
  for (pos = MAX_POS; pos >= MIN_POS; pos -= 1) {
    myServo.envoiePosition(pos);             
    delay(UPDATE_TIME);                      
  }
}

Próximos passos

Referências

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie

How useful was this post?

Click on a star to rate it!

Average rating 5 / 5. Vote count: 1

No votes so far! Be the first to rate this post.

Exit mobile version