jupyterpidaq.Boards.vernier.labquest
1# Utility sampling routines Vernier LabQuest interfaces. 2# Only Analog channels. 3# J. Gutow <gutow@uwosh.edu> April 2023 4# license GPL V3 or greater 5import time 6import numpy as np 7from multiprocessing import Lock, Value 8 9import logging 10 11try: 12 import labquest 13 labquestdrvs = True 14 starttime = Value('d',time.time()) 15 samples = [] 16 for k in range(3): 17 samples.append(Value('i',0)) 18except Exception as e: 19 print("\nLabQuest: "+str(e)) 20 labquestdrvs = False 21 22from jupyterpidaq.Boards import Board 23 24logger = logging.getLogger(__name__) 25 26# Optimized for Pi 3B+ for an installed ADS1115 ADC PiHAT. This is 27# actually ignored by this board, but necessary for ADC call 28# compatibility. 29RATE = 500 #maximum 10 kHz 30 31def find_boards(): 32 """ 33 A rountine like this must be implemented by all board packages. 34 35 :return: list of LabQuests (Types too?) 36 """ 37 boards = [] 38 # The following is a hack to get around the fact that the whole module 39 # needs to be reinstantiated on the new thread. I think the best option 40 # is to upon discovery spawn a process and then just communicate with it. 41 if labquestdrvs: 42 try: 43 LabQuests = labquest.LabQuest() 44 if LabQuests.open() == 0: 45 # Count number of boards 46 nboards = len(labquest.config.hDevice) 47 # Close things 48 LabQuests.close() 49 # launch a process to talk to, need Pipes to communicate. 50 from multiprocessing import Process, Pipe 51 cmdsend, cmdrcv = Pipe() 52 datasend, datarcv = Pipe() 53 LQ = Process(target = LQProc, 54 args = (cmdrcv, datasend, starttime, samples)) 55 LQ.start() 56 # append an object for each board that knows how to talk to the 57 # process and get information from that particular device 58 addr = 0 59 for addr in range(nboards): 60 boards.append(Board_LQ(addr, cmdsend, datarcv)) 61 addr+=1 62 except Exception as e: 63 print ("\nLabQuest(s) not found.", end='') 64 logger.debug(e) 65 return boards 66 67class Board_LQ(Board): 68 """ 69 Class defining the properties of the analog-to-digital block of the 70 LabQuests. Key characteristics: 71 72 * 3 channels (1, 2, 3) a range of +/- 10 V. 73 * 12 bit resolution 74 * Other available but not implemented facilities are Digital I/O. 75 """ 76 def __init__(self, addr, send, rcv): 77 super().__init__() 78 self.name = 'LabQuest' 79 self.vendor = 'Vernier' 80 self.channels = (1, 2, 3) 81 self.addr = addr 82 self.send = send 83 self.rcv = rcv 84 self.Vdd = 5.00 85 # samples taken from a channel and starttime kept track of in 86 # shared memory samples[i].value = # of samples taken from channel 87 # i. starttime.value = time.time() immediately after las clearing 88 # of the buffers. 89 90 def getsensors(self): 91 """ 92 Return a list of valid sensor object names for this board. 93 :return: list of classnames 94 """ 95 sensorlist = ['RawAtoD', 96 'VernierSSTemp', 97 'VernierGasP', 98 'VernierGasP_OLD', 99 'VernierpH', 100 'VernierFlatpH' 101 ] 102 # TODO: extend this list as appropriate. You can get a full list 103 # using the `Sensors.sensors.listSensors()` call. 104 # The main program will use this list to access the actual sensor 105 # objects when converting the raw board voltage and for producing 106 # a menu of valid options for this particular board. 107 return sensorlist 108 109 def V_oversampchan(self, chan, gain, avg_sec, data_rate=RATE): 110 """ 111 This routine returns the average voltage for the channel 112 averaged at the default rate for the board and returns an 113 average and observed range. 114 115 Returns a tuple of the following 5 objects: 116 V_avg -- float, the averaged voltage 117 118 V_min -- float, the minimum voltage read during 119 the interval 120 121 V_max -- float, the maximum voltage read during the 122 interval 123 124 time_stamp -- float, the time at halfway through the averaging 125 interval in seconds since the beginning of the epoch (OS 126 dependent begin time) 127 128 Vdd_avg -- float, the reference voltage (Vdd) collected 129 simultaneously. 130 131 :param int chan: the channel number (1, 2, 3) 132 133 :param gain: ignored by board. Defaults to 1. 134 135 :param int data_rate: maximum 136 137 :param float avg_sec: seconds to average for, actual 138 averaging interval will be as close as possible for an integer 139 number of samples 140 141 :returns: V_avg, V_min, V_max, time_stamp, Vdd_avg 142 :return float V_avg: description 143 :return float V_min: 144 :return float V_max: 145 :return float time_stamp: 146 :return float Vdd_avg: 147 """ 148 nsamples = round(data_rate*avg_sec) 149 self.send.send(['send',self.addr, chan, nsamples]) 150 while not self.rcv.poll(): 151 #we wait for data 152 pass 153 value = self.rcv.recv() 154 samples[chan - 1].value = samples[chan - 1].value + nsamples 155 endtime = starttime.value + samples[chan-1].value/data_rate 156 time_stamp = endtime - avg_sec / 2 157 ndata = len(value) 158 V_avg = sum(value) / ndata 159 Vdd_avg = 5.00 160 V_min = min(value) 161 V_max = max(value) 162 return V_avg, V_min, V_max, time_stamp, Vdd_avg 163 164 def V_oversampchan_stats(self, chan, gain, avg_sec, data_rate=RATE): 165 ''' 166 This routine returns the average voltage for the channel 167 averaged at the maximum rate for the board. The standard 168 deviation and the estimated deviation of the mean are also 169 returned. 170 171 Returns a tuple of the following 5 objects: 172 V_avg -- float, the averaged voltage 173 174 stdev -- float, the standard deviation of the measured values 175 during the averaging interval 176 177 stdev_avg -- float, the estimated standard deviation of the 178 returned average 179 180 time_stamp -- float, the time at halfway through the averaging 181 interval in seconds since the beginning of the epoch (OS 182 dependent begin time) 183 184 Vdd_avg -- float, returned as None. 185 186 :param int chan: the channel number (1, 2, 3) 187 188 :param gain: ignored by board. Defaults to 1. 189 190 :param int data_rate: 191 192 :param float avg_sec: seconds to average for, actual 193 averaging interval will be as close as possible for an integer 194 number of samples 195 196 :returns: V_avg, stdev, stdev_avg, time_stamp, Vdd_avg 197 :return float V_avg: 198 :return float stdev: 199 :return float stdev_avg: 200 :return float time_stamp: 201 :return float Vdd_avg: 202 ''' 203 nsamples = round(data_rate * avg_sec) 204 self.send.send(['send', self.addr, chan, nsamples]) 205 while not self.rcv.poll(): 206 # we wait for data 207 pass 208 value = self.rcv.recv() 209 samples[chan - 1].value = samples[chan - 1].value + nsamples 210 endtime = starttime.value + samples[chan-1].value/data_rate 211 time_stamp = endtime - avg_sec / 2 212 ndata = len(value) 213 V_avg = sum(value) / ndata 214 Vdd_avg = 5.00 215 stdev = np.std(value, ddof=1, dtype=np.float64) 216 stdev_avg = stdev / np.sqrt(float(ndata)) 217 return V_avg, stdev, stdev_avg, time_stamp, Vdd_avg 218 219 def V_sampchan(self, chan, gain, data_rate=RATE): 220 ''' 221 This routine returns a single reading of the voltage for the channel. 222 223 Returns a tuple of the following 5 objects: 224 V -- float, the measured voltage 225 226 time_stamp -- float, the time of the measurement in seconds since 227 the beginning of the epoch (OS dependent begin time) 228 229 ref -- float, the reference voltage (Vdd) collected 230 simultaneously. 231 232 :param int chan: the channel number (1, 2, 3). 233 234 :param gain: ignored by board. Defaults to 1. 235 236 :param int data_rate: 237 238 :returns float value: 239 240 :return float time_stamp: 241 242 :return float Vdd: 243 ''' 244 nsamples = 1 245 self.send.send(['start', ]) 246 self.send.send(['send', self.addr, chan, nsamples]) 247 while not self.rcv.poll(): 248 # we wait for data 249 pass 250 value = self.rcv.recv()[0] 251 samples[chan - 1].value = samples[chan - 1].value + nsamples 252 time_stamp = starttime.value 253 Vdd = 5.00 254 return value, time_stamp, Vdd 255 256def LQProc(cmdrcv, datasend, starttime, samples): 257 """Process to spawn that continuously collects from the LabQuests(s) 258 Parameters 259 ---------- 260 cmdrcv: Pipe 261 Where commands are received. 262 263 datasend: Pipe 264 Where data is sent in response to a command. 265 """ 266 # First set up the LabQuest(s) 267 import labquest 268 from collections import deque 269 lqs = labquest.LabQuest() 270 cmd_deque = deque() 271 PERIOD = 1000/RATE # msec 272 if lqs.open() == 0: 273 # we're good to go 274 # make a list of boards 275 boards = [] 276 nboards = len(labquest.config.hDevice) 277 for i in range(nboards): 278 # Tell the board we will monitor all three channels 279 lqs.select_sensors(ch1="raw_voltage", ch2="raw_voltage", 280 ch3="raw_voltage", 281 device=i) 282 lqs.start(PERIOD) 283 starttime.value = time.time() 284 running = True 285 while running: 286 # check for a command: start (clears buffers), send (sends content 287 # of buffers, removing the sent content), close (shutdown the process). 288 # Each command is a list ['cmd str',<cmd data>]: 289 # ['start',] 290 # ['close',] 291 # ['send',board#, ch#, num_pts]. 292 while cmdrcv.poll(): 293 cmd_deque.append(cmdrcv.recv()) 294 # Start responding to commands 295 while len(cmd_deque) > 0: 296 cmd = cmd_deque.popleft() 297 if cmd[0] == 'close': 298 # stop thread 299 running = False 300 if cmd[0] == 'start': 301 # restart data collection to get good zero 302 lqs.stop() 303 lqs.start(PERIOD) 304 starttime.value = time.time() 305 for k in range(3): 306 samples[k].value = 0 307 if cmd[0] == 'send': 308 # return requested amount of data for the channel 309 chan = 'ch'+str(cmd[2]) 310 data = [] 311 for k in range(cmd[3]): 312 data.append(lqs.read(chan, device=cmd[1])) 313 datasend.send(data) 314 lqs.close() 315 return 316 else: 317 # something happened 318 lqs.close() 319 raise IOError("") 320 return
32def find_boards(): 33 """ 34 A rountine like this must be implemented by all board packages. 35 36 :return: list of LabQuests (Types too?) 37 """ 38 boards = [] 39 # The following is a hack to get around the fact that the whole module 40 # needs to be reinstantiated on the new thread. I think the best option 41 # is to upon discovery spawn a process and then just communicate with it. 42 if labquestdrvs: 43 try: 44 LabQuests = labquest.LabQuest() 45 if LabQuests.open() == 0: 46 # Count number of boards 47 nboards = len(labquest.config.hDevice) 48 # Close things 49 LabQuests.close() 50 # launch a process to talk to, need Pipes to communicate. 51 from multiprocessing import Process, Pipe 52 cmdsend, cmdrcv = Pipe() 53 datasend, datarcv = Pipe() 54 LQ = Process(target = LQProc, 55 args = (cmdrcv, datasend, starttime, samples)) 56 LQ.start() 57 # append an object for each board that knows how to talk to the 58 # process and get information from that particular device 59 addr = 0 60 for addr in range(nboards): 61 boards.append(Board_LQ(addr, cmdsend, datarcv)) 62 addr+=1 63 except Exception as e: 64 print ("\nLabQuest(s) not found.", end='') 65 logger.debug(e) 66 return boards
A rountine like this must be implemented by all board packages.
Returns
list of LabQuests (Types too?)
68class Board_LQ(Board): 69 """ 70 Class defining the properties of the analog-to-digital block of the 71 LabQuests. Key characteristics: 72 73 * 3 channels (1, 2, 3) a range of +/- 10 V. 74 * 12 bit resolution 75 * Other available but not implemented facilities are Digital I/O. 76 """ 77 def __init__(self, addr, send, rcv): 78 super().__init__() 79 self.name = 'LabQuest' 80 self.vendor = 'Vernier' 81 self.channels = (1, 2, 3) 82 self.addr = addr 83 self.send = send 84 self.rcv = rcv 85 self.Vdd = 5.00 86 # samples taken from a channel and starttime kept track of in 87 # shared memory samples[i].value = # of samples taken from channel 88 # i. starttime.value = time.time() immediately after las clearing 89 # of the buffers. 90 91 def getsensors(self): 92 """ 93 Return a list of valid sensor object names for this board. 94 :return: list of classnames 95 """ 96 sensorlist = ['RawAtoD', 97 'VernierSSTemp', 98 'VernierGasP', 99 'VernierGasP_OLD', 100 'VernierpH', 101 'VernierFlatpH' 102 ] 103 # TODO: extend this list as appropriate. You can get a full list 104 # using the `Sensors.sensors.listSensors()` call. 105 # The main program will use this list to access the actual sensor 106 # objects when converting the raw board voltage and for producing 107 # a menu of valid options for this particular board. 108 return sensorlist 109 110 def V_oversampchan(self, chan, gain, avg_sec, data_rate=RATE): 111 """ 112 This routine returns the average voltage for the channel 113 averaged at the default rate for the board and returns an 114 average and observed range. 115 116 Returns a tuple of the following 5 objects: 117 V_avg -- float, the averaged voltage 118 119 V_min -- float, the minimum voltage read during 120 the interval 121 122 V_max -- float, the maximum voltage read during the 123 interval 124 125 time_stamp -- float, the time at halfway through the averaging 126 interval in seconds since the beginning of the epoch (OS 127 dependent begin time) 128 129 Vdd_avg -- float, the reference voltage (Vdd) collected 130 simultaneously. 131 132 :param int chan: the channel number (1, 2, 3) 133 134 :param gain: ignored by board. Defaults to 1. 135 136 :param int data_rate: maximum 137 138 :param float avg_sec: seconds to average for, actual 139 averaging interval will be as close as possible for an integer 140 number of samples 141 142 :returns: V_avg, V_min, V_max, time_stamp, Vdd_avg 143 :return float V_avg: description 144 :return float V_min: 145 :return float V_max: 146 :return float time_stamp: 147 :return float Vdd_avg: 148 """ 149 nsamples = round(data_rate*avg_sec) 150 self.send.send(['send',self.addr, chan, nsamples]) 151 while not self.rcv.poll(): 152 #we wait for data 153 pass 154 value = self.rcv.recv() 155 samples[chan - 1].value = samples[chan - 1].value + nsamples 156 endtime = starttime.value + samples[chan-1].value/data_rate 157 time_stamp = endtime - avg_sec / 2 158 ndata = len(value) 159 V_avg = sum(value) / ndata 160 Vdd_avg = 5.00 161 V_min = min(value) 162 V_max = max(value) 163 return V_avg, V_min, V_max, time_stamp, Vdd_avg 164 165 def V_oversampchan_stats(self, chan, gain, avg_sec, data_rate=RATE): 166 ''' 167 This routine returns the average voltage for the channel 168 averaged at the maximum rate for the board. The standard 169 deviation and the estimated deviation of the mean are also 170 returned. 171 172 Returns a tuple of the following 5 objects: 173 V_avg -- float, the averaged voltage 174 175 stdev -- float, the standard deviation of the measured values 176 during the averaging interval 177 178 stdev_avg -- float, the estimated standard deviation of the 179 returned average 180 181 time_stamp -- float, the time at halfway through the averaging 182 interval in seconds since the beginning of the epoch (OS 183 dependent begin time) 184 185 Vdd_avg -- float, returned as None. 186 187 :param int chan: the channel number (1, 2, 3) 188 189 :param gain: ignored by board. Defaults to 1. 190 191 :param int data_rate: 192 193 :param float avg_sec: seconds to average for, actual 194 averaging interval will be as close as possible for an integer 195 number of samples 196 197 :returns: V_avg, stdev, stdev_avg, time_stamp, Vdd_avg 198 :return float V_avg: 199 :return float stdev: 200 :return float stdev_avg: 201 :return float time_stamp: 202 :return float Vdd_avg: 203 ''' 204 nsamples = round(data_rate * avg_sec) 205 self.send.send(['send', self.addr, chan, nsamples]) 206 while not self.rcv.poll(): 207 # we wait for data 208 pass 209 value = self.rcv.recv() 210 samples[chan - 1].value = samples[chan - 1].value + nsamples 211 endtime = starttime.value + samples[chan-1].value/data_rate 212 time_stamp = endtime - avg_sec / 2 213 ndata = len(value) 214 V_avg = sum(value) / ndata 215 Vdd_avg = 5.00 216 stdev = np.std(value, ddof=1, dtype=np.float64) 217 stdev_avg = stdev / np.sqrt(float(ndata)) 218 return V_avg, stdev, stdev_avg, time_stamp, Vdd_avg 219 220 def V_sampchan(self, chan, gain, data_rate=RATE): 221 ''' 222 This routine returns a single reading of the voltage for the channel. 223 224 Returns a tuple of the following 5 objects: 225 V -- float, the measured voltage 226 227 time_stamp -- float, the time of the measurement in seconds since 228 the beginning of the epoch (OS dependent begin time) 229 230 ref -- float, the reference voltage (Vdd) collected 231 simultaneously. 232 233 :param int chan: the channel number (1, 2, 3). 234 235 :param gain: ignored by board. Defaults to 1. 236 237 :param int data_rate: 238 239 :returns float value: 240 241 :return float time_stamp: 242 243 :return float Vdd: 244 ''' 245 nsamples = 1 246 self.send.send(['start', ]) 247 self.send.send(['send', self.addr, chan, nsamples]) 248 while not self.rcv.poll(): 249 # we wait for data 250 pass 251 value = self.rcv.recv()[0] 252 samples[chan - 1].value = samples[chan - 1].value + nsamples 253 time_stamp = starttime.value 254 Vdd = 5.00 255 return value, time_stamp, Vdd
Class defining the properties of the analog-to-digital block of the LabQuests. Key characteristics:
- 3 channels (1, 2, 3) a range of +/- 10 V.
- 12 bit resolution
- Other available but not implemented facilities are Digital I/O.
77 def __init__(self, addr, send, rcv): 78 super().__init__() 79 self.name = 'LabQuest' 80 self.vendor = 'Vernier' 81 self.channels = (1, 2, 3) 82 self.addr = addr 83 self.send = send 84 self.rcv = rcv 85 self.Vdd = 5.00 86 # samples taken from a channel and starttime kept track of in 87 # shared memory samples[i].value = # of samples taken from channel 88 # i. starttime.value = time.time() immediately after las clearing 89 # of the buffers.
Should be overridden by each board and define at minimum: self.name = 'board name/adc name/type' Short an useful to end user self.vendor = 'Vendor/Manufacturer name` self.channels = tuple of available channel IDs self.gains = list of gains self.Vdd = voltage provided by board to sensors
91 def getsensors(self): 92 """ 93 Return a list of valid sensor object names for this board. 94 :return: list of classnames 95 """ 96 sensorlist = ['RawAtoD', 97 'VernierSSTemp', 98 'VernierGasP', 99 'VernierGasP_OLD', 100 'VernierpH', 101 'VernierFlatpH' 102 ] 103 # TODO: extend this list as appropriate. You can get a full list 104 # using the `Sensors.sensors.listSensors()` call. 105 # The main program will use this list to access the actual sensor 106 # objects when converting the raw board voltage and for producing 107 # a menu of valid options for this particular board. 108 return sensorlist
Return a list of valid sensor object names for this board.
Returns
list of classnames
110 def V_oversampchan(self, chan, gain, avg_sec, data_rate=RATE): 111 """ 112 This routine returns the average voltage for the channel 113 averaged at the default rate for the board and returns an 114 average and observed range. 115 116 Returns a tuple of the following 5 objects: 117 V_avg -- float, the averaged voltage 118 119 V_min -- float, the minimum voltage read during 120 the interval 121 122 V_max -- float, the maximum voltage read during the 123 interval 124 125 time_stamp -- float, the time at halfway through the averaging 126 interval in seconds since the beginning of the epoch (OS 127 dependent begin time) 128 129 Vdd_avg -- float, the reference voltage (Vdd) collected 130 simultaneously. 131 132 :param int chan: the channel number (1, 2, 3) 133 134 :param gain: ignored by board. Defaults to 1. 135 136 :param int data_rate: maximum 137 138 :param float avg_sec: seconds to average for, actual 139 averaging interval will be as close as possible for an integer 140 number of samples 141 142 :returns: V_avg, V_min, V_max, time_stamp, Vdd_avg 143 :return float V_avg: description 144 :return float V_min: 145 :return float V_max: 146 :return float time_stamp: 147 :return float Vdd_avg: 148 """ 149 nsamples = round(data_rate*avg_sec) 150 self.send.send(['send',self.addr, chan, nsamples]) 151 while not self.rcv.poll(): 152 #we wait for data 153 pass 154 value = self.rcv.recv() 155 samples[chan - 1].value = samples[chan - 1].value + nsamples 156 endtime = starttime.value + samples[chan-1].value/data_rate 157 time_stamp = endtime - avg_sec / 2 158 ndata = len(value) 159 V_avg = sum(value) / ndata 160 Vdd_avg = 5.00 161 V_min = min(value) 162 V_max = max(value) 163 return V_avg, V_min, V_max, time_stamp, Vdd_avg
This routine returns the average voltage for the channel averaged at the default rate for the board and returns an average and observed range.
Returns a tuple of the following 5 objects: V_avg -- float, the averaged voltage
V_min -- float, the minimum voltage read during
the interval
V_max -- float, the maximum voltage read during the
interval
time_stamp -- float, the time at halfway through the averaging
interval in seconds since the beginning of the epoch (OS
dependent begin time)
Vdd_avg -- float, the reference voltage (Vdd) collected
simultaneously.
Parameters
int chan: the channel number (1, 2, 3)
gain: ignored by board. Defaults to 1.
int data_rate: maximum
float avg_sec: seconds to average for, actual averaging interval will be as close as possible for an integer number of samples
:returns: V_avg, V_min, V_max, time_stamp, Vdd_avg
Returns
description
Returns
Returns
Returns
Returns
165 def V_oversampchan_stats(self, chan, gain, avg_sec, data_rate=RATE): 166 ''' 167 This routine returns the average voltage for the channel 168 averaged at the maximum rate for the board. The standard 169 deviation and the estimated deviation of the mean are also 170 returned. 171 172 Returns a tuple of the following 5 objects: 173 V_avg -- float, the averaged voltage 174 175 stdev -- float, the standard deviation of the measured values 176 during the averaging interval 177 178 stdev_avg -- float, the estimated standard deviation of the 179 returned average 180 181 time_stamp -- float, the time at halfway through the averaging 182 interval in seconds since the beginning of the epoch (OS 183 dependent begin time) 184 185 Vdd_avg -- float, returned as None. 186 187 :param int chan: the channel number (1, 2, 3) 188 189 :param gain: ignored by board. Defaults to 1. 190 191 :param int data_rate: 192 193 :param float avg_sec: seconds to average for, actual 194 averaging interval will be as close as possible for an integer 195 number of samples 196 197 :returns: V_avg, stdev, stdev_avg, time_stamp, Vdd_avg 198 :return float V_avg: 199 :return float stdev: 200 :return float stdev_avg: 201 :return float time_stamp: 202 :return float Vdd_avg: 203 ''' 204 nsamples = round(data_rate * avg_sec) 205 self.send.send(['send', self.addr, chan, nsamples]) 206 while not self.rcv.poll(): 207 # we wait for data 208 pass 209 value = self.rcv.recv() 210 samples[chan - 1].value = samples[chan - 1].value + nsamples 211 endtime = starttime.value + samples[chan-1].value/data_rate 212 time_stamp = endtime - avg_sec / 2 213 ndata = len(value) 214 V_avg = sum(value) / ndata 215 Vdd_avg = 5.00 216 stdev = np.std(value, ddof=1, dtype=np.float64) 217 stdev_avg = stdev / np.sqrt(float(ndata)) 218 return V_avg, stdev, stdev_avg, time_stamp, Vdd_avg
This routine returns the average voltage for the channel averaged at the maximum rate for the board. The standard deviation and the estimated deviation of the mean are also returned.
Returns a tuple of the following 5 objects: V_avg -- float, the averaged voltage
stdev -- float, the standard deviation of the measured values
during the averaging interval
stdev_avg -- float, the estimated standard deviation of the
returned average
time_stamp -- float, the time at halfway through the averaging
interval in seconds since the beginning of the epoch (OS
dependent begin time)
Vdd_avg -- float, returned as None.
Parameters
int chan: the channel number (1, 2, 3)
gain: ignored by board. Defaults to 1.
int data_rate:
float avg_sec: seconds to average for, actual averaging interval will be as close as possible for an integer number of samples
:returns: V_avg, stdev, stdev_avg, time_stamp, Vdd_avg
Returns
Returns
Returns
Returns
Returns
220 def V_sampchan(self, chan, gain, data_rate=RATE): 221 ''' 222 This routine returns a single reading of the voltage for the channel. 223 224 Returns a tuple of the following 5 objects: 225 V -- float, the measured voltage 226 227 time_stamp -- float, the time of the measurement in seconds since 228 the beginning of the epoch (OS dependent begin time) 229 230 ref -- float, the reference voltage (Vdd) collected 231 simultaneously. 232 233 :param int chan: the channel number (1, 2, 3). 234 235 :param gain: ignored by board. Defaults to 1. 236 237 :param int data_rate: 238 239 :returns float value: 240 241 :return float time_stamp: 242 243 :return float Vdd: 244 ''' 245 nsamples = 1 246 self.send.send(['start', ]) 247 self.send.send(['send', self.addr, chan, nsamples]) 248 while not self.rcv.poll(): 249 # we wait for data 250 pass 251 value = self.rcv.recv()[0] 252 samples[chan - 1].value = samples[chan - 1].value + nsamples 253 time_stamp = starttime.value 254 Vdd = 5.00 255 return value, time_stamp, Vdd
This routine returns a single reading of the voltage for the channel.
Returns a tuple of the following 5 objects: V -- float, the measured voltage
time_stamp -- float, the time of the measurement in seconds since
the beginning of the epoch (OS dependent begin time)
ref -- float, the reference voltage (Vdd) collected
simultaneously.
Parameters
int chan: the channel number (1, 2, 3).
gain: ignored by board. Defaults to 1.
int data_rate:
:returns float value:
Returns
Returns
Inherited Members
257def LQProc(cmdrcv, datasend, starttime, samples): 258 """Process to spawn that continuously collects from the LabQuests(s) 259 Parameters 260 ---------- 261 cmdrcv: Pipe 262 Where commands are received. 263 264 datasend: Pipe 265 Where data is sent in response to a command. 266 """ 267 # First set up the LabQuest(s) 268 import labquest 269 from collections import deque 270 lqs = labquest.LabQuest() 271 cmd_deque = deque() 272 PERIOD = 1000/RATE # msec 273 if lqs.open() == 0: 274 # we're good to go 275 # make a list of boards 276 boards = [] 277 nboards = len(labquest.config.hDevice) 278 for i in range(nboards): 279 # Tell the board we will monitor all three channels 280 lqs.select_sensors(ch1="raw_voltage", ch2="raw_voltage", 281 ch3="raw_voltage", 282 device=i) 283 lqs.start(PERIOD) 284 starttime.value = time.time() 285 running = True 286 while running: 287 # check for a command: start (clears buffers), send (sends content 288 # of buffers, removing the sent content), close (shutdown the process). 289 # Each command is a list ['cmd str',<cmd data>]: 290 # ['start',] 291 # ['close',] 292 # ['send',board#, ch#, num_pts]. 293 while cmdrcv.poll(): 294 cmd_deque.append(cmdrcv.recv()) 295 # Start responding to commands 296 while len(cmd_deque) > 0: 297 cmd = cmd_deque.popleft() 298 if cmd[0] == 'close': 299 # stop thread 300 running = False 301 if cmd[0] == 'start': 302 # restart data collection to get good zero 303 lqs.stop() 304 lqs.start(PERIOD) 305 starttime.value = time.time() 306 for k in range(3): 307 samples[k].value = 0 308 if cmd[0] == 'send': 309 # return requested amount of data for the channel 310 chan = 'ch'+str(cmd[2]) 311 data = [] 312 for k in range(cmd[3]): 313 data.append(lqs.read(chan, device=cmd[1])) 314 datasend.send(data) 315 lqs.close() 316 return 317 else: 318 # something happened 319 lqs.close() 320 raise IOError("") 321 return
Process to spawn that continuously collects from the LabQuests(s)
Parameters
cmdrcv: Pipe Where commands are received.
datasend: Pipe Where data is sent in response to a command.