MUSE PROTO board

Could you provide the simplest sketch to read a file by name from the SD card and play it back?

// Plays: 8bit mono 44100hz wav file:

#include "Arduino.h"
#include "SD.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "esp_log.h"
#include <driver/i2s.h>
#include "SPIFFS.h"

const uint8_t VOLUME = 31; // 0..63

#define I2SR (i2s_port_t)0
#define VM GPIO_NUM_0       // button
#define ONled 0
#define PW GPIO_NUM_21        // Amp power ON
#define GAIN GPIO_NUM_23      //
#define BLOCK_SIZE 128
#define SD_CS 13

const i2s_config_t i2s_configR = {
  .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX ), // Receive, transfer
  .sample_rate = 44100,                         //
  .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, //
  .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT, // although the SEL config should be left, it seems to transmit on right
  .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
  .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,     // Interrupt level 1
  .dma_buf_count = 64,                           // number of buffers
  .dma_buf_len = BLOCK_SIZE                           // samples per buffer
};

#define I2S_DOUT      26
#define I2S_BCLK      5
#define I2S_LRC       25
#define I2S_DIN       35

i2s_pin_config_t pin_configR =
{
  .bck_io_num = I2S_BCLK,   
  .ws_io_num = I2S_LRC,   
  .data_out_num = I2S_DOUT,
  .data_in_num = I2S_DIN
};

static void playAudio(char* fileName)
{
  printf("Playing file ");
  printf(fileName);
  printf("\n");
  
  int16_t s0, s1;
  static int8_t c[44100];
  int l;
  size_t t;
  uint16_t s16[64];
  int a = 0;

  i2s_set_clk(I2SR, 44100, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO);

  File f = SD.open(fileName, FILE_READ);
  if (f == NULL) printf("err opening file\n");
  
  f.read((uint8_t*)c, 44);

  do
  {
    l = (int)f.read((uint8_t*)c, 44100);
    if (l < 0) printf("Error \n");
    for (int i = 0; i < l; i++)
    {
      s0 = (((int16_t)(c[i] & 0xFF)) - 128) << 8 ;
      s0 = s0 >> a;  
      s0 = s0 * VOLUME >> 6;
      s16[i % 64] = (uint16_t)s0;
      if (((i + 1) % 64) ==  0)
      {
        int n = 0;
        while (n == 0) n = i2s_write_bytes(I2SR, (const char*)s16, 128, portMAX_DELAY);
      }
    }
  } while (l > 0);
  
  // muting after playing
  for (int i = 0; i < 64; i++)s16[i] = 0;
  int n = 0;
  while (n == 0) n = i2s_write_bytes(I2SR, (const char*)s16, 128, portMAX_DELAY);
  i2s_zero_dma_buffer(I2SR);

  f.close();
  printf ("Stop\n");
}

#define SPI_MOSI 15
#define SPI_MISO 2
#define SPI_SCK 14

void setup()
{
  Serial.begin(115200);
  esp_err_t err;

  if (!SPIFFS.begin(true))Serial.println("SPIFFS failed \n");

  SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
  if (!SD.begin(SD_CS))
  {
    Serial.printf("SD initialization failed!\n");
  } else {
    Serial.printf("SD initialization successfully\n");
  }
  
  //Init buton
  gpio_reset_pin(VM);
  gpio_set_direction(VM, GPIO_MODE_INPUT);
  gpio_set_pull_mode(VM, GPIO_PULLDOWN_ONLY);

  // Amp power enable
  gpio_reset_pin(PW);
  gpio_set_direction(PW, GPIO_MODE_OUTPUT);
  gpio_set_level(PW, 1);

  gpio_reset_pin(GAIN);
  gpio_set_direction(GAIN, GPIO_MODE_OUTPUT);  
  gpio_set_pull_mode(GAIN, GPIO_PULLDOWN_ONLY);   // 15dB
  i2s_driver_install(I2SR, &i2s_configR, 0, NULL);
  i2s_set_pin(I2SR, &pin_configR);
  i2s_stop(I2SR);
}

