Skip to content

Add INMP441 I2S Omnidirectional Microphone #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-x64",
"configurationProvider": "ms-vscode.cmake-tools"
}
],
"version": 4
}
9 changes: 9 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"files.associations": {
"pio.h": "c",
"dreq.h": "c",
"pio_instructions.h": "c",
"type_traits": "cpp",
"i2s_microphone.h": "c"
}
}
24 changes: 15 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.12)

# initialize pico_sdk from GIT
# (note this can come from environment, CMake cache etc)
# set(PICO_SDK_FETCH_FROM_GIT on)
set(ENV{PICO_SDK_PATH} "/home/ttb/raspberry-pi-pico/pico/pico-sdk")

# pico_sdk_import.cmake is a single file copied from this SDK
# note: this must happen before project()
Expand All @@ -14,33 +14,39 @@ project(pico_microphone)
pico_sdk_init()

add_library(pico_pdm_microphone INTERFACE)

target_sources(pico_pdm_microphone INTERFACE
${CMAKE_CURRENT_LIST_DIR}/src/pdm_microphone.c
${CMAKE_CURRENT_LIST_DIR}/src/OpenPDM2PCM/OpenPDMFilter.c
)

target_include_directories(pico_pdm_microphone INTERFACE
${CMAKE_CURRENT_LIST_DIR}/src/include
)

pico_generate_pio_header(pico_pdm_microphone ${CMAKE_CURRENT_LIST_DIR}/src/pdm_microphone.pio)

target_link_libraries(pico_pdm_microphone INTERFACE pico_stdlib hardware_dma hardware_pio)


add_library(pico_analog_microphone INTERFACE)
add_library(pico_i2s_microphone INTERFACE)
target_sources(pico_i2s_microphone INTERFACE
${CMAKE_CURRENT_LIST_DIR}/src/i2s_microphone.c
)
target_include_directories(pico_i2s_microphone INTERFACE
${CMAKE_CURRENT_LIST_DIR}/src/include
examples/usb_microphone
)
target_link_libraries(pico_i2s_microphone INTERFACE pico_stdlib hardware_dma hardware_pio)


add_library(pico_analog_microphone INTERFACE)
target_sources(pico_analog_microphone INTERFACE
${CMAKE_CURRENT_LIST_DIR}/src/analog_microphone.c
)

target_include_directories(pico_analog_microphone INTERFACE
${CMAKE_CURRENT_LIST_DIR}/src/include
)

target_link_libraries(pico_analog_microphone INTERFACE pico_stdlib hardware_adc hardware_dma)

add_subdirectory("examples/hello_analog_microphone")
add_subdirectory("examples/hello_pdm_microphone")
add_subdirectory("examples/hello_analog_microphone")
add_subdirectory("examples/usb_microphone")
add_subdirectory("examples/hello_i2s_microphone")
add_subdirectory("examples/hello_analog_microphone")
104 changes: 66 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,76 +2,104 @@

