Servo

tools
tools/Servo.h
tool

Gestion d'un servo-moteur standard (ex : SG90), piloté via un canal PCA9685. Cette classe ne génère plus le signal PWM elle-même (bit-banging sur une broche GPIO) : elle délègue au driver crepp::drivers::PCA9685_Handler, déjà initialisé par l'appelant, et se contente de convertir un angle (0-180°) en largeur d'impulsion, puis en valeur brute 12 bits envoyée

Méthodes publiques

Méthode Description Paramètres Retour
Servo()
Servo();
Constructeur. Initialise l'objet Servo. Le canal PCA9685 sera configuré lors de l'appel à begin(). /
Servo()
Servo();
Constructeur. Initialise l'objet Servo. Le canal PCA9685 sera configuré lors de l'appel à begin(). /
begin()
begin(crepp::drivers::PCA9685_Handler &pwmDriver, uint8_t channel = 0);
Associe le servo à un canal d'un PCA9685 déjà initialisé. / pwmDriver: Référence vers le driver PCA9685_Handler (déjà appelé begin(), à 50 Hz)
channel: Canal du PCA9685 utilisé par ce servo (0 à 15)
true
true si le canal est valide, false sinon /
setAngle()
setAngle(uint8_t angle);
Positionne le servo à un angle donné. / angle: Angle en degrés (0 à 180, borné automatiquement) /
getStatus()
getStatus() const {
Retourne l'état du servo-moteur. / DEVICE_OK
DEVICE_OK si begin() a réussi, DEVICE_ERROR_INIT/DEVICE_ERROR_CONFIG sinon. /

Méthodes privées


            angleToTicks(uint8_t angle) const;;
begin(115200);;
println("Erreur d'initialisation du PCA9685 !");;
while (1);;
println("Erreur de configuration du servo !");;
while (1);;
setAngle(0);;
delay(1000);;
setAngle(90);;
delay(1000);;
setAngle(180);;
delay(1000);;

                    

Variables membres


            return _status;

                    

Code source


        #pragma once
#include <Arduino.h>
#include "../StatusDevice.h"
#include "../drivers/PCA9685_Handler.h"

/**
 * @namespace crepp::tools
 * @brief Outils utilitaires de la bibliothèque CREPP.
 */
namespace crepp::tools {

/**
 * @class Servo
 * @brief Gestion d'un servo-moteur standard (ex : SG90), piloté via un canal PCA9685.
 *
 * @details
 * Cette classe ne génère plus le signal PWM elle-même (bit-banging sur une
 * broche GPIO) : elle délègue au driver crepp::drivers::PCA9685_Handler,
 * déjà initialisé par l'appelant, et se contente de convertir un angle
 * (0-180°) en largeur d'impulsion, puis en valeur brute 12 bits envoyée
 * sur le canal choisi.
 *
 * Utilisation typique :
 * @code
 * crepp::drivers::PCA9685_Handler pwm;
 * pwm.begin(50.0f); // 50 Hz, fréquence standard pour un servo
 *
 * crepp::tools::Servo myServo;
 * myServo.begin(pwm, 0); // canal 0 du PCA9685
 * myServo.setAngle(90);  // angle en degrés
 * @endcode
 *
 * @note L'angle doit être compris entre 0 et 180 degrés.
 * @note Le PCA9685_Handler doit être configuré à 50 Hz (fréquence standard
 *       des servos) AVANT d'utiliser Servo::setAngle(), sans quoi les
 *       largeurs d'impulsion calculées seront incorrectes.
 */
class Servo
{
public:
    /**
     * @brief Constructeur.
     *
     * Initialise l'objet Servo. Le canal PCA9685 sera configuré
     * lors de l'appel à begin().
     */
    Servo();

    /**
     * @brief Destructeur.
     */
    ~Servo();

    /**
     * @brief Associe le servo à un canal d'un PCA9685 déjà initialisé.
     *
     * @param pwmDriver Référence vers le driver PCA9685_Handler (déjà appelé begin(), à 50 Hz)
     * @param channel Canal du PCA9685 utilisé par ce servo (0 à 15)
     * @return true si le canal est valide, false sinon
     */
    bool begin(crepp::drivers::PCA9685_Handler &pwmDriver, uint8_t channel = 0);

    /**
     * @brief Positionne le servo à un angle donné.
     *
     * @param angle Angle en degrés (0 à 180, borné automatiquement)
     */
    void setAngle(uint8_t angle);

    /**
     * @brief Retourne l'état du servo-moteur.
     * @return DEVICE_OK si begin() a réussi, DEVICE_ERROR_INIT/DEVICE_ERROR_CONFIG sinon.
     */
    StatusDevice getStatus() const { return _status; }

private:
    static constexpr float    SERVO_FREQUENCY_HZ = 50.0f; ///< Fréquence standard des servos (période 20 ms)
    static constexpr uint16_t PULSE_MIN_US        = 500;   ///< Largeur d'impulsion pour 0°
    static constexpr uint16_t PULSE_MAX_US        = 2500;  ///< Largeur d'impulsion pour 180°

    crepp::drivers::PCA9685_Handler *_pwm = nullptr; /**< Driver PCA9685 partagé, non possédé */
    uint8_t _channel = 0;                            /**< Canal PCA9685 utilisé par ce servo */
    StatusDevice _status = StatusDevice::DEVICE_ERROR_INIT;

    /// Convertit un angle (0-180°) en valeur brute 12 bits (0-4095) pour PCA9685_Handler::write()
    uint16_t angleToTicks(uint8_t angle) const;
};

/*
@example

@include
#include <crepp/drivers/PCA9685_Handler.h>
#include <crepp/tools/Servo.h>
@end_include

@macro
#define SERVO_CHANNEL 0
@end_macro

@instance
crepp::drivers::PCA9685_Handler pwm;
crepp::tools::Servo servo;
@end_instance

@setup
  Serial.begin(115200);

  if (!pwm.begin(50.0f)) { // 50 Hz, fréquence standard pour un servo
      Serial.println("Erreur d'initialisation du PCA9685 !");
      while (1);
  }

  if (!servo.begin(pwm, SERVO_CHANNEL)) {
      Serial.println("Erreur de configuration du servo !");
      while (1);
  }
@end_setup

@loop
  servo.setAngle(0);
  delay(1000);
  servo.setAngle(90);
  delay(1000);
  servo.setAngle(180);
  delay(1000);
@end_loop

@end_example
*/

} // namespace crepp::tools