peterhinch / micropython-vs1053

Synchronous and asynchronous drivers for VS1053b MP3/FLAC player
MIT License
25 stars 7 forks source link

Rpi Pico #3

Open OlafM2015 opened 1 year ago

OlafM2015 commented 1 year ago

Hi, I like to use the vs1053 in combination with the Pico. Do you have recommendations before I start? Many thanks, Olaf

OlafM2015 commented 1 year ago

When a switch contact bounces it can produce voltages that do not correspond to valid logic levels. If you read a pin at that point in time, you can be confident that the Pin object will return either 1 or 0.

OK, Now I understand. Clear. By the way, in the current Oradio design, capacitive touch is used, which does not have the bounce issue. But does have unintended triggers due to (electrostatic) interference. That is the reason of the 100 ms delay, for the "short" press. Which works now excellent latest delay_ms and await WaitAny.

peterhinch commented 1 year ago

I'm glad to hear it's working. I'm working on documenting the new classes - I'll give you a pointer when this is complete.

peterhinch commented 1 year ago

Thinking about this some more, if your unintended triggers occur around the time when the button is pressed or released, you might want to consider increasing the bound variable ESwitch.debounce_ms. While ESwitch isn't yet documented, this variable's use and behaviour is as per Switch. When the driver detects a switch state change it pauses for debounce_ms ignoring further edges before checking the pin status again.

I would aim to use debounce_ms to ignore bounce-like extra transitions, using the delay values to provide the required user experience.

OlafM2015 commented 1 year ago

In the next HW update, I have added an 18650 Li-ion cell. Such that caretakers can uncouple from the mains and put it on a table, in front of the people to be used easily. (A wish I received several times during in the field testing) To save battery power, when switched off, I like to shut-down the 3V3 and 1V8 LDOs of the VS1053 circuit (including the SDCARD). This could save about 13 mA, total current from 26mA to 13 mA. After repower the LDOs, the problem is to get the player running again. I Tried player.reset() and reinitiatise. but both do not work. The no so elegant way is a machine.reset() full restarting the system. What would work better?

peterhinch commented 1 year ago

I haven't investigated low power operation of the VS1053. In general micropower work requires a lot of testing and experimentation.

I think you'll need to remount the SD card. If you don't pass sdcs to the constructor you can take control of mounting the SD card yourself. You can still pass mp=your_mount_point to enable the driver to pick up the patch file. Thn you can have code like this mount the SD card at start and after re-powering the SD card.

This is likely to be the simplest of your problems. After re-powering, is uasyncio still running properly?

Incidentally I did say I would update you when I had completed the work on event-based drivers and primitives: the doc is here.

OlafM2015 commented 1 year ago

THanks for the hint. Tried to remount the SD card. With:

            sd = sdcard.SDCard(spi, sdcs) # To test remount again
            vfs = os.VfsFat(sd)
            os.mount(vfs,'/SD')
            print('Sd card mounted')

I get error meassage: Task exception wasn't retrieved future: coro= <generator object 'play_on_ESwitch_loop' at 20020e70> Traceback (most recent call last): File "uasyncio/core.py", line 1, in run_until_complete File "", line 272, in play_on_ESwitch_loop OSError: [Errno 1] EPERM With line 272 being: os.mount(vfs,'/SD')

For now, I put it on the backlog for later. Was curious how much it would be , seems more tricky.

OlafM2015 commented 1 year ago

Have taken some time, now working HW with VS1053 + SD + Pico on one PCB. With I2S output for 2 x MAX98357. Is development PCB, will change orientation SDcard holder and will add Li-ion cell in next version. With this version, will further work on SW. IMG_1001

peterhinch commented 1 year ago

Nice board. I'm curious about a few things. Why the hole under the Pico, and why do you use the version with headers? On my most recent boards I solder the Pico direct to the board using the castellated pads. Also, given that you are already using SM technology, have you considered using the RP2 chips directly? Perhaps your production volumes aren't high enough to justify this.

OlafM2015 commented 1 year ago

"Why the hole under the Pico": In case we want to use the Pico W, we have the hole for the antenna already in the board. "why do you use the version with headers": for HW testing and small modifications, it's easier to use the headers. In the final version, we will solder the Pico direct on the board. Still have to find out how much experience the PCB manufacturer has with a full Pico automated soldering direct on the board RP2 chips direct on the board would be very nice, but we get extra risk and work. And indeed our production volumes are in range 100 - 500. So , for now we will use the Pico. By the way, if you would like to test/play with the board. I am happy to send a set of PCBs to you. Just let me know.

peterhinch commented 1 year ago

Thanks for the offer but I have too much on my plate to give this my attention. But please continue to keep me posted with developments: I'm interested to hear how this project is going.

OlafM2015 commented 1 year ago

To test the robustness against several SDcard, I have tested also some cheaper (slower ones). The slower (read 20 mB/s), clearly give problems. However, some, like a class 10 Kingston with read 91 mB/s gives problems. And other SD cards, with the same speed, work fine. This worries me, as a good speed SDcard seems not a guarantee for proper operation.
When I test these "problem" cards with a separate program, testing write and read, they work just fine. When I use these SDcards with the vs1053.py, I get:

line 534        with open('SD/SYSTEM/START_UP.mp3', 'rb') as f:
             await player.play(f)

Gives
Traceback (most recent call last):
  File "uasyncio/core.py", line 1, in run_until_complete
  File "<stdin>", line 534, in StartUpSoundOnes
  File "sdcard.py", line 255, in readblocks
OSError: [Errno 5] EIO

and line 255 of sdcard.py:
    def readblocks(self, block_num, buf):
        nblocks = len(buf) // 512
        assert nblocks and not len(buf) % 512, "Buffer length is invalid"
        if nblocks == 1:
            # CMD17: set read address for single block
            if self.cmd(17, block_num * self.cdv, 0, release=False) != 0:
                # release the card
                self.cs(1)
Line255                raise OSError(5)  # EIO
            # receive the data and release card
            self.readinto(buf)

Would it be possible to define a criteria for the SDcards, such that they can be tested and have sufficient margin to work proper. This would prevent that we use SDcards which are on the border of OK/NOK.

Edit: After rechecking all parts, I found that SD card.py I used was a littele different from and the sdcard.py belongs to vs1053.py . After checking with the vs1053 version, I found that all class 10 (6 different brands) is working properly. So, that reduces the worries. The read speed seems to be a good discriminator :-)

peterhinch commented 1 year ago

The version of sdacrd.py in my repo does have some changes relative to the official version. These may be identified by "PGH" in the code comments. I increased the timeout value - this may be unnecessary. This change is definitely necessary with some SD card types because the SPI bus is shared. See this PR.

OlafM2015 commented 1 year ago

Ok thanks, at this moment it works perfect. I will further test robustness and will report back findings.

peterhinch commented 1 year ago

My change to sdcard.py has now been merged: https://github.com/micropython/micropython-lib/pull/574#event-7808937131