Humusbêta

Cartes et capteurs

Une carte à microcontrôleur au bout d'un câble USB transforme n'importe quel capteur en bouton rotatif et n'importe quel contrôle d'Humus en interrupteur, en variateur ou en couleur. Il y a deux façons de lui parler, et cette page les parcourt toutes les deux avec un Arduino Uno :

  • Board, un organism qui n'a besoin d'aucun code sur la carte. Téléverse une fois le sketch Firmata standard et ses broches sont à toi.
  • SerialIn et SerialOut, pour un sketch à toi. Le sketch écrit et lit du texte brut ou des octets, et les deux boîtes parlent ce que le sketch a décidé : le sketch est le protocole.

Ce qu'il te faut

  • Une carte avec une connexion série USB. Les exemples utilisent un Arduino Uno : six entrées analogiques (A0 à A5) et la LED intégrée sur la broche 13. Un Nano, un Leonardo, un Mega, une carte de développement ESP32 ou un Raspberry Pi Pico fonctionnent de la même façon, et l'organism Board a un preset pour chacun.
  • L'IDE Arduino, ou l'éditeur qu'utilise ta carte, pour y téléverser le sketch.
  • Un capteur à sortie analogique pour la première histoire : un potentiomètre est le plus simple, une thermistance ou un capteur de température analogique est celui de l'histoire. Une LED et une résistance de 220 ohms pour la deuxième histoire, ou juste la LED intégrée sur la broche 13. Un anneau de 24 LED adressables pour les trois dernières.

Tous les patchs et sketchs de cette page sont dans Fichier > Exemples > Organisms dans Humus, un dossier par scénario : Board contient les deux histoires Firmata, SerialIn et SerialOut tes propres sketchs, le dossier NeoPixel l'anneau. Cette même arborescence est le dossier examples/ des sources : le sketch à téléverser se trouve donc à côté du patch qui le pilote, dans un dossier à son nom, comme l'attend l'éditeur de la carte.

Sous Linux, le port appartient au groupe dialout ; ajoute-toi avec sudo usermod -aG dialout $USER et reconnecte-toi. Sous macOS et Windows, le port est prêt dès que la carte est branchée. Quelle que soit la voie choisie, ferme le moniteur série de l'IDE après le téléversement : un seul programme à la fois peut occuper le port.

Aucun code sur la carte : Firmata

L'organism Board parle Firmata, un protocole ouvert pour lequel l'IDE Arduino fournit un sketch. Tu le téléverses une fois et tu n'ouvres plus jamais l'IDE :

  1. Ouvre l'IDE Arduino, branche la carte, choisis la carte et son port dans Outils.
  2. Fichier ▸ Exemples ▸ Firmata ▸ StandardFirmata, puis Téléverser.

Première histoire : un capteur de température joue d'un filtre

Relie la sortie du capteur à A0, son alimentation au 5V (ou au 3.3V, selon ce que veut le capteur) et sa masse à GND. Un potentiomètre se branche entre 5V et GND, avec son curseur sur A0.

Dans Humus, ouvre Exemples > Organisms > Board > Sensor, ou construis-le :

  1. Ajoute un Board depuis la catégorie Primitives et choisis Arduino Uno / Nano dans ses presets. Son menu Port indique Auto, ce qui convient quand une seule carte est branchée. Le vumètre de sa boîte se met à scintiller quelques secondes après l'ouverture du patch : la carte redémarre quand le port s'ouvre, puis envoie ses mesures.
  2. Ajoute un Number et tire la sortie out1 (A0) de Board sur la prise du Number. Le Number affiche maintenant le capteur en direct : réchauffe le capteur, ou tourne le potentiomètre, et regarde la valeur bouger. C'est la boîte nombre de la tradition du patching, l'endroit où tu lis un contrôle.
  3. Ajoute un TestGen, un Filter et un SoundOut. Câble les deux sorties de TestGen dans les deux entrées du Filter, et le Filter dans SoundOut.
  4. Fais un clic droit sur le bouton rotatif Frequency du Filter, choisis Contrôler avec ▸ Number ▸ value, et règle la plage sur 200..8000. Pas de câble cette fois : la valeur que tu regardes ouvre maintenant le filtre à mesure qu'elle monte, et le même Number peut piloter n'importe quel autre bouton rotatif de la même façon.

