Saya mengumpulkan data suhu dari kulkas. Data terlihat seperti gelombang. Saya ingin menentukan periode dan frekuensi gelombang (sehingga saya dapat mengukur apakah modifikasi pada kulkas berpengaruh).
Saya menggunakan R, dan saya pikir saya perlu menggunakan FFT pada data, tapi saya tidak yakin ke mana harus pergi dari sana. Saya sangat baru dalam analisis R dan sinyal, jadi bantuan apa pun akan sangat dihargai!
Inilah gelombang yang saya hasilkan:
Ini kode R saya sejauh ini:
require(graphics)
library(DBI)
library(RSQLite)
drv <- dbDriver("SQLite")
conn <- dbConnect(drv, dbname = "s.sqlite3")
query <- function(con, query) {
rs <- dbSendQuery(con, query)
data <- fetch(rs, n = -1)
dbClearResult(rs)
data
}
box <- query(conn, "
SELECT id,
humidity / 10.0 as humidity,
temp / 10.0 as temp,
ambient_temp / 10.0 as ambient_temp,
ambient_humidity / 10.0 as ambient_humidity,
created_at
FROM measurements ORDER BY id DESC LIMIT 3600
")
box$x <- as.POSIXct(box$created_at, tz = "UTC")
box$x_n <- box$temp - mean(box$temp)
png(filename = "normalized.png", height = 750, width = 1000, bg = "white")
plot(box$x, box$x_n, type="l")
# Pad the de-meaned signal so the length is 10 * 3600
N_fft <- 3600 * 10
padded <- c(box$x_n, seq(0, 0, length= (N_fft - length(box$x_n))))
X_f <- fft(padded)
PSD <- 10 * log10(abs(X_f) ** 2)
png(filename = "PSD.png", height = 750, width = 1000, bg = "white")
plot(PSD, type="line")
zoom <- PSD[1:300]
png(filename = "zoom.png", height = 750, width = 1000, bg = "white")
plot(zoom, type="l")
# Find the index with the highest point on the left half
index <- which(PSD == max(PSD[1:length(PSD) / 2]))
# Mark it in green on the zoomed in graph
abline(v = index, col="green")
f_s <- 0.5 # sample rate in Hz
wave_hz <- index * (f_s / N_fft)
print(1 / (wave_hz * 60))
Saya telah memposting kode R bersama dengan database SQLite di sini .
Berikut ini adalah plot grafik yang dinormalisasi (dengan mean dihapus):
Sejauh ini bagus. Berikut adalah plot kerapatan spektral:
Kemudian kita perbesar di sisi kiri plot dan tandai indeks tertinggi (yaitu 70) dengan garis hijau:
Akhirnya kami menghitung frekuensi gelombang. Gelombang ini sangat lambat, jadi kami mengonversinya menjadi menit per siklus, dan mencetak nilai tersebut yaitu 17.14286.
Berikut adalah data saya dalam format tab terbatas jika ada orang lain yang ingin mencoba.
Terima kasih untuk bantuannya! Masalah ini sulit (untuk saya) tetapi saya bersenang-senang!
Jawaban:
Proyek menarik yang telah Anda lakukan di sana! :-)
Dari analisis sinyal POV, ini sebenarnya adalah pertanyaan sederhana - dan ya, Anda benar bahwa Anda akan menggunakan FFT untuk masalah estimasi frekuensi ini.
Kemudian, dengan sangat sederhana, cari maks tempat duduk PSD Anda. Absis dari maks itu akan sesuai dengan frekuensi Anda.
Caveat Emptor, saya memberi Anda pandangan umum, dan saya menduga hasil FFT dalam R akan dinormalisasi frekuensi, dalam hal ini Anda harus mengetahui laju sampel Anda, (yang Anda lakukan), untuk mengubahnya kembali ke dalam Hz. Ada banyak detail penting lainnya yang saya tinggalkan, seperti resolusi frekuensi Anda, ukuran FFT, dan fakta bahwa Anda mungkin ingin mendefinisikan sinyal Anda terlebih dahulu, tetapi akan lebih baik untuk melihat plot terlebih dahulu.
EDIT:
Biarkan kami memperhitungkan sinyal Anda. Setelah saya maksudkan, itu terlihat seperti ini:
Anda dapat melihat bagaimana simetrisnya. Jika Anda mengabaikan bagian terakhir, dan lihat saja bagian pertama dan memperbesar Anda, dapat melihat ini:
sumber
Untuk bentuk gelombang yang halus dan stasioner ini, menghitung titik sampel antara penyeberangan positif dengan beberapa nilai ambang rata-rata akan memberi Anda perkiraan periode. Lihatlah beberapa periode persimpangan ambang untuk mendapatkan perkiraan yang lebih rata-rata atau mendeteksi tren apa pun.
sumber
Tidak perlu melakukan hal yang rumit: cukup mengukur durasi antara puncak gelombang. Inilah periode. Frekuensi hanya 1 dibagi dengan periode.
Dengan sekitar 8 siklus lebih dari 2 jam, frekuensinya adalah 4 siklus per jam, atau sekitar 1 mHz.
sumber