การกำหนดความถี่และระยะเวลาของคลื่น


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

นี่คือข้อมูลของฉันในรูปแบบที่คั่นด้วยแท็บหากใครต้องการลอง

ขอบคุณสำหรับความช่วยเหลือ! ปัญหานี้ยาก (สำหรับฉัน) แต่ฉันมีช่วงเวลาที่ดี!


แอรอนฉันคิดว่าสิ่งที่ดีที่สุดที่นี่คือให้คุณใส่ลิงค์ไปยังไฟล์ข้อมูลของคุณ (เป็นข้อความหรือบางอย่าง) ในดรอปบ็อกซ์เพื่อให้ฉันสามารถดาวน์โหลดและตอบคำถามได้ มิฉะนั้นจะมีการกลับไปกลับมามากมาย ฉันไม่สามารถหาตัวเลขทางซ้ายสุดได้ :-) (ให้อัตราตัวอย่างด้วย - นั่นคือความถี่ในการอ่านอุณหภูมิ)
Spacey

ขอโทษด้วย ข้อมูลมีอุณหภูมิเป็นองศา C ฉันแปลงเป็นองศา F สำหรับกราฟ มันเป็นข้อมูลที่ถูกต้อง แต่ (เป็นคอลัมน์ "temp")
Aaron Patterson

ปัญหาเกี่ยวกับการวัดความถี่ด้วยวิธีนี้คือถ้าคุณได้รับความแปรปรวนจำนวนมากจากวงจรหนึ่งไปสู่อีกรอบมันจะยากกว่านั้นในการกำหนดความถี่เฉลี่ย - ยอดเขาจะละเลงด้วยกัน (และคำนวณ std dev ฯลฯ ) การใช้วิธีการ FFT จะได้รับการเรียกร้องมากขึ้นหากมีเสียงดังมาก แต่ก็ไม่ได้เป็นเช่นนั้น
Daniel R Hicks

+1 สำหรับการโพสต์โค้ดข้อมูลพล็อตและลิงก์ไปยัง GitHub
nibot

@DanielRHicks ในกรณีนี้โดยเฉพาะฉันไม่คิดว่ามันสำคัญ แต่ใช่ FFT จะให้ค่าเฉลี่ยของพวกเขาทั้งหมดในขณะที่ถ้าเราทำสิ่งที่เป็นศูนย์ข้ามเราจะวัดแต่ละรอบระยะเวลา (ความถี่) และจากนั้นเราสามารถตรวจสอบว่าเราต้องการที่จะใช้ค่าเฉลี่ยมัธยฐานโหมด ฯลฯ จุดที่ดี!
Spacey

คำตอบ:


7

โครงการที่น่าสนใจที่คุณไปที่นั่น! :-)

จากการวิเคราะห์สัญญาณ POV นี่เป็นคำถามง่าย ๆ จริง ๆ และใช่คุณมีสิทธิ์ที่จะใช้ FFT สำหรับปัญหาการประมาณค่าความถี่นี้

real2+imag2

จากนั้นหาค่าสูงสุดของตำแหน่งที่ PSD ตั้งอยู่ ตัวย่อของค่าสูงสุดนั้นจะสอดคล้องกับความถี่ของคุณ

Caveat Emptor ฉันให้มุมมองทั่วไปกับคุณและฉันสงสัยว่าผลลัพธ์ของ FFT ใน R จะเป็นความถี่ปกติซึ่งในกรณีนี้คุณต้องทราบอัตราตัวอย่างของคุณ (ซึ่งคุณทำ) เพื่อที่จะแปลงกลับ เป็น Hz มีรายละเอียดที่สำคัญอื่น ๆ อีกหลายอย่างที่ฉันทิ้งไว้เช่นความละเอียดความถี่ขนาด FFT ของคุณและความจริงที่ว่าคุณอาจต้องการลดความหมายของสัญญาณของคุณก่อน แต่จะเป็นการดีที่จะได้เห็นพล็อตก่อน

แก้ไข:

ให้เราพิจารณาสัญญาณของคุณ หลังจากที่ฉันไม่ได้ตั้งใจมันดูเหมือนว่า:

ป้อนคำอธิบายรูปภาพที่นี่

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 นั่นคือเหตุผลที่ฉันเตือน OP ว่าฉันให้มุมมองทั่วไปและทำไมฉันต้องเห็นพล็อต เหมือนกันฉันได้แก้ไขเพื่อเพิ่มคำเตือนพิเศษ
Spacey

1
@AaronPatterson ไม่มีปัญหาดีใจที่ได้ช่วย สำหรับหนังสือให้ดูที่ Richard Lyons "การทำความเข้าใจกับ DSP" - เป็นหนังสือที่รวดเร็วในการเริ่มต้น
Spacey

1
1.3x105

4

สำหรับรูปแบบของคลื่นที่ราบรื่นและไม่หยุดนิ่งนี้การนับคะแนนตัวอย่างระหว่างการข้ามไปทางบวกของค่าเกณฑ์เฉลี่ยบางค่าจะให้การประมาณระยะเวลาแก่คุณ ดูช่วงเวลาที่ข้ามเกณฑ์หลายช่วงเพื่อรับค่าประมาณโดยเฉลี่ยหรือตรวจสอบแนวโน้มใด ๆ


3

ไม่จำเป็นต้องทำอะไรซับซ้อนเพียงแค่วัดระยะเวลาระหว่างยอดเขาของรูปคลื่น นี่คือช่วงเวลา ความถี่เป็นเพียง 1 หารด้วยระยะเวลา

ด้วยประมาณ 8 รอบต่อ 2 ชั่วโมงความถี่คือ 4 รอบต่อชั่วโมงหรือประมาณ 1 mHz


3
ฉันจะทำสิ่งนี้โดยใช้โปรแกรมได้อย่างไร
Aaron Patterson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.