harshas123
Posts: 5
Joined: Wed Jan 13, 2016 4:06 am

Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Python)

Wed Jan 13, 2016 4:25 am

Hi,
I am trying interface a digital MEMS Microphone with Raspberry Pi 2 Model B+, and do some signal processing in Python using pigpio. The digital MEMS Microphone needs a 2MHz Clock (which I am generating using the code:

Code: Select all

import pigpio
CLK_PIN = 4
pi = pigpio.pi()
pi.harware_clock(4,2000000)
This gives out a pretty good clock signal (which I tested using an Oscilloscope), which can be given to the MEMS microphone.
The digital MEMS microphone now gives out a Pulse Density Modulation (https://en.wikipedia.org/wiki/Pulse-density_modulation). I need a way to read this PDM data into Raspberry Pi. Essentially the microphone outputs a "1" or a "0" on the negative edge of the clock. I tried the following:
1. Create a callback for the negative edge of the clock and read the Microphone data on another GPIO Pin. This failed because the callbacks apparently cannot be called faster than 20kHz.
2. Sampling the microphone data through polling the GPIO Pin also cannot happen faster than about 100 kHz.

Has anyone tried this? Would you please tell me how I would be able to do this? I am now trying to see if i can use SPI or I2S to do this.

Regards

User avatar
joan
Posts: 14200
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Wed Jan 13, 2016 11:06 am

pigpio samples at a maximum rate of 1MHz (1Mbps) so its a non-starter for sampling at 2 MHz.

Linux interrupts (in my experience) top out at about 25 k per second so you can't use interrupts to see the clock.

You would have to use busy spins to see the clock edge, and you would have to use C. Of course with busy spin you will miss edges because of rescheduling.

I think I2S sampling is the way to go (I have no experience of that).

harshas123
Posts: 5
Joined: Wed Jan 13, 2016 4:06 am

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Thu Jan 14, 2016 5:17 am

Thank you for your response.

I realize that it may not be possible to acquire a single bit @ 2MHz. But, if I use a 8-bit shift register, then I would have to acquire 8 bits or 1 byte every 2M/8 = 250kHz. A shift register also sends out a logic 1 when the data is ready to be read in parallel. So, can I sample a set of 8 GPIO pins (all at the same time) every time I receive a digital 1 on another GPIO pin (@250kHz ) in python? The idea is better explained in the Block Diagram below:
BlockDiagram.jpg
BlockDiagram.jpg (54.47 KiB) Viewed 8364 times

User avatar
joan
Posts: 14200
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Thu Jan 14, 2016 11:43 am

I believe the best you will get with Python is using pigpio notifications (which require the script to be running on the Pi). See notify_open.

Try this experiment from the command line. It uses a hardware clock on GPIO 4 as the trigger source. The example uses a 50 kHz clock (so 100 k samples per second). See how high you can get before samples are lost.

Each sample is 12 bytes in size. In 30 seconds you expect 3 million samples. The below run produced a file of size 36176172 bytes.

36176172 / 12 = 3014681 samples
3014681 / 30 = 100489 samples per second (discrepancy due to Linux sleep).

Code: Select all

$ TRIG=4
$ sudo pigpiod -s2
$ pigs no
0
$ cp /dev/pigpio0 log&
[1] 3526
$ ls -l
total 0
-rw-r--r-- 1 joan joan 0 Jan 14 11:32 log
$ pigs nb 0 $((1<<TRIG)); sleep 30; pigs nc 0
[1]+  Done                    cp /dev/pigpio0 log
$ ls -l
total 35332
-rw-r--r-- 1 joan joan 36176172 Jan 14 11:33 log
$ od -x log|head
0000000 0000 0000 3823 b7d1 c1ef 0020 0001 0000
0000020 382b b7d1 c1ff 0020 0002 0000 3837 b7d1
0000040 c1ef 0020 0003 0000 383d b7d1 c1ff 0020
0000060 0004 0000 384b b7d1 c1ef 0020 0005 0000
0000100 3853 b7d1 c1ff 0020 0006 0000 3861 b7d1
0000120 c1ef 0020 0007 0000 3865 b7d1 c1ff 0020
0000140 0008 0000 3873 b7d1 c1ef 0020 0009 0000
0000160 387b b7d1 c1ff 0020 000a 0000 3887 b7d1
0000200 c1ef 0020 000b 0000 388d b7d1 c1ff 0020
0000220 000c 0000 389d b7d1 c1ef 0020 000d 0000
$ 

harshas123
Posts: 5
Joined: Wed Jan 13, 2016 4:06 am

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Mon Jan 18, 2016 8:50 am

Hi Joan,
I tried using the "request Notification" as you suggested using the exact same code provided by you.
Prior to running your code, I generated a 250kHz clock in Pin number 4.
The final file size is 178932636 bytes which translates to 14911053 samples ~ 15 million samples as expected.
For frequencies above 300kHz, the number of samples notified is almost half the number of samples expected.

The notify command only takes notice of changes in the gpio pin. However what I need is to be able to obtain the sample value of 8 GPIO pins @ 250 kHz, even if there is no change in the voltage in those pins.

Additionally, would you please tell me what are the bytes written to the /dev/pigpiox file by the nb command?

User avatar
joan
Posts: 14200
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Mon Jan 18, 2016 3:26 pm

harshas123 wrote:Hi Joan,
I tried using the "request Notification" as you suggested using the exact same code provided by you.
Prior to running your code, I generated a 250kHz clock in Pin number 4.
The final file size is 178932636 bytes which translates to 14911053 samples ~ 15 million samples as expected.
For frequencies above 300kHz, the number of samples notified is almost half the number of samples expected.

The notify command only takes notice of changes in the gpio pin. However what I need is to be able to obtain the sample value of 8 GPIO pins @ 250 kHz, even if there is no change in the voltage in those pins.

Additionally, would you please tell me what are the bytes written to the /dev/pigpiox file by the nb command?
That's much better than I would expect.

pigpio works by sampling the GPIO. In the example above you were sampling at 500 thousand times per second. That should reliably detect a 250 kHz clock. See Nyquist for a probably confusing reason why. You could sample at 1MHz (sudo pigpiod -s1) but I'd only use that in exceptional circumstances if nothing else worked.

The resulting file is binary. Each sample is 12 bytes long.

Code: Select all

typedef struct
{
   uint16_t seqno;
   uint16_t flags;
   uint32_t tick;
   uint32_t level;
} gpioReport_t;
seqno: starts at 0 each time the handle is opened and then increments by one for each report.

flags: two flags are defined, PI_NTFY_FLAGS_WDOG and PI_NTFY_FLAGS_ALIVE. If bit 5 is set (PI_NTFY_FLAGS_WDOG) then bits 0-4 of the flags indicate a gpio which has had a watchdog timeout; if bit 6 is set (PI_NTFY_FLAGS_ALIVE) this indicates a keep alive signal on the pipe/socket and is sent once a minute in the absence of other notification activity.

tick: the number of microseconds since system boot. It wraps around after 1h12m.

level: indicates the level of each gpio. If bit 1<<x is set then gpio x is high.

You can ignore all the data apart from level.

level is a 32 bit quantity. It gives the level of GPIO 0-31 when the sample was taken. So it has everything you need, just check that the clock bit is 1 (if the trigger is a rising edge) then extract the bits you want.

User avatar
mikronauts
Posts: 2717
Joined: Sat Jan 05, 2013 7:28 pm
Contact: Website

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Mon Jan 18, 2016 9:25 pm

My friend, I think what you are trying to do is possible - but not the way you are doing it (a screw driver used as a hammer)

1) set SPI clock to 2Mhz
2) continuously read bytes using SPI, each byte will have eight consecutive samples.

