Nous allons commencer par une base à 3 roues, dont deux motorisées. C’est un classique qui permet de diriger le mobile en faisant varier la vitesse relative des deux roues latérales et motorisées. C’est aussi générateur de difficulté, puisque que pour rouler en ligne droite, il faut s’assurer que ces deux roues tournent bien à la même vitesse. La dernière roue sera une « roue-folle » qui tournera en fonction des forces exercées par les roues motorisées. Voilà ce que peut donner ce type de base :
Liste des composants
Au vu des dimensions du socle et de sa capacité d’évolution ultérieure, on va partir sur les éléments suivants (les liens sont donnés à titre indicatifs) :
- 2 moteurs d’une 12aine de Watts chacun, avec réducteur afin que la vitesse reste raisonnable mais que le couple soit lui relativement important (ceux-là possèdent un encodeur angulaire) :
DC 12v Hall Encoder Gear 18-1930rpm 25mm Mini Encoder Motor Wheel Tire Bracket Coupled For Intelligent Toy Car DIY
en version 12v, 85 RPM ; - 1 carte L298 avec 2 ponts H qui supportent les courants des moteurs précédents (2A) :
L298N H double pont DC Stepper Motor Drive Controller Module Board ; - 4 télémètres Ultra-Son, pour éviter les collisions (3 devant, 1 derrière) :
Module à ultrasons HC-SR04 Distance mesure Capteur Capteur de distance DC 5V 2-450cm ; - 1 Arduino Nano pour les contrôler tous :
ATmega328P Nano V3 Panneau Contrôleur Compatible Arduino
On fera aussi porter par ce bloc fonctionnel, la capacité d’alimentation de l’ensemble du robot en 12V évidemment, et aussi en 5V / 2W, ainsi que quelques protections :
- 1 Batterie 12V au plomb, ou mieux 12,6V à base de Li-Ion :
12 v 4.4 Ah 4400mAh 18650 Rechargeable batteries 12.6V PCB Lithium Battery pack Protection Board +12.6V 1A Charger - 1 Convertisseur abaisseur 12V → 5V (5A) :
DC-DC 9-38V à 5V 5A Step Down Board Module Buck convertisseur d’alimentation de véhicule haute puissance 9V / 12V / 24V / 36V à 5V
Pour interconnecter tout ça, il faudra aussi quelques résistances et diodes, fusibles, interrupteurs et surtout du fil (multibrins, AWG24 et AWG20 pour l’alimentation), soudure, etc.
Bloc alimentation
Ce bloc présente une prise pour la batterie Li-Ion 12,6V, un fusible 5A, un interrupteur marche/arrêt, une diode de protection de polarité, un convertisseur vers 5V (hacheur), 2 fusibles réarmables (polyfuses), un bornier de sortie et trois leds et leurs résistances associées qui indiqueront les présences tensions (batterie, 12V et 5V).
On pourra ajouter un bouton « coup de point » pour permettre l’arrêt d’urgence.
Bloc moteurs
Ce bloc va porter plusieurs fonctions :
- Commande de puissance des moteurs ;
- Gestion des détecteurs ultra-son pour assurer une protection volumétrique autour du robot (anti-collision) ;
- Des commandes manuelles ;
- Bus de communication (SPI) pour la communication avec le bloc de commande générale.
Dans le schéma précédent, on retrouve les composants nécessaires à la réalisation des fonctions. La commande des moteurs est basée sur un circuit L298 à double pont H qui permet :
- Le contrôle des deux moteurs indépendamment,
- La rotation dans les deux directions,
- La vitesse variable de rotation.
Les moteurs sélectionnés étant équipés de codeurs angulaires, il faudra aussi prévoir leur connexion sur les entrées de l’Arduino.
Logiciel
Ce qui fait la force du microcontrôleur ATmega328 ce sont le nombre de fonctions câblées qu’il comporte, mais cela fait aussi sa faiblesse car il ne possède pas assez de broches pour les autoriser à fonctionner toutes ensemble. Il faut donc faire des compromis.
Pour assurer toutes les fonctions indiquées précédemment, il faudra donc utiliser :
- le
TIMER0
pour ses sorties en modulation de largeur d’impulsion (PWM) ainsi que 4 autres sorties pour la commande de sens des moteurs; - l’USART en mode série pour faire le débug par le port USB existant de l’Arduino Nano (2 broches :
TX0
,RX0
) ; - le port de communication SPI en mode esclave pour recevoir les ordres de l’autre carte (4 broches :
SS
,SCK
,MOSI
,MISO
) – à moins qu’une Raspberry PI face le boulot avec ses ports USB; - les entrées
INT0
etINT1
pour recevoir les séquences des capteurs angulaires des moteurs, ainsi que deux entrées supplémentaires pour l’autre phase des capteurs ; - deux sorties et deux entrées pour assurer les déclenchements des capteurs Ultra-Son respectivement leurs réponses ;
- deux entrée analogiques pour un joy-stick de commande en manuel.
Commande de hacheurs
Pour commander les hacheurs, on va moduler l’entrée EN de chacun d’eux avec le PWM de l’Arduino. On va devoir utiliser le TIMER0 (8 bits) parce que les broches associées sont les seules disponibles (OC0A
& OC0B
).
La documentation du L298 indique qu’il doit être modulé idéalement à 25 kHz et au maximum à 40 kHz. Évidemment plus la fréquence est au-dessus des 20 kHz, moins on entendra les moteurs « siffler ». Une valeur théorique de 30 kHz semble une base idéale.
Les timers n’ont pas une grande latitude de fréquence de modulation PWM, puisqu’ils utilisent la fréquence de l’horloge interne que l’on peut diviser par quelques puissances de deux.
Si l’on utilise le TIMER0 dans sa configuration la plus simple (Mode Fast PWM), il ne pourra fonctionner qu’aux fréquences données par la formule :
$$f_{osc} = {f_{io} \over {N * (TOP + 1)}}$$
AN : fio
= 16 MHz ; TOP
= 255; N
= 1, 8, 64, 256 et 1024
$$f_{osc} = {{16 \text{MHz}} \over {N * 256}}$$
$$N = 1 => f_{osc} = {{16000 \text{kHz}} \over 1*256} = 62.5 \text{kHz}$$
$$N = 8 => f_{osc} = {{16000 \text{kHz}} \over 8*256} = {{16000 \text{kHz}} \over 2048} = 7.8125 \text{kHz}$$
Si la première valeur pour N = 1 est trop haute, la suivante pour N = 8 est elle trop basse. Par contre si l’on pouvait diviser par deux la première on tomberait sur une valeur acceptable.
On peut obtenir cet effet avec les modes « PWM sans déphasage », la fréquence de modulation est données par une formule qui réduit de deux la valeur pour les mêmes paramètres :
$$f_{osc} = {f_{io} \over {N * 2 * TOP}}$$
AN : fio
= 16 MHz ; TOP
= 255; N
= 1
$$f_{osc} = {{16000 \text{ kHz}} \over {1 * 2 * 255}} = {{16000 \text{ kHz}} \over {510}} = 31.37 \text{ kHz}$$
Et ça, ça tombe dans intervalle acceptable du driver des moteurs !
On pourra donc moduler les deux entrées EN
du L298 entre 0 et 255, soient 28 (8 bits).
Le TIMER0 a ses 2 sorties modulées OC0A
& OC0B
sur les ports D5
et D6
de l’Arduino Nano ; ces deux broches iront donc directement sur les EN1
& EN2
de la carte L298.
La configuration du TIMER0 sera donc la suivante :
- Mode PWM sans déphasage #1 :
WGM02,01,00
= 001 ; - signal d’horloge à 16 MHz (pas de prédivision) :
CS02,01,00
= 001 ; - Sorties
OC0A
&OC0B
en mode non inversé :COM0A1,COM0A0
= 10 ;COM0B1,COM0B0
= 10.
TCCR0A – Timer/Counter0 Control Register ACOM0A1
= COM0B1
= 1 ; COM0A0
= COM0B0
= 0 ; WGM01
= 0 ; WGM00
= 1
Valeur : 10100001
TCCR0B – Timer/Counter0 Control Register BWGM02
= 0 ; CS02,01,00
= 001
Valeur : 00000001
TCNT0 – Timer/Compter 0
Peut être remis à zéro, avant de lancer le timer, mais sans grand intérêt
OCR0A – Output Compare Register 0A
Valeur comparée au compteur en continu pour former le signal présent sur la sortie OC0A
OCR0B – Output Compare Register 0B
Valeur comparée au compteur en continu pour former le signal présent sur la sortie OC0B
void setup() {
DDRD |= _BV(DDD5) | _BV(DDD6); // PD5 (D5) & PD6 (D6) : OUTPUT
TCCR0A = 0b10100001;
TCCR0B = 0b00000001;
OCR0A = 0; // PWM A = 0 [0,255]
OCR0B = 0; // PWM B = 0 [0,255]
}
A noter que le timer en mode PWM continue à produire un pic quand la valeur du registre OC0x
est à zéro. Si l’on veut éviter toute sortie à l’état haut, il faut repasser les sorties du timer en mode déconnecté et s’assurer que le port correspondant est bien en sortie à l’état bas.
Références
- L298 – DUAL FULL-BRIDGE DRIVER : https://www.st.com/resource/en/datasheet/l298.pdf ;
- APPLICATION NOTE AN240/1288 APPLICATIONS OF MONOLITHIC BRIDGE DRIVERS : https://www.st.com/content/ccc/resource/technical/document/application_note/05/b0/f0/25/e5/1c/4f/ba/CD00003776.pdf/files/CD00003776.pdf/jcr:content/translations/en.CD00003776.pdf.