Определение частоты и периода волны


11

Я собираю данные о температуре из холодильника. Данные выглядят как волна. Я хотел бы определить период и частоту волны (чтобы я мог измерить, если модификации холодильника имеют какой-либо эффект).

Я использую R, и я думаю, что мне нужно использовать FFT для данных, но я не уверен, куда идти дальше. Я очень плохо знаком с R и анализом сигналов, поэтому любая помощь будет принята с благодарностью!

Вот волна, которую я создаю:

Моя волна

Вот мой код R до сих пор:

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))

Я разместил код R вместе с базой данных SQLite здесь .

Вот график нормализованного графа (с удаленным средним):

нормализованный график

Все идет нормально. Вот график спектральной плотности:

спектральная плотность

Затем мы увеличиваем левую часть графика и отмечаем самый высокий индекс (который равен 70) зеленой линией:

увеличить спектральный график

Наконец мы рассчитываем частоту волны. Эта волна очень медленная, поэтому мы конвертируем ее в минуты за цикл и выводим значение, которое равно 17.14286.

Вот мои данные в формате с разделителями табуляции, если кто-то еще хочет попробовать.

Спасибо за помощь! Эта проблема была трудной (для меня), но я прекрасно провел время!


Аарон, я думаю, что лучше всего, чтобы ты поместил ссылку на свой файл данных (в виде текста или чего-то еще) в раскрывающемся списке, чтобы я мог скачать его и дать тебе ответ. В противном случае будет много движения вперед и назад. Я не могу разобрать цифры на дальнем левом конце. :-) (Также укажите частоту дискретизации - то есть как часто вы измеряете температуру).
Спейси

Ах, прости. Данные содержат температуру в градусах C, я пересчитал в градусы F для графика. Хотя это правильные данные (это столбец «temp»).
Аарон Паттерсон

Проблема с измерением частоты таким образом заключается в том, что если вы получаете значительную изменчивость от цикла к циклу, тогда будет гораздо сложнее определить среднюю частоту - пики будут смазываться вместе - тогда как простой подсчет времени между экскурсиями позволит вам хорошо усреднять вещи (а также вычислить стандартное отклонение и т. д.). Использование подхода FFT было бы более востребованным, если бы было много шума, но здесь это не так.
Даниэль Р Хикс

+1 за размещение, код, данные, графики и ссылку на github.
nibot

@DanielRHicks В данном конкретном случае я не думаю, что это имеет значение, но да, БПФ даст вам среднее значение всех из них, тогда как если бы мы сделали что-то вроде пересечения нуля, мы бы измерили продолжительность каждого цикла (частоту), и тогда мы можем определить, хотим ли мы взять среднее значение, медиану, моду и т. д. Хороший вопрос!
Спейси

Ответы:


7

Интересный проект у вас там происходит! :-)

С точки зрения анализа сигналов это на самом деле простой вопрос - и да, вы правы, что вы использовали бы БПФ для этой задачи оценки частоты.

real2+imag2

Тогда, очень просто, найдите максимум того, где находится ваш PSD. Абсцисса этого максимума будет соответствовать вашей частоте.

Будьте бдительны, я даю вам общий обзор, и я подозреваю, что результатом БПФ в R будет нормализованная частота, и в этом случае вам придется знать частоту дискретизации (что вы делаете), чтобы преобразовать ее обратно. в Гц. Есть много других важных деталей, которые я пропускаю, таких как разрешение по частоте, размер БПФ, и тот факт, что вы, вероятно, хотите сначала деинформировать свой сигнал, но сначала будет полезно увидеть график.

РЕДАКТИРОВАТЬ:

Позвольте нам принять ваш сигнал во внимание. После того, как я обманываю это, это выглядит так:

введите описание изображения здесь

x[n]

Nfft=103600=36000.

fs=0.5Hz

x[n]X(f)10log10(|X(f)|2)

введите описание изображения здесь

Вы можете видеть, как это симметрично. Если вы игнорируете последнюю половину и просто смотрите на первую половину и увеличиваете масштаб, вы можете увидеть это:

введите описание изображения здесь

FsNfft=1.3889e005Hz01.3889e005=0Hz11.3889e005=1.3889e005Hz701.3889e005=9.7222e004Hz

1(9.7222e004)60=17.14


@AaronPatterson Я редактировал пост, пожалуйста, смотрите. Кроме того, вы можете добавить свои фотографии прямо в исходное сообщение. :-). Пожалуйста, добавьте изображение результата PSD, которое вы получите.
Spacey

1
Не совсем верно, если частота оказывается между бинами результатов FFT.
hotpaw2

@ hotpaw2 Вот почему я предупредил ОП, что я даю общий взгляд и почему мне нужно увидеть сюжет. Все же я отредактировал, чтобы добавить дополнительные предостережения.
Спейси

1
@AaronPatterson Без проблем, рад помочь. Что касается книг, взгляните на Ричарда Лайонса «Понимание DSP» - это книга-фастфуд, с которой можно начать.
Spacey

1
1.3x105

4

Для сигнала, такого плавного и стационарного, подсчет точек выборки между положительными проходящими пересечениями некоторого среднего порогового значения даст оценку периода. Посмотрите на несколько периодов пересечения порогов, чтобы получить более среднюю оценку или обнаружить любую тенденцию.


3

Нет необходимости делать что-либо сложное: просто измерьте длительность между пиками формы сигнала. Это период. Частота всего 1, деленная на период.

При примерно 8 циклах в течение 2 часов частота составляет 4 цикла в час или около 1 МГц.


3
Как я могу сделать это программно?
Аарон Паттерсон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.