我如何从 Nonin Xpod PulseOxy 传感器获取数据到 Raspberry Pi
How do I get data from Nonin Xpod PulseOxy Sensor to Raspberry Pi
我正在使用 Raspberry Pi 2 板,并且已将 Nonin Xpod PulseOxy 传感器连接到它。我在 python 脚本中使用 PyUSB 模块来访问传感器的基本数据,如供应商 ID、产品 ID 等。我无法设置设备的配置并继续收集读数。我尝试安装 http://www.ftdichip.com/ 为 Raspberry Pi 提供的 ftdi 驱动程序。但是我的 python 脚本中没有导入 d2xx 模块。
我不熟悉为设备编写代码。请帮助我如何进行。
我厌倦了以下内容:
import usb.core
import usb.util
dev = usb.core.find(idVendor=0x0424, idProduct=0x9514)
dev.set_configuration()
我在设置配置中遇到错误。
Traceback (most recent call last):
File "s1.py", line 18, in <module>
main()
File "s1.py", line 13, in main
dev.set_configuration()
File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 799, in set_configuration
self._ctx.managed_set_configuration(self, configuration)
File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 128, in managed_set_configuration
self.backend.set_configuration(self.handle, cfg.bConfigurationValue)
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb0.py", line 439, in set_configuration
_check(_lib.usb_set_configuration(dev_handle, config_value))
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb0.py", line 380, in _check
raise USBError(errmsg, ret)
usb.core.USBError: [Errno None] could not set config 1: Device or resource busy
传感器的数据表是 Nonin Xpod 3012LP
首先感谢您的回答。我已尝试安装 libftd2XX,但在使用命令 make -B
后出现以下错误
for n in BitMode EEPROM/erase EEPROM/read EEPROM/write EEPROM/user/read EEPROM/user/size EEPROM/user/write Events LargeRead MultiThread SetVIDPID Simple Timeouts ; do make -C $n || exit 1; done
make[1]: Entering directory '/home/pi/iiitd/release/examples/BitMode'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/BitMode'
make[1]: Entering directory '/home/pi/iiitd/release/examples/EEPROM/erase'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/EEPROM/erase'
make[1]: Entering directory '/home/pi/iiitd/release/examples/EEPROM/read'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/EEPROM/read'
make[1]: Entering directory '/home/pi/iiitd/release/examples/EEPROM/write'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/EEPROM/write'
make[1]: Entering directory '/home/pi/iiitd/release/examples/EEPROM/user/read'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/EEPROM/user/read'
make[1]: Entering directory '/home/pi/iiitd/release/examples/EEPROM/user/size'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/EEPROM/user/size'
make[1]: Entering directory '/home/pi/iiitd/release/examples/EEPROM/user/write'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/EEPROM/user/write'
make[1]: Entering directory '/home/pi/iiitd/release/examples/Events'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/Events'
make[1]: Entering directory '/home/pi/iiitd/release/examples/LargeRead'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/LargeRead'
make[1]: Entering directory '/home/pi/iiitd/release/examples/MultiThread'
gcc main.c -o multi -Wall -Wextra -L. -lftd2xx -Wl,-rpath /usr/local/lib
/usr/bin/ld: /tmp/ccStfEVz.o: undefined reference to symbol 'pthread_join@@GLIBC_2.4'
//lib/arm-linux-gnueabihf/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: ld returned 1 exit status
Makefile:9: recipe for target 'multi' failed
make[1]: *** [multi] Error 1
make[1]: Leaving directory '/home/pi/iiitd/release/examples/MultiThread'
Makefile:11: recipe for target 'subdirs' failed
make: *** [subdirs] Error 1
我没用过Nonin Xpod PulseOxy Sensor,现在接口不清楚。如果有交流的数据表请post那个。
如果设备显示为虚拟 com 端口,Raspberry PI 应该准备好库,因此从 Python,pySerial 应该可以工作。
如果需要使用FTDI D2XX库,首先安装native library first(direct link). Details available here and check out the readme,尤其是这部分:
> If the message "FT_Open failed" appears:
> Perhaps the kernel automatically loaded another driver for the
> FTDI USB device.
>
> `sudo lsmod`
>
> If "ftdi_sio" is listed:
> Unload it (and its helper module, usbserial), as follows.
>
> `sudo rmmod ftdi_sio`
> `sudo rmmod usbserial`
>
> Otherwise, it's possible that libftd2xx does not recognise your
> device's Vendor and Product Identifiers. Call FT_SetVIDPID before
> calling FT_Open/FT_OpenEx/FT_ListDevices.
我发现 Raspberry PI 默认加载 ftdi_sio 和 usbserial 驱动程序,因此必须先禁用它们,然后才能使用 D2XX 库列出 FTDI 设备和详细信息。确保您可以先编译他们的示例(库已正确链接),然后 运行 他们的示例(您会看到列出的 FTDI 设备以及详细信息(例如 VID/PID/etc.))。只需导航到示例文件夹并使用 make -b
。
请注意,您可能需要 运行 它们作为 sudo。
如果上述操作正常,剩下的就是为 D2XX 库安装 Python 绑定。我用过这些 ftd2xx Python bindings。设置应该很简单。如果出现错误,请检查 ftd2xx 是否在正确的路径中查找 .so 文件 (/usr/local/lib/libftd2xx.so
)
安装完成后,您可以先尝试列出您的设备:
import ftd2xx
print ftd2xx.listDevices()
更新
看起来只有一个样本有错误,这取决于 pthreads 库。我现在尝试安装 ftd2xx python 库。
令人困惑的部分是普通串行应该工作:
"Green Wire = Serial Output: 9600 Baud, 8 data bits, One Start bit
(Start bit =0), One Stop bit (Stop bit = 1), No Parity."
你应该尝试用串行库简单地读取数据:
import serial,time
def stringAsHex(s):
return ":".join("{:02x}".format(ord(c)) for c in s)
sensor = serial.Serial('/dev/ttyACM0',timeout=1)#should default to 9600, 8 data bits, 1 stop bit, but feel free to use the constructor arguments to configure it
while True:
data = sensor.read()
if len(data) > 0:
print "data str:",data,"hex:",stringAsHex(data)
请务必阅读有关 3.8v 到 3.3v 转换的说明以及基于所用电阻器的不同数据格式(数据表第 3 页和第 4 页)。
注意我使用的端口 (/dev/ttyACM0
):这通常是新 Arduino 端口显示的样子。你必须检查你的设备是什么(可能显示为 /dev/ttyUSB0
,在将你的设备连接到 USB 端口之前和之后执行 ls /dev/tty*
)。
我终于可以使用以下代码从传感器获取数据了:
import serial,time,sys
#returns non zero value if the bit is set
def testbit(value,bit):
return (value & 1 << bit)
#converts raw string to hexadecimal
def stringAsHex(s):
return ":".join("{:02x}".format(ord(c)) for c in s)
#extract the information from a packet
def processpacket(p):
msb=p[19][3]
lsb=p[20][3]
hr= ((msb<<7)|(lsb)) & 0x1ff
emsb=p[21][3]
elsb=p[22][3]
ehr= ((emsb<<7)|(elsb)) & 0x1ff
oxy=p[8][3]
ol= oxy & 0x7f
eoxy=p[16][3]
eol= eoxy & 0x7f
#print "Pulse Rate:", hr
#print "Oxygen Level:", ol
#if hr != 511 and ol !=127 :
if hr > 40 and hr < 200 and ol > 85 and ol < 127:
#print "Pulse Rate:", hr
#print "Extended Pulse Rate:",ehr
#print "Oxygen Level:", ol
#print "Extended Oxygen Level:",eol
return hr,ol
else:
#print "Place your finger"
hr=0
ol=0
return hr,ol
def readsensor(n):
sd=[]
val=[]
sensor = serial.Serial('/dev/ttyUSB0',timeout=1,baudrate=9600)
frame=[]
fc=0
packet=[]
while True:
frame=[]
data = sensor.read()
d=stringAsHex(data)
intdata=int(d,16)
#print 'loop 0'
#print intdata
if intdata == 1:
data1 = sensor.read()
d1=stringAsHex(data1)
intdata1=int(d1,16)
#print 'if intdata == 1 sensor.read:',intdata1
tb = testbit(intdata1,0)
#print "test bit:", tb
if tb > 0 :
#print 'packet began'
frame.append(intdata)
frame.append(intdata1)
fc = 2
cnt = 0
wc=0
while ( fc <= 125 ):
wc = wc + 1
#print 'while inside',wc
data = sensor.read()
d=stringAsHex(data)
intdata=int(d,16)
if len(frame)<=5:
frame.append(intdata)
else:
#print 'oversized frame'
break
#print 'fc',fc
fc = fc + 1
if fc%5 == 0:
#print 'if fc%5 == 0'
#print frame
if frame[0] == 1:
cnt = cnt + 1
#print cnt
packet.append(frame)
frame=[]
#print 'frame empty'
else:
#print 'else fc%5',fc
break
if fc == 126:
n = n - 1
if n >= 0:
h,o= processpacket(packet)
sd.append([h,o])
#print sd
packet=[]
#print 'packet empty'
#print "***********Packet received***********"
fc = 1
else:
return sd
else:
continue
else:
continue
print readsensor(20)
我意识到传感器正在给出字符。然后我将数据转换成整数并放入帧中并将帧组织成一个数据包(数据sheet中提到了帧和数据包的详细信息)。然后我从数据包中提取传感器读数。
框架和数据包使用 python.
中的列表实现
我正在使用 Raspberry Pi 2 板,并且已将 Nonin Xpod PulseOxy 传感器连接到它。我在 python 脚本中使用 PyUSB 模块来访问传感器的基本数据,如供应商 ID、产品 ID 等。我无法设置设备的配置并继续收集读数。我尝试安装 http://www.ftdichip.com/ 为 Raspberry Pi 提供的 ftdi 驱动程序。但是我的 python 脚本中没有导入 d2xx 模块。 我不熟悉为设备编写代码。请帮助我如何进行。
我厌倦了以下内容:
import usb.core
import usb.util
dev = usb.core.find(idVendor=0x0424, idProduct=0x9514)
dev.set_configuration()
我在设置配置中遇到错误。
Traceback (most recent call last):
File "s1.py", line 18, in <module>
main()
File "s1.py", line 13, in main
dev.set_configuration()
File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 799, in set_configuration
self._ctx.managed_set_configuration(self, configuration)
File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 128, in managed_set_configuration
self.backend.set_configuration(self.handle, cfg.bConfigurationValue)
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb0.py", line 439, in set_configuration
_check(_lib.usb_set_configuration(dev_handle, config_value))
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb0.py", line 380, in _check
raise USBError(errmsg, ret)
usb.core.USBError: [Errno None] could not set config 1: Device or resource busy
传感器的数据表是 Nonin Xpod 3012LP
首先感谢您的回答。我已尝试安装 libftd2XX,但在使用命令 make -B
for n in BitMode EEPROM/erase EEPROM/read EEPROM/write EEPROM/user/read EEPROM/user/size EEPROM/user/write Events LargeRead MultiThread SetVIDPID Simple Timeouts ; do make -C $n || exit 1; done
make[1]: Entering directory '/home/pi/iiitd/release/examples/BitMode'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/BitMode'
make[1]: Entering directory '/home/pi/iiitd/release/examples/EEPROM/erase'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/EEPROM/erase'
make[1]: Entering directory '/home/pi/iiitd/release/examples/EEPROM/read'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/EEPROM/read'
make[1]: Entering directory '/home/pi/iiitd/release/examples/EEPROM/write'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/EEPROM/write'
make[1]: Entering directory '/home/pi/iiitd/release/examples/EEPROM/user/read'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/EEPROM/user/read'
make[1]: Entering directory '/home/pi/iiitd/release/examples/EEPROM/user/size'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/EEPROM/user/size'
make[1]: Entering directory '/home/pi/iiitd/release/examples/EEPROM/user/write'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/EEPROM/user/write'
make[1]: Entering directory '/home/pi/iiitd/release/examples/Events'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/Events'
make[1]: Entering directory '/home/pi/iiitd/release/examples/LargeRead'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/pi/iiitd/release/examples/LargeRead'
make[1]: Entering directory '/home/pi/iiitd/release/examples/MultiThread'
gcc main.c -o multi -Wall -Wextra -L. -lftd2xx -Wl,-rpath /usr/local/lib
/usr/bin/ld: /tmp/ccStfEVz.o: undefined reference to symbol 'pthread_join@@GLIBC_2.4'
//lib/arm-linux-gnueabihf/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: ld returned 1 exit status
Makefile:9: recipe for target 'multi' failed
make[1]: *** [multi] Error 1
make[1]: Leaving directory '/home/pi/iiitd/release/examples/MultiThread'
Makefile:11: recipe for target 'subdirs' failed
make: *** [subdirs] Error 1
我没用过Nonin Xpod PulseOxy Sensor,现在接口不清楚。如果有交流的数据表请post那个。
如果设备显示为虚拟 com 端口,Raspberry PI 应该准备好库,因此从 Python,pySerial 应该可以工作。
如果需要使用FTDI D2XX库,首先安装native library first(direct link). Details available here and check out the readme,尤其是这部分:
> If the message "FT_Open failed" appears:
> Perhaps the kernel automatically loaded another driver for the
> FTDI USB device.
>
> `sudo lsmod`
>
> If "ftdi_sio" is listed:
> Unload it (and its helper module, usbserial), as follows.
>
> `sudo rmmod ftdi_sio`
> `sudo rmmod usbserial`
>
> Otherwise, it's possible that libftd2xx does not recognise your
> device's Vendor and Product Identifiers. Call FT_SetVIDPID before
> calling FT_Open/FT_OpenEx/FT_ListDevices.
我发现 Raspberry PI 默认加载 ftdi_sio 和 usbserial 驱动程序,因此必须先禁用它们,然后才能使用 D2XX 库列出 FTDI 设备和详细信息。确保您可以先编译他们的示例(库已正确链接),然后 运行 他们的示例(您会看到列出的 FTDI 设备以及详细信息(例如 VID/PID/etc.))。只需导航到示例文件夹并使用 make -b
。
请注意,您可能需要 运行 它们作为 sudo。
如果上述操作正常,剩下的就是为 D2XX 库安装 Python 绑定。我用过这些 ftd2xx Python bindings。设置应该很简单。如果出现错误,请检查 ftd2xx 是否在正确的路径中查找 .so 文件 (/usr/local/lib/libftd2xx.so
)
安装完成后,您可以先尝试列出您的设备:
import ftd2xx
print ftd2xx.listDevices()
更新
看起来只有一个样本有错误,这取决于 pthreads 库。我现在尝试安装 ftd2xx python 库。 令人困惑的部分是普通串行应该工作:
"Green Wire = Serial Output: 9600 Baud, 8 data bits, One Start bit (Start bit =0), One Stop bit (Stop bit = 1), No Parity."
你应该尝试用串行库简单地读取数据:
import serial,time
def stringAsHex(s):
return ":".join("{:02x}".format(ord(c)) for c in s)
sensor = serial.Serial('/dev/ttyACM0',timeout=1)#should default to 9600, 8 data bits, 1 stop bit, but feel free to use the constructor arguments to configure it
while True:
data = sensor.read()
if len(data) > 0:
print "data str:",data,"hex:",stringAsHex(data)
请务必阅读有关 3.8v 到 3.3v 转换的说明以及基于所用电阻器的不同数据格式(数据表第 3 页和第 4 页)。
注意我使用的端口 (/dev/ttyACM0
):这通常是新 Arduino 端口显示的样子。你必须检查你的设备是什么(可能显示为 /dev/ttyUSB0
,在将你的设备连接到 USB 端口之前和之后执行 ls /dev/tty*
)。
我终于可以使用以下代码从传感器获取数据了:
import serial,time,sys
#returns non zero value if the bit is set
def testbit(value,bit):
return (value & 1 << bit)
#converts raw string to hexadecimal
def stringAsHex(s):
return ":".join("{:02x}".format(ord(c)) for c in s)
#extract the information from a packet
def processpacket(p):
msb=p[19][3]
lsb=p[20][3]
hr= ((msb<<7)|(lsb)) & 0x1ff
emsb=p[21][3]
elsb=p[22][3]
ehr= ((emsb<<7)|(elsb)) & 0x1ff
oxy=p[8][3]
ol= oxy & 0x7f
eoxy=p[16][3]
eol= eoxy & 0x7f
#print "Pulse Rate:", hr
#print "Oxygen Level:", ol
#if hr != 511 and ol !=127 :
if hr > 40 and hr < 200 and ol > 85 and ol < 127:
#print "Pulse Rate:", hr
#print "Extended Pulse Rate:",ehr
#print "Oxygen Level:", ol
#print "Extended Oxygen Level:",eol
return hr,ol
else:
#print "Place your finger"
hr=0
ol=0
return hr,ol
def readsensor(n):
sd=[]
val=[]
sensor = serial.Serial('/dev/ttyUSB0',timeout=1,baudrate=9600)
frame=[]
fc=0
packet=[]
while True:
frame=[]
data = sensor.read()
d=stringAsHex(data)
intdata=int(d,16)
#print 'loop 0'
#print intdata
if intdata == 1:
data1 = sensor.read()
d1=stringAsHex(data1)
intdata1=int(d1,16)
#print 'if intdata == 1 sensor.read:',intdata1
tb = testbit(intdata1,0)
#print "test bit:", tb
if tb > 0 :
#print 'packet began'
frame.append(intdata)
frame.append(intdata1)
fc = 2
cnt = 0
wc=0
while ( fc <= 125 ):
wc = wc + 1
#print 'while inside',wc
data = sensor.read()
d=stringAsHex(data)
intdata=int(d,16)
if len(frame)<=5:
frame.append(intdata)
else:
#print 'oversized frame'
break
#print 'fc',fc
fc = fc + 1
if fc%5 == 0:
#print 'if fc%5 == 0'
#print frame
if frame[0] == 1:
cnt = cnt + 1
#print cnt
packet.append(frame)
frame=[]
#print 'frame empty'
else:
#print 'else fc%5',fc
break
if fc == 126:
n = n - 1
if n >= 0:
h,o= processpacket(packet)
sd.append([h,o])
#print sd
packet=[]
#print 'packet empty'
#print "***********Packet received***********"
fc = 1
else:
return sd
else:
continue
else:
continue
print readsensor(20)
我意识到传感器正在给出字符。然后我将数据转换成整数并放入帧中并将帧组织成一个数据包(数据sheet中提到了帧和数据包的详细信息)。然后我从数据包中提取传感器读数。 框架和数据包使用 python.
中的列表实现