DEV Community

Cover image for Systeme de communication entre NodeJS, Madmapper et arduino
Remy Jacquand
Remy Jacquand

Posted on

Systeme de communication entre NodeJS, Madmapper et arduino

Dans le cadre de création d'une pièce d'escape game, nous expérimentons le logiciel Madmapper pour gérer toute la partie audio visuelle. La projection vidéo, le son et la lumière sont au centre de l'univers du jeu.

Concernant les interactions avec les joueurs et les énigmes, nous souhaitons contrôler ces instruments par Arduino.

Dans les prévisions, nous souhaitons contrôler la salle via une application web afin d'y accéder depuis n'importe quel périphérique (mobile, desktop...)

Les énigmes sont gérés sur arduino, madmapper récupère l'information et une application Web nous informe du status de la room et éventuellement nous permet de déclancher .

Bonne surprise, Madmapper intègre Firmata. C'est un outil de contrôle Arduino facilitant la communication entre ce dernier et un logiciel tier. Ce qui permet de nouvelles possibilités d'interaction.

Concernant l'application Web, pour mon confort, elle est en NodeJS.

Problématique

Intuitivement, aillant Firmata sur le Arduino, je pensais pouvoir contrôler ce dernier avec un montage parallèle entre Madmapper et NodeJS.

azdazd

Malheureusement, si le Arduino est en communication avec Madmapper, NodeJS ne peut interagir avec le Arduino car le port et occupé. Je pars donc sur un montage en série des applications pour simplifier le flux d'information.

montage serie

Dans cet exemple, nous allons préparer un interrupteur pour allumer et éteindre une LED.

Note : Pour ce développement, je suis sous un environnement Windows, ce qui affect la création de périphérique virtuel par NodeJs. C'est pour cela que nous installerons des applications tier pour palier à certain problème.

Hardware et Software

​Preparation de l'environnement de travail

​LoopMidi

Le logiciel permet de créer un périphérique midi virtuel. Il nous permet de communiquer entre l'app NodeJs et Madmapper.
Une fois l'installation effectuée, déclare un nouveau périphérique en lui indiquant un nom (1) en cliquant sur le "+" en bas à gauche de la fenêtre. (2)

ajouter un périphérique midi

Personnellement, j'ai laissé le nom par défaut

​Midi-OX

Midi-OX est un logiciel de consultation de log Midi. Une fois le périphérique sélectionné, nous pouvons consulter les communications IN et OUT avec ce dernier.

Ouvrez Midi-OX et le moniteur si ce dernier ne s'ouvre pas automatiquement
midi-ox monitor

Allez dans Options->Midi Devices pour lier Midi-OX à LoopMidi
midi-ox options

Sélectionne le périphérique que vous avez créé avec LoopMidi dans la partie "MIDI Inputs" (1) et "Microsoft GS Wavetable Synth" dans "MIDI Outputs" (3). Si tout est ok, ils apparaîtront respectivement dans "Port Map Objects" (2) et "Port Mapping" (3).
midi-ox midi inputs

Validez la sélection avec le bouton "OK".

Un message "Opened MIDI INPUT" et "Opened MIDI OUTPUT" apparaîtront dans le moniteur
monitor midi-ox

Lors des tests, nous pourrons observer les logs dans ce moniteur.

​Installation de Firmata dans le Arduino Uno et communication avec MadMapper

Une très bonne vidéo explique tout cela ici :)

​Communication NodeJs et MadMapper

Pour communiquer avec MadMapper depuis NodeJs, nous allons envoyer un signal MIDI depuis NodeJs et l'interpréter dans MadMapper

EasyMidi

Afin de déclencher un signal midi, nous allons utiliser le périphérique virtuel LoopMidi avec NodeJs.
Dans votre dossier de projet :

Initialisez le projet :

npm init
Enter fullscreen mode Exit fullscreen mode

Installez easymidi :

npm intall easymidi
Enter fullscreen mode Exit fullscreen mode

Et créé le script main.js :

let easymidi = require("easymidi") //on déclare easymidi
let output = new easymidi.Output("loopMIDI Port") //On connecte easymidi au periphérique midi virtuel loopMIDI grâce à son nom
// on envoi le signal midi
output.send("cc", {
    controller: 37, // numéro de la commande
    value: 127, // valeur de la commande [0-127]
    channel: 0 // channel midi
})

