Spi communication using 2 sensors on arduino mega

hi all,

so I use 2 afe4490 sensors on arduino mega 2560 with spi communication, for the cs pin of each module I have distinguished. however, in the serial monitor only module 1 is read, maybe you can provide a solution?

#include <SPI.h>
#include "protocentral_afe44xx.h"

// Konfigurasi pin untuk modul 1
#define AFE44XX_CS_PIN_1   9
#define AFE44XX_PWDN_PIN_1 4
AFE44XX afe44xx_modul1(AFE44XX_CS_PIN_1, AFE44XX_PWDN_PIN_1);

// Konfigurasi pin untuk modul 2
#define AFE44XX_CS_PIN_2   10
#define AFE44XX_PWDN_PIN_2 5
AFE44XX afe44xx_modul2(AFE44XX_CS_PIN_2, AFE44XX_PWDN_PIN_2);

afe44xx_data data_modul1;
afe44xx_data data_modul2;

int32_t heart_rate_prev1 = 0;
int32_t spo2_prev1 = 0;
int32_t heart_rate_prev2 = 0;
int32_t spo2_prev2 = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println("Initializing AFE44xx Modules..");
  
  SPI.begin();
  pinMode(AFE44XX_CS_PIN_1, OUTPUT);
  pinMode(AFE44XX_CS_PIN_2, OUTPUT);

  // Inisialisasi modul 1
  digitalWrite(AFE44XX_CS_PIN_1, LOW);   // Aktifkan CS modul 1
  digitalWrite(AFE44XX_CS_PIN_2, HIGH);  // Nonaktifkan CS modul 2
  afe44xx_modul1.afe44xx_init();
  
  // Inisialisasi modul 2
  digitalWrite(AFE44XX_CS_PIN_1, HIGH);  // Nonaktifkan CS modul 1
  digitalWrite(AFE44XX_CS_PIN_2, LOW);   // Aktifkan CS modul 2
  afe44xx_modul2.afe44xx_init();
  
  Serial.println("Modules Initialized...");
}

void loop()
{
    // read modul 1
    digitalWrite(AFE44XX_CS_PIN_1, LOW);   // Aktifkan CS modul 1
    digitalWrite(AFE44XX_CS_PIN_2, HIGH);  // Nonaktifkan CS modul 2
    delay(8);  // Waktu tunggu agar data stabil
    afe44xx_modul1.get_AFE44XX_Data(&data_modul1);
    
    if (data_modul1.buffer_count_overflow)
    {
      if (data_modul1.spo2 == -999)
      {
        Serial.println("Modul 1 - Probe error!!!!");
      }
      else if ((heart_rate_prev1 != data_modul1.heart_rate) || (spo2_prev1 != data_modul1.spo2))
      {
        heart_rate_prev1 = data_modul1.heart_rate;
        spo2_prev1 = data_modul1.spo2;

        Serial.print("Modul 1 - SpO2 : ");
        Serial.print(data_modul1.spo2);
        Serial.print("%, Pulse rate : ");
        Serial.print(data_modul1.heart_rate);
        Serial.println(" bpm");
      }
    }

    // read modul 2
    digitalWrite(AFE44XX_CS_PIN_1, HIGH);  // Nonaktifkan CS modul 1
    digitalWrite(AFE44XX_CS_PIN_2, LOW);   // Aktifkan CS modul 2
    delay(8);  // Waktu tunggu agar data stabil
    afe44xx_modul2.get_AFE44XX_Data(&data_modul2);

    if (data_modul2.buffer_count_overflow)
    {
      if (data_modul2.spo2 == -999)
      {
        Serial.println("Modul 2 - Probe error!!!!");
      }
      else if ((heart_rate_prev2 != data_modul2.heart_rate) || (spo2_prev2 != data_modul2.spo2))
      {
        heart_rate_prev2 = data_modul2.heart_rate;
        spo2_prev2 = data_modul2.spo2;

        Serial.print("Modul 2 - SpO2 : ");
        Serial.print(data_modul2.spo2);
        Serial.print("%, Pulse rate : ");
        Serial.print(data_modul2.heart_rate);
        Serial.println(" bpm");
      }
    }
}

