Search code examples
cpicmplab

Weird notes being played on piezo buzzer when deviding with not a constant integer


So this is a more complicated problem. I am currently programming a little developer test board with a PIC16F1509 with the MPLAB X IDE and flashing the compiled hex file via a custom USB UART Bridge onto the board. My problem is following: The piezo is not connected to one of the PWM pins (has a reason). Since i am pretty new to C and Programming ICs i am currently hard coding almost everything. I wanted to create a melody today and it worked fine like this:

void NOTE_A4 (void) { 
    for (int i = 0; i <= 440; i++)
    {
    sound1_SetHigh();
    __delay_us(1136);
    sound1_SetLow();
    __delay_us(1136);
    }   
}

So if i call this function i would get one second of the note.

Since i wanted to be able to change the timings length of the notes i tried following:

for (int i = 0; i <= 440/5; i++) {}

This would allow me to play for 200ms with no problems.

I also wanted to be able to change the length when i call the function so i did this:

void NOTE_A4 (int divider) { 
    for (int i = 0; i <= 440/divider; i++)
    {
    sound1_SetHigh();
    __delay_us(1136);
    sound1_SetLow();
    __delay_us(1136);
    }  
}

Now i have the problem that it just sounds weird. Recording of the song

I cant figure out why that happens since the for loop calculates the new number correctly. I appreciate any help.


Solution

  • The first thing to try is to compute 440/divider once before entering the loop, just to rule out the possibility that the particular combination of how smart/dumb your compiler is, together with the level of optimizations you have selected, causes the division to be repeated in each iteration of the loop. But I doubt that this is the problem.

    Your problem is probably aliasing, and it is a very hard problem to solve. If aliasing is your problem, and you find a solution, please post it here. For more information about aliasing read this: Stack Overflow - Efficient generation of sampled waveforms without aliasing artifacts