I want to connect the sensor max30100 to the Raspberry Pi board.I think everything is accurate.When I run the code, the red light flashes.I activated I2C.max30100 device address 0x57 is detected. When I put my hand on the sensor, I get the following error.
Error:
max30100 got exception [errno 121] remote i/o error
I use the source code below.
import os
import sys
import time
import max30100
def main():
try:
mx30 = max30100.MAX30100()
mx30.set_mode(max30100.MODE_SPO2)
# mx30.reset()
# time.sleep(1)
# mx30.startup()
# time.sleep(1)
i = 0
while i < 30:
mx30.set_mode(max30100.MODE_HR)
mx30.read_sensor()
# # The latest values are now available via .ir and .red
# print("HeartRate sensor .ir: {} and .red: {}".format(mx30.ir, mx30.red))
# time.sleep(2)
mx30 = max30100.MAX30100()
mx30.reinit()
mx30.set_mode(max30100.MODE_SPO2)
# time.sleep(1)
mx30.read_sensor()
# The latest values are now available via .ir and .red
print("HRate sensor .ir: {} and SpO2 .red: {}".format(mx30.ir, mx30.red))
# temp = mx30.get_temperature()
# print("Temperature {}\n".format(temp))
mx30.reset()
time.sleep(1)
i = i + 1
mx30.reset()
# mx30.shutdown()
except Exception as e:
print("Max30100 got exception {}".format(e))
if __name__ == "__main__":
main()
https://github.com/whilemind/MAX30100u
connection PINS GPIO and sensor max30100
(3.3V -VIN)
(I2C SDA1 - SDA)
(I2C SCL1 - SCL)
(PIN7 - INT )
(GND - GND)
Can anyone help me to fix this issue?
-
1Comments are not for extended discussion; this conversation has been moved to chat. – Ghanima♦ May 4 at 10:12
Question
The OP has setup and successfully detected an I2C MAX30100 Pulse Oximeter and Heart-Rate Sensor module. But when trying to read the sensor, he encounters two problems:
(1) Gets the "Exception remote I/O error [error 121]",
(2) Gets only zero values for the red LED and IR Led outputs.
How to fix it?
Answer
Part A – Setting up and preliminary testing
(1) Suggest to check I2C wiring and use “i2cdetect” and “i2cget” to find max30100 chip at I2C Bus #1, I2C device address 0x57, and Part ID 0x11 or 0x15 at max30100 register address 0xFF, as show below. (Note: MAX30100 Part ID is 0x11, MAX30102 is 0x15)
(2) The OP’s Test Results
(3) Using max30100’s library methods to read PartID register OK.
/ to continue, …
Part B – Pulse Oximeter and Heart Rate Measurements
(1) Hardware Setup
(2) The simplest read sensor program
(3) Minimal program to read registers and sensor
Sample Output
partID = 0x15
revID = 0x3
temperature = 14.9375
ir = 3 red = 1
ir = 3 red = 1
ir = 3 red = 1
ir = 3 red = 1
# max30100test12.py tlfong01 2020may08hkt1941
# Rpi4B buster (2020feb13), linux 4.19.97
# python 3.7.3 (2019dec20) thonny v3.2.7 (2020jan22)
import max30100lib07 as max30100
# *** Test Function ***
sensor1 = max30100.MAX30100()
def setupSensor(sensor):
sensor.reinit()
sensor.set_mode(max30100.MODE_SPO2)
return
def resetSensor(sensor):
sensor.reset()
return
def readRegisters(sensor):
# *** Read PartId ***
partId = sensor.get_part_id()
print('partID =', hex(partId))
# *** Read Rev Id ***
revId = sensor.get_rev_id()
print('revID =', hex(revId))
# *** Read Temperature ***
temperature = sensor.get_temperature()
print('temperature =', temperature)
return
def readSensor(sensor):
totalCount = 4
for count in range(totalCount):
sensor.read_sensor()
print('ir =', sensor.ir, ' red =', sensor.red)
return
# *** Main ***
setupSensor(sensor1)
readRegisters(sensor1)
readSensor(sensor1)
resetSensor(sensor1)
# *** End of program ***
# *** Sample output tlfong01 2020may08hkt2135 ***
'''
>>> %Run max30100test12.py
partID = 0x15
revID = 0x3
temperature = 14.9375
ir = 3 red = 1
ir = 3 red = 1
ir = 3 red = 1
ir = 3 red = 1
>>>
'''
* End of Sample output *
/ to continue, …
References
(1) MAX30100 Pulse Oximeter and Heart-Rate Sensor IC for Wearable Health Datasheet – Maxim
(2) MAX30102 High-Sensitivity Pulse Oximeter and Heart-Rate Sensor for Wearable Health – Maxim
(3) whilemind/MAX30100u max30100 Library
(4) whilemind/MAX30100u max30100 Class (max30100.py)
(5) whilemind/MAX30100u max30100 Test (test_max30100.py)
(6) mfitzp/max30100 max30100 Library
(8) Amazon MAX30100 Pulse Oximeter Heart Rate Sensor Module – Lysignal
(9) AliEXpress GY-MAX30100 Pulse Oximeter Heart Rate Sensor Module – US$7
(10) TaoBao Risym GY-MAX30100 MAX30102 Pulse Oximeter Heart Rate Sensor Module – ¥35
(11) Amazon MAX30102 Pulse Oximeter Heart Rate Sensor Module
(12) Pulse Oximeter Instructable – MolecularD 2019sep
(13) max30100/102 pulse sensor discussion – ParticleCommunity
(11) TaoBao GY-MAX30100 MAX30102 Pulse Oximeter and Heart-Rate Sensor – ¥35
(12) Pulse Oximeter Instructable – MolecularD 2019sep
(13) Amazon max30102 Pulse Oximeter and Heart-Rate Sensor
(14) Particle.Community max30100 Forum Discussion
(15) Implementing pulse oximeter using MAX30100 Blog – Raivis Strogonovs 2017
(16) Max30100 Heart Rate Monitor Youtube Video – Maxim
(17) AD8232 ECG / Haeart Rate Sensor Rpi.StackExchange Forum Discusson
(18) Oxygen Saturation – Wikipedia
(19) Pull-up Resistors Tutorial – Electronics.Tutorials
(20) Application note AN10441 Level shifting techniques in I2C-bus design R0.1 2007jun18 – NXP
(21) I2C Bus Pullup Resistor Calculation, Application Report SLVA689, TI 2015feb
(22) Setting up multiple I2C buses using dtoverlay [Rpi4B] – rpi.stackexchange forum post 2019sep30
(23) What is Rpi4B I2C Maximum Speed?
(24) A Guide to Voltage Translation With TXS-Type Translators – TI
(25) MAX30100/02 Oximeter – How to fix wrong board – Valeriy Yatsenkov 2018aug22
(26) SC6206B LDO 65K5 (1V5 to 5V0, 250 mA) Datasheet – LCSC
(28) How pulse oximeters work explained simply – Howeauipmentworks
(30) MAX30105 Particle and Pulse Oxmeter (Vin 5V, green LED won’t work if Vin is 3V3)
(31) Bash V5.0 User Manual – 2019may
/ to continue, …
Appendices
*Appendix A – MAX30100 *
/ to continue, …
Figures
Fig 1 – MAX3010x System Diagram
Fig 2 – MAX3010x Function Diagram
Fig 3 – MAX3010x Register Map Summary
Fig 4 – GY-MAX30102 Module Schematic
Fig 5 – GY-MAX00 ProductSheet
Fig 6 – GY-MAX30100 PCB Components Layout Diagram
Fig 7 – Rpi4B to MAX30100 Module Wiring Diagram
Fig 8 – MAX30102 PCB and Components Layout
Program Listings
(1) read_max30100.py tlfong01 2020may05hkt1936
# read_max30100.py tlfong01 2020may05hkt1936
# Rpi4B buster (release 2020feb13, linux 4.19.97), thonny v3.2.7 (release 2020jan22)
# Reference: https://github.com/whilemind/MAX30100u/blob/master/test_max30100.py
import max30100
# import max30100lib07 as max30100
# *** Test Functions ***
def readMax30100PartIdRegister():
sensor = max30100.MAX30100()
sensor.reinit()
sensor.set_mode(max30100.MODE_SPO2)
partIdRegisterContents = sensor.get_part_id()
# partIdRegisterContents = 'fakeFakeFake'
print('max30100 Part ID register contents =', partIdRegisterContents)
sensor.reset()
return
# *** Main ***
readMax30100PartIdRegister()
# End of program
(2) Setting up multiple I2C buses
# fi2c62.py tlfong01 2019aug28hkt1433
from time import sleep
import smbus
import fprint53 as fprint
import ftime53 as ftime
# I2c Bus Setup Notes
# pi@raspberrypi:~ $ date Wed 28 Aug 2019 03:26:24 PM HKT
# pi@raspberrypi:~ $ uname -a
# Linux raspberrypi 4.19.58-v7l+ #1245 SMP Fri Jul 12 17:31:45 BST 2019 armv7l GNU/Linux
# pi@raspberrypi:~ $ sudo nano /boot/config.txt
# dtoverlay=i2c1,pins_2_3 (board pins 3, 5)
# dtoverlay=i2c3,pins_4_5 (board pins 7, 29)
# dtoverlay=i2c4,pins_6_7 (board pins 31, 26)
# dtoverlay=i2c5,pins_12_13 (board pins 32, 33)
# dtoverlay=i2c6,pins_22_23 (board pins 15, 16)
# pi@raspberrypi:~ $ ls /dev/i2c*
# /dev/i2c-1 /dev/i2c-3 /dev/i2c-4 /dev/i2c-5 /dev/i2c-6
# ********************************************************************************
# ********************************************************************************
# *** I2c Bus Config ***
i2cBus1 = smbus.SMBus(1)
i2cBus3 = smbus.SMBus(3)
i2cBus4 = smbus.SMBus(4)
i2cBus5 = smbus.SMBus(5)
i2cBusDict = {'I2cBus1': i2cBus1,
'I2cBus3': i2cBus3,
'I2cBus4': i2cBus4,
'I2cBus5': i2cBus5,
}
# *** Pca9685 I2c Slave Device Congif ***
pca9685DevAddrDict = {
'Dev0': 0x40,
'Dev1': 0x41,
'Dev2': 0x42,
'Dev3': 0x43,
'Dev4': 0x44,
'Dev5': 0x45,
'Dev6': 0x46,
'Dev7': 0x47,
}
pca9685RegAddrDict = { 'Mode1': 0x00,
'Mode2': 0x01,
}
pca9685DataByteDict = {
'Mode1Reset': 0x11,
}
# ********************************************************************************
# ********************************************************************************
# *** Read Write Print Device/Register Functions ***
def writeDevTwoBytes(i2cBus, devAddr, writeByte1, writeByte2):
i2cBus.write_byte_data(devAddr, writeByte1, writeByte2)
return
def writeRegOneByte(i2cBus, devAddrDict, devName, regAddrDict, regName, writeByte):
devAddr = devAddrDict[devName]
regAddr = regAddrDict[regName]
writeDevTwoBytes(i2cBus, devAddr, regAddr, writeByte)
return
def readDevOneByte(i2cBus, devAddr, readByteAddr):
readByte = i2cBus.read_byte_data(devAddr, readByteAddr)
return readByte
def readRegOneByte(i2cBus, devAddrDict, devName, regAddrDict, regName):
devAddr = devAddrDict[devName]
regAddr = regAddrDict[regName]
readByte = i2cBus.read_byte_data(devAddr, regAddr)
return readByte
def printRegOneByte(i2cBus, devAddrDict, devName, regAddrDict, regName):
readByte = readRegOneByte(i2cBusName, devAddrDict, devName, regAddrDict, regName)
print(printTitle, hex(readByte))
return
# *** Main Test Function ***
def testWriteReadPca9685Bus1Dev0RegMode1():
fprint.printBeginExecFunction()
i2cBusName = 'I2cBus1'
devName = 'Dev0'
regName = 'Mode1'
#i2cBus = fi2c.i2cBusDict[i2cBusName]
i2cBus = i2cBusDict[i2cBusName]
devAddrDict = pca9685DevAddrDict
regAddrDict = pca9685RegAddrDict
writeByte = 0x77
writeRegOneByte(i2cBus, devAddrDict, devName, regAddrDict, regName, writeByte)
readByte = readRegOneByte(i2cBus, devAddrDict, devName, regAddrDict, regName)
if readByte == writeByte:
resultsString = 'Good'
else:
resultsString = 'Bad'
devAddr = devAddrDict[devName]
fprint.printTitleOneByteNum('PCA9685 I2C Address', fprint.indentFormat640, devAddr)
fprint.printTitleOneByteNum('PCA9685 MODE1 Register Written', fprint.indentFormat640, writeByte)
fprint.printTitleOneByteNum('PCA9685 MODE1 Register Read', fprint.indentFormat640, readByte)
fprint.printTitleString('Write/Read Results', fprint.indentFormat640, resultsString)
fprint.printEndExecFunction()
return
def testPingPca9685Bus1Dev0RegMode1():
fprint.printBeginExecFunction()
i2cBusName = 'I2cBus1'
devName = 'Dev0'
regName = 'Mode1'
#i2cBus = fi2c.i2cBusDict[i2cBusName]
i2cBus = i2cBusDict[i2cBusName]
devAddrDict = pca9685DevAddrDict
regAddrDict = pca9685RegAddrDict
devAddr = devAddrDict[devName]
readByte = readRegOneByte(i2cBus, devAddrDict, devName, regAddrDict, regName)
compareByte = pca9685DataByteDict['Mode1Reset']
if readByte == compareByte:
resultsString = 'Good'
else:
resultsString = 'Bad'
fprint.printTitleString('PCA9685 I2C Address', fprint.indentFormat640, hex(devAddr))
fprint.printTitleString('PCA9685 MODE1 Register Written', fprint.indentFormat640, hex(compareByte))
fprint.printTitleString('PCA9685 MODE1 Register Read', fprint.indentFormat640, hex(readByte))
fprint.printTitleString('Ping Results', fprint.indentFormat640, resultsString)
fprint.printEndExecFunction()
return
# ********************************************************************************
# ********************************************************************************
# *** Main Tests ***
def mainTests():
#ftime.testPrintDateTime()
testPingPca9685Bus1Dev0RegMode1()
testWriteReadPca9685Bus1Dev0RegMode1()
return
# ********************************************************************************
# ********************************************************************************
# *** Init/Main Functions ***
# *** Init Function ***
def init():
pass
return
#*** Main Function ***
def main():
init()
mainTests()
return
# ********************************************************************************
# ********************************************************************************
# *** Main ***
if __name__ == '__main__':
main()
# *** End of Program ***
# ********************************************************************************
# ********************************************************************************
Categories: Uncategorized