Zero Crossing của một làn sóng sin ồn ào


9

Tôi đang cố gắng tìm các điểm giao nhau bằng 0 của sóng hình sin để biến sóng hình sin thành sóng vuông. Vấn đề duy nhất là sóng hình sin rất ồn, vì vậy tôi nhận được rất nhiều sự dao động và sai số không.

Bất cứ ai có thể đề nghị bất kỳ psuedocode đơn giản hoặc các tài liệu có liên quan? Cho đến nay tôi có một cái gì đó như thế này:

if (sample[i]>0 && sample[i+1]<0) || (sample[i]<0 && sample[i+1]>0)

Bất cứ ai có thể đề nghị một phương pháp mạnh mẽ hơn?


Mục đích của bạn là cố gắng làm cho nó một sóng vuông là gì? Bạn đang cố gắng tìm ra nơi tín hiệu bắt đầu và kết thúc? Nếu bạn là tôi có thể đề nghị một phương pháp.
Spacey

if ((mẫu [i] * mẫu [i + 1]) <0) zero_crossing ++;
Marius Hrisca

Câu trả lời:


8

Bạn có thể thử lọc tín hiệu đầu vào để có tín hiệu đầu vào mượt mà hơn (hoặc thậm chí lọc băng thông nếu bạn có ý tưởng tốt về vị trí tần số của sóng hình sin). Rủi ro là nếu thông tin pha chính xác mẫu là cần thiết cho ứng dụng của bạn, độ trễ bổ sung từ bộ lọc có thể là một vấn đề.

Một cách tiếp cận khác: thay vì cố gắng biến đổi sóng hình sin thành sóng vuông, vậy còn việc tạo một bộ dao động sóng vuông độc lập để tự điều chỉnh theo pha / tần số với sóng hình sin thì sao? Điều này có thể được thực hiện với một vòng khóa pha .


6

Những gì bạn đã thể hiện chắc chắn là một máy dò chéo. Một vài điều đến với tâm trí có thể cải thiện tình hình của bạn:

  • Nếu bạn có nhiễu nằm ngoài dải tín hiệu của mình (gần như chắc chắn là như vậy, vì đầu vào của bạn là âm thuần), thì bạn có thể cải thiện tỷ lệ tín hiệu trên tạp âm bằng cách áp dụng bộ lọc băng thông xung quanh tín hiệu quan tâm . Độ rộng băng thông của bộ lọc nên được chọn dựa trên mức độ chính xác bạn biết tần số hình sin một tiên nghiệm . Bằng cách giảm lượng tiếng ồn hiện diện trên hình sin, số lần giao nhau bằng 0 sai và độ biến động của chúng về thời gian giao nhau chính xác sẽ giảm.

    • Một lưu ý phụ, nếu bạn không có thông tin tốt trước thời hạn, bạn có thể sử dụng một kỹ thuật phức tạp hơn được gọi là chất tăng cường dòng thích ứng , như tên gọi của nó, là một bộ lọc thích ứng sẽ tăng cường tín hiệu đầu vào định kỳ. Tuy nhiên, đây là một chủ đề hơi tiên tiến và bạn thường có ý tưởng đủ tốt về tần số tín hiệu của mình mà cách tiếp cận này không cần thiết.
  • Đối với chính máy dò không giao nhau, bạn có thể thêm một số độ trễ cho quy trình. Điều này sẽ ngăn chặn việc tạo ra các giao cắt đo lường giả xung quanh giao cắt chính xác ngay lập tức. Thêm độ trễ cho máy dò có thể trông giống như thế này:

    if ((state == POSITIVE) && (sample[i - 1] > -T) && (sample[i] < -T))
    {
        // handle negative zero-crossing
        state = NEGATIVE;
    }
    else if ((state == NEGATIVE) && (sample[i - 1] < T) && (sample[i] > T))
    {
        // handle positive zero-crossing
        state = POSITIVE;
    }
    

    Có hiệu quả, bạn thêm một số trạng thái vào máy dò không chéo của bạn. Nếu bạn tin rằng tín hiệu đầu vào có giá trị dương, bạn yêu cầu tín hiệu đó giảm xuống dưới giá trị ngưỡng đã chọn -Tđể khai báo giao thoa 0 thực. Tương tự như vậy, bạn yêu cầu tín hiệu tăng trở lại trên ngưỡng Tđể tuyên bố rằng tín hiệu đã dao động trở lại dương.

    Bạn có thể chọn các ngưỡng là bất cứ điều gì bạn muốn, nhưng đối với tín hiệu cân bằng như hình sin, sẽ có ý nghĩa khi chúng đối xứng về 0. Cách tiếp cận này có thể giúp cung cấp cho bạn một đầu ra trông gọn gàng hơn, nhưng nó sẽ thêm một chút thời gian trễ do thực tế là bạn đang thực sự đo các ngưỡng giao nhau khác không thay vì giao nhau bằng không.

Như pichenettes đã đề xuất trong câu trả lời của anh ấy, một vòng lặp khóa pha rất có thể là cách tốt nhất để đi, vì PLL thực hiện khá chính xác những gì bạn đang cố gắng thực hiện. Nói tóm lại, bạn chạy một máy phát sóng vuông chạy song song với hình sin đầu vào. PLL thực hiện các phép đo pha định kỳ trên hình sin, sau đó lọc luồng đo lường đó để điều khiển tần số tức thời của máy phát sóng vuông. Tại một thời điểm nào đó, vòng lặp sẽ (hy vọng) sẽ khóa, tại thời điểm đó, sóng vuông phải được khóa theo tần số và pha với hình sin của đầu vào (dĩ nhiên là có một số lỗi, không có gì trong kỹ thuật là hoàn hảo).


