确定波的频率和周期


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。

如果有人要尝试,这是制表符分隔格式的我的数据

谢谢您的帮助!这个问题对我来说很难,但是我过得很愉快!


Aaron,我认为最好的办法是将您指向数据文件的链接(文本或其他内容)放置在保管箱上,以便我下载该文件并给您答案。否则,将会有很多来回的事情。我无法找出最左端的数字。:-)(也可以给您采样率-也就是说,您多久获取一次温度读数)。
Spacey 2012年

啊对不起 数据包含以摄氏度为单位的温度,我将该图转换为华氏度。不过,它是正确的数据(它是“ temp”列)。
亚伦·帕特森

以这种方式测量频率的问题在于,如果每个周期之间存在很大的可变性,那么确定平均频率将变得更加困难-峰值会相互混淆-而仅计算两次偏移之间的时间可以使您很好地平均(以及计算std dev等)。如果存在很多噪声,则更需要使用FFT方法,但在这里似乎并非如此。
Daniel R Hicks,2012年

+1用于发布,代码,数据,图解以及指向github的链接。
nibot 2012年

@DanielRHicks在这种特殊情况下,我认为这并不重要,但是是的,FFT将为您提供所有参数的平均值,而如果我们做过零的操作,我们将测量每个周期的持续时间(频率),然后我们可以确定我们是否要取均值,中位数,众数等。
Spacey 2012年

Answers:


7

您正在进行的有趣项目!:-)

从信号分析POV来看,这实际上是一个简单的问题-是的,您是正确的,您可以将FFT用于此频率估计问题。

[RË一种2+一世一种G2

然后,非常简单地找到PSD的最大位置。该最大值的横坐标将与您的频率相对应。

请注意,请给我一个大致的看法,我怀疑R中FFT的结果将是归一化频率,在这种情况下,您必须知道采样率(要这样做)才能将其转换回到Hz。我还有许多其他重要的细节,例如您的频率分辨率,FFT大小以及您可能想先去除信号平均值的事实,但是最好先查看图表。

编辑:

让我们考虑您的信号。在我删除它之后,它看起来像这样:

在此处输入图片说明

X[ñ]

ñFFŤ=103600=36000。

Fs=0.5Hž

X[ñ]XF10ØG10|XF|2

在此处输入图片说明

您可以看到它是如何对称的。如果您忽略后半部分,而只是看着前半部分并放大,则可以看到以下内容:

在此处输入图片说明

FsñFFŤ=1.3889Ë-005Hž01.3889Ë-005=0Hž1个1.3889Ë-005=1.3889Ë-005Hž701.3889Ë-005=9.7222Ë-004Hž

1个9.7222Ë-00460=17.14


@AaronPatterson我已经编辑了帖子,请参阅。另外,您可以将图片直接添加到原始帖子中。:-)。请添加您获得的PSD结果的图像。
Spacey 2012年

1
如果频率原来在FFT结果块之间,则不完全正确。
hotpaw2

@ hotpaw2这就是为什么我警告OP我要给出总体前景,以及为什么我需要查看情节的原因。都一样,我进行了编辑以添加额外的警告。
Spacey 2012年

1
@AaronPatterson没问题,很乐意提供帮助。至于书籍,请看Richard Lyons的“ Understanding DSP”-这是一本入门的快速书。
Spacey

1
1.3X10-5

4

对于这种平稳的波形,在某个平均阈值的正向交叉点之间计数采样点将为您提供周期估计。查看几个阈值穿越期,以获得更平均的估计或检测任何趋势。


3

无需做任何复杂的事情:只需测量波形峰值之间的持续时间即可。这是时期。频率仅为1除以周期。

在2小时内大约有8个周期,频率是每小时4个周期,或大约1 mHz。


3
如何以编程方式执行此操作?
亚伦·帕特森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.