Machine fault diagnosis via acoustic baseline

Chẩn đoán máy qua baseline âm thanh

Rotating machinery sings in tones. A healthy induction motor produces a fundamental frequency tied to shaft speed, with harmonics stacked at integer multiples above it. Bearings add their own signature once races develop pits or cages loosen. Mounting hardware rattles when bolts fatigue. Trained vibration analysts chase all of this with accelerometers bolted to bearing housings and years of catalogued fault frequencies. Sonarish offers something humbler that still earns its keep: record a spectrum while the machine is known good, store it as a baseline on your phone, and compare later recordings to see which frequency bins grew louder. No audio leaves the device. No cloud service promises magical diagnosis.

The method is acoustic fingerprinting, not full physics simulation. Nobody here solves Newton's equations for a drum assembly. The question is narrower: does today's sound carry more energy at 87 Hz than the baseline captured 18 months ago, back when the washing machine still spun smoothly. A microphone, an FFT, and honest diff math can settle that.

Why machines hum where they do

Start from the nameplate. 600 RPM means the shaft turns f_r = 600/60 = 10 revolutions per second, so the lowest mechanical tone sits near 10 Hz. Simple imbalance pumps exactly that line, once per revolution. Misalignment tends to feed the 2nd harmonic at 20 Hz. Every panel bolted to the frame can resonate at whichever multiple matches its own stiffness, which is why a worn machine sounds like a chord.

Bearings are the interesting part. A rolling-element bearing holds N_b balls between an inner race spinning at shaft speed and a fixed outer race, spaced by a cage. The cage revolves slower than the shaft, because each ball rolls between two surfaces moving at different speeds. Work through the rolling-contact geometry and the cage rate comes out as FTF = (f_r/2)·(1 − (d/D)·cos φ), where d is ball diameter, D is pitch diameter, and φ the contact angle. A pit in the outer race gets struck once per passing ball; the impacts repeat at BPFO = (N_b/2)·f_r·(1 − (d/D)·cos φ). Swap the minus for a plus and you have the inner-race frequency. For a common 8-ball geometry with d/D near 0.2, BPFO lands around 3.2 times shaft speed, and its harmonics climb from there.

These formulas explain the shape of a machine spectrum. Sonarish does not plug numbers into them. It cannot: the app has no idea how many balls your drum bearing carries or what its pitch diameter is, and neither do you, unless you enjoy disassembling washing machines considerably more than I do.

A repeatable workflow in the field

Consistency beats clever algorithms. Place the phone at the same standoff distance every time; 0.5–1 m is typical. Use the same surface if possible; a rubber mat on a metal panel reduces extraneous vibration paths. Record 30–60 s of steady-state operation after the machine has warmed up, never the startup transient, when currents surge and everything is briefly louder. Tag the capture as a baseline with a human-readable machine name. In 18 months, a file called Recording 47 will mean nothing.

We measured what sloppy placement costs. Bench note: 1 phone, 1 workshop compressor, 12 re-placements across one afternoon, position marked with tape on the floor. With the tape mark, per-bin spread below 2 kHz stayed within about ±2 dB. Freehand placement roughly doubled that spread, and a 30 cm distance error alone shifted broadband level by about 3 dB. Half the alarm threshold, spent before the machine changed at all. Tape is cheap.

Months later, repeat the geometry as closely as you can and record again. Everything past that point is arithmetic.

The diff, bin by bin

The analysis chain runs 4096-sample Hann windows on 48 kHz microphone PCM at 50% overlap — twice the window length of the live spectrum view, trading update speed for a true 11.7 Hz resolution, the setup our FFT for mortals post walks through. Bin spacing works out to 48000/4096 ≈ 11.7 Hz. A 60 s capture with a 2048-sample hop yields about 1,400 windows, and averaging each bin across 1,400 windows squeezes the random wobble of the estimate well under 1 dB. The alarm threshold sits at +6 dB. Measurement noise is not what trips it.

Sonarish converts the averaged magnitudes to decibels and subtracts the stored baseline spectrum bin by bin. The diff view highlights sustained rises above about 6 dB. Transient clicks from solenoids or relays can be suppressed with an optional median filter: take the per-bin median across time instead of the mean and a click occupying 3 windows out of 1,400 simply vanishes, so one-off events do not paint false alarms across the spectrum.

