L293D_Handler
drivers
drivers/L293D_Handler.h
driver
stable
stable
Driver: L293D Pilote bas niveau du circuit intégré L293D (double pont en H). Un seul L293D permet de commander jusqu'à 2 moteurs DC (ou 1 moteur pas à pas bipolaire) en contrôlant indépendamment le sens et la vitesse de chaque canal via une broche Enable PWM.
Méthodes publiques
| Méthode | Description | Paramètres | Retour |
|---|---|---|---|
|
L293D_Handler()
L293D_Handler();
|
Constructeur / Destructeur Le destructeur coupe les deux canaux (roue libre) par sécurité. / | ||
|
L293D_Handler()
L293D_Handler();
|
Constructeur / Destructeur Le destructeur coupe les deux canaux (roue libre) par sécurité. / | ||
|
begin()
begin(uint8_t in1A, uint8_t in2A, uint8_t enA,
uint8_t in1B, uint8_t in2B, uint8_t enB);
|
|||
|
begin()
begin(PCA9685_Handler& pca,
uint8_t chIn1A, uint8_t chIn2A, uint8_t enA,
uint8_t chIn1B, uint8_t chIn2B, uint8_t enB);
|
|||
|
setSpeed()
setSpeed(L293D_Channel channel, int8_t speed);
|
Commande de vitesse Définit la vitesse et le sens de rotation d'un canal donné. automatiquement bornée. 0 équivaut à stop(channel). / | channel: Canal à commander (CHANNEL_A ou CHANNEL_B) speed: Vitesse de -100 (arrière max) à 100 (avant max), automatiquement bornée. 0 équivaut à stop(channel). / |
|
|
stop()
stop(L293D_Channel channel);
|
Arrêt roue libre Coupe un canal (IN1=IN2=LOW, PWM=0) : le moteur connecté peut continuer à tourner librement par inertie. / | ||
|
stopAll()
stopAll();
|
Coupe les deux canaux (équivalent à stop() sur A puis B). / | ||
|
brake()
brake(L293D_Channel channel);
|
Freinage actif Court-circuite les sorties d'un canal (IN1=IN2=HIGH, PWM=max) pour un ralentissement plus rapide qu'un simple stop(). / | ||
|
getSpeed()
getSpeed(L293D_Channel channel) const;
|
Vitesse actuellement appliquée sur le canal donné. / | ||
|
isInitialized()
isInitialized() const {
|
Indique si begin() a déjà été appelé avec succès. / | ||
|
getStatus()
getStatus() const {
|
Méthodes privées
channelRef(L293D_Channel channel);;
channelRef(L293D_Channel channel) const;;
writeDir(uint8_t pinOrChannel, bool high);;
begin(115200);;
begin(L293D_IN1A, L293D_IN2A, L293D_ENA,
L293D_IN1B, L293D_IN2B, L293D_ENB);;
setSpeed(crepp::drivers::L293D_Channel::CHANNEL_A, 70);;
setSpeed(crepp::drivers::L293D_Channel::CHANNEL_B, 40);;
delay(2000);;
stopAll();;
delay(1000);;
begin(115200);;
println("Erreur d'initialisation du PCA9685 !");;
while (1);;
begin(pca,
PCA9685_CH_1A, PCA9685_CH_2A, L293D_ENA,
PCA9685_CH_3A, PCA9685_CH_4A, L293D_ENB);;
setSpeed(crepp::drivers::L293D_Channel::CHANNEL_A, 70);;
setSpeed(crepp::drivers::L293D_Channel::CHANNEL_B, -40);;
delay(2000);;
stopAll();;
delay(1000);;
Variables membres
return _initialized;
return _status;
Code source
#pragma once
#include <Arduino.h>
#include "../StatusDevice.h"
#include "PCA9685_Handler.h"
namespace crepp::drivers {
/**
* @brief Identifie l'un des deux demi-ponts (canaux) du L293D.
*
* Le L293D intègre 2 ponts en H indépendants :
* - Canal A : broches IN1/IN2, sortie 1Y/2Y, activation 1,2EN
* - Canal B : broches IN3/IN4, sortie 3Y/4Y, activation 3,4EN
*/
enum class L293D_Channel : uint8_t {
CHANNEL_A = 0, ///< Premier pont en H du circuit
CHANNEL_B = 1 ///< Second pont en H du circuit
};
/*
* =========================
* Driver: L293D
* -------------------------
* Pilote bas niveau du circuit intégré L293D (double pont en H).
* Un seul L293D permet de commander jusqu'à 2 moteurs DC (ou 1 moteur
* pas à pas bipolaire) en contrôlant indépendamment le sens et la
* vitesse de chaque canal via une broche Enable PWM.
*
* @badge driver
* @badge stable
*
* Fonctionnalités :
* - Configuration des broches des deux canaux (A et B) en une seule
* commande begin()
* - Commande vitesse + sens par canal via PWM (-100 à 100)
* - Arrêt "roue libre" (haute impédance) par canal ou global
* - Freinage actif par canal (court-circuit des bobines)
* - Lecture de la vitesse appliquée et de l'état du driver
*
* @note Cette classe ne modélise QUE le circuit L293D lui-même
* (bas niveau, sans notion de rampe ou de moteur). Pour une
* API orientée "moteur" avec rampe d'accélération, voir
* crepp::tools::Motor_Driver qui s'appuie sur cette classe.
* =========================
*/
class L293D_Handler {
public:
/*
* =========================
* Constructeur / Destructeur
* -------------------------
* Le destructeur coupe les deux canaux (roue libre) par sécurité.
*/
L293D_Handler();
~L293D_Handler();
/*
* =========================
* Initialisation
* -------------------------
* Configure les 6 broches utilisées par le L293D (3 par canal)
* et place les deux canaux à l'arrêt.
*
* @param in1A Broche IN1 du canal A
* @param in2A Broche IN2 du canal A
* @param enA Broche Enable / PWM du canal A
* @param in1B Broche IN3 du canal B (nommée in1B pour cohérence d'API)
* @param in2B Broche IN4 du canal B
* @param enB Broche Enable / PWM du canal B
*/
void begin(uint8_t in1A, uint8_t in2A, uint8_t enA,
uint8_t in1B, uint8_t in2B, uint8_t enB);
/*
* =========================
* Initialisation (variante PCA9685)
* -------------------------
* Variante d'initialisation où les 4 broches de direction (IN1/IN2
* des deux canaux, soit 1A/2A/3A/4A côté L293D) sont pilotées via
* un crepp::drivers::PCA9685_Handler (I2C), tandis que les 2 broches
* Enable (vitesse PWM) restent en GPIO natif du Pico.
*
* @param pca Référence vers un PCA9685_Handler déjà initialisé
* (begin() du PCA9685 doit avoir été appelé au préalable)
* @param chIn1A Canal PCA9685 (0-15) relié à IN1 du canal A (broche 1A)
* @param chIn2A Canal PCA9685 (0-15) relié à IN2 du canal A (broche 2A)
* @param enA Broche GPIO native du Pico, PWM (broche 1,2EN)
* @param chIn1B Canal PCA9685 (0-15) relié à IN3 du canal B (broche 3A)
* @param chIn2B Canal PCA9685 (0-15) relié à IN4 du canal B (broche 4A)
* @param enB Broche GPIO native du Pico, PWM (broche 3,4EN)
*/
void begin(PCA9685_Handler& pca,
uint8_t chIn1A, uint8_t chIn2A, uint8_t enA,
uint8_t chIn1B, uint8_t chIn2B, uint8_t enB);
/*
* =========================
* Commande de vitesse
* -------------------------
* Définit la vitesse et le sens de rotation d'un canal donné.
* @param channel Canal à commander (CHANNEL_A ou CHANNEL_B)
* @param speed Vitesse de -100 (arrière max) à 100 (avant max),
* automatiquement bornée. 0 équivaut à stop(channel).
*/
void setSpeed(L293D_Channel channel, int8_t speed);
/*
* =========================
* Arrêt roue libre
* -------------------------
* Coupe un canal (IN1=IN2=LOW, PWM=0) : le moteur connecté peut
* continuer à tourner librement par inertie.
*/
void stop(L293D_Channel channel);
/**
* @brief Coupe les deux canaux (équivalent à stop() sur A puis B).
*/
void stopAll();
/*
* =========================
* Freinage actif
* -------------------------
* Court-circuite les sorties d'un canal (IN1=IN2=HIGH, PWM=max)
* pour un ralentissement plus rapide qu'un simple stop().
*/
void brake(L293D_Channel channel);
/**
* @brief Vitesse actuellement appliquée sur le canal donné.
*/
int8_t getSpeed(L293D_Channel channel) const;
/**
* @brief Indique si begin() a déjà été appelé avec succès.
*/
bool isInitialized() const { return _initialized; }
StatusDevice getStatus() const { return _status; }
private:
/**
* @brief Regroupe les broches et l'état d'un canal du L293D.
*/
struct ChannelPins {
uint8_t pinIn1 = 0;
uint8_t pinIn2 = 0;
uint8_t pinEn = 0;
int8_t currentSpeed = 0;
};
ChannelPins _channels[2]; ///< [0] = CHANNEL_A, [1] = CHANNEL_B
bool _initialized = false;
StatusDevice _status = StatusDevice::DEVICE_ERROR_INIT;
/// Non-nullptr si les broches IN1/IN2 sont pilotées via un PCA9685
/// (mode hybride) plutôt qu'en GPIO natif.
PCA9685_Handler* _pca = nullptr;
ChannelPins& channelRef(L293D_Channel channel);
const ChannelPins& channelRef(L293D_Channel channel) const;
/// Ecrit un état logique HIGH/LOW sur une broche de direction,
/// que ce soit un GPIO natif (digitalWrite) ou un canal PCA9685
/// (write I2C), selon le mode d'initialisation utilisé.
void writeDir(uint8_t pinOrChannel, bool high);
};
/*
@example
@include
#include <crepp/drivers/L293D_Handler.h>
@end_include
@macro
// Canal A -> moteur gauche, Canal B -> moteur droit
#define L293D_IN1A 2
#define L293D_IN2A 3
#define L293D_ENA 4
#define L293D_IN1B 5
#define L293D_IN2B 6
#define L293D_ENB 7
@end_macro
@instance
crepp::drivers::L293D_Handler l293d;
@end_instance
@setup
Serial.begin(115200);
l293d.begin(L293D_IN1A, L293D_IN2A, L293D_ENA,
L293D_IN1B, L293D_IN2B, L293D_ENB);
@end_setup
@loop
// Les deux moteurs avancent à des vitesses différentes
l293d.setSpeed(crepp::drivers::L293D_Channel::CHANNEL_A, 70);
l293d.setSpeed(crepp::drivers::L293D_Channel::CHANNEL_B, 40);
delay(2000);
l293d.stopAll();
delay(1000);
@end_loop
@end_example
@example
@include
#include <crepp/drivers/PCA9685_Handler.h>
#include <crepp/drivers/L293D_Handler.h>
@end_include
@macro
// Directions (1A/2A/3A/4A) via PCA9685, EN en PWM direct du Pico
#define PCA9685_CH_1A 0
#define PCA9685_CH_2A 1
#define PCA9685_CH_3A 2
#define PCA9685_CH_4A 3
#define L293D_ENA 14
#define L293D_ENB 15
@end_macro
@instance
crepp::drivers::PCA9685_Handler pca;
crepp::drivers::L293D_Handler l293d;
@end_instance
@setup
Serial.begin(115200);
if (!pca.begin(1000.0f)) { // fréquence indifférente pour du tout-ou-rien
Serial.println("Erreur d'initialisation du PCA9685 !");
while (1);
}
l293d.begin(pca,
PCA9685_CH_1A, PCA9685_CH_2A, L293D_ENA,
PCA9685_CH_3A, PCA9685_CH_4A, L293D_ENB);
@end_setup
@loop
l293d.setSpeed(crepp::drivers::L293D_Channel::CHANNEL_A, 70);
l293d.setSpeed(crepp::drivers::L293D_Channel::CHANNEL_B, -40);
delay(2000);
l293d.stopAll();
delay(1000);
@end_loop
@end_example
*/
} // namespace crepp::drivers