Skip to content

Commit e4ad3bd

Browse files
committed
fix PDM examples, use hard FPU with ambiq library, update example 4 with supporting files, update name of isr
1 parent 783c646 commit e4ad3bd

File tree

8 files changed

+312
-78
lines changed

8 files changed

+312
-78
lines changed

libraries/PDM/examples/Example2_ConfigureMic/Example2_ConfigureMic.ino

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ void setup()
3636

3737
// The variant files for Artemis carrier boards have Mic data and clock pins defined
3838
// but these pins can be passed to the the .begin function
39-
//if (myPDM.begin() == false) //Use Data, clock defines from variant file
40-
if (myPDM.begin(22, 23) == false) //Data, clock on Artemis Nano - These are the pin names from variant file, not pad names
39+
if (myPDM.begin() == false) //Use Data, clock defines from variant file
40+
//if (myPDM.begin(22, 23) == false) //Data, clock on Artemis Nano - These are the pin names from variant file, not pad names
4141
{
4242
Serial.println("PDM Init failed. Are you sure these pins are PDM capable?");
4343
while (1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/python
2+
from __future__ import division
3+
4+
"""
5+
Author: Justice Amoh
6+
Date: 11/01/2019
7+
Description: Python script to stream audio from Artemis Apollo3 PDM microphone
8+
"""
9+
import sys
10+
import serial
11+
import numpy as np
12+
import matplotlib.pyplot as plt
13+
14+
from serial.tools import list_ports
15+
from time import sleep
16+
from scipy.io import wavfile
17+
from datetime import datetime
18+
19+
20+
# Controls
21+
do_plot = True
22+
do_save = True
23+
wavname = 'recording_%s.wav'%(datetime.now().strftime("%m%d_%H%M"))
24+
runtime = 50#100 # runtime in frames, sec/10
25+
26+
# Find Artemis Serial Port
27+
ports = list_ports.comports()
28+
try:
29+
sPort = [p[0] for p in ports if 'cu.wchusbserial' in p[0]][0]
30+
except Exception as e:
31+
print 'Cannot find serial port!'
32+
sys.exit(3)
33+
34+
# Serial Config
35+
ser = serial.Serial(sPort,115200)
36+
ser.reset_input_buffer()
37+
ser.reset_output_buffer()
38+
39+
40+
# Audio Format & Datatype
41+
dtype = np.int16 # Data type to read data
42+
typelen = np.dtype(dtype).itemsize # Length of data type
43+
maxval = 32768. # 2**15 # For 16bit signed
44+
45+
# Plot Parameters
46+
delay = .00001 # Use 1us pauses - as in matlab
47+
fsamp = 16000 # Sampling rate
48+
nframes = 10 # No. of frames to read at a time
49+
buflen = fsamp//10 # Buffer length
50+
bufsize = buflen*typelen # Resulting number of bytes to read
51+
window = fsamp*10 # window of signal to plot at a time in samples
52+
53+
54+
# Variables
55+
x = [0]*window
56+
t = np.arange(window)/fsamp # [x/fsamp for x in range(10)]
57+
58+
#---------------
59+
# Plot & Figures
60+
#---------------
61+
plt.ion()
62+
plt.show()
63+
64+
65+
# Configure Figure
66+
with plt.style.context(('dark_background')):
67+
fig,axs = plt.subplots(1,1,figsize=(7,2.5))
68+
69+
lw, = axs.plot(t,x,'r')
70+
axs.set_xlim(0,window/fsamp)
71+
axs.grid(which='major', alpha=0.2)
72+
axs.set_ylim(-1,1)
73+
axs.set_xlabel('Time (s)')
74+
axs.set_ylabel('Amplitude')
75+
axs.set_title('Streaming Audio')
76+
plt.tight_layout()
77+
plt.pause(0.001)
78+
79+
80+
81+
# Start Transmission
82+
ser.write('START') # Send Start command
83+
sleep(1)
84+
85+
for i in range(runtime):
86+
buf = ser.read(bufsize) # Read audio data
87+
buf = np.frombuffer(buf,dtype=dtype) # Convert to int16
88+
buf = buf/maxval # convert to float
89+
x.extend(buf) # Append to waveform array
90+
91+
# Update Plot lines
92+
lw.set_ydata(x[-window:])
93+
94+
plt.pause(0.001)
95+
sleep(delay)
96+
97+
98+
# Stop Streaming
99+
ser.write('STOP')
100+
sleep(0.5)
101+
ser.reset_input_buffer()
102+
ser.reset_output_buffer()
103+
ser.close()
104+
105+
# Remove initial zeros
106+
x = x[window:]
107+
108+
109+
# Helper Functions
110+
def plotAll():
111+
t = np.arange(len(x))/fsamp
112+
with plt.style.context(('dark_background')):
113+
fig,axs = plt.subplots(1,1,figsize=(7,2.5))
114+
lw, = axs.plot(t,x,'r')
115+
axs.grid(which='major', alpha=0.2)
116+
axs.set_xlim(0,t[-1])
117+
plt.tight_layout()
118+
return
119+
120+
# Plot All
121+
if do_plot:
122+
plt.close(fig)
123+
plotAll()
124+
125+
# Save Recorded Audio
126+
if do_save:
127+
wavfile.write(wavname,fsamp,np.array(x))
128+
print "Recording saved to file: %s"%wavname
129+
130+
131+
132+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#!/usr/bin/python
2+
3+
4+
"""
5+
Author: Justice Amoh
6+
Date: 11/01/2019
7+
Description: Python script to stream audio from Artemis Apollo3 PDM microphone
8+
"""
9+
import sys
10+
import serial
11+
import numpy as np
12+
import matplotlib.pyplot as plt
13+
14+
from serial.tools import list_ports
15+
from time import sleep
16+
from scipy.io import wavfile
17+
from datetime import datetime
18+
19+
20+
# Controls
21+
do_plot = True
22+
do_save = True
23+
wavname = 'recording_%s.wav' % (datetime.now().strftime("%m%d_%H%M"))
24+
runtime = 50 # 100 # runtime in frames, sec/10
25+
26+
# Auto port assignment for Mac/Linux machines
27+
# try:
28+
# sPort = [p[0] for p in ports if 'cu.wchusbserial' in p[0]][0]
29+
# except Exception as e:
30+
# print('Cannot find serial port!')
31+
# sys.exit(3)
32+
33+
# Manual port assignment for windows machines
34+
sPort = "COM16"
35+
36+
# Serial Config
37+
ser = serial.Serial(sPort, 500000)
38+
ser.reset_input_buffer()
39+
ser.reset_output_buffer()
40+
41+
42+
# Audio Format & Datatype
43+
dtype = np.int16 # Data type to read data
44+
typelen = np.dtype(dtype).itemsize # Length of data type
45+
maxval = 32768. # 2**15 # For 16bit signed
46+
47+
# Plot Parameters
48+
delay = .00001 # Use 1us pauses - as in matlab
49+
fsamp = 16000 # Sampling rate
50+
nframes = 10 # No. of frames to read at a time
51+
buflen = fsamp//10 # Buffer length
52+
bufsize = buflen*typelen # Resulting number of bytes to read
53+
window = fsamp*10 # window of signal to plot at a time in samples
54+
55+
56+
# Variables
57+
x = [0]*window
58+
t = np.arange(window)/fsamp # [x/fsamp for x in range(10)]
59+
60+
# ---------------
61+
# Plot & Figures
62+
# ---------------
63+
plt.ion()
64+
plt.show()
65+
66+
67+
# Configure Figure
68+
with plt.style.context(('dark_background')):
69+
fig, axs = plt.subplots(1, 1, figsize=(7, 2.5))
70+
71+
lw, = axs.plot(t, x, 'r')
72+
axs.set_xlim(0, window/fsamp)
73+
axs.grid(which='major', alpha=0.2)
74+
axs.set_ylim(-1, 1)
75+
axs.set_xlabel('Time (s)')
76+
axs.set_ylabel('Amplitude')
77+
axs.set_title('Streaming Audio')
78+
plt.tight_layout()
79+
plt.pause(0.001)
80+
81+
82+
# Start Transmission
83+
ser.write('START'.encode()) # Send Start command
84+
sleep(1)
85+
86+
for i in range(runtime):
87+
buf = ser.read(bufsize) # Read audio data
88+
buf = np.frombuffer(buf, dtype=dtype) # Convert to int16
89+
buf = buf/maxval # convert to float
90+
x.extend(buf) # Append to waveform array
91+
92+
# Update Plot lines
93+
lw.set_ydata(x[-window:])
94+
95+
plt.pause(0.001)
96+
sleep(delay)
97+
98+
99+
# Stop Streaming
100+
ser.write('STOP'.encode())
101+
sleep(0.5)
102+
ser.reset_input_buffer()
103+
ser.reset_output_buffer()
104+
ser.close()
105+
106+
# Remove initial zeros
107+
x = x[window:]
108+
109+
110+
# Helper Functions
111+
def plotAll():
112+
t = np.arange(len(x))/fsamp
113+
with plt.style.context(('dark_background')):
114+
fig, axs = plt.subplots(1, 1, figsize=(7, 2.5))
115+
lw, = axs.plot(t, x, 'r')
116+
axs.grid(which='major', alpha=0.2)
117+
axs.set_xlim(0, t[-1])
118+
plt.tight_layout()
119+
return
120+
121+
122+
# Plot All
123+
if do_plot:
124+
plt.close(fig)
125+
plotAll()
126+
127+
# Save Recorded Audio
128+
if do_save:
129+
wavfile.write(wavname, fsamp, np.array(x))
130+
print("Recording saved to file: %s" % wavname)
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Author: @justiceamoh and Nathan Seidle
2+
Created: November 19th, 2019
3+
License: MIT. See SparkFun Arduino Apollo3 Project for more information
4+
5+
This example demonstrates how to read audio data and output it to a WAV file. A sketch reads PDM data and outputs raw serial, and the ConverToWav python script (python versions 2 and 3 are both available) visualizes and coverts the serial data to a WAV file.
6+
7+
Gotchas:
8+
9+
* You will need to modify the python script to match the COM port used on your computer. For Windows based machines find the
10+
* You may need to use VLC to play the WAV clips. The bitrate is 256kbps which is higher than some audio players can handle.
11+
* Audio samples are generated fast enough that we need to output serial at 500kbps.

0 commit comments

Comments
 (0)