fbpixel
Etiquetas: , , , ,
0
(0)

O módulo PCA9685 é um controlador de 16 canais que permite controlar 16 saídas PWM através de comunicação I2C. Seu uso libera entradas e saídas do seu microcontrolador, possibilitando conduzir até 16 LEDs ou servomotores (ou qualquer outro módulo que tome um sinal PWM como entrada) usando dois pinos (SCL e SDA). Com isso, os pinos do seu microcontrolador ficam livres para outros módulos, como sensores.

Pré-requisito: Conduzir um servomotor com o Arduino

Material

  • Computador
  • Arduino UNO
  • Cabo USB A Macho/B Macho
  • Módulo PCA9685

Princípio de funcionamento

O módulo é baseado no controlador PCA9685, que controla saídas PWM usando comunicação I2C e um relógio integrado. Este módulo comporta 6 pontes que permitem selecionar o endereço da placa e colocar, no mesmo barramento, até 62 controladores, para um total de 992 servomotores (endereços disponíveis de 0x40 a 0x7F).
Ele permite acionar saídas PWM com uma frequência ajustável e uma resolução de 12 bits. O módulo é compatível com microcontroladores de 5V e 3,3V.

Esquema

O módulo é equipado com um barramento I2C e uma entrada de energia. O barramento I2C se conecta da seguinte forma:

  • Pino A5 ou SCL no pino SCL do módulo
  • Pino A4 ou SDA no pino SDA do módulo
  • Pino 5V no pino Vcc do módulo
  • Pino GND no pino GND do módulo

Neste tutorial, usamos a placa Arduino UNO, mas ele pode ser adaptado a outros microcontroladores. Basta adaptar os pinos I2C disponíveis no microcontrolador em questão e, possivelmente, o código.

Código

Para utilizar o módulo PCA9685, usamos a biblioteca Adafruit_PWMServoDriver.h. As larguras de PWM são geralmente dadas em microssegundos por um período de 20ms (50Hz), mas estes valores podem mudar conforme o fornecedor e o servomotor utilizado. Nesse caso, é preciso modificar os valores do código para adaptá-los ao seu servomotor.
Aqui, utilizamos o servomotor MG90S, cujos gamas são de 400-2400µs por 20ms.

Para definir o comando PWM, a biblioteca apresenta duas funções: setPWM() e writeMicroseconds(). A função writeMicroseconds() permite utilizar diretamente os valores do construtor. Para a função setPWM, precisamos encontrar a largura de pulso correspondente em 4096 (2^12, 12bits).

Exemplo: A frequência é de 50Hz, logo um período de 20ms ou 20000µs.
pwmvalmin=400/20000*4096=81.92-> 90 arredondando com uma margem de segurança
pwmvalmax=2400/20000*4096=491.52 -> 480 arredondando com uma margem de segurança
Isso nos dá as seguintes equivalências:
pca.writeMicroseconds(i,400) equivale a pca.setPwm(i,0,90)
pca.writeMicroseconds(i,2400) equivale a pca.setPwm(i,0,480)
Utilize a função que melhor lhe convier.

//Libraries
#include <Wire.h>//https://www.arduino.cc/en/reference/wire
#include <Adafruit_PWMServoDriver.h>//https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library

//Constants
#define nbPCAServo 16

//Parameters
int MIN_IMP [nbPCAServo] ={500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500};
int MAX_IMP [nbPCAServo] ={2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500};
int MIN_ANG [nbPCAServo] ={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int MAX_ANG [nbPCAServo] ={180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180};

//Objects
Adafruit_PWMServoDriver pca= Adafruit_PWMServoDriver(0x40);

void setup(){
//Init Serial USB
Serial.begin(9600);
Serial.println(F("Initialize System"));
pca.begin();
pca.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
}

void loop(){
  pcaScenario();
}

void pcaScenario(){/* function pcaScenario */ 
////Scenario to test servomotors controlled by PCA9685 I2C Module
for (int i=0; i<nbPCAServo; i++) {
  Serial.print("Servo");
  Serial.println(i);
      //int middleVal=((MAX_IMP[i]+MIN_IMP[i])/2)/20000*4096; // conversion µs to pwmval
      //pca.setPWM(i,0,middleVal);
      for(int pos=(MAX_IMP[i]+MIN_IMP[i])/2;pos<MAX_IMP[i];pos+=10){
        pca.writeMicroseconds(i,pos);delay(10);
      }
      for(int pos=MAX_IMP[i];pos>MIN_IMP[i];pos-=10){
        pca.writeMicroseconds(i,pos);delay(10);
      }
      for(int pos=MIN_IMP[i];pos<(MAX_IMP[i]+MIN_IMP[i])/2;pos+=10){
        pca.writeMicroseconds(i,pos);delay(10);
      }
      pca.setPin(i,0,true); // deactivate pin i
    }
}

int jointToImp(double x,int i){/* function jointToImp */ 
////Convert joint angle into pwm command value
     
      int imp=(x - MIN_ANG[i]) * (MAX_IMP[i]-MIN_IMP[i]) / (MAX_ANG[i]-MIN_ANG[i]) + MIN_IMP[i];
      imp=max(imp,MIN_IMP[i]);
      imp=min(imp,MAX_IMP[i]);
      
 return imp;
}

Aplicações

  • Controlar o robô Quadrina6

Fontes

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 0 / 5. Vote count: 0

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

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?