Agora o código:
Código: Selecionar todos
from pybricks.hubs import TechnicHub
from pybricks.parameters import Port
from pybricks.tools import wait, StopWatch
from pybricks.iodevices import UARTDevice
hub = TechnicHub()
watch_midi = StopWatch()
watch_dmx = StopWatch()
midi_out = UARTDevice(Port.A, baudrate=31250)
midi_in = UARTDevice(Port.B, baudrate=31250)
dmx_out = UARTDevice(Port.C)
# MIDI output payload
midi_payload = bytearray(3)
# DMX output payload
dmx_payload = [b'\x00']*513 # DMX512 supports up to 512 channels
# preceded by a Start Code
dmx_payload[0] = b'\x00' # Start Code
# PAR RGB has 7 channels and DMX address = 1
dmx_payload[1] = b'\x00' # CH1 Mode
dmx_payload[2] = b'\xFF' # CH2 RGB Color
dmx_payload[3] = b'\x00' # Speed
dmx_payload[4] = b'\xFF' # Master dimmer
dmx_payload[5] = b'\xFF' # R
dmx_payload[6] = b'\x00' # G
dmx_payload[7] = b'\x00' # B
# PAR UV has 4 channels and DMX address = 8
dmx_payload[8] = b'\xFF' # Master Dimmer
dmx_payload[9] = b'\xFF' # UV Color
dmx_payload[10] = b'\x00' # Strobe off
dmx_payload[11] = b'\x00' # Mode
dmx_channels = 11 # no need to send more frames than the
# number of channels usable in the whole fixture
r = 0
g = 0
b = 0
uv = 0
watch_midi.reset()
watch_midi.resume()
watch_dmx.reset()
watch_dmx.resume()
print("\n*****\n")
while True:
if watch_midi.time() >= 100 :
# every 100 ms:
# check MIDI IN
# refresh DMX values (RGB and UV)
watch_midi.reset()
while midi_in.waiting() > 0:
data = int.from_bytes(midi_in.read(1))
# print(data, end=' ')
if data == 0xFE:
# Active Sense, some controllers keep sending it
#print('Activ Sense')
pass
elif data == 0xF8 or data == 0xFA or data == 0xFB or data == 0xFC:
# Beat Clock / Start / Continue / Stop
#print('Beat clock')
pass
#elif data & 0x90 == 0x90:
elif data in range(0x90, 0x9F):
# note on, read note and velocity
note = int.from_bytes(midi_in.read(1))
velocity = int.from_bytes(midi_in.read(1))
channel = data & 0x0F
if velocity != 0 :
print('Note ON: ', note, velocity, 'on Ch: ', channel)
midi_payload[0] = 144 # note on
midi_payload[1] = note
midi_payload[2] = 127 # velocity
midi_out.write(midi_payload)
if 36 <= note <= 51 : # Yellow Pads
uv = (note - 36) * 17
elif 52 <= note <= 67 : # Pink Pads
r = (note - 52) * 17
elif 68 <= note <= 83 : # Blue Pads
b = (note - 68) * 17
elif 84 <= note <= 99 : # Green Pads
g = (note - 84) * 17
else:
print('Note OFF: ', note)
midi_payload[0] = 128 # note off
midi_payload[2] = 0 # velocity
midi_out.write(midi_payload)
elif data in range(0x80, 0x8F):
# note offm read note and veolocity
note = int.from_bytes(midi_in.read(1))
velocity = int.from_bytes(midi_in.read(1))
channel = data & 0x0F
print('Note OFF: ', note, velocity, 'on Ch: ', channel)
midi_payload[0] = 128 # note off
midi_payload[2] = 0 # velocity
midi_out.write(midi_payload)
if watch_dmx.time() >= 50 :
# every 50 ms:
# send DMX data to all fixtures in the universe
watch_dmx.reset()
print("R G B UV: ", r, g, b, uv)
# control PARs
dmx_payload[5] = r.to_bytes(1,'endian') # R
dmx_payload[6] = g.to_bytes(1,'endian') # G
dmx_payload[7] = b.to_bytes(1,'endian') # B
dmx_payload[8] = uv.to_bytes(1,'endian') # UV Brightness
# Break + Mark-After-Break
# need an hack because Pybricks UART doesn't allow to define a preamble
# so we send something similar at a lower baud rate
dmx_out.set_baudrate(90909)
dmx_out.write(b'\x80')
dmx_out.set_baudrate(250000)
for frame in range(0, dmx_channels):
dmx_out.write(dmx_payload[frame])
os mais atentos (doidos? nerds?) vão reparar que uso 3 portas:
Código: Selecionar todos
midi_out = UARTDevice(Port.A, baudrate=31250)
midi_in = UARTDevice(Port.B, baudrate=31250)
dmx_out = UARTDevice(Port.C)
Isto porque o "adaptador" que mostrei na foto do post acima, com circuito soldado directamente ao cabo, faz apenas a conversão midi2uart.
É possível um adaptador único, bidirecional (midi2uart + uart2midi) e assim que tiver acesso a uma protoboard suficientemente pequena vou fazer um, para poder utilizar uma única porta do Hub (e um único cabo Powered Up) para simultâneamente poder enviar e receber sinais MIDI.