// per capture, off the audio thread
S = stft(pcm48k, window = hann(4096), hop = 2048)
for each bin b:
    level[b] = median(|S[:, b]|)      // median beats mean: clicks vanish
    db[b]    = 20·log10(level[b] + eps) + calib_offset

if capture is BASELINE:
    store(machine_name, db, date, device_model)
else:
    base = load(machine_name)
    for each bin b:
        diff[b] = db[b] − base.db[b]  // bin-by-bin subtraction
    flag bins where diff[b] > +6 dB
         and rise spans ≥ 2 adjacent bins   // lone spikes ignored

The 11.7 Hz bins carry one consequence worth naming. A 10 Hz shaft fundamental sits below the first usable bin center and smears into the spectrum's DC shoulder. Low-speed machines are read through their harmonic stacks instead, and those land comfortably inside the resolved range.

Reading a diff without pretending to be an oracle

Suppose a front-loading washer spins at 600 RPM during the extract cycle. 600 revolutions per minute equals 10 revolutions per second, so you expect strong energy near 10 Hz and its harmonics. After a year and a half of service, the diff view might show +12 dB near 87 Hz and at nearby multiples. That frequency may line up with a ball-pass frequency calculation for the drum bearing. It may equally be a loose counterweight. Sonarish does not auto-label the fault. It shows the change clearly enough that you can search bearing frequency formulas, call a technician, or decide the noise is still acceptable.

That restraint is intentional. False confidence destroys trust faster than any raw graph could. We would rather be the instrument you carry down to the basement than the app that confidently mislabels a belt squeal as catastrophic bearing failure.

What we tried and discarded

Version one had an auto-diagnosis table. Feed the strongest diff peaks into a lookup of fault classes and print a verdict: imbalance, misalignment, outer race, inner race. It demoed beautifully on our own bench compressor. On any other machine it needed the bearing geometry from the formulas above, which no user has, so the classifier fell back on generic frequency ratios and produced confident nonsense often enough to scare us. Discarded.

Cepstrum analysis came next. The cepstrum (an FFT of the log spectrum) collapses a whole harmonic family into a single peak and is standard practice in industrial vibration monitoring. It works. It may still ship someday. Every interface draft died at the same spot, though: explaining a quefrency axis to someone standing next to a rattling dryer. Parked.

Full-spectrum level normalization we shipped and then partly removed. Early builds rescaled each new capture so its broadband level matched the baseline before diffing, to forgive distance errors. That also silently erased genuine growth in overall loudness, and for a wearing bearing the overall trend is half the story. Current builds apply the calibration offset, diff honestly, and report the broadband delta as its own number.

Limits you should respect

Microphone saturation ruins everything. Press the phone against a vibrating metal panel and the analog front end clips. The clipped waveform looks louder in the time domain but its spectrum lies — harmonics appear that were never physically present, right in the region where you hunt for bearing tones. Keep the phone at the marked standoff, in air, and re-record any capture that touched full scale.

Low frequencies bring their own trap. Phone microphones are built for voice. Bench note: 5 phones, swept sine from a sealed speaker at 0.5 m, one evening in the lab — every mic was at least 10 dB down by 30 Hz, and two had lost 20 dB. A 10 Hz fundamental is effectively invisible to the hardware, so slow machinery gets diagnosed through the harmonics the mic still passes.

Background room noise changes between sessions when HVAC seasons shift or a door stands open, so check what the room was doing before trusting a small diff. Different phone models have different frequency responses, and comparing a Pixel capture against an iPhone baseline mixes two unknown curves into the result; track a given machine on the same device across the years. For what the level numbers themselves mean, and why the display always says approximate SPL, see A-weighting and decibels explained.

Where this fits in the uranashel stack

Baseline comparison is the feature that turned Sonarish from a party trick decibel meter into something I keep installed next to the fuse panel. It shares FFT parameters with the live spectrum view, uses the same approximate SPL calibration, and stores sessions in the app sandbox, following the on-device architecture the whole studio runs on. No account, no upload, no model trained on your washing machine humming at odd hours. The capture path also obeys the studio's audio rules: nothing allocates on the audio thread, as documented in life on the audio thread, while the heavy averaging runs afterwards, where a slow millisecond costs nobody anything.

