blippy
Posts: 25
Joined: Fri Nov 03, 2017 3:07 pm

Slightly glitchy sound producing tones via GPIO pins

Tue Dec 25, 2018 1:45 pm

I am trying to produce tones via GPIO pins. Here is the circuit:
speaker.svg.png
speaker.svg.png (5.48 KiB) Viewed 747 times
and here is the code:

Code: Select all

#include <wiringPi.h>

//constexpr auto freq = 400; // Hz
constexpr auto freq = 1000; // Hz
constexpr auto d = 1e6/freq/2; // delay in microseconds

void wait() { delayMicroseconds(d); }

int main (void)
{
        wiringPiSetup () ;
        pinMode (0, OUTPUT) ;
        for (;;)
        {
                digitalWrite (0, HIGH) ; wait() ;
                digitalWrite (0,  LOW) ; wait() ;
        }
        return 0 ;
}



The above code "works", and even produces a tone of the right frequency. But there is a slight glitchiness to it. I can hear distortions, whether I use an active or a passive speaker.

Any idea what might be causing this, and what the fix is?

klricks
Posts: 6591
Joined: Sat Jan 12, 2013 3:01 am
Location: Grants Pass, OR, USA
Contact: Website

Re: Slightly glitchy sound producing tones via GPIO pins

Tue Dec 25, 2018 3:24 pm

blippy wrote:
Tue Dec 25, 2018 1:45 pm
.......
The above code "works", and even produces a tone of the right frequency. But there is a slight glitchiness to it. I can hear distortions, whether I use an active or a passive speaker.

Any idea what might be causing this, and what the fix is?
The typical Linux OS is not a Real Time OS. Therefore the OS will add random delays to any timing loops.
Unless specified otherwise my response is based on the latest and fully updated Raspbian Buster w/ Desktop OS.

User avatar
Joel_Mckay
Posts: 289
Joined: Mon Nov 12, 2012 10:22 pm
Contact: Website

Re: Slightly glitchy sound producing tones via GPIO pins

Tue Dec 25, 2018 3:59 pm

It is usually a bad idea to direct drive anything from a logic gate, and at the bare minimum a small low voltage FET or Darlington transistor should be considered. The snubber diode also dampens the motion of the speaker, and will cause some additional distortion in your tone.

Note that square-waves (includes PWM modes) have a lot of harmonics, and this can be shown in several lectures on DFT or FFT ( https://www.youtube.com/watch?v=0R8qGPXv0JM ). Even the Class-D amplifier in most cellphones will usually have a low-pass filter on the output to suppress the high frequency harmonics.

I am not sure if the Pi GPIO connector gives access to the SoC's PCM_FS and PCM_DIN pins, but it may be worth looking into as a lm386 is easy to setup. If not, there are USB sound cards that work very well on a pi, and are usually under a few $ off ebay.

Cheers,
J

edit, this topic has been discussed before: viewtopic.php?t=171165

blippy
Posts: 25
Joined: Fri Nov 03, 2017 3:07 pm

Re: Slightly glitchy sound producing tones via GPIO pins

Tue Dec 25, 2018 5:08 pm

The odd thing is that I did a similar thing with the Arduino tone library and even the ATTiny85 (with a hand-rolled tone library), using the same speaker and diode. It works fine.

I then tried to translate the above code to Ultibo, which is a unikernel. I don't think it describes itself as a RTOS, but I guess it must be close, because it isn't doing all the fancy stuff that the Linux kernel is doing. it is a "bare metal environment". Running under Ultibo, most of the glitchiness is gone, but there still seems to be some "cyclicity" (on the order of 1-2 seconds) to the note.

Bizarre.

Could it actually be a hardware issue? I'll make enquiries on the Ultibo website, and see if there's anything that it does under the hood that might explain it.

BTW, I am pretty new to electronics, so a lot of stuff is going to be over my head.

blippy
Posts: 25
Joined: Fri Nov 03, 2017 3:07 pm

Re: Slightly glitchy sound producing tones via GPIO pins

Tue Dec 25, 2018 6:06 pm

I have noticed that WiringPi does have a Tone library http://wiringpi.com/reference/software-tone-library/.

Here's an example I concocted:

Code: Select all

#include <cassert>
#include <wiringPi.h>
#include <softTone.h>


int main(void)
{
        wiringPiSetup () ;
        pinMode (0, OUTPUT) ;
        auto ret = softToneCreate(0);
        assert(ret == 0);
        softToneWrite(0, 1000);
        for(;;) ;

        return 0 ;
}

It seems to work pretty well, except that the "cyclicity" is still noticeable.

ghans
Posts: 7873
Joined: Mon Dec 12, 2011 8:30 pm
Location: Germany

Re: Slightly glitchy sound producing tones via GPIO pins

Tue Dec 25, 2018 6:13 pm

The Raspberry Pi has a PWM peripherial which sidesteps timing issues. I believe that it is available through WiringPi.

Being able and willing to interrupt processes by force is a feature of all so-called preemptive operating systems like Windows, Linux and Mac OS X.

ghans
• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org

blippy
Posts: 25
Joined: Fri Nov 03, 2017 3:07 pm

Re: Slightly glitchy sound producing tones via GPIO pins

Tue Dec 25, 2018 6:31 pm

Hmmm, interesting. The WiringPi softTone library is limited to 5kHz, which is quite a low value. Human hearing can go up to 20kHz, although mine is more like 10kHz.

So it seems that it might be an OS thing, as you suggested.

Interestingly, I am looking at the Ultibo website. I can see a few forum threads on system sounds. I see that it is possible to "take control of a CPU in Ultibo core and use it as a high speed micro controller doing real time operations."

Cool. I'll need to check that out.

User avatar
Joel_Mckay
Posts: 289
Joined: Mon Nov 12, 2012 10:22 pm
Contact: Website

Re: Slightly glitchy sound producing tones via GPIO pins

Wed Dec 26, 2018 1:53 pm

blippy wrote:
Tue Dec 25, 2018 5:08 pm
BTW, I am pretty new to electronics, so a lot of stuff is going to be over my head.
There are many ways to look at a phenomena, and usually I try to initially get an intuitive understanding of how something works. Otherwise, a detailed explanation of an abstracted model is not really that useful. ;-)
Perhaps start with a simple design, if you are interested in understanding why there are several types of amp types around: https://www.youtube.com/watch?v=9SclQIWkOtk

Note for people that play with hardware frequency synthesis, they usually set the GPU to 250Mhz in order to be stable:
gpu_freq=250
Otherwise, the output can drift around as the dynamic clocking throttles to control die temperature.

I personally tend to prefer this gpio C library for time critical tasks.
http://www.airspayce.com/mikem/bcm2835/
It includes an example for a hardware "PWM output on RPi Plug P1 pin 12 (which is GPIO pin 18)"
We include this lib pre-installed on the clubs raspbian distro, as it has proven so useful over the years. ;-)

Best of luck,
J

Return to “Graphics, sound and multimedia”