Skip to content

Commit 4f9c423

Browse files
authored
Merge branch 'master' into Fix/issue-18-use-threading
2 parents bbd7680 + f05ca67 commit 4f9c423

File tree

3 files changed

+43
-34
lines changed

3 files changed

+43
-34
lines changed

example.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919

2020
ppk2_test = PPK2_API(ppk2_port)
2121
ppk2_test.get_modifiers()
22-
ppk2_test.use_ampere_meter() # set ampere meter mode
23-
ppk2_test.toggle_DUT_power("OFF") # disable DUT power
22+
ppk2_test.set_source_voltage(3300)
23+
24+
ppk2_test.use_source_meter() # set source meter mode
25+
ppk2_test.toggle_DUT_power("ON") # enable DUT power
2426

2527
ppk2_test.start_measuring() # start measuring
2628
# measurements are a constant stream of bytes
@@ -34,14 +36,16 @@
3436
print(f"Average of {len(samples)} samples is: {sum(samples)/len(samples)}uA")
3537
time.sleep(0.01)
3638

37-
ppk2_test.toggle_DUT_power("ON")
39+
ppk2_test.toggle_DUT_power("OFF") # disable DUT power
40+
41+
ppk2_test.use_ampere_meter() # set ampere meter mode
3842

3943
ppk2_test.start_measuring()
4044
for i in range(0, 1000):
4145
read_data = ppk2_test.get_data()
4246
if read_data != b'':
4347
samples = ppk2_test.get_samples(read_data)
4448
print(f"Average of {len(samples)} samples is: {sum(samples)/len(samples)}uA")
45-
time.sleep(0.001) # lower time between sampling -> less samples read in one sampling period
49+
time.sleep(0.01) # lower time between sampling -> less samples read in one sampling period
4650

4751
ppk2_test.stop_measuring()

example_mp.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,51 @@
11

22
"""
3-
Basic usage of PPK2 Python API - multiprocessing version
3+
Basic usage of PPK2 Python API - multiprocessing version.
44
The basic ampere mode sequence is:
55
1. read modifiers
66
2. set ampere mode
77
3. read stream of data
88
"""
99
import time
10-
from ppk2_api.ppk2_api import PPK2_MP
10+
from ppk2_api.ppk2_api import PPK2_MP as PPK2_API
1111

12-
ppk2s_connected = PPK2_MP.list_devices()
12+
ppk2s_connected = PPK2_API.list_devices()
1313
if(len(ppk2s_connected) == 1):
1414
ppk2_port = ppk2s_connected[0]
1515
print(f'Found PPK2 at {ppk2_port}')
1616
else:
1717
print(f'Too many connected PPK2\'s: {ppk2s_connected}')
1818
exit()
1919

20-
ppk2_test = PPK2_MP(ppk2_port)
20+
ppk2_test = PPK2_API(ppk2_port, buffer_max_size_seconds=1, buffer_chunk_seconds=0.01)
2121
ppk2_test.get_modifiers()
22-
ppk2_test.use_ampere_meter() # set ampere meter mode
23-
ppk2_test.toggle_DUT_power("OFF") # disable DUT power
22+
ppk2_test.set_source_voltage(3300)
2423

25-
ppk2_test.start_measuring() # start measuring
24+
ppk2_test.use_source_meter() # set source meter mode
25+
ppk2_test.toggle_DUT_power("ON") # enable DUT power
2626

27+
ppk2_test.start_measuring() # start measuring
2728
# measurements are a constant stream of bytes
28-
# multiprocessing variant starts a process in the background which constantly
29-
# polls the device in order to prevent losing samples. It will buffer the
30-
# last 10s (by default) of data so get_data() can be called less frequently.
31-
for i in range(0, 10):
29+
# the number of measurements in one sampling period depends on the wait between serial reads
30+
# it appears the maximum number of bytes received is 1024
31+
# the sampling rate of the PPK2 is 100 samples per millisecond
32+
for i in range(0, 1000):
3233
read_data = ppk2_test.get_data()
3334
if read_data != b'':
3435
samples = ppk2_test.get_samples(read_data)
3536
print(f"Average of {len(samples)} samples is: {sum(samples)/len(samples)}uA")
36-
time.sleep(0.5)
37+
time.sleep(0.001)
3738

38-
ppk2_test.toggle_DUT_power("ON")
39+
ppk2_test.toggle_DUT_power("OFF") # disable DUT power
40+
41+
ppk2_test.use_ampere_meter() # set ampere meter mode
3942