If you want to see raw spectra before diffing, Phyzix exposes a live microphone analyzer suitable for classroom demos. The payoff of the whole discipline is boring in the best way. When the diff stays flat for months, you have evidence the repair held. When it creeps upward, you have a timestamped graph to show a technician instead of vague words about “sounding rougher lately.”

Máy quay hát bằng tone. Motor induction khỏe phát một tần cơ bản bám theo tốc trục, hài xếp chồng ở các bội nguyên phía trên. Bạc đạn góp giọng riêng khi race bắt đầu lõm hoặc cage lỏng. Bulong mỏi thì khung kêu lạch cạch. Dân phân tích rung chuyên nghiệp gắn accelerometer lên nhà bạc đạn, tra catalog tần lỗi tích cóp nhiều năm. Sonarish chọn đường khiêm tốn hơn mà vẫn được việc: ghi phổ lúc máy còn chắc chắn tốt, lưu làm baseline ngay trên điện thoại, sau này ghi tiếp rồi so xem bin tần nào to lên. Audio không rời máy. Không cloud nào hứa chẩn đoán thần kỳ ở đây.

Đây là lấy vân tay âm thanh chứ không mô phỏng vật lý đầy đủ. Không ai giải phương trình Newton cho cụm lồng giặt cả. Câu hỏi hẹp hơn nhiều: tiếng hôm nay có nhiều năng lượng ở 87 Hz hơn baseline ghi 18 tháng trước, hồi máy giặt còn quay êm, hay không. Micro, FFT và phép trừ thật thà là đủ để trả lời.

Vì sao máy kêu đúng mấy tần đó

Bắt đầu từ tem máy. 600 RPM nghĩa là trục quay f_r = 600/60 = 10 vòng mỗi giây, tone cơ khí thấp nhất nằm quanh 10 Hz. Mất cân bằng bơm đúng vạch đó, mỗi vòng một lần. Lệch trục hay đổ vào hài bậc 2 ở 20 Hz. Tấm vỏ nào bắt vào khung cũng có thể cộng hưởng ở cái bội hợp với độ cứng riêng của nó. Vậy nên máy mòn nghe như một hợp âm.

Bạc đạn mới là phần hay. Một bạc đạn bi giữ N_b viên bi giữa race trong quay theo trục và race ngoài đứng yên, chia đều nhờ cage. Cage quay chậm hơn trục vì mỗi viên bi lăn giữa hai mặt chạy hai tốc khác nhau. Làm hết phần hình học lăn sẽ ra FTF = (f_r/2)·(1 − (d/D)·cos φ), với d là đường kính bi, D đường kính pitch, φ góc tiếp xúc. Race ngoài mà có vết lõm thì mỗi viên bi đi qua đập một cái; chuỗi va đập lặp ở BPFO = (N_b/2)·f_r·(1 − (d/D)·cos φ). Đổi dấu trừ thành cộng là ra tần race trong. Hình học 8 bi hay gặp với d/D quanh 0,2 cho BPFO cỡ 3,2 lần tốc trục, hài leo dần từ đó.

Mấy công thức này giải thích hình dạng phổ máy. Sonarish không thay số vào. Không thể: app đâu biết bạc đạn lồng giặt của bạn có mấy viên bi hay pitch bao nhiêu. Bạn cũng không biết, trừ khi mê tháo máy giặt hơn mình nhiều.

Quy trình lặp lại được ngoài hiện trường

Nhất quán ăn đứt thuật toán khôn. Mỗi lần đo đặt điện thoại đúng một khoảng cách; 0,5–1 m là tầm hay dùng. Cùng một mặt đặt nếu được; thảm cao su lót trên tấm kim loại cắt bớt đường rung lạc. Ghi 30–60 s lúc máy chạy ổn định, sau khi đã ấm. Đừng ghi đoạn khởi động: dòng điện vọt lên, cái gì cũng to hơn bình thường trong chốc lát. Đặt tên máy dễ đọc cho bản baseline. 18 tháng sau, file tên Recording 47 chẳng nói lên điều gì.

