Ich weiß, dass diese Frage ziemlich alt ist, aber ich musste kürzlich den Nulldurchgang implementieren. Ich habe die von Dan vorgeschlagene Art umgesetzt und bin ziemlich zufrieden mit dem Ergebnis. Hier ist mein Python-Code, wenn jemand interessiert ist. Ich bin nicht wirklich ein eleganter Programmierer, bitte tragen Sie mit mir.
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()
Bitte beachten Sie: Mein Code erkennt keine Anzeichen und verwendet ein wenig a priori Kenntnis einer Zielfrequenz, um die Zeitschwelle zu bestimmen. Dieser Schwellenwert wird verwendet, um die Mehrfachkreuzung (verschiedene Farbpunkte im Bild) zu gruppieren, aus der diejenige ausgewählt wird, die dem Gruppenmedian am nächsten liegt (blaue Kreuze im Bild).