Repository navigation
Expand file tree
/
Copy pathSerialWombatPulseTimer.py
More file actions
238 lines (187 loc) · 10.3 KB
/
Copy pathSerialWombatPulseTimer.py
File metadata and controls
238 lines (187 loc) · 10.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
"""
Copyright 2020-2023 Broadwell Consulting Inc.
"Serial Wombat" is a registered trademark of Broadwell Consulting Inc. in
the United States. See SerialWombat.com for usage guidance.
Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
"""
import SerialWombatPin
from SerialWombat import SerialWombatPinMode_t
from SerialWombatAbstractProcessedInput import SerialWombatAbstractProcessedInput
"""! \file serialWombatPulseTimer.h
"""
def SerialWombatPulseTimerUnits():
SW_PULSETIMER_uS = 0
SW_PULSETIMER_mS = 1
"""! @brief A Class which uses a Serial Wombat pin to measure the length of a pulse high and low time
This class is used to measure the length of pulses in mS or in uS. On the Serial Wombat 4A/B the
precision is about 8uS in uS mode, with an accuracy of +/- 2% because of variation in the
Serial Wombat chip's internal oscillator.
One SerialWombatPulseTimer should be declared per Serial Wombat pin in this mode.
A video Tutorial on this pin mode is available:
\htmlonly
<iframe width="560" height="315" src="https://www.youtube.com/embed/YtQWUub9gYw" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
\endhtmlonly
https://youtu.be/YtQWUub9gYw
This pinmode is useful for measuring RC Servo outputs, PWM frequency and duty cycle, or any other signal where the pulse width
is relevant. It is designed to measure repetitive signals. It is not intended to read a number of differing independent pulse
widths that come one after another, such as WS2812 or similar output.
\warning Care must be taken when using this pinmode with high frequency ( > 5 kHz) signals or pins that may be left floating on the Serial Wombat 4A / 4B because
the Serial Wombat 4A and 4B chip uses an interrupt internally to capture transition timestamps. Excessively frequent pin transitions may cause the interrupt
handler to starve the main processing loop, impacting function of all pin modes and communications.
The Serial Wombat chip can be queried for overflow frames. If overflow frames are occuring, then the system is overloaded.
The Serial Wombat 4A and 4B chips can measure a maxium of 8 transitions per mS across all pulse input pins. More frequent transitions than
this may result in incorrect measurements. The MeasurementOverflowOccurred flag is set if at any time more than 8 transitions occured
without processing.
The Serial Wombat 18AB chip uses a DMA based sampling scheme with samples taken at 57600 Hz. It has lower
resolution than the Serial Wombat 4A/B (17 uS resolution), but can measure up to 18 simultaneous pulse trains and
is not subject to being overloaded by faster signals.
The number of pulses over time can be used for rough frequency measurements.
Consecutive High and low periods can be used to calculate duty cycle, although there is no indication whether high or low was
most recent.
"""
class SerialWombatPulseTimer(SerialWombatPin.SerialWombatPin):
"""!
@brief Class constructor for SerialWombatPulseTimer
@param serialWombat The Serial Wombat chip on which the SerialWombatPulseTimer pinmode will be run
"""
def __init__(self,serial_wombat):
self._sw = serial_wombat
self.HighCounts = 0
self.LowCounts = 0
self.Pulses = 0
self.MeasurementOverflowOccurred = False
"""!
@brief Initialization routine for SerialWombatPulseTimer
@param pin The Serial Wombat pin used for pulse measurments. All 4 pins on the SW4A/SW4B and all 20 pins on the SW18AB may be used.
@param units SW_PULSETIMER_uS (0) or SW_PULSETIMER_mS (1). Default uS
@param pullUpEnabled TRUE = Pull Up Enabled, FALSE = Pull Up Disabled. Default disabled.
"""
def begin(self,pin, units = 0 , pullUpEnabled = False):
self._pin = pin
self._pinMode = SerialWombatPinMode_t.PIN_MODE_PULSETIMER
tx = [ 200,self._pin,self._pinMode,pullUpEnabled,units,0x55,0x55,0x55 ]
count,rx = self._sw.sendPacket(tx)
return count
"""!
@brief Retreive the latest values for HighCounts, LowCounts, Pulses, and MeasurementOverflowOccured
This happens in two packets to the Serial Wombat chip, so data may not be coherent
"""
def refresh(self):
self.refreshHighCountsLowCounts()
tx = [ 202,self._pin,self._pinMode,0x55,0x55,0x55,0x55,0x55 ]
count,rx = self._sw.sendPacket(tx)
self.Pulses = rx[5] + 256 * rx[6]
self.MeasurementOverflowOccurred = rx[7]
"""!
@brief Retreive the High and Low counts from the Serial Wombat chip in a single transaction
This command will retreive consecutive high and low periods from the Serial Wombat chip.
It it not guaranteed which is the most recent.
"""
def refreshHighCountsLowCounts(self):
tx = [ 201,self._pin,self._pinMode,0x55,0x55,0x55,0x55,0x55 ]
count,rx = self._sw.sendPacket(tx)
self.HighCounts = rx[3] + 256 * rx[4]
self.LowCounts = rx[5] + 256 * rx[6]
"""
@brief Retreive the High counts and number of pulses Serial Wombat chip in a single transaction
This command will retreive consecutive high and low periods from the Serial Wombat chip.
It it not guaranteed which is the most recent.
"""
def refreshHighCountsPulses(self):
tx = [ 202,self._pin,self._pinMode,0x55,0x55,0x55,0x55,0x55 ]
count,rx = self._sw.sendPacket(tx)
self.HighCounts = rx[3] + 256 * rx[4]
self.Pulses = rx[5] + 256 * rx[6]
self.MeasurementOverflowOccurred = rx[7]
"""
@brief Retreives the most recent Counts in the configured units for the most recent high pulse
@return Counts in mS or uS depending on configuration.
"""
def readHighCounts(self):
self.refreshHighCountsLowCounts()
return (self.HighCounts)
"""
@brief Retreives the most recent Counts in the configured units for the most recent low pulse
@return Counts in mS or uS depending on configuration.
"""
def readLowCounts(self):
self.refreshHighCountsLowCounts()
return (self.LowCounts)
"""
@brief Retreives the number of pulses
This value overflows at 65535. Reading this value does not clear it.
This function has a side effect of reading MeasurementOverflowOccured from the Serial Wombat chip,
which clears it for future readings.
@return Number of pulses counted (1 count per high/low cycle). Rolls over at 65535 to 0
"""
def readPulses(self):
self.refreshHighCountsPulses()
return(self.Pulses)
"""
@brief Count in selected units of last retreived high pulse
This value is updated by refresh, refreshHighCountsLowCounts, refreshHighCountsPulses, readHighCounts, readLowCounts
"""
HighCounts = 0
"""
@brief Count in selected units of last retreived low pulse
This value is updated by refresh, refreshHighCountsLowCounts, readHighCounts, readLowCounts
"""
LowCounts = 0
"""
@brief Count of last retreived pulses
This value is updated by refresh, and refreshHighCountsPulses
"""
Pulses = 0
MeasurementOverflowOccurred = False
"""!
@brief extends the SerialWombatPulseTimer class with SW18AB specific functionality
///
This class adds functionality that is specific to the SW18AB firmware in addition
to generic SerialWombatPulseTimer functionality avaialble on all Serial Wombat chips
"""
class SerialWombatPulseTimer_18AB(SerialWombatPulseTimer, SerialWombatAbstractProcessedInput):
"""!
@brief constructor for SerialWombatPulseTimer_18AB
@param serialWombat reference to the SerialWombat chip on which the SerialWombatPulseTimer_18AB will run
"""
def __init__(self,serial_wombat):
SerialWombatPulseTimer.__init__(self,serial_wombat)
SerialWombatAbstractProcessedInput.__init__(self,serial_wombat)
self._asosw = serial_wombat
self.PDO_HIGH_TIME = 0 #!< The pulse high time in uS. Updated on each high to low transition.
self.PDO_LOW_TIME = 1 #!< the pulse low time in uS. Update on each low to high transition.
self.PDO_PULSE_COUNT = 2 #!< The number of pulses that have occured since initialization. Updated on each high to low transition
self.PDO_PERIOD_ON_LTH_TRANSITION = 3 #!< The period of the pulse in uS, based on the previous high and low times, updated on low to high transition
self.PDO_PERIOD_ON_HTL_TRANSITION = 4 #!< The period of the pulse in uS, based on the previous high and low times, updated on high to low transition
self.PDO_FREQUENCY_ON_LTH_TRANSITION = 5 #!< The frequency of the pulse in Hz, based on the previous high and low times, updated on low to high transition
self.PDO_FREQUENCY_ON_HTL_TRANSITION = 6 #!< The frequency of the pulse in Hz, based on the previous high and low times, updated on high to low transition
self.PDO_DUTYCYCLE_ON_LTH_TRANSITION = 7 #!< Duty cycle of the pulse as a ratio from 0 to 65535, updated on low to high transition
self.PDO_DUTYCYCLE_ON_HTL_TRANSITION = 8 #!< Duty cycle of the pulse as a ratio from 0 to 65535, updated on high to low transition
"""!
@brief configures which measurement is the Public Data Output of this pin mode
This function sets what data is avaialble through the public data
This function is only avaialble on the Serial Wombat 18AB chip
@param publicDataOutput An enumerated type indicating what data to output
@return returns 0 or higher for success or a negative error code.
"""
def configurePublicDataOutput(self, publicDataOutput):
tx = [ 203,self._pin,self._pinMode, publicDataOutput, 0x55,0x55,0x55, 0x55]
count,rx = self._sw.sendPacket(tx)
return count
def begin(self,pin, units = 0 , pullUpEnabled = False):
SerialWombatPulseTimer.begin(self,pin,units,pullUpEnabled)
self.abstractProcessedInputBegin(pin,self._pinMode)