TP 4 — Les ventilateurs
Objectifs
commander une charge de puissance (un moteur) par un transistor et un PWM ;
choisir une fréquence de PWM adaptée à un moteur ;
constater, mesures à l’appui, les limites d’un ventilateur à deux fils, et en tirer la bonne solution ;
faire un thermostat en tout ou rien, avec hystérésis.
Durée indicative : une séance de 3 h. Prérequis : TP 2 — PWM et couleurs. Matériel :
un ventilateur 5 V à deux fils, branché sur le connecteur VENTILO_2.
Ce qu’il faut savoir
Le circuit
La carte a deux sorties de ventilateur, VENTILO_1 (PB14, TIM12_CH1) et
VENTILO_2 (PB15, TIM12_CH2), sur des connecteurs JST XH. Le ventilateur
est alimenté en +5 V et commuté côté masse par un transistor MOSFET :

Commande d’un ventilateur : le transistor coupe la masse ; la diode protège de la surtension du moteur.
La diode de roue libre protège le transistor : un moteur est une bobine, et une bobine dont on coupe brutalement le courant produit une surtension. La diode offre au courant un chemin pour s’éteindre doucement.
Pourquoi 25 kHz
Un moteur découpé à une fréquence audible siffle. On choisit donc une fréquence au-dessus de l’audible : 25 kHz, la valeur normalisée des ventilateurs d’ordinateur. Avec l’horloge HSI à 64 MHz, TIM12 compte à 64 MHz : prédiviseur 0, période 2 559 donnent exactement 25 kHz.
Étape 1 — Le ventilateur en PWM
Créez un projet
tp04_ventilateurscomme au TP 1 (STM32H750VBTx, SYS → Debug : Serial Wire, horloge par défaut).Cliquez sur PB15 et choisissez TIM12_CH2. Dans Timers → TIM12, réglez Channel2 sur PWM Generation CH2, Prescaler 0, Counter Period 2559.
Générez le code, démarrez le PWM, et faites tourner le ventilateur à 100 % (comparaison = 2 560).
Descendez par paliers de 5 %, en restant 5 s sur chaque palier. Notez à quel rapport cyclique le ventilateur ralentit, et à quel rapport il s’arrête.
Questions
Vérifiez par le calcul la fréquence de 25 kHz.
Le ventilateur ralentit-il progressivement ? À quel rapport cyclique s’arrête-t-il ?
Relancez-le à 100 % pendant une seconde, puis passez directement à 70 % : continue-t-il de tourner ?
Solution de l’étape 1
Une fonction règle le rapport cyclique en pourcentage
(USER CODE BEGIN 0) :
#define FAN_PERIOD 2560u /* ARR + 1 */
static void fan_set_pct(uint32_t pct)
{
if (pct > 100u) { pct = 100u; } /* borne : jamais plus de 100 % */
__HAL_TIM_SET_COMPARE(&htim12, TIM_CHANNEL_2, (FAN_PERIOD * pct) / 100u);
}
Dans USER CODE BEGIN 2 : HAL_TIM_PWM_Start(&htim12, TIM_CHANNEL_2);.
Dans la boucle, la descente par paliers :
for (int32_t p = 100; p >= 0; p -= 5)
{
fan_set_pct((uint32_t)p);
HAL_Delay(5000);
}
100 % = CCR 2 560, et non 2 559. La sortie est à 1 tant que le compteur est strictement sous CCR. Le compteur va de 0 à 2 559 : avec CCR = 2 559, il passe un pas à 0 par période (99,96 %) ; avec CCR = 2 560, jamais — la sortie reste à 1 en permanence, un vrai 100 %.
L’ordre des opérations. (2560 × pct) / 100 multiplie avant de
diviser : en entiers, 2560 / 100 × pct donnerait 25 × pct, soit 2 500 à
100 % au lieu de 2 560, à cause de la troncature de la division.
Pour suivre le palier courant sans terminal, on peut le ranger dans une
variable globale volatile et la lire dans le débogueur (fenêtre
Live Expressions de CubeIDE).
Réponses aux questions 1 à 3
1. La fréquence. TIM12 reçoit 64 MHz ; PSC = 0 ne divise pas ; le compteur fait 2 560 pas par période :
f = 64 000 000 / ((0 + 1) × (2 559 + 1)) = 25 000 Hz période : 40 µs
La résolution est de 2 560 pas, soit 0,04 % : bien plus fin que nécessaire.
2. Le comportement. Non, il ne ralentit pas progressivement : il garde sa vitesse jusqu’à un certain rapport cyclique, puis cale d’un coup. Sur le ventilateur des robots, c’est dès 95 %. Selon le modèle, le seuil peut être un peu plus bas, mais on n’obtient jamais une plage de vitesses réglable.
3. Après un démarrage à 100 %. Il ne continue pas : même lancé à pleine vitesse, il cale à 70 %. Ce n’est donc pas un problème de couple au démarrage (qui serait réglé par l’élan) : quelque chose dans le ventilateur ne supporte pas le découpage lui-même. L’étape 2 explique quoi.
Étape 2 — Comprendre ce qui se passe
Un ventilateur à deux fils n’est pas un simple moteur : il contient une petite électronique de commutation, qui fait tourner son moteur sans balais. Elle est alimentée par les deux mêmes fils que le moteur. En découpant la masse, le PWM coupe aussi l’alimentation de cette électronique, des milliers de fois par seconde : elle décroche, et le ventilateur s’arrête bien avant que le rapport cyclique ne soit faible.
Sur les cartes RatBot, le ventilateur à deux fils mesuré tourne à 100 %, et cale dès 95 %, même après un démarrage à pleine vitesse. La vitesse d’un tel ventilateur ne se règle pas par découpage de son alimentation.
Questions
Vos mesures confirment-elles ce comportement ? Votre ventilateur se comporte-t-il exactement de la même façon ? Pourquoi un autre modèle pourrait-il tenir un peu plus bas ?
Un ventilateur à quatre fils a une entrée dédiée au PWM, séparée de son alimentation. Pourquoi règle-t-il ce problème ?
Réponses aux questions 4 et 5
4. Pourquoi ça cale. Un ventilateur à deux fils contient un moteur sans balais : ses bobines sont commutées par un petit circuit (un capteur à effet Hall et un pilote), qui tire son alimentation des mêmes deux fils. Quand le transistor coupe la masse, 25 000 fois par seconde, ce circuit perd son alimentation à chaque coupure. Il tient tant que les coupures sont très brèves, grâce au petit condensateur qu’il a en interne ; au-delà, il redémarre sans cesse et perd le fil de la commutation : le moteur s’arrête.
Le seuil dépend donc de la réserve d’énergie de ce circuit (la taille de son condensateur, sa consommation), qui varie d’un modèle à l’autre : un autre ventilateur pourra tenir à 80 %, mais aucun ne se réglera vraiment.
5. Le ventilateur à quatre fils. Il a deux fils d’alimentation permanente (+12 V ou +5 V, et masse), un fil de vitesse mesurée (tachymètre), et un fil d”entrée PWM, qui n’alimente rien : c’est une simple consigne, lue par son électronique. Celle-ci reste alimentée en continu, et règle elle-même le courant du moteur. Le PWM n’est plus de la puissance, mais de l”information.
Étape 3 — Un thermostat
Puisque le ventilateur à deux fils ne se règle pas, on le commande en tout ou rien, d’après la température de la carte (TMP102, voir TP 7 — Le bus I²C : température, accéléromètre et gyroscope) :
Ajoutez la lecture du TMP102 (I2C2), une fois par seconde.
Ventilateur en marche au-dessus de 35 °C, arrêté en dessous de 32 °C.
Question
Pourquoi deux seuils, et non un seul à 33,5 °C ? Que se passerait-il avec un seul seuil, quand la température est juste à cette valeur ?
Solution de l’étape 3
Il faut I2C2 (PB10, PB11) en plus, configuré comme au TP 7. La lecture du
TMP102 (USER CODE BEGIN 0) :
#define TMP102_ADDR (0x48u << 1)
static int temp_read_mC(int32_t *out)
{
uint8_t b[2];
int32_t raw;
if (HAL_I2C_Mem_Read(&hi2c2, TMP102_ADDR, 0x00u, I2C_MEMADD_SIZE_8BIT,
b, 2u, 5u) != HAL_OK) { return 0; }
raw = (int32_t)((((uint16_t)b[0] << 8) | b[1]) >> 4); /* 12 bits */
if (raw & 0x800) { raw -= 4096; } /* signe */
*out = (raw * 625) / 10; /* 0,0625 °C par pas */
return 1;
}
et le thermostat, dans la boucle :
#define FAN_ON_mC 35000
#define FAN_OFF_mC 32000
static uint32_t fan_on = 0u;
int32_t t;
if (temp_read_mC(&t))
{
if (!fan_on && (t >= FAN_ON_mC)) { fan_on = 1u; }
else if (fan_on && (t <= FAN_OFF_mC)) { fan_on = 0u; }
}
fan_set_pct(fan_on ? 100u : 0u);
HAL_Delay(1000);
Les températures en millièmes de degré, dans des entiers : on évite les nombres à virgule, et 35 °C s’écrit 35 000 sans perte. Le détail de la conversion du TMP102 est expliqué au TP 7.
Si la lecture échoue, on garde l’état précédent du ventilateur plutôt que de l’arrêter : une panne du capteur ne doit pas couper le refroidissement. Un vrai produit allumerait même le ventilateur par précaution.
Réponse à la question 6
6. Deux seuils : l’hystérésis. Avec un seul seuil à 33,5 °C, quand la température est juste à cette valeur, le bruit de mesure (le dernier bit du capteur vaut 0,0625 °C) et le ventilateur lui-même la font osciller de part et d’autre : le ventilateur démarrerait et s’arrêterait à chaque seconde. C’est le pompage : bruyant, et qui use le moteur.
Avec deux seuils, il y a une bande morte de 3 °C : une fois lancé à 35 °C, le ventilateur ne s’arrête qu’à 32 °C, et la carte doit se réchauffer de 3 °C avant qu’il redémarre. Le thermostat a une mémoire : son état ne dépend pas seulement de la température, mais aussi de son état précédent. C’est le principe de tous les thermostats, et d’un composant électronique classique, le trigger de Schmitt.
Tout le code de la correction
main_user_code.c
— compilé sans avertissement contre la HAL du STM32H7.
Ce n’est pas un main.c complet : ce sont les extraits à placer dans
les blocs USER CODE du main.c généré par CubeMX, chacun sous le
commentaire qui indique son bloc. La boucle while (1) contient une
variante par étape, encadrée par #if 0 / #if 1 : n’en activer
qu’une à la fois. La configuration CubeMX attendue est rappelée en tête
du fichier, et les réponses aux questions à la fin.
Exercices supplémentaires
Ces exercices n’ont pas de correction.
Les deux sorties : branchez un second ventilateur sur
VENTILO_1(PB14, TIM12_CH1) et commandez-les indépendamment.Seuils au terminal : réglez les deux seuils du thermostat par la liaison série (TP 5 — La liaison série avec le PC).
Ventilateur à quatre fils : si vous en avez un, alimentez-le en permanence et envoyez le PWM sur son entrée de commande. Relevez la plage de vitesse obtenue.
Après le TP
Pour rendre la carte au robot, voir Remettre la carte en état RatBot.