indirect frequency measurement support in FCAP
This commit is contained in:
+3
-3
@@ -159,7 +159,7 @@ class Client:
|
||||
buf.extend(pld)
|
||||
return self.tf.query(type=gex.MSG_UNIT_REQUEST, id=id, pld=buf, listener=listener)
|
||||
|
||||
def query(self, cmd:int, cs:int=None, id:int=None, pld=None) -> TF_Msg:
|
||||
def query(self, cmd:int, cs:int=None, id:int=None, pld=None, timeout=3) -> TF_Msg:
|
||||
"""
|
||||
Query a unit. If cs is None, cmd is used as message type
|
||||
Returns the message
|
||||
@@ -174,8 +174,8 @@ class Client:
|
||||
self.send(cs=cs, cmd=cmd, id=id, pld=pld, listener=lst)
|
||||
# Wait for the response (hope no unrelated frame comes in instead)
|
||||
|
||||
# timeout after 3s
|
||||
self.transport.poll(3, lambda: self._theframe is not None)
|
||||
# timeout
|
||||
self.transport.poll(timeout, lambda: self._theframe is not None)
|
||||
|
||||
if self._theframe is None:
|
||||
raise Exception("No response to query")
|
||||
|
||||
+2
-2
@@ -36,9 +36,9 @@ class Unit:
|
||||
else:
|
||||
return self.client.send(cs=self.callsign, cmd=cmd, pld=pld, id=id)
|
||||
|
||||
def _query(self, cmd:int, pld=None, id:int=None) -> TF_Msg:
|
||||
def _query(self, cmd:int, pld=None, id:int=None, timeout=3) -> TF_Msg:
|
||||
""" Query the unit. Returns TF_Msg """
|
||||
return self.client.query(cs=self.callsign, cmd=cmd, pld=pld, id=id)
|
||||
return self.client.query(cs=self.callsign, cmd=cmd, pld=pld, id=id, timeout=timeout)
|
||||
|
||||
def _query_async(self, cmd:int, callback, pld=None, id:int=None):
|
||||
"""
|
||||
|
||||
@@ -18,6 +18,7 @@ from gex.units.USART import USART
|
||||
from gex.units.OneWire import OneWire
|
||||
from gex.units.ADC import ADC
|
||||
from gex.units.SIPO import SIPO
|
||||
from gex.units.FCAP import FCAP
|
||||
|
||||
|
||||
# General, low level
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
import gex
|
||||
|
||||
CMD_STOP = 0
|
||||
CMD_PWM_CONT_START = 1
|
||||
CMD_PWM_BURST_START = 2
|
||||
CMD_PWM_CONT_READ = 10
|
||||
|
||||
class FCAP_Report:
|
||||
def __init__(self):
|
||||
self.period = 0
|
||||
self.ontime = 0
|
||||
self.frequency = 0
|
||||
self.duty = 0
|
||||
|
||||
# Raw data (can be used to avoid distortion by float arithmetics)
|
||||
self.period_raw = 0
|
||||
self.ontime_raw = 0
|
||||
self.sample_count = 0
|
||||
self.clock_freq = 0
|
||||
|
||||
def __str__(self):
|
||||
return "{\n f = %f Hz\n T = %f s\n Ton = %f s\n duty = %f\n}" % \
|
||||
(self.frequency, self.period, self.ontime, self.duty)
|
||||
|
||||
class FCAP(gex.Unit):
|
||||
"""
|
||||
Frequency and pulse measurement
|
||||
"""
|
||||
|
||||
def _type(self):
|
||||
return 'FCAP'
|
||||
|
||||
def stop(self, confirm=True):
|
||||
""" Stop any ongoing capture """
|
||||
self._send(CMD_STOP, confirm=confirm)
|
||||
|
||||
def indirect_start(self, confirm=True):
|
||||
""" Start continuous PWM measurement """
|
||||
self._send(CMD_PWM_CONT_START, confirm=confirm)
|
||||
|
||||
def indirect_read(self):
|
||||
"""
|
||||
Read the current continuous measurement values
|
||||
Returns value of the last measurement in continuous mode
|
||||
"""
|
||||
|
||||
resp = self._query(CMD_PWM_CONT_READ)
|
||||
pp = gex.PayloadParser(resp.data)
|
||||
|
||||
mhz = pp.u16()
|
||||
period = pp.u32()
|
||||
ontime = pp.u32()
|
||||
|
||||
rp = FCAP_Report()
|
||||
rp.period = period / (mhz*1e6) # to seconds
|
||||
rp.frequency = 1 / rp.period
|
||||
rp.ontime = ontime / (mhz*1e6) # in seconds
|
||||
rp.duty = rp.ontime / rp.period
|
||||
|
||||
rp.clock_freq = mhz*1e6
|
||||
rp.sample_count = 1
|
||||
rp.period_raw = period
|
||||
rp.ontime_raw = ontime
|
||||
|
||||
# returned in microseconds
|
||||
return rp
|
||||
|
||||
def indirect_single(self, timeout=5):
|
||||
"""
|
||||
Perform a burst measure with averaging (sum/count)
|
||||
"""
|
||||
return self.indirect_burst(count=1, timeout=timeout)
|
||||
|
||||
def indirect_burst(self, count, timeout=5):
|
||||
"""
|
||||
Perform a burst measure with averaging (sum/count)
|
||||
"""
|
||||
|
||||
pb = gex.PayloadBuilder()
|
||||
pb.u16(count)
|
||||
|
||||
resp = self._query(CMD_PWM_BURST_START, pld=pb.close(), timeout=timeout)
|
||||
pp = gex.PayloadParser(resp.data)
|
||||
|
||||
mhz = pp.u16()
|
||||
nsamp = pp.u16()
|
||||
period = pp.u64()
|
||||
ontime = pp.u64()
|
||||
|
||||
rp = FCAP_Report()
|
||||
rp.period = period / (nsamp*mhz*1e6) # to seconds
|
||||
rp.frequency = 1 / rp.period
|
||||
rp.ontime = ontime / (nsamp*mhz*1e6) # in seconds
|
||||
rp.duty = rp.ontime / rp.period
|
||||
|
||||
rp.clock_freq = mhz*1e6
|
||||
rp.sample_count = 1
|
||||
rp.period_raw = period
|
||||
rp.ontime_raw = ontime
|
||||
|
||||
return rp
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import time
|
||||
|
||||
import gex
|
||||
|
||||
with gex.Client(gex.TrxRawUSB()) as client:
|
||||
fcap = gex.FCAP(client, 'fcap')
|
||||
|
||||
fcap.stop()
|
||||
fcap.indirect_start()
|
||||
|
||||
while True:
|
||||
time.sleep(1)
|
||||
print(fcap.indirect_read())
|
||||
#print(fcap.indirect_burst(3, timeout=20))
|
||||
|
||||
# print(fcap.indirect_burst(10, timeout=20))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user