onlaj / Piano-LED-Visualizer

Piano LED Visualizer: Connect an LED strip to your Raspberry Pi and create an immersive visual experience for your piano playing
MIT License
545 stars 115 forks source link

MIDI Connection Fails #1

Closed MrBromaba closed 5 years ago

MrBromaba commented 5 years ago

I successfully installed all the requirements listed in your documentation. By executing the command 'aconnect -l' it gives me the following result:

pi@raspberrypi:~ $ aconnect -l client 0: 'System' [type=Kernel] 0 'Timer ' 1 'Announce ' client 14: 'Midi Through' [type=Kernel] 0 'Midi Through Port-0' client 20: 'MIDI 1 x 1' [type=Kernel,card=1] 0 'MIDI 1 x 1 MIDI 1'

By executing the command 'mido-ports' I get this:

pi@raspberrypi:~/Piano-LED-Visualizer/tests $ mido-ports

Available input Ports: 'MIDI 1 x 1:MIDI 1 x 1 MIDI 1 20:0' 'Midi Through:Midi Through Port-0 14:0'

Available output Ports: 'MIDI 1 x 1:MIDI 1 x 1 MIDI 1 20:0' 'Midi Through:Midi Through Port-0 14:0'

MIDO_DEAFULT_INPUT not set. MIDO_DEFAULT_OUTPUT not set. MIDO_DEFAULT_IOPORT not set. MIDO_BACKEND not set.

Using backend mido.backends.rtmidi.

Running the test program lightkeys.py fails in line 37 with the following result:

pi@raspberrypi:~/Piano-LED-Visualizer/tests $ sudo -E python lightkeys.py Traceback (most recent call last): File "lightkeys.py", line 37, in inport = mido.open_input('mio:mio MIDI 1 20:0') File "/usr/local/lib/python2.7/dist-packages/mido/backends/backend.py", line 91, in open_input return self.module.Input(name, self._add_api(kwargs)) File "/usr/local/lib/python2.7/dist-packages/mido/ports.py", line 161, in init BasePort.init(self, name, kwargs) File "/usr/local/lib/python2.7/dist-packages/mido/ports.py", line 86, in init self._open(**kwargs) File "/usr/local/lib/python2.7/dist-packages/mido/backends/rtmidi.py", line 125, in _open virtual=virtual, api=self.api) File "/usr/local/lib/python2.7/dist-packages/mido/backends/rtmidi.py", line 93, in _open_port raise IOError('unknown port {!r}'.format(name)) IOError: unknown port 'mio:mio MIDI 1 20:0'

Any idea what the problem could be? I searched the net for any issue but couldn't find any result. The strandtest.py runs well and the LED stripe lightens up. I connected my piano using a MIDI-to-USB adapter to the USB socket of the Pi. The Raspberry is running Python 2.7.13. The system is updated with the latest updates/upgrades.

onlaj commented 5 years ago

I'm sorry I didn't specify that anywhere, but you are suppose to change line 37 and put there your port name. In your case this line should look like this:

inport = mido.open_input('MIDI 1 x 1:MIDI 1 x 1 MIDI 1 20:0')

In full version of my script you can change ports using screen and buttons.

MrBromaba commented 5 years ago

@onlaj thank you really much, changing line 37 solved the problem! However, when I press down a key and release it again, the corresponding LED still keeps enlightened and doesn't go off. Do you know why this happens?

I'm planning to set up the little LCD screen in the next steps. How did you manage to start the program automatically and show the settings on the screen by powering your piano? And how did you connect it to the Raspi, it needs all GPIOs but the LED stripe already takes two of them?

onlaj commented 5 years ago

Check what messages your piano sends when you release the key. Run printmidimessages.py from tests folder (remember to change port name) and see what it prints. On my piano when I release the key it sends message with "velocity = 0". My script runs 24/7, when I turn on piano it doesn't send any signals so there is no way to detect new activity. There is free space between Pi Zero and screen hat with visible pins.

MrBromaba commented 5 years ago

@onlaj when I release the key it sends different velocity levels every time (108, 102, 107, 81,...). What do you mean with free space between the screen and the pins? The screen needs all of the pins so that I can‘t plug in the LED strip anymore or am I wrong?

onlaj commented 5 years ago

Does it send anything else? Show me example of message when you press the key and when you release it. You can solder it or just screw wires around the pins. Pins are longer than holes in the hat, so you can still see and touch them.

MrBromaba commented 5 years ago

@onlaj here's an example of what it sends:

pi@raspberrypi:~/Piano-LED-Visualizer/tests $ sudo -E python printmidimessages.py note_on channel=0 note=23 velocity=60 time=0 note_off channel=0 note=23 velocity=97 time=0 note_on channel=0 note=28 velocity=57 time=0 note_off channel=0 note=28 velocity=85 time=0 note_on channel=0 note=38 velocity=80 time=0 note_off channel=0 note=38 velocity=102 time=0 note_on channel=0 note=50 velocity=92 time=0 note_off channel=0 note=50 velocity=97 time=0 note_on channel=0 note=40 velocity=29 time=0 note_on channel=0 note=38 velocity=23 time=0 note_off channel=0 note=38 velocity=67 time=0 note_off channel=0 note=40 velocity=92 time=0 note_on channel=0 note=42 velocity=69 time=0 note_on channel=0 note=43 velocity=26 time=0 note_off channel=0 note=42 velocity=73 time=0 note_off channel=0 note=43 velocity=90 time=0 note_on channel=0 note=42 velocity=50 time=0 note_on channel=0 note=52 velocity=62 time=0 note_on channel=0 note=53 velocity=60 time=0 note_off channel=0 note=42 velocity=88 time=0 note_off channel=0 note=53 velocity=108 time=0