the results that come out on the serial monitor are just like that

Have you swapped the sensors to check device 2 is working at all?

The code has some branches that do nothing.
Add some code to see what happens, something like

    if (data_modul2.buffer_count_overflow)
    {
      if (data_modul2.spo2 == -999)
      {
        Serial.println("Modul 2 - Probe error!!!!");
      }
      else if ((heart_rate_prev2 != data_modul2.heart_rate) || (spo2_prev2 != data_modul2.spo2))
      {
        heart_rate_prev2 = data_modul2.heart_rate;
        spo2_prev2 = data_modul2.spo2;

        Serial.print("Modul 2 - SpO2 : ");
        Serial.print(data_modul2.spo2);
        Serial.print("%, Pulse rate : ");
        Serial.print(data_modul2.heart_rate);
        Serial.println(" bpm");
      }
      else 
      {
        Serial.print("HR:\t");
        Serial.println((heart_rate_prev2 != data_modul2.heart_rate));
        Serial.print("SPO:\t");
        Serial.println((spo2_prev2 != data_modul2.spo2));
      }
    }
    else Serial.println("Hello");

In addition to trying them one at a time:
I recommend setting both CS pins to OUTPUT and HIGH in setup, then don't change them again. The library will deal with the CS pins. The init call will set the PWDN pins.

  pinMode(AFE44XX_CS_PIN_1, OUTPUT);
  digitalWrite(AFE44XX_CS_PIN_1,HIGH);
  pinMode(AFE44XX_CS_PIN_2, OUTPUT);
  digitalWrite(AFE44XX_CS_PIN_2,HIGH);

yes, module 2 works well

Try this as the loop, I can't check it because I don't have that module.

void loop()
{
    // read modul 1
    afe44xx_modul1.get_AFE44XX_Data(&data_modul1);
    
    if (data_modul1.buffer_count_overflow)
    {
      if (data_modul1.spo2 == -999)
      {
        Serial.println("Modul 1 - Probe error!!!!");
      }
      else
      {
        heart_rate_prev1 = data_modul1.heart_rate;
        spo2_prev1 = data_modul1.spo2;

        Serial.print("Modul 1 - SpO2 : ");
        Serial.print(data_modul1.spo2);
        Serial.print("%, Pulse rate : ");
        Serial.print(data_modul1.heart_rate);
        Serial.println(" bpm");
      }
    }

    // read modul 2
    afe44xx_modul2.get_AFE44XX_Data(&data_modul2);

    if (data_modul2.buffer_count_overflow)
    {
      if (data_modul2.spo2 == -999)
      {
        Serial.println("Modul 2 - Probe error!!!!");
      }
      else
      {
        heart_rate_prev2 = data_modul2.heart_rate;
        spo2_prev2 = data_modul2.spo2;

        Serial.print("Modul 2 - SpO2 : ");
        Serial.print(data_modul2.spo2);
        Serial.print("%, Pulse rate : ");
        Serial.print(data_modul2.heart_rate);
        Serial.println(" bpm");
      }
   }
   delay(1000);  
}

okeyy, i will try, thankss

void setup()
{
  Serial.begin(115200);
  Serial.println("Initializing AFE44xx Modules..");

  SPI.begin();
  afe44xx_modul1.afe44xx_init();
  pinMode(AFE44XX_CS_PIN_1, OUTPUT);
  digitalWrite(AFE44XX_CS_PIN_1, HIGH);

  afe44xx_modul2.afe44xx_init();
  pinMode(AFE44XX_CS_PIN_2, OUTPUT);
  digitalWrite(AFE44XX_CS_PIN_2, HIGH);



  Serial.println("Modules Initialized...");
}

