Close
0%
0%

NFC Music Box

Touch and see your curated music (again).

Similar projects worth following
Using NFC music tags to drive a networked music playing device. There are a few examples of these, notably inspired by https://brendandawes.com/projects/plasticplayer2. This started with a simple Automate process on an Android tablet for my toddler and escalated with attempt to fix a random person's home made version of the Brendan's Plastic Player. Down the rabbit hole I went!

Stops along the way:
* Android Intents
* Automate app
* NXP Tagwriter app
* Investigating Espruino(espruino.com)
* Depreciated Spotify API
* Spotify API
* Librespot Spotify Connect
* (Unofficial) TIDAL APIs
* International Standard Recording Code
* Music Player Daemon
* HifiBerry DAC
* NFC Type 2 Tag Operation Specification
* NFC NDEF messages
* Reversal film (via 35mm Movie film)
* Vintage slide transparency viewers
* NeoPixels
* PN532 modules
* SSD1306 OLED screen
* Building with ESP32-WROOM-32 module
* Micropython (vs Circuitpython)
* Heap memory troubleshooting
* OTA updates
* PCB design with KiCAD

  • keeping up with the current

    Adam Chasen3 hours ago 0 comments

    Any external dependency is an ocean current you have to keep up with or get left behind.

    The external dependencies of this project are:

    * Spotify API

    * Spotify player (i.e. Raspotify)

    * Airtable

    * Micropython and Libraraies

    Airtable is a legacy dependency to provide a convenient, though, overly heavy interface to manage you tags and spotify links. The experience of maintaining columns of tags and spotify URIs isn't great, but it was inherited from the original project I re-implemented. I probably should get rid of it, but support is there already...

    Airtable decided to change the way they deal with API authentication. I noticed when I was writing the integration that the API authorization was all or nothing, which didn't seem right. They implemented Personal Access Tokens (PAT) https://airtable.com/developers/web/guides/personal-access-tokens which support scopes, and disabled all legacy api keys. The switch to PAT requires sending a Bearer Authorization HTTP Header, so implemented that and the settings form to support setting it.

    Spotify decided to add a attribute "supports_volume" to their device JSON which the library I am using chokes on. This only is exposed during initial setup when we query all devices for you to choose from. I added "supports_volume" to the device model. I should change it to support whatever new attributes Spotify may come up or ignore all but the critical attributes (e.g. name and id)

    Changes to the Spotify API disabled the username and password login pathway used by librespot, the open source library many spotify players use including Raspotify. Unfortunately with this change, the error output on older librespot versions indicates "incorrect password". Newer versions indicate user/password is depreciated in a log message. Updating to latest versions of librespot and going through the Spotify token generation process will get your player back up and running: https://github.com/librespot-org/librespot/wiki/Options#access-token

    Micropython and libraries don't necessarily need to be updated, but always a good idea to stay current on connected devices. I built a micropython build off master with ESP-IDF 5.3.2 including all of the required libraries of this project frozen into the firmware via a manifest.py

    ```

    git checkout tags/v5.3.2

    ./install.sh esp32

    . ./export.sh

    cd ~/git/micropython/ports/esp32

    make submodules

    make BOARD=ESP32_GENERIC BOARD_VARIANT=OTA FROZEN_MANIFEST=${HOME}/git/PlasticPlayerRedux/manifest.py

    ```

    I often ran into TLS memory issues with Micropython on ESP32. This got worse with some of the new IDF versions, but the latest Micropython and IDF have not triggered the errors for me yet. Previously I had done some digging into the issue, especially for OTA updates with larger payloads. HTTP didn't have any issues in my experience (can negotiate down the record size and is accessible via TCP directly?) and allows smaller buffers. TLS has it's own maximum record size of *16 KiB* and most servers will rationally use that full record size for any bulk transfer. This includes packaging up a bunch of smaller HTTP packets into one giant one. TLS supports packet re-assembly as well. Significant RAM requirements for TLS comparative to straight HTTP. That is why the firmware OTA updates I run are over HTTP (despite the risks).

    There is a setting on the client side in the ESP-IDF which uses mbedTLS MBEDTLS_SSL_MAX_CONTENT_LEN. There is "Maximum Fragment Length Negotiation" in https://datatracker.ietf.org/doc/html/rfc6066#page-8, but servers do not have to support this. This thread mentions changing the Fragment Length to tradeoff between latency and throughput https://issues.apache.org/jira/browse/TS-2503 including starting off with as small as a single TCP segment.

    ## Other News

    I have been playing with some OLED screen scrolling and brighness to avoid burn in.

    Added passing of the display object into the Spotify authentication flow to allow display of the Spotify OAuth links when pairing the device. I am not happy that...

    Read more »

  • Shipped!

    Adam Chasen10/25/2022 at 14:33 0 comments

    These logs are not in order as I am kinda starting from the end and moving backwards.

    I am shipping my first unit out to NY this week. It supports (insecure) OTA firmware and code updates, so it shouldn't require a serial connection to consume updates.

    It isn't pretty and the code is a bit slapped together but it works and is robust enough to send out