Mình đo thử xem đặt máy cẩu thả tốn bao nhiêu. Ghi chú bench: 1 điện thoại, 1 máy nén khí trong xưởng, 12 lần đặt lại trong một buổi chiều, vị trí dán băng keo đánh dấu trên sàn. Có vạch keo, độ lệch từng bin dưới 2 kHz nằm trong khoảng ±2 dB. Đặt tay không thì lệch gần gấp đôi. Riêng sai 30 cm khoảng cách đã xê mức broadband chừng 3 dB, tức mất nửa ngưỡng cảnh báo trước khi máy kịp thay đổi gì. Băng keo rẻ mà.

Vài tháng sau, lặp lại hình học sát nhất có thể rồi ghi tiếp. Phần còn lại là số học.

Phép trừ, từng bin một

Chuỗi phân tích chạy cửa sổ Hann 4096 sample trên PCM micro 48 kHz, overlap 50% — cửa sổ dài gấp đôi view phổ live, đổi tốc độ cập nhật lấy độ phân giải thật 11,7 Hz — bộ này bài FFT cho người bình thường đã mổ kỹ. Bước bin ra 48000/4096 ≈ 11,7 Hz. Bản ghi 60 s với hop 2048 mẫu cho khoảng 1.400 cửa sổ; trung bình từng bin qua 1.400 cửa sổ ép dao động ngẫu nhiên của ước lượng xuống dưới 1 dB. Ngưỡng cảnh báo là +6 dB. Nhiễu đo không phải thứ kích được nó.

Sonarish đổi biên độ trung bình sang decibel rồi trừ phổ baseline từng bin. View diff tô đậm mức tăng bền vượt khoảng 6 dB. Click thoáng từ solenoid hay relay chặn được bằng median filter tùy chọn: lấy median theo thời gian cho từng bin thay vì mean, một cú click chiếm 3 trên 1.400 cửa sổ coi như biến mất. Sự kiện một lần hết đường vẽ báo động giả lên phổ.

// per capture, off the audio thread
S = stft(pcm48k, window = hann(4096), hop = 2048)
for each bin b:
    level[b] = median(|S[:, b]|)      // median beats mean: clicks vanish
    db[b]    = 20·log10(level[b] + eps) + calib_offset

if capture is BASELINE:
    store(machine_name, db, date, device_model)
else:
    base = load(machine_name)
    for each bin b:
        diff[b] = db[b] − base.db[b]  // bin-by-bin subtraction
    flag bins where diff[b] > +6 dB
         and rise spans ≥ 2 adjacent bins   // lone spikes ignored

Bin 11,7 Hz kéo theo một hệ quả đáng nói. Tần cơ bản 10 Hz nằm dưới tâm bin dùng được đầu tiên, nhòe vào vai DC của phổ. Máy quay chậm vì thế được đọc qua dàn hài — dàn này rơi gọn vào vùng phân giải tốt.

Đọc diff mà không đóng vai thầy bói

Giả sử máy giặt cửa trước vắt ở 600 RPM. 600 vòng mỗi phút là 10 vòng mỗi giây, nên kỳ vọng năng lượng mạnh quanh 10 Hz cùng các hài. Sau một năm rưỡi, diff có thể hiện +12 dB quanh 87 Hz và ở vài bội lân cận. Tần đó có thể khớp phép tính cage bạc đạn cho đường kính lồng. Cũng có thể chỉ là đối trọng đang lỏng dần. Sonarish không tự dán nhãn lỗi. Nó hiện thay đổi đủ rõ để bạn tra công thức tần bạc đạn, gọi thợ hoặc kết luận tiếng đó vẫn chịu được.

Kiềm chế này là cố ý. Tự tin giả tạo phá lòng tin nhanh hơn bất kỳ đồ thị thô nào. Mình thà làm cái dụng cụ bạn xách xuống tầng hầm còn hơn làm cái app dõng dạc gán tiếng rít dây đai thành hỏng bạc đạn thảm khốc.

Những thứ đã thử rồi bỏ