4043
ppk2_test.start_measuring()
41-
for i in range(0, 10):
44+
for i in range(0, 1000):
4245
read_data = ppk2_test.get_data()
4346
if read_data != b'':
4447
samples = ppk2_test.get_samples(read_data)
4548
print(f"Average of {len(samples)} samples is: {sum(samples)/len(samples)}uA")
46-
time.sleep(0.5) # lower time between sampling -> less samples read in one sampling period
47-
48-
ppk2_test.stop_measuring()
49+
time.sleep(0.001) # lower time between sampling -> less samples read in one sampling period
4950

51+
ppk2_test.stop_measuring()

src/ppk2_api/ppk2_api.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
The PPK2 uses Serial communication.
44
The official nRF Connect Power Profiler was used as a reference: https://github.com/NordicSemiconductor/pc-nrfconnect-ppk
55
"""
6-
import threading
6+
77
import time
88
import serial
99
import struct
1010
import logging
1111
import os
1212
import queue
13-
13+
import threading
1414

1515
class PPK2_Command():
1616
"""Serial command opcodes"""
@@ -243,7 +243,7 @@ def stop_measuring(self):
243243
self._write_serial((PPK2_Command.AVERAGE_STOP, ))
244244

245245
def set_source_voltage(self, mV):
246-
"""Inits device - based on observation only REGULATOR_SET is the command.
246+
"""Inits device - based on observation only REGULATOR_SET is the command.
247247
The other two values correspond to the voltage level.
248248
249249
800mV is the lowest setting - [3,32] - the values then increase linearly
@@ -290,7 +290,7 @@ def get_adc_result(self, current_range, adc_value):
290290
self.rolling_avg = adc
291291
else:
292292
self.rolling_avg = self.spike_filter_alpha * adc + (1 - self.spike_filter_alpha) * self.rolling_avg
293-
293+
294294
if self.rolling_avg4 is None:
295295
self.rolling_avg4 = adc
296296
else:
@@ -313,7 +313,7 @@ def get_adc_result(self, current_range, adc_value):
313313
adc = self.rolling_avg4
314314
else:
315315
adc = self.rolling_avg
316-
316+
317317
self.after_spike -= 1
318318

319319
self.prev_range = current_range
@@ -360,7 +360,7 @@ def get_samples(self, buf):
360360

361361
class PPK_Fetch(threading.Thread):
362362
'''
363-
Background process for polling the data in multi-threading variant
363+
Background process for polling the data in multi-threaded variant
364364
'''
365365
def __init__(self, ppk2, quit_evt, buffer_len_s=10, buffer_chunk_s=0.5):
366366
super().__init__()
@@ -397,7 +397,7 @@ def run(self):
397397
self._buffer_q.get()
398398
local_buffer = local_buffer[self._buffer_chunk:]
399399
self._last_timestamp = tm_now
400-
#print(len(d), len(local_buffer), self._buffer_q.qsize())
400+
# print(len(d), len(local_buffer), self._buffer_q.qsize())
401401

402402
# calculate stats
403403
s += len(d)
@@ -423,7 +423,7 @@ def get_data(self):
423423
count = 0
424424
while True:
425425
try:
426-
ret += self._buffer_q.get(timeout=0.01) # get_nowait sometimes skips a chunk for some reason
426+
ret += self._buffer_q.get(timeout=0.001) # get_nowait sometimes skips a chunk for some reason
427427
count += 1
428428
except queue.Empty:
429429
break
@@ -435,15 +435,18 @@ class PPK2_MP(PPK2_API):
435435
Multiprocessing variant of the object. The interface is the same as for the regular one except it spawns
436436
a background process on start_measuring()
437437
'''
438-
def __init__(self, port, buffer_seconds=10):
438+
def __init__(self, port, buffer_max_size_seconds=10, buffer_chunk_seconds=0.1):
439439
'''
440440
port - port where PPK2 is connected
441-
buffer_seconds - how many seconds of data to keep in the buffer
441+
buffer_max_size_seconds - how many seconds of data to keep in the buffer
442+
buffer_chunk_seconds - how many seconds of data to put in the queue at once
442443
'''
443444
super().__init__(port)
445+
444446
self._fetcher = None
445447
self._quit_evt = threading.Event()
446-
self._buffer_seconds = buffer_seconds
448+
self._buffer_max_size_seconds = buffer_max_size_seconds
449+
self._buffer_chunk_seconds = buffer_chunk_seconds
447450

448451
def __del__(self):
449452
"""Destructor"""
@@ -466,8 +469,8 @@ def start_measuring(self):
466469
self._quit_evt.clear()
467470
if self._fetcher is not None:
468471
return
469-
470-
self._fetcher = PPK_Fetch(self, self._quit_evt, self._buffer_seconds)
472+
473+
self._fetcher = PPK_Fetch(self, self._quit_evt, self._buffer_max_size_seconds, self._buffer_chunk_seconds)
471474
self._fetcher.start()
472475

473476
def stop_measuring(self):

0 commit comments

Comments
 (0)