Difference between revisions of "Equipment Sound Analysis"
(→Test1) |
|||
(2 intermediate revisions by the same user not shown) | |||
Line 20: | Line 20: | ||
*https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | *https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | ||
*https://makersportal.com/blog/2019/2/26/raspberry-pi-vibration-analysis-experiment-with-free-free-bar | *https://makersportal.com/blog/2019/2/26/raspberry-pi-vibration-analysis-experiment-with-free-free-bar | ||
*https://stackoverflow.com/questions/36250228/read-frequency-from-mic-on-raspberry-pi | |||
== Test1 == | |||
<pre> | |||
from __future__ import print_function, division | |||
import wave | |||
import numpy as np | |||
import matplotlib.pyplot as plt | |||
wr = wave.open('input.wav', 'r') | |||
sz = wr.getframerate() | |||
q = 5 # time window to analyze in seconds | |||
c = 12 # number of time windows to process | |||
sf = 1.5 # signal scale factor | |||
for num in range(c): | |||
print('Processing from {} to {} s'.format(num*q, (num+1)*q)) | |||
avgf = np.zeros(int(sz/2+1)) | |||
snd = np.array([]) | |||
# The sound signal for q seconds is concatenated. The fft over that | |||
# period is averaged to average out noise. | |||
for j in range(q): | |||
da = np.fromstring(wr.readframes(sz), dtype=np.int16) | |||
left, right = da[0::2]*sf, da[1::2]*sf | |||
lf, rf = abs(np.fft.rfft(left)), abs(np.fft.rfft(right)) | |||
snd = np.concatenate((snd, (left+right)/2)) | |||
avgf += (lf+rf)/2 | |||
avgf /= q | |||
# Plot both the signal and frequencies. | |||
plt.figure(1) | |||
a = plt.subplot(211) # signal | |||
r = 2**16/2 | |||
a.set_ylim([-r, r]) | |||
a.set_xlabel('time [s]') | |||
a.set_ylabel('signal [-]') | |||
x = np.arange(44100*q)/44100 | |||
plt.plot(x, snd) | |||
b = plt.subplot(212) # frequencies | |||
b.set_xscale('log') | |||
b.set_xlabel('frequency [Hz]') | |||
b.set_ylabel('|amplitude|') | |||
plt.plot(abs(avgf)) | |||
plt.savefig('simple{:02d}.png'.format(num)) | |||
plt.clf() | |||
</pre> | |||
<pre> | |||
sudo apt-get update | |||
sudo apt-get install python3-pip | |||
pip3 install numpy | |||
pip3 install wave | |||
pip3 install matplotlib | |||
</pre> | |||
[[Category:Functions]] | [[Category:Functions]] |
Latest revision as of 23:22, 28 May 2022
Take a simple USB microphone, feed the sounds of plantroom equipment into machine learning (Tensorflow) to identify problems at an early stage.
Many equipment failures are preceded by some form of mechanical change that can be detected by the sound they make.
Equipment starts, such as boiler firing sequences, follow patterns that can be listened to and an alarm raised if something sounds different to normal.
This is mainly a task of training. As a machine is fed more and more examples, and trained on what sounds are, it becomes better at detecting the problems.
Sounds are fairly easy to analyse when broken down into a series of frequency bands, just as on any stereo graphic equaliser.
High frequencies often indicate metal-metal contact in rotating equipment such as pumps.
Flow rates through pipes generate noise relative to velocity (flow rate).
Microphones are cheap. https://www.amazon.co.uk/s?k=USB+directional+Microphone
- https://github.com/bartbutenaers/node-red-contrib-audio-analyser
- https://pimylifeup.com/raspberrypi-microphone/
- https://flows.nodered.org/node/node-red-contrib-mic
- https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API
- https://makersportal.com/blog/2019/2/26/raspberry-pi-vibration-analysis-experiment-with-free-free-bar
- https://stackoverflow.com/questions/36250228/read-frequency-from-mic-on-raspberry-pi
Test1
from __future__ import print_function, division import wave import numpy as np import matplotlib.pyplot as plt wr = wave.open('input.wav', 'r') sz = wr.getframerate() q = 5 # time window to analyze in seconds c = 12 # number of time windows to process sf = 1.5 # signal scale factor for num in range(c): print('Processing from {} to {} s'.format(num*q, (num+1)*q)) avgf = np.zeros(int(sz/2+1)) snd = np.array([]) # The sound signal for q seconds is concatenated. The fft over that # period is averaged to average out noise. for j in range(q): da = np.fromstring(wr.readframes(sz), dtype=np.int16) left, right = da[0::2]*sf, da[1::2]*sf lf, rf = abs(np.fft.rfft(left)), abs(np.fft.rfft(right)) snd = np.concatenate((snd, (left+right)/2)) avgf += (lf+rf)/2 avgf /= q # Plot both the signal and frequencies. plt.figure(1) a = plt.subplot(211) # signal r = 2**16/2 a.set_ylim([-r, r]) a.set_xlabel('time [s]') a.set_ylabel('signal [-]') x = np.arange(44100*q)/44100 plt.plot(x, snd) b = plt.subplot(212) # frequencies b.set_xscale('log') b.set_xlabel('frequency [Hz]') b.set_ylabel('|amplitude|') plt.plot(abs(avgf)) plt.savefig('simple{:02d}.png'.format(num)) plt.clf()
sudo apt-get update sudo apt-get install python3-pip pip3 install numpy pip3 install wave pip3 install matplotlib