Now you may need to play with the mode to get the clock edge you want, but based on your post, this should work for you.
harshas123 wrote:Hi,
I am trying interface a digital MEMS Microphone with Raspberry Pi 2 Model B+, and do some signal processing in Python using pigpio. The digital MEMS Microphone needs a 2MHz Clock (which I am generating using the code:

Code: Select all

import pigpio
CLK_PIN = 4
pi = pigpio.pi()
pi.harware_clock(4,2000000)
This gives out a pretty good clock signal (which I tested using an Oscilloscope), which can be given to the MEMS microphone.
The digital MEMS microphone now gives out a Pulse Density Modulation (https://en.wikipedia.org/wiki/Pulse-density_modulation). I need a way to read this PDM data into Raspberry Pi. Essentially the microphone outputs a "1" or a "0" on the negative edge of the clock. I tried the following:
1. Create a callback for the negative edge of the clock and read the Microphone data on another GPIO Pin. This failed because the callbacks apparently cannot be called faster than 20kHz.
2. Sampling the microphone data through polling the GPIO Pin also cannot happen faster than about 100 kHz.

Has anyone tried this? Would you please tell me how I would be able to do this? I am now trying to see if i can use SPI or I2S to do this.

Regards
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi

harshas123
Posts: 5
Joined: Wed Jan 13, 2016 4:06 am

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Thu Jan 21, 2016 5:29 am

Hi mikromauts,
Thank you for your response.
I am able to setup SPI @ 2MHz and transfer and receive a byte of data (through loopback by connecting the MOSI and MISO Pins). I am using pigpio to do this using the following piece of code:

Code: Select all

import pigpio
import time

pi = pigpio.pi()
h = pi.spi_open(0,20000000,3)
tx_data='Hello123'
while True:
    (count,rx_data)=pi.spi_xfer(h,tx_data)
I am then observing the SPI clk pin using an oscilloscope. I observed that when the spi_xfer command is executed, only 8 clock cycles at 2MHz are generated and then the clock stops. Thus SPI communication is happening in bursts and not continuously using the above piece of code. So, now my question is how do I use SPI communication in continuous mode ?

I also tried the bcm2835 library with the same effect.

User avatar
mikronauts
Posts: 2717
Joined: Sat Jan 05, 2013 7:28 pm
Contact: Website

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Thu Jan 21, 2016 6:12 am

You are welcome.

You are only seeing eight clocks as you are using the high level API, and Python cannot cycle back fast enough to continuously read and generate clocks without breaks.

I can think of two solutions using SPI:

1) google for the DMA enabled SPI driver, set up a large circular buffer, or double buffer, and use DMA to read your data

2) use the SPI registers directly

