Custom wavtooeasy board

Hello Ivan thank you for your last message it really helped me find the issue, (It was the hps switch of the lm49450 as well as the i2c resistors I left out.

I have gotten the ability to play wavs now. However I am currently having a noise issue. The circuit is totally silent when nothing is playing, however as I play a wav file, there’s an audible noise . Do you have any ideas,
Is this typical?
Ps I am using a boost converter to supply the 5v(tps61023) and a 3.3v ldo. I have attached a sample. I am playing a file containing 10 seconds of silence on the wavtooeasy.

Sorry for the late reply. I was out of office.

It sounds like electrical interference. Maybe a layout problem. The WaveTooEasy is completely silent (noise wise) whenever there is audio or not.

Thanks Ivan. I actually fixed it, the noise was coming from a boost converter I chose.

I am in the process of modifying how the io mode works , I have 6 buttons on my device and I want to use them to control 6 wavs. The catch is that I have multiple folders with wavs, and I want to switch to other folders using the 6th button.
Do you have any advise for me?
I am abit stuck

i modified the initializeio mode function but im looking for a way to dynamically change the folder the wavs are in. i plan on having 6 folders(00 to 05 each containing 6 wavs. then 6 buttons that play the wavs in those folders(1.wav to 6.wav) however to change folders i want to press either an extra button or the button 6 then an extra button that would switch to the folder corresponding to that button

bool initializeIoMode()
    // Initialize players list

    // hardcoded settings for pin1 through pin6
    for (uint8_t i = 0; i < 6; i++)
        char file_path[128];
      sprintf(file_path, "\\%s\\%i.wav", current_folder, i+1);

        io_pins[i] = new IoPin(i, file_path, PinActiveLow, EdgeTrigger, PlayModeNormal, 5.0, DeassertPause, 5);
        if (!io_pins[i]->begin())
            debugMsg(DebugError, "Could not initialize pin %i", i);
            return false;

    return true;

thats my current code

@Ivan i would appreciate your advose.
also do you know if the stm32f4 would work with the adafruit neopixel library. i am considering rgb leds

Hi @Oluwadara_Olaifa ,

Doing a program like that will require to heavily modify the code. Perhaps modifying the IoPin class to do what you want it to do.

I wouldn’t know. There is the LedStrip Library included in the core files, but I never tested it with the WaveTooEasy (it works fine with PropBoard). It uses the SPI on pins PB5, PA6 and PA5, so I don’t think it will work on WaveTooEasy HW since PB5 is not exposed. Maybe in your board it is, or you can search for another combination of SPI pins, but again it will require some study to understand its limits on WaveTooEasy HW.

hi ivan, on my board pb5 us exposed however pb6 is in use by the i2c port for the lm49450
there are 3 ports, I2C1(PB6/7), I2C2(PB10/3), I2C3(PA8/PB4)
i2c 2 looks like the most suitable. Any idea where in the code i can change the port? then I can use the spi led controller.
if i focus my attention to the io pin class would i be able to modify it?
can i use the arduino pin naming and functions, like (digitalRead(pa0); )?
or do i need to use the io_pins[i] array (digitalRead(io_pins[2])

The function that initializes the SPI is here:

You can use digitalRead and digitalWrite with pins on the WaveTooEasy. The values for those functions can be found here:

The mapping for the pins is here:

If you use the Arduino way, you shouldn’t use the IoPin class for those pins. The IoPin class is there to glue together IO handling and audio playing.

Hi, Ivan, I put modifying the button controls on hold for abit. I have been trying to swap the lm49450 to an adau1701 that also has i2s however the code seems to be deeply meshed with the i2c functions provided by the lm49450.
I also noticed a couple of files in the bootloader, do you have any advise for me concerning making these modifications.

It’s really kicking my butt so far

Hi @Oluwadara_Olaifa,

I wouldn’t know how to help on this. You can try to replace the 7 function calls for the codec in the Audio Manager module.

The functions for the codec are the ones starting with “lm49450”.

I don’t recall files in the bootloader regarding audio.

Hello Ivan, how do I compile the bootloader file to get a bin file?

Sorry @Oluwadara_Olaifa for the late reply.

The bootloader compiles with GCC. I used Eclipse CDT + ARM Cortex Plugin + GCC, and OpenOCD for flashing.

thanks, i have a working sketch currently for the stm32, can you suggest any improvements? i basically stole functions from the player.h file as well as the led strip library of the prop board

#include <Arduino.h>
#include "Player.h"
#include "Led.h"
#include <LedStrip.h>
LedStrip myLedStrip;
// Initialize PlayersPool instance
PlayersPool players = PlayersPool::getInstance();
Player* channelPlayers[6] = {NULL, NULL, NULL, NULL, NULL, NULL};

#define DEBOUNCE_DELAY 50  // in milliseconds
bool lastChannelStates[6] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};  // assume all pins are HIGH initially
unsigned long lastDebounceTimes[6] = {0, 0, 0, 0, 0, 0};

BoardLed led1(LED1);
BoardLed led2(LED2);

// Additional variables for bank switching
bool bankSwitchMode = false;
unsigned long bankSwitchStartTime = 0;
const unsigned long BANK_SWITCH_DURATION = 3000; // 3 seconds
const unsigned long LONG_PRESS_DURATION = 2000; // 2 seconds
unsigned long channel6PressStartTime = 0;
bool channel6Pressed = false;
char currentBank = '1';  // Default bank

bool checkingLongPress = false;  // New flag to track if we're checking for a long press on CHANNEL6

void debugMsg(const char* type, const char* format, int pin_num) {
    char msg[100];
    sprintf(msg, format, pin_num);
    Serial.print(": ");

void releaseIfStopped(Player*& player) {
    if (player && player->getStatus() == playerStopped) {
        player = NULL;

static void pollAudioActivityLED() {
    static bool playing = false;

    if (Audio.isPlaying() && !playing) {
        playing = true;
        led1.blink(250, 125);
    } else if (!Audio.isPlaying() && playing) {
        playing = false;
        led1.blink(1000, 500);

void setup() {
    pinMode(CHANNEL1, INPUT);
    pinMode(CHANNEL2, INPUT);
    pinMode(CHANNEL3, INPUT);
    pinMode(CHANNEL4, INPUT);
    pinMode(CHANNEL5, INPUT);
    pinMode(CHANNEL6, INPUT);

    led1.blink(1000, 500);
 myLedStrip.begin(6, WS2812B);

     // Set the 1st LED with white color
    myLedStrip.set(1, 255, 255, 255);

    // Set the 2nd LED with red color
    myLedStrip.set(2, 255, 0, 0);

    // Set the 3rd LED with green color
    myLedStrip.set(3, 0, 255, 0);

    // Set the 4th LED with blue color
    myLedStrip.set(4, 0, 0, 255);

    // Update all the LEDs

    // Delay a second

    // Sets all the LEDs with some color
    // Note the first parameter: when zero
    // all the LEDs are set with the same color
    myLedStrip.set(0, 111, 55, 255);

    // Update all the LEDs

    // Delay half a second

void loop() {

    bool currentChannel6State = digitalRead(CHANNEL6);
    debugMsg("DebugInfo", "Current Channel 6 State:", currentChannel6State);

    if (currentChannel6State == LOW && !channel6Pressed) {
        channel6PressStartTime = millis();
        channel6Pressed = true;
        checkingLongPress = true;  
        debugMsg("DebugInfo", "Channel 6 Press Detected", 0);
    } else if (currentChannel6State == HIGH && channel6Pressed) {
        channel6Pressed = false;
        channel6PressStartTime = 0;
        checkingLongPress = false;
        debugMsg("DebugInfo", "Channel 6 Release Detected", 0);

    if (channel6Pressed && (millis() - channel6PressStartTime > LONG_PRESS_DURATION)) {
        led1.blink(500, 500);
        led2.blink(500, 500);
        bankSwitchMode = true;
        bankSwitchStartTime = millis();
        channel6Pressed = false;

    if (bankSwitchMode && (millis() - bankSwitchStartTime > BANK_SWITCH_DURATION)) {
        bankSwitchMode = false;

    if (bankSwitchMode) {
        for (int i = 0; i < 5; i++) {
            int pin = CHANNEL1 + i;
            if (digitalRead(pin) == LOW) {
                currentBank = '1' + i;
                bankSwitchMode = false;
    } else {
        for (int i = 0; i < 6; i++) {
            int pin = CHANNEL1 + i;
            bool currentReading = digitalRead(pin);

            if (checkingLongPress && i == 5) continue;

            if (currentReading != lastChannelStates[i]) {
                lastDebounceTimes[i] = millis();

            if ((millis() - lastDebounceTimes[i]) > DEBOUNCE_DELAY) {
                if (currentReading == LOW && !channelPlayers[i]) {
                    channelPlayers[i] = players.acquire();
                    if (channelPlayers[i]) {
                        char filename[] = "\\0X\\Y.wav";
                        filename[2] = currentBank;
                        filename[4] = '1' + i;
                        if (!channelPlayers[i]->play(filename, PlayModeNormal)) {
                            debugMsg("DebugError", "Pin %i - error playing", pin);
                        } else {
                            debugMsg("DebugInfo", "Pin %i playing", pin);

            lastChannelStates[i] = currentReading;


Hello @Oluwadara_Olaifa,

I’m glad you could combine all the pieces together!

I can see one thing. Maybe changing

void releaseIfStopped(Player*& player)


void releaseIfStopped(Player* player)

Just for clarity.

hello ivan i extracted this function from your prop bord power api however i cant seem to figure out the naming convention for this " ADC_Channel_17". i changed the read battery pin to ADC_Channel_14 thinking it would be conneted to pc4 instead of pc0 that you used(ADC_Channel_10)

`uint16_t readBattery()
uint16_t battery;
uint16_t vrefint;

while (ADC_GetSoftwareStartConvStatus(ADC1) != RESET);
ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 1, ADC_SampleTime_84Cycles);
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);

vrefint = ADC1->DR;

while (ADC_GetSoftwareStartConvStatus(ADC1) != RESET);
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_84Cycles);
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);

battery = ADC1->DR;
battery = battery * 1210 / vrefint;

return battery / 0.233f;

@ivan i am making some slight changes to the bootloader can i possibly get your gcc commands for compiling the bootloader bin


The bootloader project is compiled from within the Eclipse environment. We don’t use the command line since commands are directly generated by the IDE.

About installing Eclipse, please see this answer.

@ Oluwadara_Olaifa Have you had any luck with compiling the bootloader?

Not much luck, I have spent the last few days trying to install open CD and the other components

@Oluwadara_Olaifa Ok. If you send me a private message with your email, I can keep you updated on my daily progress on it (or bounce around ideas). (it doesn’t let me send private messages here yet).

I will post here when I do finally figure it out as well for others.

1 Like