def meas2(addr, addr2): ow.write([0x44], addr=addr) ow.write([0x44], addr=addr2) ow.wait_ready() data = ow.query([0xBE], 9, addr=addr) pp = gex.PayloadParser(data) a = pp.i16() * 0.0625 data = ow.query([0xBE], 9, addr=addr2) pp = gex.PayloadParser(data) b = pp.i16() * 0.0625 return a, b
def _on_stream_capt(self, msg: TF_Msg): pp = gex.PayloadParser(msg.data) if not self._stream_running: raise Exception("Unexpected stream data frame") if msg.type == EVT_CAPT_DONE: if self._stream_listener is not None: self._stream_listener(None) # Indicate it's closed # We keep the stream listener, so user doesnt have to set it before each stream self._stream_running = False return TF.CLOSE else: # All stream data frames are prefixed by a sequence number idx = pp.u8() if idx != self._stream_next_id: self._stream_running = False raise Exception("Lost stream data frame! Expected %d, got %d" % (self._stream_next_id, idx)) self._stream_next_id = (self._stream_next_id + 1) % 256 tail = pp.tail() if self._stream_listener is not None: self._stream_listener(self._parse_buffer(tail)) return TF.STAY
def read_regs(self, address: int, reg, count: int, width: int = 1, a10bit: bool = False, endian='little'): """ Read multiple registers from an address """ pb = self._begin_i2c_pld(address, a10bit) pb.u8(reg) pb.u16(width * count) # we assume the device will auto-increment (most do) resp = self._query(0x03, pb.close()) fields = [] pp = gex.PayloadParser(resp.data, endian=endian) if width == 1: for i in range(0, count): fields.append(pp.u8()) elif width == 2: for i in range(0, count): fields.append(pp.u16()) elif width == 3: for i in range(0, count): fields.append(pp.u24()) elif width == 4: for i in range(0, count): fields.append(pp.u32()) else: raise Exception("Bad width") return fields
def _on_trig_capt(self, msg: TF_Msg): pp = gex.PayloadParser(msg.data) if self._trig_buf is None: raise Exception("Unexpected capture data frame") # All but the first trig capture frame are prefixed by a sequence number idx = pp.u8() if idx != self._trig_next_id: raise Exception("Lost capture data frame! Expected %d, got %d" % (self._trig_next_id, idx)) self._trig_next_id = (self._trig_next_id + 1) % 256 self._trig_buf.extend(pp.tail()) if msg.type == EVT_CAPT_DONE: if self._trig_listener is not None: self._trig_listener( TriggerReport(data=self._parse_buffer(self._trig_buf), edge=self._trig_edge, pretrig=self._trig_pretrig_len, timestamp=self._trig_ts)) self._trig_buf = None # We keep the trig listener return TF.CLOSE else: return TF.STAY
def indirect_read(self): """ Read the current indirect continuous measurement values Returns value of the last measurement in continuous indirect mode """ resp = self._query(CMD_INDIRECT_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_burst(self, count, timeout=5): """ Perform a burst measure with averaging (sum/count) """ pb = gex.PayloadBuilder() pb.u16(count) resp = self._query(CMD_INDIRECT_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
def _on_event(self, evt: EventReport): """ Handle a trigger or stream start event. - EVT_CAPT_START First frame payload: edge:u8, pretrig_len:u32, payload:tail Following are plain TF frames with the same ID, each prefixed with a sequence number in 1 byte. Type EVT_CAPT_MORE or EVT_CAPT_DONE indicate whether this is the last frame of the sequence, after which the ID listener should be removed. """ pp = gex.PayloadParser(evt.payload) msg = evt.msg if evt.code == EVT_CAPT_START: if self._trig_buf is not None: raise Exception("Unexpected start of capture") self._trig_ts = evt.timestamp self._trig_buf = bytearray() self._trig_pretrig_len = pp.u32() self._trig_edge = pp.u8() self._trig_next_id = 0 msg.data = pp.tail() # the rest is a regular capture frame with seq self._on_trig_capt(msg) self.client.tf.add_id_listener( msg.id, lambda tf, msg: self._on_trig_capt(msg))
def read_address(self, as_array=False): """ Read the address of a lone device on the bus """ resp = self._query(4) pp = gex.PayloadParser(resp) if as_array: return list(pp.tail()) else: return pp.u64()
def counter_clear(self): """ Restart the free-running counter, returns current value before the clear. This should lose at most 1 tick for signals where f < core clock speed """ resp = self._query(CMD_FREECOUNT_CLEAR) pp = gex.PayloadParser(resp.data) return pp.u32()
def _on_event(self, evt: EventReport): l = [] pp = gex.PayloadParser(evt.payload) snap = pp.u32() changed = pp.u32() for i in range(0, 32): if changed & (1 << i): if i in self._handlers: self._handlers[i]((snap & (1 << i)) != 0, evt.timestamp)
def read_smooth(self): """ Read smoothed values (floats). Returns a dict. """ msg = self._query(CMD_READ_SMOOTHED) pp = gex.PayloadParser(msg) chs = dict() i = 0 while pp.length() > 0: chs[self.channels[i]] = pp.float() i += 1 return chs
def read_raw(self): """ Read raw values. Returns a dict. """ msg = self._query(CMD_READ_RAW) pp = gex.PayloadParser(msg) chs = dict() i = 0 while pp.length() > 0: chs[self.channels[i]] = pp.u16() i += 1 return chs
def read(self): """ Read raw values """ msg = self._query(CMD_READ) pp = gex.PayloadParser(msg) items = [] while pp.length() > 0: items.append(pp.u16()) return items
def _on_event(self, evt: EventReport): if evt.code == 0x00: # trigger interrupt pp = gex.PayloadParser(evt.payload) triggersources = pp.u16() # multiple can happen at once snapshot = pp.u16() for i in range(0, 16): if triggersources & (1 << i): if i in self.handlers: self.handlers[i](snapshot, evt.timestamp)
def get_sample_rate(self): """ Get the current real sample rate as float. Returns tuple (requested:int, real:float) """ msg = self._query(CMD_GET_SAMPLE_RATE) pp = gex.PayloadParser(msg.data) req = pp.u32() real = pp.float() return (req, real)
def set_sample_rate(self, freq: int): """ Set sample rate in Hz. Returns the real achieved frequency as float. """ pb = gex.PayloadBuilder() pb.u32(freq) msg = self._query(CMD_SET_SAMPLE_RATE, pld=pb.close()) pp = gex.PayloadParser(msg.data) req = pp.u32() real = pp.float() self.sample_rate = real return real
def search(self, alarm=False): """ Find all devices, or devices with alarm """ devices = [] resp = self._query(2 if alarm else 1) hasmore = True while hasmore: pp = gex.PayloadParser(resp) hasmore = pp.bool() while pp.length() > 0: devices.append(pp.u64()) if hasmore: resp = self._query(3) return devices
def _handleRx(self, frame): if len(frame) != 64: raise Exception("Frame len not 64") pp = gex.PayloadParser(frame) frame_type = pp.u8() if frame_type == 1: # network address report self._address = list(pp.blob(4)) elif frame_type == 2: slave_addr = pp.u8() pld_len = pp.u8() pld = pp.blob(pld_len) #print("Rx chunk(%d): %s" % (pld_len, pld)) if slave_addr == self._slaveAddr: if self._listener is not None: self._listener(pld)
def _process_direct_resp(self, resp): pp = gex.PayloadParser(resp.data) presc = pp.u8() msec = pp.u16() count = pp.u32() * presc rp = FCAP_Report() if count > 0: sec = msec / 1000 freq = count / sec period = 1 / freq rp.period = period rp.frequency = freq rp.sample_count = count * presc rp.meas_time_ms = msec return rp
def measure_pulse(self, polarity=None, timeout=5): """ Measure a pulse. Optionally set polarity """ if polarity is not None: self.configure(polarity=polarity) resp = self._query(CMD_MEASURE_SINGLE_PULSE, timeout=timeout) pp = gex.PayloadParser(resp.data) mhz = pp.u16() ontime = pp.u32() rp = FCAP_Report() rp.ontime = ontime / (mhz * 1e6) # in seconds rp.clock_freq = mhz * 1e6 rp.sample_count = 1 rp.ontime_raw = ontime return rp
def _lst(frame): pp = gex.PayloadParser(frame.data) if frame.type == EVT_CAPT_MORE or len(frame.data) != 0: index = pp.u8() if index != self._bcap_next_id: self._bcap_done = True raise Exception( "Lost capture data frame! Expected %d, got %d" % (self._bcap_next_id, index)) #return TF.CLOSE XXX self._bcap_next_id = (self._bcap_next_id + 1) % 256 buffer.extend(pp.tail()) if frame.type == EVT_CAPT_DONE: self._bcap_done = True if async: lst(self._parse_buffer(buffer)) self._stream_running = False return TF.CLOSE return TF.STAY
print("Presence: ", ow.test_presence()) print("Starting measure...") ow.write([0x44]) time.sleep(1) print("Scratch:", ow.query([0xBE], 9)) # testing ds1820 temp meas with polling if False: ow = gex.OneWire(client, 'ow') print("Presence: ", ow.test_presence()) print("Starting measure...") ow.write([0x44]) ow.wait_ready() data = ow.query([0xBE], 9) pp = gex.PayloadParser(data) temp = pp.i16() / 2.0 th = pp.i8() tl = pp.i8() reserved = pp.i16() remain = float(pp.u8()) perc = float(pp.u8()) realtemp = temp - 0.25 + (perc - remain) / perc print("Temperature = %f °C (th %d, tl %d)" % (realtemp, th, tl)) if False: buf = client.bulk_read(gex.MSG_INI_READ) print(buf.decode('utf-8'))
def meas(addr): ow.write([0x44], addr=addr) ow.wait_ready() data = ow.query([0xBE], 9, addr=addr) pp = gex.PayloadParser(data) return pp.i16() * 0.0625
def get_calibration_data(self): """ Read ADC calibration data """ msg = self._query(CMD_READ_CAL_CONSTANTS) return ADC_CalData(gex.PayloadParser(msg.data))
def counter_read(self): """ Read the free counter value """ resp = self._query(CMD_FREECOUNT_READ) pp = gex.PayloadParser(resp.data) return pp.u32()
def test_presence(self): """ Test presence fo any 1wire devices on the bus """ resp = self._query(0) pp = gex.PayloadParser(resp) return pp.bool()
def get_channel_count(self, confirm=True): """ Read nbr of channels """ resp = self._query(CMD_GET_CH_COUNT) pp = gex.PayloadParser(resp) return pp.u8()
def read(self): """ Read pins """ msg = self._query(0x00) pp = gex.PayloadParser(msg) return pp.u16()
def get_len(self): """ Get the neopixel strip length """ resp = self._query(10) pp = gex.PayloadParser(resp) return pp.u16()
import time import gex # basic NDIR CO2 sensor readout with gex.Client(gex.TrxRawUSB()) as client: ser = gex.USART(client, 'ser') while True: ser.clear_buffer() ser.write([0xFF, 0x01, 0x86, 0, 0, 0, 0, 0, 0x79]) data = ser.receive(9, decode=None) pp = gex.PayloadParser(data, endian="big").skip(2) print("%d ppm CO₂" % pp.u16()) time.sleep(1)