Enter fullscreen mode Exit fullscreen mode

Dans le cadre de notre interrupteur, nous allons utiliser l'opérateur "change control" qui change d'état quand on l'active et reste dans ce même état jusqu'à ce qu'on le déclenche de nouveau (un interrupteur en somme).

Le numéro contrôleur 37 est reconnue comme une commande "change control". En fonction de cette valeur, il peut être reconnu comme un changement de pitch ou de modulation ou beaucoup d'autre commande.
Entre 30 et 40 (à vérifier) sont reconnues les commandes de type Gate.

Note : il est possible de créer un périphérique midi virtuel à la volée avec easymidi. Cependant, Windows bloque sa création :

MidiOutWinMM::openVirtualPort: cannot be implemented in Windows MM MIDI API!

Enter fullscreen mode Exit fullscreen mode

Je n'ai pas essayé avec d'autres OS mais la plupart des tutos trouvé sur YouTube sont iOS et semble fonctionner sans trop de difficultés.

source

En lançant le script, une ligne apparaît dans la console de log de Midi-OX.

log monitor

Nous pourrons donc par la suite configurer un déclencheur avec MadMappeur avec cette commande.

Création page web express

À présent, nous allons modifier le script pour créer une page web et y afficher un bouton pour déclencher plus facilement la commande midi avec express.

Installation de express

npm install express
Enter fullscreen mode Exit fullscreen mode

Ajoutez le fichier index.html pour le front

<!-- ./index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Panel Control</title>
</head>
<body>
    <button id="button">ON/OFF</button>
    <script>
        document.getElementById('button').onclick = () => {
            fetch('/click', {method: 'POST'})
        }
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Et le back

let easymidi = require("easymidi")
let express = require('express')
let output = new easymidi.Output("loopMIDI Port")
const app = express()
let is_on = false;
app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html');
})

app.post('/click', (req, res)=>{
    console.log('received')

    output.send("cc", {
        controller: 37,
        value: (is_on) ? 0:127,
        channel: 0
    })

    is_on = !is_on;
    res.sendStatus(201);
})

app.listen(3000)
Enter fullscreen mode Exit fullscreen mode

Coté front, le but est simple: lorsqu'on clique sur le bouton, on envoie une requête POST au endpoint "/click" pour allumer ou éteindre la LED.

Coté back, nous mettons en place l'API:

Implémentation de express

let express = require('express') 
const app = express()
Enter fullscreen mode Exit fullscreen mode

Création de l'index

app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html');
})
Enter fullscreen mode Exit fullscreen mode

Création de l'endpoint

let is_on = false;
app.post('/click', (req, res)=>{
    console.log('received')
    output.send("cc", {
        controller: 37,
        value: (is_on) ? 0:127,
        channel: 0
    })

    is_on = !is_on;
    res.sendStatus(201);
})
Enter fullscreen mode Exit fullscreen mode

À présent, nous pouvons tester le script et voir le resultat dans la console de log de Midi-OX.

Le script est prêt

​Parametrage d'action midi sur MadMapper

Rendez-vous sur MadMapper et connectez l'application au Arduino avec le module Firmata. Ensuite, choisissez un pin (je préconise le Pin3 pour le test) et cliquez sur le bouton "OUTPUT" pour activer la sortie.

pin3

La LED s'illumine. Dans le cas contraire, il faut sélectioner de nouveau le model du Arduino et le port pour forcer la connexion.

Continuons avec click droit sur le bouton "OUTPUT" -> Add Control -> MIDI
learn midi 1

Dans le nouveau panneau qui apparaît, clique sur le bouton "Learn"
learn midi 2

execute l'application NodeJs

node main.js
Enter fullscreen mode Exit fullscreen mode

et clique sur le bouton ON/OFF de votre page. MadMapper va alors capturer l'information et l'assigner au bouton "OUTPUT"

Désormais, chaque fois que vous cliquerez sur ce bouton "ON/OFF" vous commanderez la LED :D

Félicitations !

Latest comments (0)