Vous êtes ici:

Menu


Stacks Image 36912
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.

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.
Stacks Image 969865
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.

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.
Pour démarrer le moteur 7, on utilisera la commande comme ceci :
./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é).
Stacks Image 969651
Vue de la fenêtre principale
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.
Stacks Image 969785
Lancement de 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.
Stacks Image 969790
Double-cliquez sur le premier objet. Choisir number pour le Paylod. Initialisez à 1 et nommez l'objet Start.
Stacks Image 969802
Double-cliquez sur le deuxième objet. Choisir number pour le Paylod. Initialisez à 0 et nommez l'objet Stop.
Stacks Image 969805
Ajoutez l'objet fonction pour inverser la sortie Start.
Stacks Image 969808
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.
Stacks Image 969811
Ensuite, ajoutez deux objets rpi gpio out pour initialiser les GPIO.
Stacks Image 969814
Pour le GPIO 38, initialisez à zéro pour le démarrage du traitement.
Stacks Image 969817
Idem pour le GPIO 40.
Stacks Image 969820
Reliez les objets comme ci-dessous :
  • Start -> Moteur 5 - Pin38
  • Start -> insert -> Moteur 5 - Pin40
  • Stop -> Moteur 5 - Pin38 & Moteur 5 - Pin40
Stacks Image 969823
Cliquez sur Deploy pour démarrer le traitement.
Stacks Image 969826
Test de démarrage du moteur.
Stacks Image 969829
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/
comments powered by Disqus
 Vous êtes ici: