Déballage du shield Geekcreit PCA9685 I2C 16 servos + 2 moteurs pour Arduino ou ESPDuino (ESP8266) • Domotique et objets connectés à faire soi-même

L’Arduino Uno ou les cartes ESP8266 ne délivrent pas assez de puissance pour alimenter les 6 servo-moteurs du bras robotique présenté précédemment dans cet article. Il faut donc acheter une carte fille disposant d’un alimentation externe qui permet de délivrer suffisamment de puissance. On trouve de nombreuses cartes basées sur le circuit PCA9685 qui permet de piloter jusqu’à 16 servo-moteurs via le bus I2C.

Je trouve qu’il est plus intéressant de pouvoir piloter un bras robotique en WiFi. On pourra par exemple développer des applications avec une interface WEB pour piloter le bras robotique depuis une tablette ou un smartphone. On pourra également mettre à profit l’accéléromètre intégré pour piloter le bras en suivant le mouvement de son téléphone. Je vous propose donc de tester la carte d’extension 16 canaux PWM PCA9685 et 2 moteurs DC de Doit.am (ancien Geekcreit). Elle est compatible avec le connecteur de l’Arduino Uno. Comme on utilise le bus i2c pour piloter les servo-moteurs, on pourra également utiliser les cartes ESPDuino (ou la Wemos D1 R2), n’importe quel autre clone à base d’ESP8266…et pourquoi pas un Raspberry Pi !

Déballage et caractéristiques de la carte PCA9685, 16 servos + 2 moteurs DC (Geekcreit/Doit)

La carte PCA9685 Doit se présente sous la forme d’une carte d’extension compatible avec l’Arduino Uno. Elle est construite autour d’un circuit PCA9685 de NXP assez bien documenté. On trouve de plusieurs librairies pour Arduino et des adaptations pour les modules ESP8266.

L’intérêt du bus I2C est de pouvoir piloter jusqu’à 16 servomoteurs à l’aide du bus I2C.

Le bus I2C n’utilisent que 2 fils ce qui est parfait pour les projets à base ESP8266.

Cette carte est compatible avec les connecteurs de l’Arduino. Elle vient s’empiler sur ce dernier. On pourra également l’utiliser sur les clones d’Arduino construit autour du module ESP8266. C’est le cas par exemple des cartes ESPDuino ou la Wemos d1 R2 qui j’ai utilisé ici. Cette carte coûte environ 10€. Si vous n’avez pas besoin de piloter des moteurs, il existe également des cartes plus compacts pour moins de 3€.

L’ESP8266 et l’Arduino Uno partagent les mêmes broches pur le bus I2C. GPIO5 pour SCL et GPIO4 pour SDA. Le code sera donc parfaitement identique. Les servomoteurs et les deux moteurs peuvent utiliser l’alimentation de la carte Arduino ou Espduino. Si la puissance délivrée est insuffisante, un bornier permet d’alimenter séparément les moteurs et les servomoteurs. Vous pouvez utiliser un adaptateur DC IN équipé d’un bornier pour alimenter la carte par exemple La carte peut être alimentée entre 6 et 18V. Un sélecteur permet de choisir entre l’alimentation externe et l’alimentation 5V de l’Arduino/ESP8266. Les connecteurs d’origine de la carte Arduino/Espduino sont déportés à l’intérieur de la carte. Il suffira de souder un header mâle ou femelle si on à besoin de piloter d’autres actionneurs ou récupérer des mesures de capteurs (capteur de couleur, proximité, fin de course…).

Voici les autres caractéristiques de la carte. Désolé, Doit ne documente pas ses cartes (ou du moins, c’est très difficile de trouver des documentations en anglais !). J’ai du reconstituer les caractéristiques en recoupant les infos et en tâtonnant !

  • Connecteur compatible Arduino Uno, ESPDuinoWemos d1 R2
  • Circuit PCA9685PW (documentation technique) sur bus I2C permettant de piloter jusqu’à 16 servos ou LEDs, entrée 2.3V-5.5V, découpage 1MHz, Sortie 5.5V/25mA, boitier TSSOP-28
  • Circuit L293DD permettant de piloter 2 moteurs à courant continu jusqu’à 18V.
  • 1x bornier d’alimentation externe 6 à 18V pour moteurs
  • 1x bornier d’alimentation externe 6 à 18V pour servomoteurs
  • 2x borniers d’alimentation pour moteurs DC (A et B)
  • Sélecteurs d’alimentation
    • VM/VIN shunté pour alimenter les moteurs depuis l’alimentation externe
    • VS/5V shunté pour alimenter les servos depuis l’alimentation externe
  • 1x Led orange pour signaler le fonctionnement du circuit PCA9685PW
  • Boutons RESET et POWER (?)

Comment utiliser le GPIO de l’Arduino

Comme vous avez du le remarquer, les broches de l’Arduino sont encore accessibles sur le dessus de la carte. C’est très pratique car on pourra par exemple y brancher un (ou plusieurs) joysticks analogiques pour piloter un bras robotique.

Faites attention toutefois à la seconde ligne de connecteur pré-percée. Aucune piste n’est connecté sur le PCB ! Je suis bêtement tombé dans le panneau  😕

Si vous voulez utiliser le GPIO de l’Arduino, il faudra acheter des headers empilables (stackable header).

Test avec la librairie Adafruit 12-bit PWM/Servo Driver pour Arduino Uno

Cette carte étant construite autour du même circuit que la carte Adafruit, elle est très bien prise en charge par la librairie du constructeur. Comme toute les librairies Adafruit, il est très simple de l’installer depuis le gestionnaire de librairie de l’IDE Arduino. Faites une recherche avec les mots clés adafruit PWM pour la trouver.