Chaque paramètre d'Humus accepte un contrôle de cette façon, et chaque prise accepte un câble de contrôle. Un capteur qui lit 0..1 sur la sortie est ce qu'il y a de plus simple à router ; mets-le à l'échelle dans la plage du routage, ou avec un Slider ou un Math entre les deux quand il lui faut une courbe.

Chaque sortie lit le canal analogique réglé à côté d'elle : pour lire l'A8 d'un Mega, il suffit donc de changer un nombre, et Outlets règle combien de sorties la boîte affiche. Par défaut, les mesures arrivent toutes les 19 ms (Read every).

Deuxième histoire : la musique allume une LED

Garde la LED intégrée sur la broche 13, ou branche une LED avec une résistance de 220 ohms entre la broche 11 et GND pour la partie qui fait varier l'intensité.

Ouvre Exemples > Organisms > Board > LED, ou construis-le :

  1. Ajoute un SoundIn et un Follower ; câble la sortie de SoundIn dans le Follower. Règle le Threshold du Follower pour que son gate s'ouvre à chaque coup de ce que tu joues dans le micro.
  2. Ajoute un Board avec le preset Uno. Tire la sortie gate du Follower sur la prise 1 de Board. La prise 1 pilote Pin 1, qui vaut 13 en mode Digital : la LED s'allume à chaque coup.
  3. Tire la sortie env du Follower sur la prise 2. La prise 2 pilote la broche 11 en mode PWM, et la deuxième LED respire avec le niveau.