Capture audio from a microphone on your [Raspberry Pi Pico](https://www.raspberrypi.org/products/raspberry-pi-pico/) or any [RP2040](https://www.raspberrypi.org/products/rp2040/) based board. 🎤


## Hardware

* RP2040 board
* [Raspberry Pi Pico](https://www.raspberrypi.org/products/raspberry-pi-pico/)
* Microphones
* Analog
* [Electret Microphone Amplifier - MAX9814 with Auto Gain Control](https://www.adafruit.com/product/1713)
* PDM
* [Adafruit PDM MEMS Microphone Breakout](https://www.adafruit.com/product/3492)
* RP2040 board

* [Raspberry Pi Pico](https://www.raspberrypi.org/products/raspberry-pi-pico/)

* Microphones

* I2S

* [INMP441 I2S Omnidirectional Microphone](https://hshop.vn/products/cam-bien-am-thanh-inmp441-i2s-omnidirectional-microphone)

* Analog

* [Electret Microphone Amplifier - MAX9814 with Auto Gain Control](https://www.adafruit.com/product/1713)

* PDM

* [Adafruit PDM MEMS Microphone Breakout](https://www.adafruit.com/product/3492)

### Default Pinout

#### I2S Microphone

| Raspberry Pi Pico / RP2040 | Analog Microphone |
| -------------------------- | ----------------- |
| 3.3V | VCC |
| GND | GND |
| GPIO 2 | SCK |
| GPIO 3 | WS |
| GPIO 6 | SD |
| GND | L/R |

#### Analog Microphone

| Raspberry Pi Pico / RP2040 | Analog Microphone |
| -------------------------- | ----------------- |
| 3.3V | VCC |
| GND | GND |
| GPIO 26 | OUT |
| 3.3V | VCC |
| GND | GND |
| GPIO 26 | OUT |

#### PDM Microphone

| Raspberry Pi Pico / RP2040 | PDM Microphone |
| -------------------------- | ----------------- |
| 3.3V | VCC |
| GND | GND |
| GND | SEL |
| GPIO 2 | DAT |
| GPIO 3 | CLK |
| -------------------------- | -------------- |
| 3.3V | VCC |
| GND | GND |
| GND | SEL |
| GPIO 2 | DAT |
| GPIO 3 | CLK |

GPIO pins are configurable in examples or API.

## Examples

See [examples](examples/) folder.
[Git Examples about microphone](https://github.com/dattran-itrvn/microphone-library-for-pico/tree/Binh_Dev)

#### Set up Pico SDK

## Cloning
[Set up the Pico C/C++ SDK](https://datasheets.raspberrypi.org/pico/getting-started-with-pico.pdf)

```sh
git clone https://github.com/ArmDeveloperEcosystem/microphone-library-for-pico.git
```
1. Set `PICO_SDK_PATH`

```sh
export PICO_SDK_PATH=/path/to/pico-sdk
```

## Building
2. Create `build` dir, run `cmake` and `make`:

```
mkdir build
cd build
cmake .. -DPICO_BOARD=pico
make
```

1. [Set up the Pico C/C++ SDK](https://datasheets.raspberrypi.org/pico/getting-started-with-pico.pdf)
2. Set `PICO_SDK_PATH`
```sh
export PICO_SDK_PATH=/path/to/pico-sdk
```
3. Create `build` dir, run `cmake` and `make`:
```
mkdir build
cd build
cmake .. -DPICO_BOARD=pico
make
```
4. Copy example `.uf2` to Pico when in BOOT mode.
3. Copy example `.uf2` to Pico when in BOOT mode.

## License

[Apache-2.0 License](LICENSE)

## Acknowledgements

This project was created on behalf of the [Arm Software Developers](https://developer.arm.com/) team, follow them on Twitter: [@ArmSoftwareDev](https://twitter.com/armsoftwaredev) and YouTube: [Arm Software Developers](https://www.youtube.com/channel/UCHUAckhCfRom2EHDGxwhfOg) for more resources!
##### - Mic Analog or Mic PDM

The [OpenPDM2PCM](https://os.mbed.com/teams/ST/code/X_NUCLEO_CCA02M1//file/53f8b511f2a1/Middlewares/OpenPDM2PCM/) library is used to filter raw PDM data into PCM. The [TinyUSB](https://github.com/hathach/tinyusb) library is used in the `usb_microphone` example.

---

Disclaimer: This is not an official Arm product.
##### - Mic I2S

Get data raw using I2S protocol and using algorithm fill buffer to decode audio.

Buffer App = Buffer Ring / 4 = Buffer DMA / 8.

To record data, using [TinyUSB]([GitHub - hathach/tinyusb: An open source cross-platform USB stack for embedded system](https://github.com/hathach/tinyusb)) library is used in the `usb_microphone` example. Buffer output <= 32 bytes <=> 256 bytes in DMA buffer

Using [Audacity software]([Download | Audacity ®](https://www.audacityteam.org/download/) get audio output

---
19 changes: 19 additions & 0 deletions examples/hello_i2s_microphone/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.12)

# rest of your project
add_executable(hello_i2s_microphone
main.c
usb_descriptors.c
usb_microphone.c
)

target_include_directories(hello_i2s_microphone PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(hello_i2s_microphone PRIVATE tinyusb_device tinyusb_board pico_i2s_microphone)

# enable usb output, disable uart output
# pico_enable_stdio_usb(hello_i2s_microphone 1)
pico_enable_stdio_uart(hello_i2s_microphone 1)

# create map/bin/hex/uf2 file in addition to ELF.
pico_add_extra_outputs(hello_i2s_microphone)
61 changes: 61 additions & 0 deletions examples/hello_i2s_microphone/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "stdio.h"
#include "tusb.h"
#include "pico/stdlib.h"
#include "pico/i2s_microphone.h"
#include "usb_microphone.h"


#define SCK 2
#define WS 3 // needs to be SCK +1
#define SD 6
#define BPS 16
#define RATE 16000
#define BUTTON 15
#define SIZE_APP_BUFFER (SIZEOF_DMA_BUFFER_IN_BYTES/8)

uint32_t countByte = 0;
uint32_t byteReads = 0;
int16_t sample_buffer[SIZE_APP_BUFFER/2];
machine_i2s_obj_t* i2s0;
uint8_t id_i2s = 0;

//// Callback function I2S /////
void on_i2s_samples_ready(){
byteReads = machine_i2s_stream_read(i2s0, (void*)&sample_buffer, SIZE_APP_BUFFER); // app buffer len <= dma buffer len / 8
}

// Callback function USB //
void on_usb_microphone_tx_ready(){
usb_microphone_write(sample_buffer, sizeof(sample_buffer));
}

void init(){
stdio_init_all();
gpio_init(BUTTON);
gpio_set_dir(BUTTON, GPIO_IN);
gpio_pull_up(BUTTON);
}

int main(){
init();
printf("START RECORD\r\n");
printf("\r\n");
printf("----- START DATA -----\r\n");
sleep_ms(500);

i2s0 = machine_i2s_make_new(id_i2s, SCK, WS, SD,
RX, BPS, MONO,
SIZEOF_DMA_BUFFER_IN_BYTES, // set ring buffer len >= dma buffer len
RATE);

i2s_microphone_set_samples_ready(on_i2s_samples_ready, id_i2s);

usb_microphone_init();
usb_microphone_set_tx_ready_handler(on_usb_microphone_tx_ready);

while (1){
usb_microphone_task();
}

return 0;
}
Loading