is this really what you mean??

#include <SPI.h>
#include "protocentral_afe44xx.h"

// Konfigurasi pin untuk modul 1
#define AFE44XX_CS_PIN_1   6
#define AFE44XX_PWDN_PIN_1 10
AFE44XX afe44xx_modul1(AFE44XX_CS_PIN_1, AFE44XX_PWDN_PIN_1);

// Konfigurasi pin untuk modul 2
#define AFE44XX_CS_PIN_2   7
#define AFE44XX_PWDN_PIN_2 4
AFE44XX afe44xx_modul2(AFE44XX_CS_PIN_2, AFE44XX_PWDN_PIN_2);

afe44xx_data data_modul1;
afe44xx_data data_modul2;

int32_t heart_rate_prev1 = 0;
int32_t spo2_prev1 = 0;
int32_t heart_rate_prev2 = 0;
int32_t spo2_prev2 = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println("Initializing AFE44xx Modules..");

  SPI.begin();
  afe44xx_modul1.afe44xx_init();
  pinMode(AFE44XX_CS_PIN_1, OUTPUT);
  digitalWrite(AFE44XX_CS_PIN_1, HIGH);

  afe44xx_modul2.afe44xx_init();
  pinMode(AFE44XX_CS_PIN_2, OUTPUT);
  digitalWrite(AFE44XX_CS_PIN_2, HIGH);



  Serial.println("Modules Initialized...");
}

void loop()
{
    // read modul 1
    afe44xx_modul1.get_AFE44XX_Data(&data_modul1);
    
    if (data_modul1.buffer_count_overflow)
    {
      if (data_modul1.spo2 == -999)
      {
        Serial.println("Modul 1 - Probe error!!!!");
      }
      else
      {
        heart_rate_prev1 = data_modul1.heart_rate;
        spo2_prev1 = data_modul1.spo2;

        Serial.print("Modul 1 - SpO2 : ");
        Serial.print(data_modul1.spo2);
        Serial.print("%, Pulse rate : ");
        Serial.print(data_modul1.heart_rate);
        Serial.println(" bpm");
      }
    }

    // read modul 2
    afe44xx_modul2.get_AFE44XX_Data(&data_modul2);

    if (data_modul2.buffer_count_overflow)
    {
      if (data_modul2.spo2 == -999)
      {
        Serial.println("Modul 2 - Probe error!!!!");
      }
      else
      {
        heart_rate_prev2 = data_modul2.heart_rate;
        spo2_prev2 = data_modul2.spo2;

        Serial.print("Modul 2 - SpO2 : ");
        Serial.print(data_modul2.spo2);
        Serial.print("%, Pulse rate : ");
        Serial.print(data_modul2.heart_rate);
        Serial.println(" bpm");
      }
   }
   delay(1000);  
}

I have tried this program, but still only read module 1

If the code isn't displaying anything from modul2, then this is evaluating to false.
if (data_modul2.buffer_count_overflow)

but at least if it is wrong it should be able to display a probe error

No, it won't display a probe error. It will bypass everything inside that if statement. That was the test.
if (data_modul2.buffer_count_overflow)
I haven't looked at the library yet to determine what causes the variable to evaluate as false.
Usually, an overflow would be a bad thing.

Edit: I took a look at the library, and the overflow is a bad thing. I would try this instead.
if (afe44xx_data_ready)

Edit2: The library has a bug. The variable afe44xx_data_ready will always evaluate to false.

1 Like

I didn't mean to leave you with bad code and a faulty library.
Do you know where your libraries are stored? I might be able to help you fix your library.

Are you really asking where my library is saved? I saved it in the arduino libraries file.
protocentral_afe44xx.cpp (7,1 KB)
Is this really the file you're referring to?
if so, please help me to fix this library

