Lixie-Labs / Emotiscope

Let your eyes enjoy the music too ✨ Extremely low-latency audio processing lets LEDs perfectly synchronize to your music's notation and tempo.
GNU General Public License v3.0
27 stars 5 forks source link

Installing and Running on ESP32-S3 Dev Board with PSRAM #75

Open larryqiann opened 2 months ago

larryqiann commented 2 months ago

There are some challenges with getting the code to run correctly on the most popular ESP32-S3 dev boards sold on AliExpress etc. First of all, where possible, you should order the N8 version, which will match the original the closest (I mistakenly bought the N16R8 version, with 16MB of SPI Flash and 8MB of PSRAM, thinking they would be compatible). This board (YD-ESP32-23) can be identified by the two USB-C ports, a NeoPixel on the left, and three serial port LEDs on the right.

The problems with this board (depending on the version you buy) are as follows:

  1. The ROM size is mismatched. This may not actually be a problem, as 8MB code appears to work perfectly fine on the 16MB chip I have.

  2. The PSRAM. By default, the PSRAM is disabled or not used in the platformio.ini. However, there appears to be a bug with the ESP32 chips where if PSRAM is present, but not used, the WLAN stack will attempt to use it (?) and the WLAN will not successfully enable, leading to the "254 unhandled state" in the serial console. Furthermore, simply enabling the PSRAM in the config will result in a boot loop, because the PSRAM pins have been used for I2S.

  3. Specific to the YD-ESP32-23 boards, perhaps, some of the pins 5-7 cannot output a correct I2S BCLK. On the oscilloscope, a triangular wave is generated, instead of a clean square wave.

The following is a summary of how I got mine working:

  1. Install PlatformIO extension in VSCode, and open the repository; the application will attempt to install some dependencies.

  2. [For 16MB Flash and 8MB RAM Only] Add the attached file to the "Boards" folder. On Unix this is in your home folder, ~.platformio/platforms/espressif32[@src...]/boards.

  3. [For 16MB Flash and 8MB RAM Only] Change the corresponding lines to the following in platformio.ini:

    board_build.partitions = default_16MB.csv
    board = S3-N16R8-Reddit
  4. Plug the board in using the direct USB port, not the serial port adapter. Make sure to set it in platformIO. If not working, try to press and hold BOOT button while plugging in USB to enter the ROM boot loader mode.

  5. Use the following commands: pio run -t upload to build and upload, build to just build pio run -t uploadfs to copy the web application files to the LittleFS partition on the chip pio run -t monitor to open the serial console and view the logs

  6. Once the project is building, we need to change some pin assignments.

In led_driver.h, LED_DATA_1_PIN and LED_DATA_2_PIN can be left as 21 and 17. The canonical configuration of the LEDs appears to be 64 LEDs from left to center on DATA_1, then 64 LEDs from center to right on DATA_2.

You need to break the string in the middle (and should, for power distribution anyway). My 147-LED string consumes roughly 7A in total, which I power from three 3A USB leads connected to a multiport desktop charger (benefit of doing this is you get independent OCP for each channel for safety). A separate data line needs to be run to the second string. Be careful not to create a ground loop here, and only connect the data line since ground is already connected at one end.

If you have a different number of LEDs from 128, despite the disclaimer, the only features that will break are Mirror Mode. In Mirror Mode, the background will not extend beyond 128 LEDs (but will otherwise work). I have tested 64, 128, 148 and they work fine. I haven't tried an odd number (and just to avoid weird errors in the code, I would recommend an even one). It's okay to have more configured than you actually have. The pins in leds.h appear to be unused.

In microphone.h, you will need to change the pin assignments if you are using a board with PSRAM [and possibly if not]. I picked:

#define I2S_LRCLK_PIN 39
#define I2S_BCLK_PIN  40
#define I2S_DIN_PIN   41

The LRCK, BCLK, and DOUT pins of the mic should be connected correspondingly to the SPH0645 microphone. Provide 3.3V, ground, and ground the SEL pin (the SEL pin selects the left or right channel)

The Touch Sensors on pins 4, 6, and 8 can be left as they are. I have some wires attached to the pins which when touched, appear to activate. There is a routine to calibrate the touch sensors, and you might want to have a look at the Espressif design guide on capacitive touch sensors. I did not spend a long time on this as I will not be using this functionality.

  1. Make the necessary changes and upload the code to the board. Enjoy your developer board version of Emotiscope! Thank you to the developer for open sourcing this project and delivering a great audio-visual experience!

S3-N16R8-Reddit.json

larryqiann commented 2 months ago

Bonus: Changing the standby_brightness *= 0.999; line in standby.h can reduce the amount of time it takes for the device to enter standby. I set mine at 0.995, which will allow the dots to go out and back in, once, then turn off. You can experiment with this value, but a value too low will effectively disable the standby effect.

connornishijima commented 2 months ago

Great feedback! Emotiscope was designed more like "a console" than "a PC", in that all my code is currently pretty specific to the shipped hardware for optimization and to meet physical constraints, but I'm looking to increase compatibility wherever possible for DIY builds this year.

Thank you for opening issue tickets, these are all great additions and documentation for others!

(Quick note, you can toggle a mode in Chrome Dev Tools that emulates a mobile device on PC with a responsize layout adjuster for PC development purposes until I officially support desktop control.

chrismiller commented 2 weeks ago

Thanks @larryqiann, this is really helpful! I'm waiting for a dev board (ESP32-S3 N8R2) to arrive, at which point I hope to try this out and will report back if there are any issues I hit along the way. One thing I noticed so far though, is that if you put the board definition file in the ~.platformio/platforms/espressif32[@src...]/boards directory as you suggest, there's a risk of it being deleted. Better is to put it either in a boards directory in the project itself, or put it in ~.platformio\boards. See here for a discussion explaining why. Hopefully that saves someone from a bit of pain down the line :)

larryqiann commented 2 weeks ago

Thanks @larryqiann, this is really helpful! I'm waiting for a dev board (ESP32-S3 N8R2) to arrive, at which point I hope to try this out and will report back if there are any issues I hit along the way. One thing I noticed so far though, is that if you put the board definition file in the ~.platformio/platforms/espressif32[@src...]/boards directory as you suggest, there's a risk of it being deleted. Better is to put it either in a boards directory in the project itself, or put it in ~.platformio\boards. See here for a discussion explaining why. Hopefully that saves someone from a bit of pain down the line :)

Thank you for the suggestion! This is a good point - I did actually run into this problem since at some point the "esp32" platform got updated and the file was stuck in the old folder.

One problem that I kept encountering on the S3-N16R8 was that the system would be rather unstable, rather, the WiFi would freeze and/or crash the system after many hours of continuous operation (this is a guess, because its not very easy to do debugging). My module wasn't an official WROOM module but am uncertain whether this is the cause.

I have purchased a N8 (no PSRAM) version of the module and soldered it onto the dev board, and this appears to have greatly improved the stability. My hypothesis is that there was something wrong with the PSRAM on the board I had, and unfortunately I never figured out how to build platformIO without PSRAM support (if the PSRAM is simply disabled using the usual board flags, the WiFi will be non functional/the AP won't start with an unknown error). Last I checked it still does occasionally run into hiccups but they appear to be better. Additionally, I can now make full use of the original pinout of the project without needing to change the pins.

I would be curious to see what your experiences with the N8R2 are - as I understand it, the N8 is not commonly available on AliExpress right now so this could be an important consideration to look into

Thanks!