Il est temps de voir la commande des moteurs Lego. Nous étudierons plusieurs solutions pour commander ces moteurs Lego.
Les moteurs Lego fonctionnent généralement sous une alimentation de 9 Volts. Lors des achats de boîtes Technic, ils sont équipés de boîtier d'alimentation à piles. Nous opterons pour une alimentation universelle fonctionnant sous secteur que l'on trouve dans de nombreux magasins. J'ai opté pour ma part pour une alimentation qui offre 2.2 A en sortie avec une tension maximum de 12 Volts. Ce qui est largement suffisant pour ce type de moteur. Je vous mets en lien un article sur les différentes caractéristiques des nombreux moteurs Lego. Il est possible de les faire fonctionner en 12 Volts mais je préfère rester à la tension nominale de 9 Volts préconisée par le fournisseur.
Pour brancher ces moteurs Lego, je ne voulais pas sacrifier leur connexion spécifique, j'ai donc sacrifié des câbles d'extension Lego de 50 cm.
Pour brancher ces moteurs Lego, je ne voulais pas sacrifier leur connexion spécifique, j'ai donc sacrifié des câbles d'extension Lego de 50 cm.
1 Principe de fonctionnement
Nous utiliserons un shield L298N pour commander des moteurs en vitesse continue. Ce shield, dit à double pont en H, permet l'inversion de sens du moteur. Nous utiliserons seulement les entrées IN 1 à 4.
Pour commander chaque moteur, il suffira de mettre à 1 l'entrée IN1 ou IN2 pour le moteur de gauche et de mettre à 1 l'entrée IN3 ou IN4 pour le moteur de droite. Pour inverser le sens du moteur, il faudra inverser les valeurs des entrées. Pour arrêter les moteurs, il faudra positionner les entrées à zéro.
Il faut aussi alimenter le shield avec le raspberry et mettre une alimentation externe.
Il faut aussi alimenter le shield avec le raspberry et mettre une alimentation externe.
2 Python
le but recherché est de réaliser un script centralisant toutes les commandes d'arrêt de démarrage des moteurs et du ventilateur. Ce script servira pour le gestionnaire d'événement de Centreon. Ce script aura 3 arguments :
- Type de matériel : moteur ou ventilateur
- Statut : démarré ou arrêté
- id du matériel : numéro identifiant le matériel en fonction de l'attribution des GPIO.
./commandmotor.py motor start 7
Le script commandmotor.py n'est pas très compliqué à comprendre, il utilise la numérotation BCM des GPIO du Raspberry. Vous le trouvez dans le dossier python du dépôt pi-gbc. Pour modifier le sens d'orientation du moteur, il suffira d'inverser les valeurs d'entrées des GPIO.
#!/usr/bin/python3 import RPi.GPIO as GPIO import sys def syntax(): print('Syntax: commandmotor type status num') print(' type : motor/fan') print(' status : start/stop') print(' num : number motor/fan') exit(1) def cmd_line(args): nb_args = len(args) if nb_args != 4: syntax() if args[1] != 'motor' and args[1] != 'fan': syntax() if args[2] != 'start' and args[2] != 'stop': syntax() if int(args[3]) < 1 or int(args[3]) > 7: syntax() if args[1] == 'motor': chaine = 'Action ' + actionmotor (args[2], int(args[3])) else: chaine = 'Action ' + actionfan (args[2]) return chaine def init(): GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(1, GPIO.OUT) GPIO.setup(5, GPIO.OUT) GPIO.setup(6, GPIO.OUT) GPIO.setup(7, GPIO.OUT) GPIO.setup(9, GPIO.OUT) GPIO.setup(10, GPIO.OUT) GPIO.setup(11, GPIO.OUT) GPIO.setup(12, GPIO.OUT) GPIO.setup(13, GPIO.OUT) GPIO.setup(16, GPIO.OUT) GPIO.setup(17, GPIO.OUT) GPIO.setup(19, GPIO.OUT) GPIO.setup(21, GPIO.OUT) GPIO.setup(20, GPIO.OUT) GPIO.setup(22, GPIO.OUT) GPIO.setup(27, GPIO.OUT) def actionmotor(status, num): init() if status == 'start': if num == 1: GPIO.output(10, False) GPIO.output(22, True) elif num == 2: GPIO.output(27, False) GPIO.output(17, True) elif num == 3: GPIO.output(5, True) GPIO.output(6, False) elif num == 4: GPIO.output(13, True) GPIO.output(19, False) elif num == 5: GPIO.output(20, True) GPIO.output(21, False) elif num == 6: GPIO.output(12, True) GPIO.output(16, False) elif num == 7: GPIO.output(7, True) GPIO.output(1, False) else: if num == 1: GPIO.output(10, False) GPIO.output(22, False) elif num == 2: GPIO.output(27, False) GPIO.output(17, False) elif num == 3: GPIO.output(5, False) GPIO.output(6, False) elif num == 4: GPIO.output(13, False) GPIO.output(19, False) elif num == 5: GPIO.output(20, False) GPIO.output(21, False) elif num == 6: GPIO.output(12, False) GPIO.output(16, False) elif num == 7: GPIO.output(7, False) GPIO.output(1, False) return 'Motor ' + status def actionfan(status): init() if status == 'start': GPIO.output(9, False) GPIO.output(11, True) else: GPIO.output(9, False) GPIO.output(11, False) return 'Fan ' + status if __name__ == '__main__': args = cmd_line(sys.argv) print(args)
3 Gambas 3
Le programme réalisé avec Gambas3 nous permet d'avoir une interface plus conviviale sous l'environnement graphique. Nous utiliserons la bibliothèque WiringPI, attention la numérotation des ports GPIO change.
Nous utilisons des objets SwitchButton pour l'inversion du sens de rotation des moteurs et des objets ColorButton pour représenter le démarrage des moteurs (vert moteur allumé, rouge moteur arrêté).
Nous utilisons des objets SwitchButton pour l'inversion du sens de rotation des moteurs et des objets ColorButton pour représenter le démarrage des moteurs (vert moteur allumé, rouge moteur arrêté).
Le programme est relativement simple.
' Gambas class file Library "/usr/lib/libwiringPi" Public Extern wiringPiSetup() As Integer Public Extern pinMode(pin As Integer, pud As Integer) Public Extern pullUpDnControl(pin As Integer, mode As Integer) Public Extern digitalRead(pin As Integer) As Integer Public Extern digitalWrite(pin As Integer, value As Integer) Const PI_INPUT As Integer = 0 Const PI_OUTPUT As Integer = 1 Public Const PIN_LOW As Integer = 0 Public Const PIN_HIGH As Integer = 1 Public Sub CmdClose_Click() Quit End Public Sub Form_Open() wiringPiSetup() GpioSetup() Catch Me.text = "WiringPi setup failed - run as root?" End Public Sub GpioSetup() pinMode(0, PI_OUTPUT) 'motor 2 pinMode(2, PI_OUTPUT) 'motor 2 pinMode(3, PI_OUTPUT) 'motor 1 pinMode(11, PI_OUTPUT) 'motor 7 pinMode(12, PI_OUTPUT) 'motor 1 pinMode(13, PI_OUTPUT) 'fan pinMode(14, PI_OUTPUT) 'fan pinMode(21, PI_OUTPUT) 'motor 3 pinMode(22, PI_OUTPUT) 'motor 3 pinMode(23, PI_OUTPUT) 'motor 4 pinMode(24, PI_OUTPUT) 'motor 4 pinMode(26, PI_OUTPUT) 'motor 6 pinMode(27, PI_OUTPUT) 'motor 6 pinMode(28, PI_OUTPUT) 'motor 5 pinMode(29, PI_OUTPUT) 'motor 5 pinMode(31, PI_OUTPUT) 'motor 7 End Public Sub cmdStart1_Click() If CmdReverse1.Value = False Then digitalWrite(12, PIN_LOW) digitalWrite(3, PIN_HIGH) Else digitalWrite(12, PIN_HIGH) digitalWrite(3, PIN_LOW) Endif ColorButton6.color = Color.Green End Public Sub CmdStop1_Click() digitalWrite(3, PIN_LOW) digitalWrite(12, PIN_LOW) ColorButton6.color = Color.Red End Public Sub cmdStart6_Click() If CmdReverse6.Value = False Then digitalWrite(26, PIN_LOW) digitalWrite(27, PIN_HIGH) Else digitalWrite(26, PIN_HIGH) digitalWrite(27, PIN_LOW) Endif ColorButton6.color = Color.Green End Public Sub CmdStop6_Click() digitalWrite(27, PIN_LOW) digitalWrite(26, PIN_LOW) ColorButton6.color = Color.Red End Public Sub cmdStart7_Click() If CmdReverse7.Value = False Then digitalWrite(31, PIN_LOW) digitalWrite(11, PIN_HIGH) Else digitalWrite(31, PIN_HIGH) digitalWrite(11, PIN_LOW) Endif ColorButton7.color = Color.Green End Public Sub CmdStop7_Click() digitalWrite(11, PIN_LOW) digitalWrite(31, PIN_LOW) ColorButton7.color = Color.Red End Public Sub cmdStart5_Click() If CmdReverse5.Value = False Then digitalWrite(28, PIN_LOW) digitalWrite(29, PIN_HIGH) Else digitalWrite(28, PIN_HIGH) digitalWrite(29, PIN_LOW) Endif ColorButton5.color = Color.Green End Public Sub CmdStop5_Click() digitalWrite(28, PIN_LOW) digitalWrite(29, PIN_LOW) ColorButton5.color = Color.red End Public Sub cmdStart4_Click() If CmdReverse4.Value = False Then digitalWrite(23, PIN_LOW) digitalWrite(24, PIN_HIGH) Else digitalWrite(23, PIN_HIGH) digitalWrite(24, PIN_LOW) Endif ColorButton4.color = Color.Green End Public Sub cmdStart2_Click() If CmdReverse2.Value = False Then digitalWrite(0, PIN_LOW) digitalWrite(2, PIN_HIGH) Else digitalWrite(0, PIN_HIGH) digitalWrite(2, PIN_LOW) Endif ColorButton2.color = Color.Green End Public Sub CmdStop2_Click() digitalWrite(0, PIN_LOW) digitalWrite(2, PIN_LOW) ColorButton2.color = Color.red End Public Sub cmdStart3_Click() If CmdReverse3.Value = False Then digitalWrite(21, PIN_LOW) digitalWrite(22, PIN_HIGH) Else digitalWrite(21, PIN_HIGH) digitalWrite(22, PIN_LOW) Endif ColorButton3.color = Color.Green End Public Sub CmdStop3_Click() digitalWrite(21, PIN_LOW) digitalWrite(22, PIN_LOW) ColorButton3.color = Color.red End Public Sub CmdStop4_Click() digitalWrite(23, PIN_LOW) digitalWrite(24, PIN_LOW) ColorButton4.color = Color.red End
Une petite vidéo pour visualiser le fonctionnement de notre programme.
00:00
/
00:00
4 Node-Red
Node-Red est une application Web reposant sur Node.js et permettant de réaliser des chaînes de traitement graphiquement dans un environnement Web. Les GPIO sont supportés dans cette application, on aurait tort de ne pas en profiter.
4.1 Installation de Node-Red
L'installation de Node-Red n'a pas fonctionné avec l'utilitaire fourni par Raspbian (Menu -> Preferences -> Recommended Software). J'ai trouvé une autre solution en ligne de commande.
bash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)
Après quelques minutes, vous pouvez utiliser le menu pour lancer Node-Red. Menu -> Programmation -> Node-RED.
Une fenêtre s'affiche et lance le serveur Web en indiquant l'adresse URL : http://127.0.0.1:1880/
Commençons, pour l'exemple, par commander le moteur 5. Ajoutez deux objets inject.
Commençons, pour l'exemple, par commander le moteur 5. Ajoutez deux objets inject.
Double-cliquez sur le premier objet. Choisir number pour le Paylod. Initialisez à 1 et nommez l'objet Start.
Double-cliquez sur le deuxième objet. Choisir number pour le Paylod. Initialisez à 0 et nommez l'objet Stop.
Ajoutez l'objet fonction pour inverser la sortie Start.
Cette fonction n'est pas obligatoire car le positionnement à 1 du GPIO 38 suffit à démarrer le moteur. Mais je préfère initialiser tous les GPIO dépendant du moteur 5.
Ensuite, ajoutez deux objets rpi gpio out pour initialiser les GPIO.
Pour le GPIO 38, initialisez à zéro pour le démarrage du traitement.
Idem pour le GPIO 40.
Reliez les objets comme ci-dessous :
- Start -> Moteur 5 - Pin38
- Start -> insert -> Moteur 5 - Pin40
- Stop -> Moteur 5 - Pin38 & Moteur 5 - Pin40
Cliquez sur Deploy pour démarrer le traitement.
Test de démarrage du moteur.
Voici le code de cet exemple :
[{"id":"96d78944.2b0d38","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"ec13a454.f6bbf8","type":"inject","z":"96d78944.2b0d38","name":"Start","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":100,"wires":[["62829164.14a04","89bfafbe.331ed"]]},{"id":"464d717f.eac58","type":"inject","z":"96d78944.2b0d38","name":"Stop","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":240,"wires":[["3fbea87d.ddad18","62829164.14a04"]]},{"id":"89bfafbe.331ed","type":"function","z":"96d78944.2b0d38","name":"invert","func":"if (msg.payload == 1)\n{\n msg.payload = 0;\n}\nreturn msg;","outputs":1,"noerr":0,"x":270,"y":140,"wires":[["3fbea87d.ddad18"]]},{"id":"62829164.14a04","type":"rpi-gpio out","z":"96d78944.2b0d38","name":"Moteur 5 - Pin38","pin":"38","set":true,"level":"0","freq":"","out":"out","x":550,"y":100,"wires":[]},{"id":"3fbea87d.ddad18","type":"rpi-gpio out","z":"96d78944.2b0d38","name":"Moteur 5 - Pin40","pin":"40","set":true,"level":"0","freq":"","out":"out","x":560,"y":240,"wires":[]}]
Maintenant il est temps de voir comment réaliser la communication entre le Raspberry et l'Arduino.
Références
Un site incontournable pour les moteurs Lego : https://www.philohome.com/
Montage du shield L298N utilisé dans ce tuto : https://www.piddlerintheroot.com/l298n-dual-h-bridge/
Montage du shield L298N utilisé dans ce tuto : https://www.piddlerintheroot.com/l298n-dual-h-bridge/