2MHz clock / 8 bits = 250k bytes per second, so if interrupts are fast enough, use that, or busy wait on SPI status.

Personally, I would use an external microcontroller, 2MHz would be a piece of cake in Propeller assembly language, and the gathered data could be sent up to the Pi in serial packets at 4Mbps.
harshas123 wrote:Hi mikromauts,
Thank you for your response.
I am able to setup SPI @ 2MHz and transfer and receive a byte of data (through loopback by connecting the MOSI and MISO Pins). I am using pigpio to do this using the following piece of code:

Code: Select all

import pigpio
import time

pi = pigpio.pi()
h = pi.spi_open(0,20000000,3)
tx_data='Hello123'
while True:
    (count,rx_data)=pi.spi_xfer(h,tx_data)
I am then observing the SPI clk pin using an oscilloscope. I observed that when the spi_xfer command is executed, only 8 clock cycles at 2MHz are generated and then the clock stops. Thus SPI communication is happening in bursts and not continuously using the above piece of code. So, now my question is how do I use SPI communication in continuous mode ?

I also tried the bcm2835 library with the same effect.
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi

User avatar
joan
Posts: 14200
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Thu Jan 21, 2016 8:51 am

The Pi SPI hardware introduces a 1.5 bit time gap between each byte (I think it's 1.5, search the forum for SPI, LED strips, and gap).

User avatar
joan
Posts: 14200
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Thu Jan 21, 2016 8:56 am

@harshas123

The last pipe post seemed to suggest that you were capturing the samples using the pipe interface. Was that in error?

User avatar
mikronauts
Posts: 2717
Joined: Sat Jan 05, 2013 7:28 pm
Contact: Website

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Thu Jan 21, 2016 3:02 pm

Good info, did not realize that, thanks.
joan wrote:The Pi SPI hardware introduces a 1.5 bit time gap between each byte (I think it's 1.5, search the forum for SPI, LED strips, and gap).
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi

Givigy
Posts: 1
Joined: Mon Nov 07, 2016 7:56 am

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Mon Nov 07, 2016 8:07 am

Hello harshas123,

I'm dealing with a similar project,
but I'm not sure what is the end of the story:

Did you manage to communicate with the MEMS mic in the desired clock speed?
Is it possible to use the SPI for that, as suggested by mikronauts?

Thanks,
Givigy

harshas123
Posts: 5
Joined: Wed Jan 13, 2016 4:06 am

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Mon Nov 07, 2016 2:57 pm

Hi Givigy,
I did manage to record using a MEMS microphone but not using Raspberry Pi.
My final solution involved using the STM32 micro-controller in a Nucleo Board and the drivers already available from the STM website.
Let me know if you are interested to go along those lines and I can send you a detailed set of links which helped me.
Regards

Fisek
Posts: 7
Joined: Mon Dec 05, 2016 12:28 pm
Location: Belgium

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Wed Dec 07, 2016 11:08 am

harshas123 wrote:Hi Givigy,
I did manage to record using a MEMS microphone but not using Raspberry Pi.
My final solution involved using the STM32 micro-controller in a Nucleo Board and the drivers already available from the STM website.
Let me know if you are interested to go along those lines and I can send you a detailed set of links which helped me.
Regards
Hello harshas123,

I am also interested in your results. You have mentioned about Nucleo Board setup of STM. Could you give me some details about it please?

Kind regards

antonms
Posts: 1
Joined: Mon Apr 24, 2017 6:14 pm

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Mon Apr 24, 2017 6:19 pm

Hi harshas123
I am working on a project that will use ST's MP34DT02TR digital mic.
It would be really helpful if you could provide the links you mentioned in the above post.
Thanks
antonms

pyrog
Posts: 2
Joined: Sun Apr 30, 2017 10:00 am

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Sun Apr 30, 2017 10:06 am

Hi Givigy,

I founded a link to the ST Application note AN3998: "PDM audio software decoding on STM32 microcontrollers"
http://www.st.com/content/ccc/resource/ ... 040808.pdf

Regards

pyrog
Posts: 2
Joined: Sun Apr 30, 2017 10:00 am

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Sun Apr 30, 2017 1:39 pm

Hi harshas123,

The Raspberry pi SoC (Broadcom BCM2835…) have a "PDM input".
See https://github.com/raspberrypi/linux/issues/1981

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 12130
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Sun Apr 30, 2017 2:48 pm

Perhaps this helps.

from page 124 of the broadcom BCM2835 ARM peripherals .PDF https://www.raspberrypi.org/documentati ... herals.pdf
8.6 PDM Input Mode Operation
The PDM input mode is capable of interfacing with two digital half-cycle PDM microphones and implements a 4th order CIC decimation filter with a selectable decimation factor. The clock input of the microphones is shared with the PCM output codec and it should be configured to provide the correct clock rate for the microphones. As a result it may be necessary to add a number of padding bits into the PCM output and configure the output codec to allow for this.
When using the PDM input mode the bit width and the rate of the data received will depend on the decimation factor used. Once the data has been read from the peripheral a further decimation and filtering stage will be required and can be implemented in software. The software filter should also correct the droop introduced by the CIC filter stage. Similarly a DC correction stage should also be employed.

vipinv23
Posts: 7
Joined: Sun Dec 09, 2018 5:57 am

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Sun Dec 09, 2018 6:01 am

harshas123 wrote:
Thu Jan 14, 2016 5:17 am
Thank you for your response.

I realize that it may not be possible to acquire a single bit @ 2MHz. But, if I use a 8-bit shift register, then I would have to acquire 8 bits or 1 byte every 2M/8 = 250kHz. A shift register also sends out a logic 1 when the data is ready to be read in parallel. So, can I sample a set of 8 GPIO pins (all at the same time) every time I receive a digital 1 on another GPIO pin (@250kHz ) in python? The idea is better explained in the Block Diagram below:
BlockDiagram.jpg
Hello,
Please may I know which shift register IC to use for this interface?
Also more details of program for this interface

vipinv23
Posts: 7
Joined: Sun Dec 09, 2018 5:57 am

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Mon Dec 10, 2018 5:12 pm

harshas123 wrote:
Thu Jan 14, 2016 5:17 am
Thank you for your response.

I realize that it may not be possible to acquire a single bit @ 2MHz. But, if I use a 8-bit shift register, then I would have to acquire 8 bits or 1 byte every 2M/8 = 250kHz. A shift register also sends out a logic 1 when the data is ready to be read in parallel. So, can I sample a set of 8 GPIO pins (all at the same time) every time I receive a digital 1 on another GPIO pin (@250kHz ) in python? The idea is better explained in the Block Diagram below:
BlockDiagram.jpg
Hello
I am Vipin
Please may I have the shift register IC number

User avatar
mikronauts
Posts: 2717
Joined: Sat Jan 05, 2013 7:28 pm
Contact: Website

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Mon Dec 10, 2018 6:34 pm

I would use a 74hc299 or 74hc595 (google for sample usage)

vipinv23 wrote:
Mon Dec 10, 2018 5:12 pm
harshas123 wrote:
Thu Jan 14, 2016 5:17 am
Thank you for your response.

I realize that it may not be possible to acquire a single bit @ 2MHz. But, if I use a 8-bit shift register, then I would have to acquire 8 bits or 1 byte every 2M/8 = 250kHz. A shift register also sends out a logic 1 when the data is ready to be read in parallel. So, can I sample a set of 8 GPIO pins (all at the same time) every time I receive a digital 1 on another GPIO pin (@250kHz ) in python? The idea is better explained in the Block Diagram below:
BlockDiagram.jpg
Hello
I am Vipin
Please may I have the shift register IC number
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi

vipinv23
Posts: 7
Joined: Sun Dec 09, 2018 5:57 am

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Tue Dec 11, 2018 5:05 pm

mikronauts wrote:
Mon Dec 10, 2018 6:34 pm
I would use a 74hc299 or 74hc595 (google for sample usage)

vipinv23 wrote:
Mon Dec 10, 2018 5:12 pm
harshas123 wrote:
Thu Jan 14, 2016 5:17 am
Thank you for your response.

I realize that it may not be possible to acquire a single bit @ 2MHz. But, if I use a 8-bit shift register, then I would have to acquire 8 bits or 1 byte every 2M/8 = 250kHz. A shift register also sends out a logic 1 when the data is ready to be read in parallel. So, can I sample a set of 8 GPIO pins (all at the same time) every time I receive a digital 1 on another GPIO pin (@250kHz ) in python? The idea is better explained in the Block Diagram below:
BlockDiagram.jpg
Hello
I am Vipin
Please may I have the shift register IC number

Thank you very much for the information.
I have read datasheet of both 74hc299 or 74hc595, but in both I could not find data ready (DR) pin.

After the serial bits are converted to parallel bits, how would I come to know that serial-to-parallel conversion is over and parallel data is ready on output pins?

Reference to DR pin in BlockDiagram.jpg

User avatar
mikronauts
Posts: 2717
Joined: Sat Jan 05, 2013 7:28 pm
Contact: Website

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Tue Dec 11, 2018 5:30 pm

That is because those chips don't have them...

I would use a 4 bit binary counter driven by the shit clock signal, look for a change on q3 (highest bit) which would indicate 8 clock pulses have been seen.

vipinv23 wrote:
Tue Dec 11, 2018 5:05 pm
mikronauts wrote:
Mon Dec 10, 2018 6:34 pm
I would use a 74hc299 or 74hc595 (google for sample usage)

vipinv23 wrote:
Mon Dec 10, 2018 5:12 pm


Hello
I am Vipin
Please may I have the shift register IC number

Thank you very much for the information.
I have read datasheet of both 74hc299 or 74hc595, but in both I could not find data ready (DR) pin.

After the serial bits are converted to parallel bits, how would I come to know that serial-to-parallel conversion is over and parallel data is ready on output pins?

Reference to DR pin in BlockDiagram.jpg
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi

vipinv23
Posts: 7
Joined: Sun Dec 09, 2018 5:57 am

Re: Reading PDM data @ 2MHz with Raspberry Pi + pigpio (Pyth

Wed Dec 12, 2018 5:03 am

HI,
Thanks for response

I shall try 4 bit one

mikronauts wrote:
Tue Dec 11, 2018 5:30 pm
That is because those chips don't have them...

I would use a 4 bit binary counter driven by the shit clock signal, look for a change on q3 (highest bit) which would indicate 8 clock pulses have been seen.

vipinv23 wrote:
Tue Dec 11, 2018 5:05 pm
mikronauts wrote:
Mon Dec 10, 2018 6:34 pm
I would use a 74hc299 or 74hc595 (google for sample usage)



Thank you very much for the information.
I have read datasheet of both 74hc299 or 74hc595, but in both I could not find data ready (DR) pin.

After the serial bits are converted to parallel bits, how would I come to know that serial-to-parallel conversion is over and parallel data is ready on output pins?

Reference to DR pin in BlockDiagram.jpg

Return to “Python”