La librairie est livrée avec deux exemples. Voici l’exemple qui permet de piloter le premier servomoteur connecté à la carte.

/*************************************************** 
  This is an example for our Adafruit 16-channel PWM & Servo driver
  Servo test - this will drive 16 servos, one after the other

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/products/815

  These displays use I2C to communicate, 2 pins are required to  
  interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4

  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include 
#include 

// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);

// Depending on your servo make, the pulse width min and max may vary, you 
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
#define SERVOMIN  150 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  600 // this is the 'maximum' pulse length count (out of 4096)

// our servo # counter
uint8_t servonum = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("16 channel Servo test!");

  pwm.begin();
  
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
}

// you can use this function if you'd like to set the pulse length in seconds
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. its not precise!
void setServoPulse(uint8_t n, double pulse) {
  double pulselength;
  
  pulselength = 1000000;   // 1,000,000 us per second
  pulselength /= 60;   // 60 Hz
  Serial.print(pulselength); Serial.println(" us per period"); 
  pulselength /= 4096;  // 12 bits of resolution
  Serial.print(pulselength); Serial.println(" us per bit"); 
  pulse *= 1000;
  pulse /= pulselength;
  Serial.println(pulse);
  pwm.setPWM(n, 0, pulse);
}

void loop() {
  // Drive each servo one at a time
  Serial.println(servonum);
  for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
    pwm.setPWM(servonum, 0, pulselen);
  }
  delay(500);
  for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
    pwm.setPWM(servonum, 0, pulselen);
  }
  delay(500);

  servonum ++;
  if (servonum > 15) servonum = 0;
}

La librairie Adafruit PCA9685 n’est pas compatible avec les ESP8266. Elle est marquée comme testée et fonctionnelle sur GitHub mais j’ai rencontré cette erreur de compilation sur la Wemos d1 :

/Users/christophe/Documents/Arduino/libraries/Adafruit_PWM_Servo_Driver_Library/Adafruit_PWMServoDriver.cpp:25:15: error: 'Wire1' was not declared in this scope
  #define WIRE Wire1
               ^/pre> Sur Arduino Uno, la librairie est parfaitement gérée. Je n'ai as été plus loin car l'objectif est d'utiliser une carte à base d'ESP8266 dans les prochains tutoriels.

Test avec un ESPDuino / Wemos d1 R2 (librairie Sumotoy)

Si la librairie Adafruit ne fonctionne pas chez vous également, vous pouvez utiliser la librairie développée par Sumotoy. Vous pouvez la récupérer sur GitHub ici. Commencez par télécharger le dépôt. Décompressez ensuite le fichier ZIP et copiez le dossier décompressé dans le répertoire Library de l’IDE Arduino. Il se trouve (la plupart du temps) dans votre dossier Documents. Relancer l’IDE Arduino pour ajouter les exemples au menu. La librairie est livrée avec 4 exemples qui permettent de piloter les servos en PWM. La librairie s’utilise comme n’importe quelle autre. On créé un objet servo qui est attaché au bus I2C. Par défaut, la broche SCL est sur le GPIO5 (D1), la broche SDA sur le GPIO4 (D2). Le PCA9685 se trouve par défaut à l’adresse 0x40, ce qui est le cas aussi pour la carte Geekcreit / Doit. Ensuite, on dispose de plusieurs méthodes pour manipuler les servomoteurs :

    • setServoType(), on lui passe la constante STANDARD pour les servos de 0 à 190°. CONTINUOUS (ou rien) pour un servomoteur à rotation continue sur 360°
    • setPWMFreq(float freq), pour ajuster la fréquence PWM. Ajustez le paramètre en fonction des spécifications du fabricant si besoin
    • moveServo(uint8_t servo,uint8_t pos), déplace le servo à la position angulaire indiquée.
      • setServoMin, setServoMax
      • getServoMin, getServoMaxLire ou modifier les caractéristiques de chaque servomoteur

Créez un nouveau croquis et collez le code suivant. Il réalise juste un balayage de 0 à 180°. La position change toutes les 200ms. Arrivé à 180°, il retourne à la position d’origine.

/*
  Test PCA9685 driver Doit.am 16 servos I2C shield
  Compatible Arduino Uno / Espduino / ESP8266
*/

#include 
#include 

#define MAX_SERVOS 16

/*
 * ESP8266 I2C - pins
 * SDA: 4 - D2
 * SCL: 5 - D1
 */

servo_PCA9685 servo = servo_PCA9685();

uint8_t servonum = 0;

void setup() {
#if defined(ESP8266)
  Serial.begin(115200);
#else
  Serial.begin(38400);
#endif
  Serial.println("\nservo start");
  servo.begin();
}
int angle = 0;

void loop() {
  if ( angle == 180 ) {
    angle = 0;
  }  
  servo.moveServo(0,angle);
  Serial.println("Move to "+angle);
  angle++;
  delay(200);
}

Test en MicroPython

Le PCA9685 est également très bien pris en charge en MicroPython. On trouve une librairie développée par Adafruit et McHobby. J’ai testé les deux sans succès avec ma carte. Dès que j’exécute le code, la carte se déconnecte du port USB sans que le servomoteur ne bouge. Si quelqu’un a des infos, je suis preneur.

Voilà, tout est en place pour piloter le bras robotique. Nous disposons maintenant d’une carte permettant de piloter séparément chaque articulation du bras robotique. En utilisant une carte Espduino, nous pourrons même piloter le bras en WiFi depuis une Web App ou un navigateur.

Avez-vous aimé cet article ?