Construire un voyant d'avertissement de machine

Construire un voyant d'avertissement de machine

Si vous avez déjà visité une usine équipée de machines à commandes numériques, vous avez peut-être remarqué que chacune d'entre elles est généralement surmontée d'un curieux poteau lumineux. Loin d'être un gadget, ces indicateurs permettent aux opérateurs de vérifier d'un coup d'œil l'état de chaque machine du parc, par exemple: "en fonctionnement", "erreur", "travail terminé/libre". Il se trouve que chez Yoctopuce, on a besoin d'un système similaire mais en miniature. On a évidemment décidé de le construire nous-même.

On cherche à construire ça, mais en plus petit
On cherche à construire ça, mais en plus petit


Motivations

On a besoin d'évaluer la stabilité à long terme d'un futur produit Yoctopuce. Cela implique de faire tourner des programmes de stress durant des jours, voire des semaines. On n'a pas trop envie de consacrer un ordinateur complet à chaque expérience, alors on a décidé d'utiliser des mini-PCs sans clavier ni écran que l'on pilotera à distance. Chacun de ces PC sera équipé d'un petit poteau de signalisation qui indiquera l'état de l'expérience en cours. Ainsi, chaque expérience ne devrait pas occuper plus de 2-3 décimètres carré sur une table. En cas de problème, il suffira de faire un "remote desktop" sur la machine concernée pour comprendre ce qu'il s'est passé.

L'électronique du système : un anneau de LED et un Yocto-Color-V2
L'électronique du système : un anneau de LED et un Yocto-Color-V2


L'électronique est archi-simple: on compte utiliser un Yocto-Color-V2 et un anneau de 12 LEDs Neopixel. Et on va même mettre à profit le système d'animations internes du Yocto-Color-V2 pour que le poteau signale automatiquement si l'expérience s'est terminée inopinément.

La partie mécanique

Comme on va devoir en fabrique plusieurs, on a opté pour design simple: un pied contenant le Yocto-Color-V2, un tube en aluminium et une tête contenant l'anneau de LED. La tête est en trois parties maintenues ensemble avec des vis et des inserts filetés. Le pied est muni d'aimants, juste au cas où on aurait besoin d'un peu de stabilité supplémentaire. Rien de très original, à part la partie optique qui imite la géométrie d'un prisme pour réfléchir un maximum de lumière vers l'extérieur.

Modélisation 3D, observez la géométrie de l'anneau transparent
Modélisation 3D, observez la géométrie de l'anneau transparent


Les parties en plastique sont imprimées avec une imprimante FDM à l'exception de l'anneau optique qui a été imprimé avec une imprimante SLS dans de la résine transparente. Bien qu'un peu translucide, le résultat est tout à fait acceptable, même si le fait d'avoir dû imprimer l'anneau penché lui confère des propriétés optiques un peu étranges sous certains angles. Ceci dit, il est probable qu'imprimer l'anneau avec du filament "transparent" aurait marché aussi.


  

  
Le même, en vrai


La partie logicielle

On aimerait que notre indicateur se comporte de la manière suivante:

  • Bleu à la mise sous tension, ainsi on pourra remarquer un power-cycle de l'expérience
  • Vert pendant le fonctionnement de l'expérience
  • Rouge si pas de nouvelles de l'expérience depuis plus de 5 secondes
  • Blanc quand l'expérience s'est terminée sans encombre

On pourrait aussi appeler ça un watchdog lumineux. Cela se traduit par un code d'initialisation qui fait l'essentiel du travail:

