From dbce1f376378eff82f0d903b0ae564afd03efa8c Mon Sep 17 00:00:00 2001 From: NejcKle Date: Fri, 2 Jun 2023 11:42:57 +0200 Subject: [PATCH 1/3] Add digital channels --- example.py | 22 ++++++++++++++++++-- example_mp.py | 38 ++++++++++++++++++++++++++++------ src/ppk2_api/ppk2_api.py | 44 ++++++++++++++++++++++++++++++++-------- 3 files changed, 87 insertions(+), 17 deletions(-) diff --git a/example.py b/example.py index e892231..10058e2 100644 --- a/example.py +++ b/example.py @@ -32,8 +32,17 @@ for i in range(0, 1000): read_data = ppk2_test.get_data() if read_data != b'': - samples = ppk2_test.get_samples(read_data) + samples, raw_digital = ppk2_test.get_samples(read_data) print(f"Average of {len(samples)} samples is: {sum(samples)/len(samples)}uA") + + # Raw digital contains the raw digital data from the PPK2 + # The number of raw samples is equal to the number of samples in the samples list + # We have to process the raw digital data to get the actual digital data + digital_channels = ppk2_test.digital_channels(raw_digital) + for ch in digital_channels: + # Print last 10 values of each channel + print(ch[-10:]) + print() time.sleep(0.01) ppk2_test.toggle_DUT_power("OFF") # disable DUT power @@ -44,8 +53,17 @@ for i in range(0, 1000): read_data = ppk2_test.get_data() if read_data != b'': - samples = ppk2_test.get_samples(read_data) + samples, raw_digital = ppk2_test.get_samples(read_data) print(f"Average of {len(samples)} samples is: {sum(samples)/len(samples)}uA") + + # Raw digital contains the raw digital data from the PPK2 + # The number of raw samples is equal to the number of samples in the samples list + # We have to process the raw digital data to get the actual digital data + digital_channels = ppk2_test.digital_channels(raw_digital) + for ch in digital_channels: + # Print last 10 values of each channel + print(ch[-10:]) + print() time.sleep(0.01) # lower time between sampling -> less samples read in one sampling period ppk2_test.stop_measuring() \ No newline at end of file diff --git a/example_mp.py b/example_mp.py index bc16bad..7d68129 100644 --- a/example_mp.py +++ b/example_mp.py @@ -17,10 +17,13 @@ print(f'Too many connected PPK2\'s: {ppk2s_connected}') exit() -ppk2_test = PPK2_API(ppk2_port, buffer_max_size_seconds=1, buffer_chunk_seconds=0.01) +ppk2_test = PPK2_API(ppk2_port, buffer_max_size_seconds=70, buffer_chunk_seconds=0.5) ppk2_test.get_modifiers() ppk2_test.set_source_voltage(3300) +""" +Source mode example +""" ppk2_test.use_source_meter() # set source meter mode ppk2_test.toggle_DUT_power("ON") # enable DUT power @@ -29,23 +32,46 @@ # the number of measurements in one sampling period depends on the wait between serial reads # it appears the maximum number of bytes received is 1024 # the sampling rate of the PPK2 is 100 samples per millisecond -for i in range(0, 1000): +while True: read_data = ppk2_test.get_data() if read_data != b'': - samples = ppk2_test.get_samples(read_data) + samples, raw_digital = ppk2_test.get_samples(read_data) print(f"Average of {len(samples)} samples is: {sum(samples)/len(samples)}uA") + + # Raw digital contains the raw digital data from the PPK2 + # The number of raw samples is equal to the number of samples in the samples list + # We have to process the raw digital data to get the actual digital data + digital_channels = ppk2_test.digital_channels(raw_digital) + for ch in digital_channels: + # Print last 10 values of each channel + print(ch[-10:]) + print() + time.sleep(0.001) ppk2_test.toggle_DUT_power("OFF") # disable DUT power +ppk2_test.stop_measuring() +""" +Ampere mode example +""" ppk2_test.use_ampere_meter() # set ampere meter mode ppk2_test.start_measuring() -for i in range(0, 1000): +while True: read_data = ppk2_test.get_data() if read_data != b'': - samples = ppk2_test.get_samples(read_data) + samples, raw_digital = ppk2_test.get_samples(read_data) print(f"Average of {len(samples)} samples is: {sum(samples)/len(samples)}uA") + + # Raw digital contains the raw digital data from the PPK2 + # The number of raw samples is equal to the number of samples in the samples list + # We have to process the raw digital data to get the actual digital data + digital_channels = ppk2_test.digital_channels(raw_digital) + for ch in digital_channels: + # Print last 10 values of each channel + print(ch[-10:]) + print() time.sleep(0.001) # lower time between sampling -> less samples read in one sampling period -ppk2_test.stop_measuring() \ No newline at end of file +# ppk2_test.stop_measuring() \ No newline at end of file diff --git a/src/ppk2_api/ppk2_api.py b/src/ppk2_api/ppk2_api.py index 8c56078..13b5e43 100644 --- a/src/ppk2_api/ppk2_api.py +++ b/src/ppk2_api/ppk2_api.py @@ -189,11 +189,10 @@ def _generate_mask(self, bits, pos): mask = self._twos_comp(mask) return {"mask": mask, "pos": pos} - def _get_masked_value(self, value, meas): + def _get_masked_value(self, value, meas, is_bits=False): + # print(f"Value: {value}") + # print(f"Meas: {meas}") masked_value = (value & meas["mask"]) >> meas["pos"] - if meas["pos"] == 24: - if masked_value == 255: - masked_value = -1 return masked_value def _handle_raw_data(self, adc_value): @@ -205,10 +204,10 @@ def _handle_raw_data(self, adc_value): bits = self._get_masked_value(adc_value, self.MEAS_LOGIC) analog_value = self.get_adc_result( current_measurement_range, adc_result) * 10**6 - return analog_value + return analog_value, bits except Exception as e: print("Measurement outside of range!") - return None + return None, None @staticmethod def list_devices(): @@ -327,6 +326,26 @@ def _digital_to_analog(self, adc_value): """Convert discrete value to analog value""" return int.from_bytes(adc_value, byteorder="little", signed=False) # convert reading to analog value + def digital_channels(self, bits): + """ + Convert raw digital data to digital channels. + + Returns a 2d matrix with 8 rows (one for each channel). Each row contains HIGH and LOW values for the selected channel. + """ + + # Prepare 2d matrix with 8 rows (one for each channel) + digital_channels = [[], [], [], [], [], [], [], []] + for sample in bits: + digital_channels[0].append((sample & 1) >> 0) + digital_channels[1].append((sample & 2) >> 1) + digital_channels[2].append((sample & 4) >> 2) + digital_channels[3].append((sample & 8) >> 3) + digital_channels[4].append((sample & 16) >> 4) + digital_channels[5].append((sample & 32) >> 5) + digital_channels[6].append((sample & 64) >> 6) + digital_channels[7].append((sample & 128) >> 7) + return digital_channels + def get_samples(self, buf): """ Returns list of samples read in one sampling period. @@ -338,13 +357,16 @@ def get_samples(self, buf): sample_size = 4 # one analog value is 4 bytes in size offset = self.remainder["len"] samples = [] + raw_digital_output = [] first_reading = ( self.remainder["sequence"] + buf[0:sample_size-offset])[:4] adc_val = self._digital_to_analog(first_reading) - measurement = self._handle_raw_data(adc_val) + measurement, bits = self._handle_raw_data(adc_val) if measurement is not None: samples.append(measurement) + if bits is not None: + raw_digital_output.append(bits) offset = sample_size - offset @@ -352,14 +374,18 @@ def get_samples(self, buf): next_val = buf[offset:offset + sample_size] offset += sample_size adc_val = self._digital_to_analog(next_val) - measurement = self._handle_raw_data(adc_val) + measurement, bits = self._handle_raw_data(adc_val) if measurement is not None: samples.append(measurement) + if bits is not None: + raw_digital_output.append(bits) self.remainder["sequence"] = buf[offset:len(buf)] self.remainder["len"] = len(buf)-offset - return samples # return list of samples, handle those lists in PPK2 API wrapper + # return list of samples and raw digital outputs + # handle those lists in PPK2 API wrapper + return samples, raw_digital_output class PPK_Fetch(threading.Thread): From faccfcc3a13dee6e8ddff9c6af12e85e3a055fbc Mon Sep 17 00:00:00 2001 From: NejcKle Date: Fri, 9 Jun 2023 15:31:34 +0200 Subject: [PATCH 2/3] Add newlines to examples, remove unused prints --- example.py | 2 +- example_mp.py | 2 +- src/ppk2_api/ppk2_api.py | 3 --- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/example.py b/example.py index 731aadf..5753754 100644 --- a/example.py +++ b/example.py @@ -66,4 +66,4 @@ print() time.sleep(0.01) # lower time between sampling -> less samples read in one sampling period -ppk2_test.stop_measuring() \ No newline at end of file +ppk2_test.stop_measuring() diff --git a/example_mp.py b/example_mp.py index 8a313cd..183d5ad 100644 --- a/example_mp.py +++ b/example_mp.py @@ -74,4 +74,4 @@ print() time.sleep(0.001) # lower time between sampling -> less samples read in one sampling period -# ppk2_test.stop_measuring() \ No newline at end of file +ppk2_test.stop_measuring() diff --git a/src/ppk2_api/ppk2_api.py b/src/ppk2_api/ppk2_api.py index 13b5e43..58bab9c 100644 --- a/src/ppk2_api/ppk2_api.py +++ b/src/ppk2_api/ppk2_api.py @@ -190,8 +190,6 @@ def _generate_mask(self, bits, pos): return {"mask": mask, "pos": pos} def _get_masked_value(self, value, meas, is_bits=False): - # print(f"Value: {value}") - # print(f"Meas: {meas}") masked_value = (value & meas["mask"]) >> meas["pos"] return masked_value @@ -427,7 +425,6 @@ def run(self): self._buffer_q.get() local_buffer = local_buffer[self._buffer_chunk:] self._last_timestamp = tm_now - # print(len(d), len(local_buffer), self._buffer_q.qsize()) # calculate stats s += len(d) From 719a0b5e993b6bb6617c6e4ee3432ab75fe2e9b4 Mon Sep 17 00:00:00 2001 From: NejcKle Date: Fri, 9 Jun 2023 15:33:14 +0200 Subject: [PATCH 3/3] Change version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b53262e..bab7e24 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ def read(*names, **kwargs): setup( name="ppk2-api", - version="0.9.1", + version="0.9.2", description="API for Nordic Semiconductor's Power Profiler Kit II (PPK 2).", url="https://github.com/IRNAS/ppk2-api-python", packages=find_packages("src"),