3 Replies Latest reply on Jan 3, 2017 12:34 PM by Intel Corporation

    Maximintergrated MAXREFDES117 with Intel Galileo Gen 1

    destin

      Hi,

      I have the same problem this post MAXREFDES117 . However, I rewrite max30102.cpp using Wire for Galileo board. But, it can not write register address and data.

      I have tried using Wire with my Arduino Uno board and it not working (It working fine with SoftI2Cmaster.h on Arduino Uno). I'm thinking MAXREFDES117 not support Wire library.

      Please provide a solution in this case.

      Here my result on Arduino Uno and Galileo:

      Uno.PNG                      Galileo.PNG

      max30102.cpp on Arduino Uno:

      #include <SoftI2CMaster.h>
      #include "max30102.h"
      #include "algorithm.h"
      
      
      bool maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data)
      /**
      * \brief        Write a value to a MAX30102 register
      * \par          Details
      *               This function writes a value to a MAX30102 register
      *
      * \param[in]    uch_addr    - register address
      * \param[in]    uch_data    - register data
      *
      * \retval       true on success
      */
      {
        if(!i2c_start(I2C_WRITE_ADDR))
          return false;
        if(!i2c_write(uch_addr))
          return false;
        if(!i2c_write(uch_data))
          return false;
        i2c_stop();
        return true;
      }
      
      
      bool maxim_max30102_read_reg(uint8_t uch_addr, uint8_t *puch_data)
      /**
      * \brief        Read a MAX30102 register
      * \par          Details
      *               This function reads a MAX30102 register
      *
      * \param[in]    uch_addr    - register address
      * \param[out]   puch_data    - pointer that stores the register data
      *
      * \retval       true on success
      */
      {
        if(!i2c_start(I2C_WRITE_ADDR))
          return false;
        if(!i2c_write(uch_addr))
          return false;
        if(!i2c_rep_start(I2C_READ_ADDR))
          return false;  
        *puch_data=i2c_read(true);
        i2c_stop();
        return true;
      }
      
      
      bool maxim_max30102_init()
      /**
      * \brief        Initialize the MAX30102
      * \par          Details
      *               This function initializes the MAX30102
      *
      * \param        None
      *
      * \retval       true on success
      */
      {
        i2c_init();
        if(!maxim_max30102_write_reg(REG_INTR_ENABLE_1,0xc0)) // INTR setting
          return false;
        if(!maxim_max30102_write_reg(REG_INTR_ENABLE_2,0x00))
          return false;
        if(!maxim_max30102_write_reg(REG_FIFO_WR_PTR,0x00))  //FIFO_WR_PTR[4:0]
          return false;
        if(!maxim_max30102_write_reg(REG_OVF_COUNTER,0x00))  //OVF_COUNTER[4:0]
          return false;
        if(!maxim_max30102_write_reg(REG_FIFO_RD_PTR,0x00))  //FIFO_RD_PTR[4:0]
          return false;
        if(!maxim_max30102_write_reg(REG_FIFO_CONFIG,0x4f))  //sample avg = 4, fifo rollover=false, fifo almost full = 17
          return false;
        if(!maxim_max30102_write_reg(REG_MODE_CONFIG,0x03))   //0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
          return false;
        if(!maxim_max30102_write_reg(REG_SPO2_CONFIG,0x27))  // SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (411uS)
          return false;
        
        if(!maxim_max30102_write_reg(REG_LED1_PA,0x24))   //Choose value for ~ 7mA for LED1
          return false;
        if(!maxim_max30102_write_reg(REG_LED2_PA,0x24))   // Choose value for ~ 7mA for LED2
          return false;
        if(!maxim_max30102_write_reg(REG_PILOT_PA,0x7f))   // Choose value for ~ 25mA for Pilot LED
          return false;
        return true;  
      }
      
      
      #if defined(ARDUINO_AVR_UNO)
      //Arduino Uno doesn't have enough SRAM to store 100 samples of IR led data and red led data in 32-bit format
      //To solve this problem, 16-bit MSB of the sampled data will be truncated.  Samples become 16-bit data.
      bool maxim_max30102_read_fifo(uint16_t *pun_red_led, uint16_t *pun_ir_led)
      #else
      bool maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led)
      #endif
      /**
      * \brief        Read a set of samples from the MAX30102 FIFO register
      * \par          Details
      *               This function reads a set of samples from the MAX30102 FIFO register
      *
      * \param[out]   *pun_red_led   - pointer that stores the red LED reading data
      * \param[out]   *pun_ir_led    - pointer that stores the IR LED reading data
      *
      * \retval       true on success
      */
      {
        uint32_t un_temp;
        uint8_t uch_temp;
        *pun_ir_led=0;
        *pun_red_led=0;
        maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
        maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
        if(!i2c_start(I2C_WRITE_ADDR))
          return false;
        if(!i2c_write(REG_FIFO_DATA))
          return false;
        if(!i2c_rep_start(I2C_READ_ADDR))
          return false;  
        un_temp=i2c_read(false);
        un_temp<<=16;
        *pun_red_led+=un_temp;
        
        un_temp=i2c_read(false);
        un_temp<<=8;
        *pun_red_led+=un_temp;
        
        un_temp=i2c_read(false);
        *pun_red_led+=un_temp;
        
        un_temp=i2c_read(false);
        un_temp<<=16;
        *pun_ir_led+=un_temp;
        
        un_temp=i2c_read(false);
        un_temp<<=8;
        *pun_ir_led+=un_temp;
        
        un_temp=i2c_read(true);
        *pun_ir_led+=un_temp;
        
        i2c_stop();
        *pun_red_led&=0x03FFFF;  //Mask MSB [23:18]
        *pun_ir_led&=0x03FFFF;  //Mask MSB [23:18]
        return true;
      }
      
      
      bool maxim_max30102_reset()
      /**
      * \brief        Reset the MAX30102
      * \par          Details
      *               This function resets the MAX30102
      *
      * \param        None
      *
      * \retval       true on success
      */
      {
          if(!maxim_max30102_write_reg(REG_MODE_CONFIG,0x40))
              return false;
          else
              return true;    
      }
      
      
      float readMLX90614(uint8_t mode){
          int dev = MLX90614_ADDR<<1;
          int data_low = 0;
          int data_high = 0;
          int pec = 0;
          
          i2c_start_wait(dev);
          i2c_write(mode);
          
          // read
      

       

      max30102.cpp on Galileo:

      #include <Wire.h>
      #include "max30102.h"
      
      
      void maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data){
        Wire.beginTransmission(I2C_WRITE_ADDR);
        Wire.write(uch_addr);
        Wire.write(uch_data);
        Wire.endTransmission();
      }
      
      
      void maxim_max30102_read_reg(uint8_t uch_addr, uint8_t *puch_data){
        Wire.beginTransmission(I2C_WRITE_ADDR);
        Wire.write(uch_addr);
        Wire.endTransmission(false);
      
        Wire.requestFrom(I2C_WRITE_ADDR, 1);
        *puch_data = Wire.read();
        Wire.endTransmission();
      }
      
      
      void maxim_max30102_init(){
        Wire.begin();
        maxim_max30102_write_reg(REG_INTR_ENABLE_1,0xc0);
        maxim_max30102_write_reg(REG_INTR_ENABLE_2,0x00);
        maxim_max30102_write_reg(REG_FIFO_WR_PTR,0x00);
        maxim_max30102_write_reg(REG_OVF_COUNTER,0x00);
        maxim_max30102_write_reg(REG_FIFO_RD_PTR,0x00);
        maxim_max30102_write_reg(REG_FIFO_CONFIG,0x0f);
        maxim_max30102_write_reg(REG_MODE_CONFIG,0x03);
        maxim_max30102_write_reg(REG_SPO2_CONFIG,0x27);
        maxim_max30102_write_reg(REG_LED1_PA,0x24);
        maxim_max30102_write_reg(REG_LED2_PA,0x24);
        maxim_max30102_write_reg(REG_PILOT_PA,0x7f);
      }
      
      
      void maxim_max30102_read_fifo(uint16_t *pun_red_led, uint16_t *pun_ir_led){
        uint32_t un_temp;
        uint8_t uch_temp;
        *pun_ir_led=0;
        *pun_red_led=0;
      
        maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
        maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
      
        Wire.beginTransmission(I2C_WRITE_ADDR);
        Wire.write(REG_FIFO_DATA);
        Wire.endTransmission(false);
      
        Wire.requestFrom(I2C_WRITE_ADDR, 6);
      
        //red led 
        un_temp = Wire.read();
        un_temp <<= 16;
        *pun_red_led += un_temp;
      
        un_temp = Wire.read();
        un_temp <<= 8;
        *pun_red_led += un_temp;
      
        un_temp = Wire.read();
        *pun_red_led += un_temp;
      
        //ir led
        un_temp = Wire.read();
        un_temp <<= 16;
        *pun_ir_led += un_temp;
      
        un_temp = Wire.read();
        un_temp <<= 8;
        *pun_ir_led += un_temp;
      
        un_temp = Wire.read();
        *pun_ir_led += un_temp;
      
        Wire.endTransmission();
      
        *pun_red_led&=0x03FFFF;  //Mask MSB [23:18]
        *pun_ir_led&=0x03FFFF;  //Mask MSB [23:18]
      }
      
      
      void maxim_max30102_reset(){
        maxim_max30102_write_reg(REG_MODE_CONFIG,0x40);
      }
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      

       

      main.ino on my Galileo board:

      #include <Arduino.h>
      #include "max30102.h"
      uint16_t aun_ir_buffer[100]; //infrared LED sensor data  //edit 32bit if enough sram
      uint16_t aun_red_buffer[100];  //red LED sensor data
      
      int32_t n_ir_buffer_length; //data length
      uint8_t uch_dummy;
      
      void setup(){
        maxim_max30102_reset();
        Serial.begin(115200);
        pinMode(10, INPUT);
        maxim_max30102_read_reg(REG_INTR_STATUS_1,&uch_dummy);
        delay(1000);
        while(Serial.available() == 0){
          Serial.println("Press any key to start conversion!");
         delay(1000);
        }
        uch_dummy=Serial.read();
        maxim_max30102_init();
      }
      
      void loop(){
        uint32_t un_min, un_max, un_prev_data, un_brightness;  //variables to calculate the on-board LED brightness that reflects the heartbeats
        int32_t i;
       float f_temp;
       un_brightness=0;
        un_min=0x3FFFF;
        un_max=0;
      
      n_ir_buffer_length=100;
      //read the first 100 samples, and determine the signal range
        for(i=0;i<n_ir_buffer_length;i++)
        {
          while(digitalRead(10)==1);  //wait until the interrupt pin asserts
             maxim_max30102_read_fifo((aun_red_buffer+i), (aun_ir_buffer+i));  //read from MAX30102 FIFO
          
          if(un_min>aun_red_buffer[i])
              un_min=aun_red_buffer[i];  //update signal min
          if(un_max<aun_red_buffer[i])
                 un_max=aun_red_buffer[i];  //update signal max
          Serial.print(F("red="));
          Serial.print(aun_red_buffer[i], DEC);
          Serial.print(F(", ir="));
          Serial.println(aun_ir_buffer[i], DEC);
        }
      

      Regard,

      phunguyen