void loop() {
  if (gpio_get_level(VM) == 0)
  {
    i2s_start(I2SR);
    //playAudio("/500hz44100Mono.wav"); 
    playAudio("/1/cherepaha-aha-aha-8bit-mono.wav");
    delay(100);
    i2s_stop(I2SR);
  }
}

My new Muse Proto board will not show up as a bluetooth device.

I followed the (1-Quick and dirty (no soldering)) instuctions on

downloaded the bin-file and the program.
Ran the program and added the bin-file and found the port
The progress took about 5 seconds to go from Idle to Sync, Download and then to Finish. (Not 3 minutes like the instruction indicated).

The command window that pops up shows this
Uploading stub…
Running stub…
Stub running…
FLASH_CRYPT_CNT 0
ABS_DONE_0 False

is stub and send flash finish

I’m no progarmmer so is there an easy way to get tihs to work?

Hi Chris and welcome!
Seems that you forgot to tick the checkbox on the left of the path of the file to upload :sweat_smile:image

Silly me, I missed that one. So this time it took about 3 minutes to run the process but still no Bluetooth device MUSE_SEAKER shows up.

I will have to try myself next week.

But meanwhile may I recommend you to try Squeezelite it does Bluetooth too and much more such as multirooms

Use the new method 1 with a Chrome browser. Looking forward to have your feedback on how easy to use this method.

That worked! And so supereasy :slight_smile: It took me a while to find the IP-address to log in to the device, the description on the chrome browser installation mentioned how to log in on the temporary wi-fi created but didn’t mention the IP-adddress 192.168.4.1 to the user interface. But after that it’s been a breeze. Thank you.

COOL don’t hesitate to share your creation!

Hi Raspiaudio:slight_smile:

Maybe you can help with a few problems I have with the board.

  1. Each time I upload firmware I need to press on/off and only after that process starts. Is there a way how to avoid this manual step? In my project there is no access to the board except through usb.
  2. Please, suggest a way how to control battery discharging states.

Hi
1-What environment dev are you using? Arduino?

2-what would you like to achieve? Just tracking the battery level?

Thx
Olivier

  1. VSCode
  2. I’d like to play some sound if the battery is empty.

1- just to try, go to https://raspiaudio.github.io/ with a chrome browser, choose Muse proto, connect to the right com port. Open the console and click on reset? do you see you device rebooting? if yes there is no hardware defect. And you should look in the VScode how to do a soft reset after uploading some code.

2-check what we have done here with the battery around line 128

  1. Perfectly worked for me, thank you. It restarts from the console. I’ll try to find a way how to do a soft reset in VSCode.

  2. Very good example, exactly what I needed.

Thank you!

p.s. BTW, very cool approach with https://raspiaudio.github.io!

  1. I’ve just tryed to upload Squeezelitexxx from https://raspiaudio.github.io/ and it also fails.

Then did an experiment and uploaded empty sketch into the board. It works just fine and I can continuously upload it again and again. So something wrong with my sketch. Maybe you have some ideas what service or IO port can interfere with reset capability and setting the device into boot mode?

Could be something related to IO0 check this in your code

If I comment these lines in my setup function, I can upload correctly:

#define SD_CS 13

if (!SD.begin(SD_CS))
{
Serial.printf(“SD initialization failed!”);
}

I see, have you a SD card in when you upload? It could be the issue

Yes, it is in a slot all the time. And you are right, if I remove it, it seems like I can upload firmware without manual intervention with the button. But now I need to manually remove SD card :slight_smile:

ideed this is a known limitation, I will add it it the guide thx

1 Like

So it is a limitation of esp32? Looks like I found a workaround here:

Before writing firmware, I trigger Unmount_SD() by clicking some combination of buttons that my device has and it works fine.

If there is a better workaround, maybe a hardware patch, let me know, please.
I would like to work with an assembled device and have the possibility to upgrade firmware via USB without opening it.