O objectivo de ambos (uart2midi e uart2dmx) é poder estender a demonstração do meu gira-discos vinil
para um ambiente "disco" com sintetizadores, luzes, máquinas de bolhas de sabão e quem sabe canhões
de confetti
Agora a introdução LONGA e no final o video. O código segue logo à noite.
DMX surgiu em 1986 como um standard para controlo de iluminação de palco, para acabar com a confusão de incompatibilidades entre diferentes fabricantes. Evoluiu depois para um standard ANSI e é agora um padrão universal, com evoluções para wireless e até TCP. E já não se limita a iluminação, foram adicionados efeitos e coisas mais complexas.
Na prática, um controlador DMX (um PC ou um equipamento semelhante a uma mesa de mistura) tem pelo menos uma ams habitualmente mais portas de saída, cada porta gerindo um "universo" de dispositivos ligados em daisy chain:
- do controlador sai um cabo DMX que liga à ficha IN do dispositivo mais próximo
- cada um dos restantes dispositivos liga à ficha OUT do dispositivo anterior
- o ultimo dispositivo termina a rede ligando-se um terminador à ficha OUT (à semelhança das primeiras
redes Ethernet que usavam cabo coaxial)
Internamente cada dispositivo tem a porta IN ligada à porta OUT. Assim se estiver desligado ou avariado não põe em causa a comunicação com os restantes dispositivos da cadeia (como é suposto acontecer nas luzes de natal).
A comunicação em si é semelhante aos outros protocolos série, sendo enviados 8 bits seguidos de 2 stop bits, sem paridade (portanto 8N2). Só o ritmo de transmissão é um bocado invulgar (250 kbps) e antes da transmissão é gerado um preâmbulo que é um género de start bit mas bastante mais longo. Depois é enviado um primeiro byte (o Start Code, que em geral e para o caso é 0) seguido de um byte para cada endereço no universo (por exemplo se tiver 2 projectores de palco, um que responde ao endereço 1 e outro que responde ao endereço 9, é enviado um byte com os dados para o endereço 1, depois 7 bytes vazios e finalmente outro byte para o endereço 9).
Isto significa que, querendo efeitos rápidos, é preferível ajustar cada dispositivo para endereços baixos para reduzir a duração de cada broadcast. No limite, distribuir por vários universos (controladores com várias portas).
Além disso como a comunicação não é bidirectional 1 para 1 (em que se cruzam os Tx/Rx de 2 dispositivos) e sim unidirectional 1 para muitos (broadcast) o meio é um pouco mais complexo, tendo sido escolhido o RS-485, muito utilizado em ambientes industriais e laboratoriais por ser muito mais imune ao ruído e permitir distâncias muito grandes.
Como existem circuitos conversores UART-RS485 foi só uma questão de arranjar um que suportasse a alimentação e níveis lógicos dos Hubs Powered Up (3.3 Volt). Bastou ligar os mesmos 3 fios do meu adaptador uart2midi (3V3, GND e TX) ao lado UART do circuito e ligar meio cabo DMX aos pontos A, B e GND do lado RS484.
(na verdade tive também de soldar uma resistência para puxar o pino RTS do circuito para poder pô-lo
em modo de envio. Há circuitos que controlam o fluxo automáticamente, mas este não)
Do lado do software, a implementação UART do Pybricks só prevê 8N1 sem preâmbulos. 8N2 não é problema, basta fazer uma pausa muito curta entre cada byte enviado (depois acabei por descobrir que nem é preciso) mas o preâmbulo é mais complicado e ainda por cima é vital por servir para acordar todos os dispositivos no mesmo universo para estarem atentos a um broadcast. Depois dalgumas contas arranjei um hack: baixo o baudrate de 250 kbps para 90909 kbps e envio um 80h que na prática são 7 bits zero seguido de um bit 1 e acaba funcionando como preâmbulo.
A prova de conceito: um Hub Technic a controlar um universo DMX com dois focos PAR (um RGB no endereço 1 e outro RGB no endereço 8 orque o primeiro requer 8 bytes para as várias funcionalidades). O script python lê o IMU do hub para controlar os valores de Red, Green e Blue com a orientação e um contador para controlar a luminosidade do UV:

