#!/usr/bin/python3
# ====================================================================
# test sgn function and square wave
# https://en.wikipedia.org/wiki/Square_wave
# ====================================================================
import math
import matplotlib.pyplot as plt
# --------------------------------------------------------------------
# ---- class - square wave object
# ---- t0 start (time +/- ? if random)
# ---- hz frequency (hertz) (cycles/second)
# ---- ran randomize start time
# --------------------------------------------------------------------
class squareWave:
def __init__(self,t0,hz):
self.t0 = t0
self.hz = hz
# ---- return wave's size/value/magnitude/strength at
# ---- time t (seconds since t0)
def value(self,t):
freq = self.hz
rad = 2.0*math.pi*freq*t
v = sgn(math.sin(rad))
return v
# -------------------------------------------------------------------
# ---- float range generator (start and end inclusive)
# -------------------------------------------------------------------
def frange(start,end,steps):
step = abs((end-start)/(steps))
f = start
while True:
yield(f)
if f is not None: f += step
if f > end: f = None
# --------------------------------------------------------------------
# ---- my sign function
# --------------------------------------------------------------------
def sgn(x):
if x > 0: return 1
if x == 0: return 0
return -1
# --------------------------------------------------------------------
# ---- calculate/generate a list of values
# ----
# ---- tlst is a list of sample times within the sample
# ---- range. Every wave function should use the same tlst.
# ---- Sample times are monotonically increasing from sample
# ---- start time to sample end time (inclusive).
# --------------------------------------------------------------------
def calculate_wave_values(tlst,wave):
slst = []
for t in tlst:
s = wave.value(t)
slst.append(s)
return slst
# --------------------------------------------------------------------
# ---- create a list of sample times
# ---- based on the sample start and end time, and the sample size
# ---- Note: the time list is a monotonic increasing list
# --------------------------------------------------------------------
def time_list(sstart,send,ssize):
tlst = []
for t in frange(sstart,send,ssize):
if t is None: break # end of range?
tlst.append(t)
return tlst
# --------------------------------------------------------------------
# ---- main
# --------------------------------------------------------------------
if __name__ == '__main__':
# ---- required: t0 < tstart < tend
hz = 1.0 # wave frequency (hertz) (cycles/second)
t0 = 0.0 # wave start time (second)
sstart = 0.0 # sample start time (second)
send = 2.0 # sample end time (second)
ssize = 1000 # sample size
print(f't0 = {t0}')
print(f'hz = {hz}')
print(f'sstart = {sstart}')
print(f'send = {send}')
print(f'ssize = {ssize}')
# ---- get a list of sample time values
tlst = time_list(sstart,send,ssize)
# ---- get a list of value samples for each time in tlst
square_wave = squareWave(t0,hz)
vlst = calculate_wave_values(tlst,square_wave)
# ---- plot data
plt.figure(figsize=(10,4))
plt.title('Square Wave')
plt.xlabel('sample time', fontsize=14)
plt.ylabel('sample value', fontsize=14)
plt.plot(tlst,vlst,'black')
plt.grid()
plt.show()