View all 2 project logs

  • 1
    Setup Raspberry Pi Spotify Connect Device
    1. Install raspberrypi os https://www.raspberrypi.com/software/
    2. install raspotify https://dtcooper.github.io/raspotify/
    3. configure raspotify for username/password auth (/etc/raspotify/conf)
    4. configure raspotify for playback settings
    5. (optional) configure DAC
    6. restart raspotify

    Hints:

    xz -d < 2022-09-06-raspios-bullseye-armhf-lite.img.xz | sudo dd of=/dev/sdg bs=4M conv=fsync status=progress
    touch /run/mediaXXX/boot/ssh
    openssl passwd -6
    vi /run/media/xxx/boot/userconf.txt

    Headless rpi setup: https://www.raspberrypi.com/documentation/computers/configuration.html#setting-up-a-headless-raspberry-pi

    Setup user: https://www.raspberrypi.com/documentation/computers/configuration.html#configuring-a-user

    SSH enable by adding `ssh` file to boot partition: https://www.raspberrypi.com/documentation/computers/remote-access.html#ssh

    sudo apt-get -y install curl && curl -sL https://dtcooper.github.io/raspotify/install.sh | sh
    
    sudo vi /etc/raspotify/conf
    sudo systemctl restart raspotify.service
    #LIBRESPOT_AUTOPLAY=
    #LIBRESPOT_DISABLE_CREDENTIAL_CACHE=
    LIBRESPOT_DISABLE_DISCOVERY=
    LIBRESPOT_BITRATE="320"
    LIBRESPOT_FORMAT="S24"
    LIBRESPOT_USERNAME="<username>"
    LIBRESPOT_PASSWORD="<password>"
     #TMPDIR=/tmp

     HiFiberry DAC already included in upstream Raspberry Pi OS, but needs configuration. Note the kernel 5.14+ instructions.

    https://www.hifiberry.com/docs/software/configuring-linux-3-18-x/

  • 2
    Configure Network

    I assume the Spotify Connect device is functional and visible as a "device" in the Spotify interface (or API).

    This is for NFC reader portion.

    Factory reset if need:

    1. Remove power
    2. Hold down button A (or both if you don't know)
    3. Apply power
    4. Release button A
    5. Press button 0 (boot select button on PCB next to ESP32 module)
    6. Release button 0
    7. Wait 10 seconds
    8. Remove power
    9. Apply power and you are in factory reset state

    Configure Network:

    1. Apply power
    2. Join WifiManager SSID with PSK `tayfunulu`
    3.  Navigate to http://192.168.4.1
    4. Select SSID
    5. Enter WLAN PSK
    6. Submit
  • 3
    Configure Spotify API

    This requires a client which supports mDNS addresses. Most major web browsers and operating systems support mDNS. I have tested with Firefox on Fedora 36.

    1. Navigate to Spotify config address of device indicated on OLED
    2. Enter Spotify API client id: 4efe77ff069f45a79d7cc3279e2ba870
    3. Enter Spotify Secret: 8d52b8bd5e8f48ed96987d07d76adf37
    4. Submit
    5. Wait for device to reboot (~10-20 seconds)
    6. Web browser may timeout
    7. Click "retry" on web browser after 10 seconds
    8. Select Spotify Connect device
    9. Submit

View all 5 instructions

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates