Skip to content

Add get CIR ability #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion pypozyx/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from pypozyx.core import PozyxCore

from pypozyx.structures.generic import Data, SingleRegister, dataCheck
from pypozyx.structures.generic import Data, SingleRegister, dataCheck, Buffer
from pypozyx.structures.device import *
from pypozyx.structures.sensor_data import *

Expand Down Expand Up @@ -884,6 +884,63 @@ def getDeviceRangeInfo(self, device_id, device_range, remote_id=None):
assert device_id[0] != 0, 'getDeviceRangeInfo: device ID = 0'
return self.useFunction(POZYX_DEVICE_GETRANGEINFO, device_id, device_range, remote_id)

def getDeviceCir(self, list_offset, data_length, cir_buffer, remote_id=None):
"""
Obtain the CIR buffer of the device
Args:
list_buffer_offset: list of different values of the buffer offset
to start reading the the data bytes. Possible values range
between 0 and 1015. Type: uint16_t
data_length : Data length. The number of coefficients to read from the CIR buffer.
possible values range between 1 and 49.
Kwargs:
remote_id: Remote Pozyx ID. Not et implemented
Returns:
POZYX_SUCCESS, POZYX_FAILURE, POZYX_TIMEOUT

Example usage:

>>> list_offset = range(600,1015,49)
>>> cirbuff = Buffer([0]*96,size=2,signed=1)
>>> self.getDeviceCir(list_offset,49,Buff)
>>> print Buff
"""
if not dataCheck(cir_buffer):
cir_buffer = Buffer(cir_buffer)
if not isinstance(list_offset, list):
list_offset = [list_offset]
status = []
for uoff, offset in enumerate(list_offset):
buff_tmp = Buffer([0] * 96, size=2, signed=1)
status.append(self.getDeviceCirData(offset, data_length, buff_tmp,remote_id))
cir_buffer.fill(uoff * len(buff_tmp.data), buff_tmp.data)
return sum(status) / len(list_offset)

def getDeviceCirData(self, buffer_offset, data_length, cir_buffer, remote_id=None):
"""
Obtain the CIR buffer of the device at a given buffer_offset and a given data_length.
Args:
buffer_offset: CIR buffer offset. This value indicates where the offset inside the CIR
buffer to start reading the the data bytes. Possible values range
between 0 and 1015. Type: uint16_t
data_length : Data length. The number of coefficients to read from the CIR buffer.
possible values range between 1 and 49.
Kwargs:
remote_id: Remote Pozyx ID. Not et implemented
Returns:
POZYX_SUCCESS, POZYX_FAILURE, POZYX_TIMEOUT

Example usage:

>>> cirbuff = Buffer([0]*96,size=2,signed=1)
>>> self.getDeviceCirData(0,49,Buff)
>>> print Buff
"""
if not dataCheck(cir_buffer):
cir_buffer = Buffer(cir_buffer)
params = Data([buffer_offset, data_length], 'Hb')
return self.useFunction(POZYX_CIR_DATA, params, cir_buffer, remote_id)

def setInterruptMask(self, mask, remote_id=None):
"""
Set the Pozyx's interrupt mask.
Expand Down
2 changes: 2 additions & 0 deletions pypozyx/pozyx_serial.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class PozyxSerial(PozyxLib):
def __init__(self, port, baudrate=115200, timeout=0.1, print_output=False):
"""Initializes the PozyxSerial object. See above for details."""
self.print_output = print_output

try:
self.ser = Serial(port, baudrate, timeout=timeout)
except:
Expand Down Expand Up @@ -174,6 +175,7 @@ def regFunction(self, address, params, data):
"""
params.load_hex_string()
s = 'F,%0.2x,%s,%i\r' % (address, params.byte_data, data.byte_size + 1)

try:
r = self.serialExchange(s)
except:
Expand Down
1 change: 1 addition & 0 deletions pypozyx/structures/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ def load(self, data):
self.data[i] = data[i]



class UWBSettings(ByteStructure):
"""
Container for a device's UWB settings.
Expand Down
47 changes: 47 additions & 0 deletions pypozyx/structures/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,50 @@ def __str__(self):
return bin(self.data[0])
else:
return str(self.data[0])



class Buffer(Data):
"""
Buffer is container for the data from a Pozyx buffer.

By default, this represents a UInt8 register. Used for both reading and writing.
The size and whether the data is a 'signed' integer are both changeable by the
user using the size and signed keyword arguments.

Kwargs:
value: list of values of the buffer.
size: Size of each data of the buffer. 1, 2, or 4. Default 0.
signed: Whether the data is signed. unsigned by default.
print_hex: How to print the register output. Hex by default. Special options are 'hex' and 'bin'
other things, such as 'dec', will return decimal output.
"""

def __init__(self, value=[0], size=1, signed=0, print_style='hex'):
self.print_style = print_style
if size == 1:
data_format = 'b'
elif size == 2:
data_format = 'h'
elif size == 4:
data_format = 'i'
if signed == 0:
data_format = data_format.capitalize()
extend_data_format = ''.join([data_format]*len(value))
Data.__init__(self, value, extend_data_format)

def load(self, data, convert=1):
self.data = data

def __str__(self):
if self.print_style is 'hex':
return str([hex(d).capitalize() for d in self.data])
elif self.print_style is 'bin':
return str([bin(d) for d in self.data])
else:
return str([d for d in self.data])

def fill(self,offset,values):
if not isinstance(values,list):
values = [values]
self.data[offset:offset+len(values)] = values
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from distutils.core import setup
from setuptools import setup

setup(
name='pypozyx',
Expand Down
55 changes: 55 additions & 0 deletions tutorials/get_cir.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
ready_to_range.py - Tutorial intended to show how to perform ranging between two Pozyx devices.

It is planned to make a tutorial on the Pozyx site as well just like there is now
one for the Arduino, but their operation is very similar.
You can find the Arduino tutorial here:
https://www.pozyx.io/Documentation/Tutorials/ready_to_range
"""
from pypozyx import *

from pypozyx.definitions.registers import *


port = '/dev/ttyACM1'
p = PozyxSerial(port)

remote_id = 0x6830 # the network ID of the remote device
remote = False # whether to use the given remote device for ranging
if not remote:
remote_id = None

destination_id = 0x6830 # network ID of the ranging destination
range_step_mm = 1000 # distance that separates the amount of LEDs lighting up.


device_range = DeviceRange()
status = p.doRanging(destination_id, device_range, remote_id)
if status:
list_offset = range(0, 1015, 49)
data_length = 49
cir_buffer = Buffer([0] * 98 * len(list_offset), size=2, signed=1)
status_cir = p.getDeviceCir(list_offset, data_length, cir_buffer, remote_id)
if status_cir:
try:
import matplotlib.pyplot as plt
import numpy as np
#  get real and imaginarypart of the cir buffer
real = np.array(cir_buffer.data[0::2])
imag = np.array(cir_buffer.data[1::2])
# create an image of the CIR
cira = real + 1j*imag
# That plots the CIR contains in the buffer.
# It still requires post-procesing to
# re-align delay and received power level.
plt.plot(20*np.log10(abs(cira[:-36])))
plt.show()
except:
print cir_buffer
else:
print 'error in getting cir'
else:
print 'Ranging failed'
4 changes: 2 additions & 2 deletions tutorials/ready_to_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ def ledControl(self, distance):
return status

if __name__ == "__main__":
port = 'COM1' # COM port of the Pozyx device
port = '/dev/ttyACM0' # COM port of the Pozyx device

remote_id = 0x605D # the network ID of the remote device
remote = False # whether to use the given remote device for ranging
if not remote:
remote_id = None

destination_id = 0x1000 # network ID of the ranging destination
destination_id = 0x6830 # network ID of the ranging destination
range_step_mm = 1000 # distance that separates the amount of LEDs lighting up.

pozyx = PozyxSerial(port)
Expand Down