def initWatchDog(ledcluster):
    # make sure, Power-on color is blue
    colorAtStartUp = 0x000080  #blue
    startupcolor = ledcluster.get_rgbColorArrayAtPowerOn(0,12)
    mustSetStartUpColor = False
    for c in startupcolor :
      if c!=colorAtStartUp : mustSetStartUpColor=True
    if mustSetStartUpColor:
      ledcluster.set_rgbColorAtPowerOn(0, 12, colorAtStartUp)
      ledcluster.saveLedsConfigAtPowerOn()
    # Create two animations
    green  = 0x008000
    red    = 0x400000
    redhot = 0xFF0000
    #  animation #0 : steady green
    ledcluster.resetBlinkSeq(0)
    ledcluster.addRgbMoveToBlinkSeq(0, green, 0)
    ledcluster.addRgbMoveToBlinkSeq(0, green, 5000)
    ledcluster.addJumpToBlinkSeq(0,1)
    #  animation #1 : flashing red
    ledcluster.resetBlinkSeq(1)
    ledcluster.addRgbMoveToBlinkSeq(1, red, 0)
    ledcluster.addRgbMoveToBlinkSeq(1, red, 2950)
    ledcluster.addRgbMoveToBlinkSeq(1, redhot, 0)
    ledcluster.addRgbMoveToBlinkSeq(1, redhot, 50)
    # link leds to animation #0, and start both animations
    ledcluster.linkLedToBlinkSeq(0,12,0,0)
    ledcluster.startBlinkSeq(0)
    ledcluster.startBlinkSeq(1)



Cette fonction commence par vérifier que les 12 premières LEDs sont bleues à la mise sous tension et dans le cas contraire, configure le module en conséquence. Puis on construit une première animation qui allume les LEDs en vert pendant 5 secondes et saute à une deuxième animation qui fait clignoter les LEDs en rouge. Les 12 premières LEDs sont affectées au début de la première animation puis les animations sont lancées.

En pratique, quand cette fonction est appelée, les LEDs passent au vert, et au bout de 5 secondes, elles se mettent automatiquement à clignoter en rouge. Ce comportement est géré en interne par le Yocto-Color-V2 et ne dépend plus du programme de contrôle une fois qu'il a été lancé.

On a ensuite besoin d'une fonction qui empêche les LEDs de tourner au rouge si on l’appelle. Ce qui est fait en réaffectant les LEDs au début de la première séquence. Après l'appel de cette fonction, il faut donc à nouveau attendre 5 secondes pour que les LEDs passent au rouge.

def resetWatchDog(ledcluster):
    # remapping the LEDs to the start of animation #0
    # and thus prevent them from jumping to animation #1
    ledcluster.linkLedToBlinkSeq(0, 12, 0, 0)


Tant qu'on appelle la fonction resetWatchDog au moins toutes les 5 secondes, les LEDs restent vertes, si cette fonction n'est plus appelée, parce que le programme a planté par exemple, elles passeront au rouge.

Si le programme se termine correctement, on peut réinitialiser les LEDs à une couleur fixe ce qui les déconnecte des animations.

def jobDone(ledcluster):
    # assign a steady color to the LED ,
    # this will unlink them from the animations
    ledcluster.set_rgbColor(0,12,0x404040)



Le programme de test ressemble à ça:

# Sets up the API to use local USB devices
errmsg = YRefParam()
if YAPI.RegisterHub("usb", errmsg) != YAPI.SUCCESS:
    sys.exit("Init error" + errmsg.value)

leds = YColorLedCluster.FirstColorLedCluster()
print("found  %s"%leds.get_friendlyName())
if leds is None: exit("No LED Cluster found")

initWatchDog(leds)
for i in range (0,10):
 print("doing arbitrary work...")
 YAPI.Sleep(1000,errmsg)
 resetWatchDog(leds)

jobDone(leds)
YAPI.FreeAPI()
print("Done.")


Si vous lancez ce programme, les LEDs vont passer au vert, et une fois le programme terminé, les LEDs vont virer au blanc. Par contrôle si vous interrompez le programme en plein milieu, les LEDs vont devenir rouges au bout de 5 secondes.

Pour conclure

La logique qui contrôle les LEDs du Yocto-Color-V2 permet de fabriquer des automatismes assez intéressants à peu de frais. Notez que vous trouverez la même logique dans d'autres modules capables de piloter des LEDs Neopixel, par exemple le Yocto-MaxiBuzzer, Yocto-MaxiKnob ou encore le Yocto-RFID-15693.

Quant à notre notre petite expérience, on l'a placée en haut d'une étagère d'où elle est visible de loin, tout en restant accessible.

Le premier nœud de notre petit banc de test est déjà en train de bosser
Le premier nœud de notre petit banc de test est déjà en train de bosser


Bon, maintenant que ça marche, il reste à construire les autres..

Au boulot!
Au boulot!


Commenter aucun commentaire Retour au blog












Yoctopuce, get your stuff connected.