Tout ce qui porte un contrôle peut piloter une broche : un Button pour un relais, un LFO pour un fondu lent, un Slider pour une main sur un variateur. Le mode Digital bascule à 0.5 ; PWM fait correspondre 0..1 au rapport cyclique de la broche, et seules les broches PWM peuvent varier en intensité (3, 5, 6, 9, 10 et 11 sur l'Uno).

Ton propre sketch : SerialIn et SerialOut

Quand la carte doit faire quelque chose dont StandardFirmata est incapable - lire un capteur numérique en I2C, piloter un anneau de LED adressables, gérer l'anti-rebond d'un pavé de touches - écris le sketch toi-même et parle à Humus en texte brut ou en octets. Pas de bibliothèque à nous, pas de protocole à apprendre : le sketch est le protocole, et la boîte SerialOut montre exactement les octets qui partent sur le fil.

HumusBoard.ino est le sketch de départ, dans le dossier HumusBoard sous SerialIn comme sous SerialOut, et il marche dans les deux sens : toutes les 30 ms, il écrit A0 et A1 sur une ligne, 0.512 0.087, et chaque fois qu'une ligne arrive, il allume ou éteint la broche 13 avec le premier nombre et règle l'intensité de la broche 11 avec le second. Téléverse-le comme plus haut.

D'abord, l'autotest

Avant tout câblage, vérifie la liaison. Téléverse SerialTest.ino depuis Organisms > SerialIn > SerialTest et ouvre le patch qui est à côté. Le sketch écrit trois nombres vingt fois par seconde : une rampe qui monte de 0 à 1 une fois par seconde, la dernière chose qu'il a reçue d'Humus, et A0. Un SerialIn les envoie sur trois Number. Si la rampe bouge, la carte parle au port et le débit en bauds est le bon ; si l'écho suit le LFO sur la première prise de SerialOut, Humus est entendu et le Format correspond ; le Button sur la deuxième prise allume la LED intégrée de la carte, la seule chose à regarder sur la carte elle-même. Si la rampe reste immobile, vérifie le port et le débit ; si seul l'écho reste immobile, vérifie le Format.

Les deux mêmes histoires, via le sketch

serial-sensor.hum est la première histoire via le sketch : un SerialIn lit la ligne que le sketch écrit, sa sortie a arrive sur un Number, et la valeur du Number ouvre le Filter par un routage Contrôler avec. Le menu Port indique Auto et le débit est de 115200, celui qu'ouvre le sketch. L'affichage dans la boîte bouge un instant après l'ouverture du patch.

serial-led.hum est la deuxième histoire : la sortie gate du Follower sur la prise 1 de SerialOut et sa sortie env sur la prise 2, envoyées sous la forme de la ligne par défaut %1 %2\n trente fois par seconde ; le sketch allume ou éteint la broche 13 et règle l'intensité de la broche 11.

Troisième histoire : un anneau de pixels, de trois façons

L'anneau montre un protocole à toi. NeoPixel.ino, sous Organisms > SerialOut > NeoPixel, pilote un anneau de 24 LED adressables sur la broche 6 et lit une commande par ligne, chaque nombre entre 0 et 1 sauf le nombre de pixels : P i r g b peint un pixel, F n r g b allume les n premiers et éteint les autres, A r g b les peint tous, H h s v les peint tous par teinte, B v règle la luminosité. Relie la broche de données de l'anneau à la broche 6, son alimentation au 5V et sa masse à GND, téléverse le sketch, et ouvre l'un des trois patchs qui sont à côté.

paint.hum est le plus simple : quatre Sliders sur quatre prises de SerialOut, le Format P %1 %2 %3 %4\n, Send réglé sur On change. La première prise a Scale 23 et Int activé, donc un slider 0..1 choisit un pixel par son numéro ; les autres règlent la quantité de rouge, de vert et de bleu. Bouge un slider et ce pixel suit.

vu-meter.hum calcule tout le message à partir d'une seule valeur. Le env du Follower est sur la prise 1 et le Format est F %(floor(v1*24+0.5)) %(v1) %(1-v1) 0\n : le niveau choisit combien de pixels s'allument, et la couleur va du vert au repos au rouge à fond, trente lignes par seconde. C'est la boîte message qui fait le calcul, et le sketch peut rester tout bête.

spectrum.hum est le patch Pd qui associe la fréquence à la couleur, reconstruit : un Crossover à trois bandes sépare le micro, un Follower par bande lit son niveau, et les trois sorties env arrivent sur trois prises envoyées sous la forme A %1 %2 %3\n, les basses en rouge, les médiums en vert, les aigus en bleu, sur tout l'anneau. Déplace les deux fréquences du Crossover pour décider de ce qui compte comme basse et de ce qui compte comme air. Remplace les sources des Followers par des LFO et l'anneau dérive tout seul ; mets un Slider entre un Follower et sa prise pour dompter une bande. Chacun des trois pourrait aussi envoyer H %1 1 %2\n, avec une teinte sur la prise 1 et un niveau sur la prise 2, et le sketch ferait la roue des couleurs.

Les deux boîtes

D'Humus à la carte. Un SerialOut affiche autant de prises de valeur que l'indique son champ Values, deux au départ et jusqu'à huit, plus une prise de déclenchement en mode On trigger, et il a un champ Format. %1 à %8 écrivent les valeurs, \n termine une ligne, \t est une tabulation, \xNN est un octet brut. Chaque valeur a un Scale et un interrupteur Int : un contrôle 0..1 part en 0..255 en deux clics, et une prise sur laquelle rien n'est tiré envoie le nombre tapé dans son champ. Send choisit quand : Continuous à la cadence que tu règles, On change pour qu'une commande parte une seule fois, ou On trigger quand la prise de déclenchement monte, ce qui transforme un Button en boîte de commande.

Plusieurs commandes dans une boîte. Écris un message par ligne dans le champ Format et une prise Message apparaît : le nombre qu'elle reçoit choisit la ligne, donc un Number ou un Slider choisit entre home, M %1 et stop, et un Button sur la prise de déclenchement envoie la ligne choisie.

De la carte à Humus. Un SerialIn a jusqu'à huit sorties, de a à h : le premier nombre de chaque ligne arrive sur a, le deuxième sur b, et ainsi de suite. Un sketch qui écrit sa propre forme reçoit un modèle Parse, le miroir de Format : T=%1;L=%2 lit T=23.5;L=0.4, et une ligne qui ne correspond pas est ignorée. Avec un modèle défini, une sortie match se déclenche chaque fois qu'une ligne correspond, si bien qu'un sketch qui écrit pressed devient un appui sur un Button. L'affichage dans la boîte montre ce qui est arrivé. Ramène les valeurs à 0..1 sur la carte ; Humus utilise les nombres tels qu'ils sont envoyés.

Messages calculés. %(v1*180) écrit le résultat d'une expression, dans le langage de la boîte Math, et %?(v1>0.5){LED 1} n'écrit le contenu de ses accolades que si le test est vrai : un message peut ainsi changer de forme selon une valeur. %b(expr) et %w(expr) envoient le résultat sous forme d'octets.

Ce que montre la boîte. Chaque boîte série indique en bas sur quel port elle est et ce qu'elle a envoyé ou reçu en dernier, chaque octet en clair, et SerialIn marque comme ignorée une ligne qui ne correspond pas à son Parse. Quand un protocole ne marche pas, c'est cette ligne qu'il faut regarder. Le menu des presets de SerialOut et de SerialIn contient les formes de message habituelles pour démarrer.

Des noms sur le fil. Un Var est une valeur qui porte un nom. Tire un Var appelé temp sur la prise 1 de SerialOut et écris %n1 %1\n, et la carte reçoit temp 0.5. Dans l'autre sens, un SerialIn qui lit temp 23.5 light 0.4 donne chaque nombre au Var qui porte ce nom, où qu'il soit dans le patch, sans aucun câble : le send et receive de Pd, avec le nom qui voyage avec la valeur.

Des octets, pas du texte. Un sketch qui parle en octets bruts utilise %b1 pour un octet et %w1 pour un mot de deux octets, dans l'un ou l'autre champ. Dans Format, Scale 255 transforme un contrôle 0..1 en octet complet ; dans Parse, \xAA%b1%w2 attend l'octet d'en-tête et prend les trois suivants, en sautant tout ce qui se trouve entre deux pour se resynchroniser.

Sommes de contrôle, mots et listes. %x ou %s dans un Format ajoute le XOR ou la somme des octets jusque-là, %X et %S font de même en deux chiffres hexadécimaux, et %[ et %] délimitent la partie qu'ils couvrent : $%[HUM,%1,%2%]*%X\r\n est donc une trame façon GPS. %{slow,fast,turbo}1 écrit un mot d'une liste, choisi par la valeur 1, et se relit comme une position de 0 à 1. %c est un octet de comptage et %b* les octets comptés, pour un paquet dont la longueur change ; %* prend ou écrit tous les nombres d'une ligne. Un Parse vérifie la somme de contrôle et rejette une ligne qui échoue. La liste complète est dans l'aide de chaque boîte.

Le port lui-même. Frame, sur chaque boîte, règle la parité et les bits de stop pour le rare périphérique qui n'est pas en 8N1 ; la liste des débits va jusqu'à 1000000 et Custom accepte n'importe quel autre débit. Reset décide si l'ouverture du port redémarre la carte comme le fait l'éditeur de la carte ; désactive-le pour une carte qui doit continuer de tourner pendant qu'Humus se reconnecte.

OSC sur port série. Une carte qui parle OSC enveloppé dans du SLIP, comme le font les bibliothèques Teensy et ESP, n'a pas du tout besoin de SerialIn : active OSC sur port série dans Réglages ▸ MIDI et OSC et ses messages rejoignent le bus de contrôle OSC, si bien que l'Apprentissage OSC sur n'importe quel bouton rotatif les assigne. Voir MIDI et OSC.

Autant de boîtes Board, SerialIn et SerialOut que tu veux peuvent partager un même port : un câble, trois formats, trois boîtes, et chaque boîte dit ce qu'elle envoie.

Quand ça ne marche pas

  • Rien ne scintille. Un autre programme occupe le port : le moniteur série de l'IDE Arduino, un Humus précédent encore en train de se fermer. Appuie sur Reconnect sur la boîte, ou débranche et rebranche la carte ; les boîtes se reconnectent toutes seules.
  • Le vumètre scintille mais les sorties restent à zéro. La carte ne fait pas tourner StandardFirmata. Téléverse-le à nouveau, ou utilise SerialIn pour un sketch à toi.
  • Le vumètre scintille mais l'affichage reste immobile. Le débit ne correspond pas à celui qu'ouvre le sketch, ou le sketch écrit une forme que le champ Parse n'attend pas. Vide Parse pour prendre tous les nombres de la ligne.
  • Les mesures n'atteignent qu'une partie de la plage. Un capteur utilise rarement toute la plage de 0 à 5V. Règle la plage de Contrôler avec sur la partie qu'il utilise vraiment, ou mets un Slider entre la sortie et la destination et règle ses Min et Max.
  • La broche ne varie pas en intensité. Toutes les broches n'ont pas de PWM ; passe sur une qui en a.
  • Linux refuse l'accès au port. Le groupe dialout, plus haut.