Đó có phải là một kích hoạt Schmitt?
Davorin

Thật vậy, bạn có thể nói rằng đó là phiên bản phần mềm của trình kích hoạt Schmitt . Đặc điểm xác định của trình kích hoạt Schmitt là nó là một bộ so sánh với độ trễ
Jason R

Để tránh không phát hiện quá trình chuyển đổi bao gồm trong bất kỳ cả hai điều kiện cũng là ngưỡng T. Ý nghĩa thay vì && (sample[i - 1] > -T) && (sample[i] < -T)), sử dụng && (sample[i - 1] >= -T) && (sample[i] < -T)). Điều này cần phải được áp dụng cho cả hai ifelse ifbáo cáo.
marc

2

Đôi khi tôi có kinh nghiệm với một phương pháp rất đơn giản để tìm thấy các thay đổi dấu hiệu trong tín hiệu:

  1. a = diff (dấu (tín hiệu))! = 0 # điều này phát hiện các thay đổi dấu hiệu
  2. ứng cử viên = lần [a] # đây là tất cả các điểm ứng cử viên, bao gồm cả giao điểm sai
  3. tìm cụm điểm trong thí sinh
  4. trung bình / trung bình mỗi cụm, đây là thay đổi dấu hiệu của bạn

  5. làm tương quan với chức năng bước tại điểm dự đoán bởi 4

  6. đường cong phù hợp với kết quả tương quan và tìm đỉnh

Trong trường hợp của tôi 5 và 6 không làm tăng độ chính xác của phương pháp. Bạn có thể hòa tín hiệu của bạn với nhiễu và xem nếu nó giúp.


2

Tôi biết câu hỏi này khá cũ, nhưng tôi đã phải thực hiện vượt qua gần đây. Tôi thực hiện theo cách Dan đề xuất và khá hài lòng với kết quả. Đây là mã trăn của tôi, nếu có ai quan tâm. Tôi không thực sự là một lập trình viên thanh lịch, xin vui lòng chịu với tôi.

import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle

fig = plt.figure()
ax = fig.add_subplot(111)

sample_time = 0.01
sample_freq = 1/sample_time

# a-priori knowledge of frequency, in this case 1Hz, make target_voltage variable to use as trigger?
target_freq = 1
target_voltage = 0

time = np.arange(0.0, 5.0, 0.01)
data = np.cos(2*np.pi*time)
noise = np.random.normal(0,0.2, len(data))
data = data + noise


line, = ax.plot(time, data, lw=2)

candidates = [] #indizes of candidates (values better?)
for i in range(0, len(data)-1):
    if data[i] < target_voltage and data[i+1] > target_voltage:
        #positive crossing
        candidates.append(time[i])
    elif data[i] > target_voltage and data[i+1] < target_voltage:
        #negative crossing
        candidates.append(time[i])

ax.plot(candidates, np.ones(len(candidates)) * target_voltage, 'rx')
print('candidates: ' + str(candidates))

#group candidates by threshhold
groups = [[]]
time_thresh = target_freq / 8;
group_idx = 0;

for i in range(0, len(candidates)-1):
    if(candidates[i+1] - candidates[i] < time_thresh):
        groups[group_idx].append(candidates[i])
        if i == (len(candidates) - 2):
            # special case for last candidate
            # in this case last candidate belongs to the present group
            groups[group_idx].append(candidates[i+1])
    else:
        groups[group_idx].append(candidates[i])
        groups.append([])
        group_idx = group_idx + 1
        if i == (len(candidates) - 2):
            # special case for last candidate
            # in this case last candidate belongs to the next group
            groups[group_idx].append(candidates[i+1])



cycol = cycle('bgcmk')
for i in range(0, len(groups)):
    for j in range(0, len(groups[i])):
        print('group' + str(i) + ' candidate nr ' + str(j) + ' value: ' + str(groups[i][j]))
    ax.plot(groups[i], np.ones(len(groups[i])) * target_voltage, color=next(cycol), marker='o',  markersize=4)


#determine zero_crosses from groups
zero_crosses = []

for i in range(0, len(groups)):
    group_median = groups[i][0] + ((groups[i][-1] - groups [i][0])/2)
    print('group median: ' + str(group_median))
    #find index that best matches time-vector
    idx = np.argmin(np.abs(time - group_median))
    print('index of timestamp: ' + str(idx))
    zero_crosses.append(time[idx])


#plot zero crosses
ax.plot(zero_crosses, np.ones(len(zero_crosses)) * target_voltage, 'bx', markersize=10) 
plt.show()

Xin lưu ý: mã của tôi không phát hiện các dấu hiệu và sử dụng một ít kiến ​​thức tiên tiến về tần số mục tiêu để xác định ngưỡng thời gian. Ngưỡng này được sử dụng để nhóm nhiều giao thoa (các chấm màu khác nhau trong ảnh) từ đó chọn một điểm gần nhất với các nhóm trung bình được chọn (các dấu chéo màu xanh trong hình).

Sóng hình sin ồn ào với chữ thập không được đánh dấu

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.