MiczFlor / RPi-Jukebox-RFID

A Raspberry Pi jukebox, playing local music, podcasts, web radio and streams triggered by RFID cards, web app or home automation. All plug and play via USB. GPIO scripts available.
http://phoniebox.de
MIT License
1.33k stars 395 forks source link

Hardware hack: Play only if RFID is near the reader #62

Open zxa opened 6 years ago

zxa commented 6 years ago

Not an "issue" at all, but i want to leave it anywhere as documentation if somebody else is interested (like in #43):

I wanted to have a feature that the player stops if you remove the RFID card from the reader. The problem, discussed here before, is that the reader transmits the card number via USB only one time after it read it and there's no way via USB to "see" for the RPi if the card is still near the reader.

When i got my reader (it's a Neuftech 125 kHz (Amazon link) i found an interesting behaviour: if the reader "sees" the card, a light turns from red to green and stays green, as long as the card is near. So i opened it up and found following:

neuftech1

When the red led is on ("the idle state") there are approx. 2.7 V on point A and a few mV on point B. When the green LED is active (a card is near), there are 3.2 V on point B. This is almost exactly the voltage a GPIO of the RPi can bear. So i attached a 5k Ohm ( found by trial and error: i started with higher values and ended up with that, where it was working reliable) to point B (thanks to the manufacturer for the convenient soldering point in the board) and wired that with a GPIO pin:

neuftech2

Then i defined the stop key in the gpio-buttons.py as following:

stop = Button(6, pull_up=False) (the Pin has to be pulled down, as i apply the voltage from the reader) stop.when_released = def_stop

So, when a card comes near the reader, the rfid_trigger_play.sh starts the audio. My "LED voltage GPIO button" is pressed and stays in that state until the card is removed. Then the "released" event is triggered by the gpio-buttons.py.

I'm planing to enhance this function in that way, that the audio is paused on removal, but this is not as easy as the solution above. Maybe the code from #47 may help.

I don't know if this works with other readers as well, but if your device shows the same behaviour as i described above, chances are high.

MiczFlor commented 6 years ago

Hi @zxa can I add this to the documentation?

Luegengladiator commented 6 years ago

Nice one. I've the same reader so I'll give it a try. There is a "Pause on removal" in pr50-testing-changeplayer now. Worked on that and other things in #50

zxa commented 6 years ago

@MiczFlor of course, that is definitely the better place to put.

Franzformator commented 6 years ago

Hi,

I am on my way to build a Kids Jukebox based on your How-to. I really like the idea of "Stop on RFID removal"! I will definitely try to implement this. An improvement of this function could be to differentiate between tracks. My use-case would be that for audio books the RFID-Tag must be placed on the Jukebox (with restart on the last position). For short audio tracks such as animal sounds it would be sufficient that it is only swiped over the RFID-Reader.

Maybe it is possible to make a classification of the audio tracks in the playlist?

zxa commented 6 years ago

Hi @Franzformator

the restart on the last position is implemented yet in the "pr80-mpd-as-audio-player" branch of this repo. As it will be standard in the near future and all new features go into that branch, it's a good idea to switch to it especially if you are in the process of building a new box. Install instructions here: https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/79

Regarding the classification thing: The restart on the last position feature is implemented in that way, that you can toggle the feature for every audio directory. So it would be an easy solution for your use case to have a script which is called by gpio-buttons.py if a rfid card is removed. This script checks, if "resume play" is activated for that folder (the activation is simply done with writing a file called "lastplayed.dat" into that folder). If it finds the file: it stops the playout. If it doesn't find the file: The script does nothing (the playout continues).

It's maybe not the most sophisticated "mooing and meowing"-feature as it is coupled with resume play, but it's maybe enough for your use case.

Raspfarbend commented 6 years ago

Hey @Franzformator , i think this little sneaky function (+stop on remove) is important for the user experience.

at the same time it must be possible to realize that without iron soldering. I think with a component of this, it's possible: https://www.ebay.de/itm/SunFounder-PN532-NFC-Module-Development-Antenna-RFID-Readers-for-Raspberry-Pi-2/371222618000

Let's do it

Franzformator commented 6 years ago

@zxa Thank you for your detailed answer. I think the "lastplayed.dat" will do all i want (-:

MalteHST commented 6 years ago

Thanks for this neat instruction. I've tested this on my own and can confirm the function (also with 5kOhm resistance). But before defining the button action you have to add: def def_stop(): check_call("./scripts/playout_controls.sh -c=playerstop", shell=True) ...in gpio-buttons.py to call the function from playout_controls.sh

Nice job.

Buffi79 commented 5 years ago

Hey, erstmal cooles Projekt! Danke dafür!

Also, ich benutze den mfrc522-Reader. Dieser übermittelt ob eine RFID erkennt worden ist oder eben nicht. Dies kann also schon frühzeitig genutzt werden für das "nur Abspielen bei RFID-Kontakt". siehe: https://github.com/MiczFlor/RPi-Jukebox-RFID/compare/Version-1.1.5-dynamicRFIDreader...Buffi79:Version-1.1.5-dynamicRFIDreader

Interessant sind rfid_trigger_play.sh & rfid_trigger_play.sh

Für diejenigen die es interssiert: Reader.py habe ich modifiziert, dass es die selbe RFID auspuckt wie bei einem ESP8266 mit PN532 (Welche ID-Berechnung korrekt ist, weiss ich jedoch nicht)

Gruss Buffi

alienfactor commented 5 years ago

Gibt es außer der Änderung in der gpio-buttons.py weitere? Ich habe die o.g. Anpassungen vorgenommen, einen 4.7k/5.3k Ohm Widerstand an GPIO6 verwendet .. aber es tut sich nichts. Auch nach langem basteln (und verschiedenen Widerständen) konnte ich das Problem nicht lösen.

Hat jemand einen Rat? Danke


Besides the change in gpio-buttons.py, are there any other needed? I have made the aforesaid adjustments, used a 4.7k/5.3k ohm resistor on GPIO6 ... but it doesn't work. Even after long tinkering (with different resistors) I couldn't solve the problem.

Does anyone have any advice? Thanks

pschaefers commented 5 years ago

Hi all,

I think I just got the feature "Play only if RFID is near the reader" working almost properly. I followed the steps zxa described and linked a 5k Ohm resistor between point B (see zxa's first picture) and GPIO-21. To go from simply stopping the sound output to the desired pause-and-play feature, the only things I changed in the code were:

This worked fine for me apart from a minor issue, which I am sure can be fixed rather easily as well. When a playlist finishes and output stops (with the ID still on the reader), the playlist will start playing again as soon as the ID is removed from the scanner. Then, things behave just the opposite, i.e. the playlist pauses when the ID is put on and played/continued when the ID is removed until the playlist finishes again. This is mainly due to the fact that pausing an already paused playlist resumes the playlist again.

I will try to figure out a solution for this as well, which should not be too hard I hope.

Cheers, P

MalteHST commented 5 years ago

You may solve your problem if you define your action in gpio-buttons.py like that:

def def_stop():
    check_call("./scripts/playout_controls.sh -c=playerstop", shell=True)

stop = Button(21,pull_up=False)

stop.when_released = def_stop

So the player does not pause, but stop the playlist. I'm using it like that and doesn't configurated anything for second swipe. Advantage here is that you can easily differ between 'resume play' or 'start from beginning' for several playlists with the web interface.

alienfactor commented 5 years ago

..weird: If i change when_released to when_pressed it works for me

UndIch commented 4 years ago

So it’s working for me as well - but not completely satisfying. The issue is still, that at the end of a Album or Playlist it would restart after removal. So here is my idea: can’t we duplicate the “pause/resume” function as a special version for the RFID reader but modify it to be just a “pause” function and use another gpio for it? The resuming of the play should then still be working because of the “actual” reading of the rfid card? Any thoughts ?

thiesschneider commented 4 years ago

is there a solution yet? I think the documentation is also outdated.

I would love to have this feature as well but cannot find a way to make it work

s-martin commented 4 years ago

Not really, #910 and #932 are related.

thiesschneider commented 4 years ago

For me, the feature does not work. In some other tickets people report to get the base functionality working, but for me the behaviour does not change. I solder it to the pin, add a 5,1kohm resistor (only have 5.1 or 4.7) and modify the three lines in my gpio file. Do I miss something to have the basic functionality?

UndIch commented 4 years ago

The function is working almost perfect to be honest - but we do need some more information of your set up to try to help. Did you install wiringPi? Are you sure you are using the right “numbering”? Which version (Master/Develop) are U using ? Have you tried just to put a LED “between” your wiring so that you see the soldering is working? Next step would be to show that the pull is registered when removing/placing the chip in the reader (command gpio readall with wiring pi installed).

UndIch commented 4 years ago

And have a look at #869

thiesschneider commented 4 years ago

Hey @UndIch,

thx for your quick help! So I installed wiringpi and can see, that the pull is registered: No chip: | 22 | 0 | IN | GPIO. 6 | 6 | 25 | With chip in range: | 22 | 1 | IN | GPIO. 6 | 6 | 25 |

I use the master branch and did not try the LED inbetween, but I think it is working because wiringpi :) In my scripts/gpio-buttons.py I defined the BMC 25 btn_rfidoff = 25.

(sidenote: I copied over the gpio-buttons.py from the gpio-buttons.sample git repo and modified only the three lines which were discribed on the wiki page.)

Should I try the develop branch?

UndIch commented 4 years ago

I am using the develop branch - and with the #869 it is working for me. If the normal branch is yet on python as well (Is it?) - this “hack” here probably would not work any longer due to complete different structure of the “new” python version. I’m a little bit preoccupied right now - I try to look into my modification if the numbering is the right one. If you hadn’t installed wiring pi until now - have you tested if it is working now - could be because wiring pi was required?

thiesschneider commented 4 years ago

Hey @UndIch,

I changed the branch to develop and then it worked! Thank you very much for the hint. Now I have to find the correct configuration for me.

Ramblurr commented 2 years ago

Hey, erstmal cooles Projekt! Danke dafür!

Also, ich benutze den mfrc522-Reader. Dieser übermittelt ob eine RFID erkennt worden ist oder eben nicht. Dies kann also schon frühzeitig genutzt werden für das "nur Abspielen bei RFID-Kontakt". siehe: https://github.com/MiczFlor/RPi-Jukebox-RFID/compare/Version-1.1.5-dynamicRFIDreader...Buffi79:Version-1.1.5-dynamicRFIDreader

Interessant sind rfid_trigger_play.sh & rfid_trigger_play.sh

Für diejenigen die es interssiert: Reader.py habe ich modifiziert, dass es die selbe RFID auspuckt wie bei einem ESP8266 mit PN532 (Welche ID-Berechnung korrekt ist, weiss ich jedoch nicht)

Gruss Buffi

Hey @Buffi79 your link seems to not work anymore.

I also have a RC522 reader and would like this feature. Could you share your solution again?

Buffi79 commented 2 years ago

Repo should be public... https://github.com/Buffi79/RPi-Jukebox-RFID/compare/Version-1.1.5-dynamicRFIDreader