Here is how I see it: According to the library, you would have to call this function 2000 times before it should overflow and send anything. Obviously, one of your sensors is not waiting for 2000 calls. With the one second delay between calls, it would be 2000 seconds before an overflow. Does it take 2000 seconds before any output?

Here is the function you are calling. Check out the variables "dec" and "n_buffer_count". This function has to be called 20 times before n_buffer_count is incremented. Then the overflow happens when n_buffer_count == 100. Note the variable declaration of n_buffer_count is not being initialized. I would have set it to zero, the same as the declaration for dec.

boolean AFE44XX::get_AFE44XX_Data(afe44xx_data *afe44xx_raw_data)
{
  afe44xxWrite(CONTROL0, 0x000001);
  IRtemp = afe44xxRead(LED1VAL);
  afe44xxWrite(CONTROL0, 0x000001);
  REDtemp = afe44xxRead(LED2VAL);
  afe44xx_data_ready = true;
  IRtemp = (unsigned long) (IRtemp << 10);
  afe44xx_raw_data->IR_data = (signed long) (IRtemp);
  afe44xx_raw_data->IR_data = (signed long) ((afe44xx_raw_data->IR_data) >> 10);
  REDtemp = (unsigned long) (REDtemp << 10);
  afe44xx_raw_data->RED_data = (signed long) (REDtemp);
  afe44xx_raw_data->RED_data = (signed long) ((afe44xx_raw_data->RED_data) >> 10);

  if (dec == 20)
  {
    aun_ir_buffer[n_buffer_count] = (uint16_t) ((afe44xx_raw_data->IR_data) >> 4);
    aun_red_buffer[n_buffer_count] = (uint16_t) ((afe44xx_raw_data->RED_data) >> 4);
    n_buffer_count++;
    dec = 0;
  }

  dec++;

  if (n_buffer_count > 99)
  {
    Spo2.estimate_spo2(aun_ir_buffer, 100, aun_red_buffer, &n_spo2, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
    afe44xx_raw_data->spo2 = n_spo2;
    //afe44xx_raw_data->heart_rate = n_heart_rate;
    n_buffer_count = 0;
    afe44xx_raw_data->buffer_count_overflow = true;
  }

  hral.statHRMAlgo(afe44xx_raw_data->RED_data);
  afe44xx_raw_data->heart_rate = hral.HeartRate;

  afe44xx_data_ready = false;
  return true;
}

Okey, i will try this code. Maybe if i have any question, i will ask again, thankyou

That is the original library code. It should fail.

Go to the top of that file and change this (add the = 0):
volatile int8_t n_buffer_count = 0; //data length
Try that. If nothing is displayed right away, don't panic. Nothing should be displayed from either sensor. Let me know if it starts displaying right away.

Otherwise, go to the bottom of your code and remove the "delay(1000)".
Try that. Both should start output about the same time. Might take a few seconds.

Are you sure you have it wired correctly?
I noticed that you changed the CS and PWDN pin assigments in the code you show in post #8
if the code works for 1 module it should also work for 2.
Are you using protocentral shields or modules?

yes, i changed the cs and PWDN pins in post 8. i am using protocentral module.

I have changed the code in the library, after I tried it, only module 1 was read.

when I give logic high only, the fingertip will not turn on. so I keep adding logic low so that the fingetip stays on.

  pinMode(AFE44XX_CS_PIN_1, OUTPUT);
  digitalWrite(AFE44XX_CS_PIN_1, HIGH); // Pastikan tidak aktif
  pinMode(AFE44XX_PWDN_PIN_1, OUTPUT);
  digitalWrite(AFE44XX_PWDN_PIN_1, LOW); // Aktifkan modul
  afe44xx_modul1.afe44xx_init();

It's the library error. I think I have it corrected. I can't tell if it is accurate because I don't have the modules to test, but I am getting both modules displaying

Modul 1 - Probe error!!!!
Modul 2 - Probe error!!!!

Let me test it a bit and I'll post the new library code.