Bản một có bảng tự chẩn đoán. Đưa các đỉnh diff mạnh nhất vào bảng tra lớp lỗi rồi in phán quyết: mất cân bằng, lệch trục, race ngoài, race trong. Demo trên máy nén của studio thì đẹp mê. Sang máy khác, nó cần đúng bộ hình học bạc đạn ở mấy công thức trên, thứ chẳng người dùng nào có, nên classifier tụt về tỉ lệ tần generic rồi phun ra nhảm nhí đầy tự tin. Đủ thường xuyên để cả team sợ. Bỏ.

Kế đến là cepstrum. Cepstrum (FFT của phổ log) gom cả họ hài về một đỉnh duy nhất, là bài bản trong ngành giám sát rung công nghiệp. Nó chạy được. Có ngày sẽ ship. Nhưng mọi bản nháp giao diện đều chết ở cùng một chỗ: giải thích trục quefrency cho người đang đứng cạnh cái máy sấy kêu lạch cạch. Treo lại.

Chuẩn hóa mức toàn phổ thì ship rồi gỡ bớt. Bản đầu scale cả phổ mới cho mức broadband khớp baseline trước khi trừ, để tha lỗi sai khoảng cách. Cách đó cũng lặng lẽ xóa luôn phần to lên thật; với bạc đạn đang mòn, xu hướng tổng là nửa câu chuyện. Bản hiện tại áp offset calibrate, trừ trung thực, còn chênh broadband hiện thành một con số riêng.

Giới hạn phải tôn trọng

Bão hòa micro phá sạch mọi thứ. Ép điện thoại vào tấm kim loại đang rung là front-end analog clip ngay. Dạng sóng clip nhìn to hơn ở miền thời gian nhưng phổ của nó nói dối — mọc ra những hài chưa từng tồn tại vật lý, ngay đúng vùng đang săn tone bạc đạn. Giữ điện thoại lơ lửng đúng khoảng cách đã đánh dấu; bản ghi nào chạm full scale thì bỏ, ghi lại.

Tần thấp có bẫy riêng. Micro điện thoại sinh ra cho giọng nói. Ghi chú bench: 5 điện thoại, quét sine từ loa kín ở 0,5 m, một buổi tối trong lab — máy nào cũng tụt ít nhất 10 dB tại 30 Hz, hai máy tụt tới 20 dB. Tần cơ bản 10 Hz gần như vô hình với phần cứng, nên máy quay chậm phải chẩn qua các hài mà micro còn cho qua.

Ồn nền đổi giữa các session khi HVAC sang mùa hoặc cửa mở hé; trước khi tin một diff nhỏ, nhớ lại xem phòng hôm ghi baseline đang làm gì. Mỗi đời điện thoại một đáp tuyến tần. Đem bản ghi Pixel so baseline iPhone là trộn hai đường cong không ai biết vào kết quả; theo một máy thì bám một thiết bị qua các năm. Còn con số mức nghĩa là gì, vì sao màn hình luôn ghi SPL xấp xỉ — xem A-weighting và decibel.

Chỗ đứng trong stack uranashel

So baseline là tính năng biến Sonarish từ máy đo decibel làm trò vui thành thứ mình giữ cài cạnh tủ điện. Nó dùng chung tham số FFT với view phổ live, chung bộ calibrate SPL xấp xỉ, lưu session trong sandbox của app theo kiến trúc on-device cả studio đang chạy. Không tài khoản, không upload, không model nào train trên tiếng máy giặt ù lúc nửa đêm. Đường capture theo đúng luật audio của studio: không allocate gì trên audio thread, như đã ghi trong sống trên audio thread; phần trung bình nặng chạy sau, chậm một mili giây cũng chẳng ai thiệt.

Muốn xem phổ thô trước khi trừ, Phyzix có analyzer micro live hợp demo lớp học. Phần thưởng của cả quy trình thì nhạt theo kiểu dễ chịu nhất. Diff phẳng nhiều tháng là bằng chứng lần sửa còn giữ. Diff bò dần lên là một đồ thị có timestamp đưa cho thợ, thay cho câu mơ hồ “dạo này nghe gắt hơn”.