I guess my piano detects how fast I release the keys, that's why the key release velocity isn't 0. Is there any other way to turn off the LEDs after release than using the velocity?

onlaj commented 5 years ago

Yes, it clearly says note_on or note_off, your piano is more clever than mine :) But the sad part is that my script won't work with your piano.

MrBromaba commented 5 years ago

@onlaj dang... any way I could use the note_off info in your script? :/

onlaj commented 5 years ago

You would have to rewrite some parts. Add simple condition, instead of (pseudocode) if(velocity == 0){ turn off led } you should write something like if(message contain note_off){ turn off led}

edit: or search for "note_off" in message, if found just edit velocity in message to 0, it should me much simplier Accidentally edited your comment instead of mine :D

MrBromaba commented 5 years ago

@onlaj Could you please write that in actual code for me? I have zero coding experience (just some Java :P). I'd be really thankful!

Edit: The if-statement in line 56 checks whether the note is off, right?

onlaj commented 5 years ago

Yes, just use "in" operator. Like: if "note_off" in str(msg): turn off led

MrBromaba commented 5 years ago

OH MY GOD THANKS DUDE! It finally works! You're the boss :D

jsm174 commented 5 years ago

Last night, I finished assembling the LED bar and put as much of the pi together as I could while waiting for the Waveshare to clear customs (for the past three weeks).

When firing up visualizer.py I get:

pi@raspberrypi:~/Piano-LED-Visualizer $ sudo python visualizer.py
no input port
no playback port
no output port
no light port
Traceback (most recent call last):
  File "visualizer.py", line 726, in <module>
    midipending = midiports.inport.iter_pending()
AttributeError: MidiPorts instance has no attribute 'inport'

I updated https://github.com/onlaj/Piano-LED-Visualizer/blob/master/visualizer.py#L609 to:

self.inport =  mido.open_input('Williams Allegro 2 MIDI 1')

And it started working!

@onlaj, above you said:

In full version of my script you can change ports using screen and buttons.

Does this mean when I finally get the Waveshare, I can leave the script the way it was, or will I still have to update the device names?

IMG_2587

onlaj commented 5 years ago

You will still have to update port names. But now when I think about it I should have just make script choose random port which does not have "Through" in name. I can also make exception condition, so it won't crash with wrong port name. I will add this to my to-do list. It looks really nice, gj! Does the leds are placed correctly above the keys? I was afraid that pianos might have different spacing between keys.

jsm174 commented 5 years ago

Great. Thanks!

This is such an awesome project!

The LEDs seem to be perfectly spaced at two per key. The only problem I ran into is the WS2812B spool I purchased, are soldered together every 72 lights. This solder joint offsets each segment pretty bad.

I ended up hacking them up and re-soldering to make it continuous. Not my finest solder job, but it works :)

IMG_2505

MrBromaba commented 5 years ago

My strip also has this problem... the offset isn‘t noticeable from a top-down angle but when I turn on all the LEDs you can see it. :/

bo7abib commented 5 years ago

when i sudo -E python lightkeys it shows :

Traceback (most recent call last): File "lightkeys.py", line 37, in <module> inport = mido.open_input('MIDI 1 x 1:MIDI 1 x 1 MIDI 1 20:0') File "/home/pi/.local/lib/python2.7/site-packages/mido/backends/backend.py", line 91, in open_input return self.module.Input(name, **self._add_api(kwargs)) File "/home/pi/.local/lib/python2.7/site-packages/mido/ports.py", line 161, in __init__ BasePort.__init__(self, name, **kwargs) File "/home/pi/.local/lib/python2.7/site-packages/mido/ports.py", line 86, in __init__ self._open(**kwargs) File "/home/pi/.local/lib/python2.7/site-packages/mido/backends/rtmidi.py", line 125, in _open virtual=virtual, api=self.api) File "/home/pi/.local/lib/python2.7/site-packages/mido/backends/rtmidi.py", line 93, in _open_port raise IOError('unknown port {!r}'.format(name)) IOError: unknown port 'MIDI 1 x 1:MIDI 1 x 1 MIDI 1 20:0'

note the aconnect -l connection log is ::

client 0: 'System' [type=kernel] 0 'Timer ' 1 'Announce ' client 14: 'Midi Through' [type=kernel] 0 'Midi Through Port-0' client 20: 'Clavinova' [type=kernel,card=1] 0 'Clavinova MIDI 1'

so what should i put the port number i changed it to the same of what you give the author but its not working.

jsm174 commented 5 years ago

I think you need to adjust

inport = mido.open_input('MIDI 1 x 1:MIDI 1 x 1 MIDI 1 20:0') 

to

inport = mido.open_input('Clavinova MIDI 1')

I think I used amidi -l to figure out the name of my device

bo7abib commented 5 years ago

thank you very much worked