frame

Can't change sample rate of Maxim 30101 module

Hello!

I'm trying to use the Maxim Max 30101 sensor integrated in Hexiwear in order to extract raw data from it and then to apply a better heart rate algorithm than the one available.
However, when i try to change the sample_rate and pulse_width using the set_mode function available, even if i use the standard parameters available in the docs, i'm getting always this error:
" TypeError  at line 63 of __main__
raised at line 507 of maxim.max30101.max30101.set_mode
raised at line 550 of maxim.max30101.max30101._set_led
raised at line 104 of i2c.write_bytes "

My code is:
max = max30101.MAX30101(I2C0)
print("start...")
max.start()
max.set_mode(mode = 'spo2', adc_range = 3, sample_rate = 50, pulse_width = 411, led_current = [256,256,0,0], proximity_thrs = 0, slot_multi = [0,0,0,0])
max.init()

Even if i change the parameters and the mode to "hr" or multy. i always get the same error. I've tried also to change the parameters in the max.init() function although i don't get the error the sample_rate still not changing.
I couldn't get access to the code of the max30101.set_mode function in order to check which problem is ocurring.

I would like to know how to use or which is the problem with my code to change it
Thanks in Advance for your help

Comments

  • Hi Josè,

    Thanks to join our community :)
    The TypeError you get is referred to values assigned in led_current list; as you can see in our documentation (link) max values available in led_current list are 255 (1 byte) for each element.

    If you want to analyze and check MAX30101 library source files, you can find them under:

    Linux and MacOS: "~/.zerynth2/dist/r2.0.9/libs/official/maxim/max30101"
    Windows: "C:/Users/your_user/zerynth2/r2.0.9/libs/official/maxim/max30101"

    Hope this can help you
    Matteo Cipriani
    Zerynth Support Team
  • Firstly i would like to thank you! It has worked

    Then i had another question that i would be like to be answer if you know. The example available of heart beat, uses a polling method in order to extract the data. However i would like to extract the samples when they are available.

    From what i understood from the datasheet of the sensor i should read the interrupt status in order to check if a new sample is available in FIFO. However, from the library i saw that we can enable the interrupt, but we have no function to check when the interrupt is triggered, this is, when the sample is ready for reading.
    I don't know if i'm thinking correct but i couldn't find a way to do it from the functions available in the library. So i would like to know if i'm thinking completely wrong and how can i do it from the functions available

    It would be great if you help me with the question.
    Thanks in advance
    Greetings
  • Hi Josè,

    there is no functions that manage interrupts because, according to their behaviour (active-low or active-high), you can implement your callback function through our builtin onPinRise and onPinFall; as described in Max30101 datasheet, this component has an active-low interrupt pin so you can use the onPinFall method for your callback.

    As you can see from Hexiwear pinmap image - peripherals view (clicking the "Device Pinmap Info" in the Zerynth Studio Toolbar) D47 is linked to Max30101 interrupt pin.

    To enable different interrupt on Max30101 you can use the enable_interrupt function and following int values can be passed as source argument (despite what current documentation says, string arguments will be available on next release):
    "full"  = 0x80
    "data"  = 0x40
    "alc"   = 0x20
    "prox"  = 0x10
    "temp"  = 0x02
    for example to enable full fifo interrupt:
    max.enable_interrupt(0x80)
    Let me know if this can help you :)
    Matteo Cipriani
    Zerynth Support Team
  • Thank you so much! Yes, it helped me!
  • Sorry for the incovenience, but i just tried to use the functions that you mentioned but i'm not obtained the expected results.

    I'm using

    intPin = D47
    pinMode(intPin, OUTPUT) 

    I don't know which type of Pin i have to choose but i have tried also the OUTPUT_PUSHPULL and i obtained the same.

    Then i just enable my interruptor in order to allow trigger the interruptor when a sample is received in FIFO

    max.enable_interrupt(0x40)
    Then i introduced my main while loop in order to find every fall of my interruptor

    while True:
         onPinFall(intPin, detect_pulse(max))

    My detect_pulse has a print and it is always appearing in the console, this is from what i understood, the triggering is always happening (from 3 ms to 3 ms, obtained through a timer). As my sample_rate is 50 Hz i should only obtain a Fall in intervals of 20 ms, right? Even adding a debounce time, this is:

    onPinFall(intPin, detect_pulse(max), debounce=100, time_unit=MILLIS)

    I'm obtaining the same thing.

    My main objective is to get the timming for each sample in order to evaluate which will be the best sample_rate and pulse_width (i can change it now) for the measurements. So i would like to know what i'm doing wrong in my code.


    Thanks in advance.
    Best Regards

  • Hi Josè,

    to check an digital event on a specific pin, you have to define this pin as INPUT pin.

    To avoid spurious transitions, you can also set this pin with internal pull-up so when the pin state is floating microcontroller forces the pin to high level; only if the interrupt occurs (interrupt pin of max30101 is active low) the pin state turns low and the onPinFall function is correctly called.

    I notice that the use of onPinFall function is not correct; args for your callback function must be passed as *args in onPinFall function.

    The debounce arg in onPinFall function needs to avoid multiple, too close, transictions usually due to press mechanical buttons; you don't need this feature when you want to receive an external digital interrupt.

    To enable properly interrupts in Max30101, you have to call the enable_interrupt function after sensor initialization (max.init()) and as reported in Max30101 datasheet: "The interrupts are cleared whenever the interrupt status register is read, or when the register that triggered the interrupt is read. For example, if the SpO2 sensor triggers an interrupt due to finishing a conversion, reading either the FIFO data register or the interrupt register clears the interrupt pin (which returns to its normal HIGH state). This also clears all the bits in the interrupt status register to zero".   

    Here few line of code for handling temperature interrupts:

    import streams
    from maxim.max30101 import max30101
    
    streams.serial()
    
    MAX30101_INT = {
        "full"  : 0x80,
        "data"  : 0x40,
        "alc"   : 0x20,
        "prox"  : 0x10,
        "temp"  : 0x02
    }
    
    # return list of triggered interrupts
    def read_triggered_interrupt(obj):
        interrupts = []
        data = obj.write_read(max30101.MAX30101_INT_STATUS_1,2)
        for k,v in MAX30101_INT.items():
            if v == max30101.MAX30101_INT_TEMP:
                res = data[1] & v
            else:
                res = data[0] & v
            if res:
                interrupts.append(k)
        return interrupts
    
    # test fun with args to print temperature data when is ready
    def fnc(obj):
        try:
            print("INTERRUPT TRIGGERED")
            print(read_triggered_interrupt(obj))
            print("Temp", obj.get_temperature())
            print("---------------------------")
        except Exception as e:
            print(e)
    
    # create an instance of the MAX30101 class
    try:
        # Setup sensor
        # This setup is referred to max30101 mounted on hexiwear device 
        # Power up and init sequence for max30101 inside hexiwear device
        pinPowerOn = D70
        pinMode(pinPowerOn,OUTPUT)
        digitalWrite(pinPowerOn,HIGH)
        
        # init sensor
        max = max30101.MAX30101(I2C0)
        print("start...")
        max.start()
        print("init...")
        max.init()
        print("enable interrupts")
        max.enable_interrupt(MAX30101_INT["temp"])
        
        # set up interrupt pin and onPinFall callback function
        pinMode(D47,INPUT_PULLUP)
        onPinFall(D47,fnc,max)
        
        print("Ready!")
        print("---------------------------")
    except Exception as e:
        print(e)
    
    while True:
        print("start temperature measurement")
        max.enable_temperature()
        sleep(3000)
    
    

    keep me posted :)
    Matteo Cipriani
    Zerynth Support Team
  • Wow!! Thank you very much! I have just done it!

    A big thank you!!!!
    Greetings
  • I'm sorry for my incovenience, but your code and my adapted code to extract the raw data of the Heart Sensor when the interrupt triggers was working but then suddently it stopped working with no reason. I was just changing the sample rate in the source library code. If i try to extract only the heart rate or temperature data through polling i obtain the data but using interrupts i can't obtain it.

    Do you have any idea how to fix it?

    I just tried to upload  the Hexiwear Docking Station Firmware but it didn't work and i just restore the source code of maxim30101.py and it didn't work as well.
Sign In or Register to comment.

ZERYNTH Community

@ 2016 Zerynth.com, all rights reserved.