Hello. I have this code:
#include<SPI.h>
#include "MAX30003.h"
#define IO_DELAY 50
#define MAX30003_CS_PIN PB0
uint8_t buff[4] = {0};
unsigned long etagFifoOvf = 0;
unsigned long interruptsError = 0;
boolean output_on = false;
boolean print_time = false;
long print_time_start;
long print_time_duration;
void setup() {
Serial.begin(9600); //Serial begin
pinMode(MAX30003_CS_PIN, OUTPUT);
digitalWrite(MAX30003_CS_PIN, HIGH);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
MAX30003_begin();
}
void loop() {
long c_time = millis();
if (Serial.available()) {
char command = Serial.read();
if (command == '1') {
printConfigs();
} else if (command == '2') {
printStat();
} else if (command == '3') {
output_on = true;
} else if (command == '4') {
output_on = false;
} else if (command == '5') {
output_on = false;
print_time = true;
print_time_duration = 1000;
print_time_start = millis();
} else if (command == '6') {
output_on = false;
print_time = true;
print_time_duration = Serial.parseInt();
print_time_start = millis();
} else if (command == '7') {
int fcal = Serial.parseInt();
CalConfiguration_u CNFG_CAL_r;
readConfig(Registers_e::CNFG_ALL, CNFG_CAL_r.all);
CNFG_CAL_r.bits.fcal = fcal;
MAX30003_Reg_Write(Registers_e::CNFG_ALL, CNFG_CAL_r.all);
max30003_synch();
} else if (command == '0') {
Serial.println("0. Show menu");
Serial.println("1. Print configs");
Serial.println("2. Print status");
Serial.println("3. On print output");
Serial.println("4. Off print output");
Serial.println("5. Print samples 1 second");
Serial.println("6. Print samples N millisecond");
Serial.println("7. Change FCAL to N");
} else {
Serial.print("Unknown command: '");
Serial.print(command);
Serial.println("'");
}
}
Status_u s = readStatus();
if (!s.bits.eint) {
interruptsError++;
delayMicroseconds(IO_DELAY);
return;
}
if (s.bits.eovf) {
max30003_fifo_rst();
etagFifoOvf++;
return;
}
byte etag;
int_least32_t ecgdata = readEcg(etag);
if (etag == FIFO_VALID_SAMPLE || etag == FIFO_LAST_SAMPLE) {
if (output_on || print_time && c_time - print_time_start <= print_time_duration) {
Serial.println(ecgdata);
} else if (print_time && c_time - print_time_start > print_time_duration) {
print_time = false;
}
} else if (etag == FIFO_OVF) {
max30003_fifo_rst();
etagFifoOvf++;
}
}
void printStat() {
Serial.print("FIFO overflow: ");
Serial.println(etagFifoOvf);
Serial.print("Interrupts error: ");
Serial.println(interruptsError);
}
Status_u readStatus() {
return Status_u{ MAX30003_Read_uint32(Registers_e::STATUS) };
}
int_least32_t readEcg(byte& etag) {
uint32_t data = MAX30003_Read_uint32(Registers_e::ECG_FIFO);
etag = (data >> 3) & 0x7;
return (((int_least32_t)((int_least16_t)(data >> 8))) << 2) | ((int_least32_t)(data & 0b11));
}
uint32_t MAX30003_Read_uint32(const Registers_e address) {
MAX30003_Reg_Read(address);
uint32_t data = (uint32_t)buff[0];
data <<= 8;
data |= ((uint32_t)buff[1]);
data <<= 8;
data |= ((uint32_t)buff[2]);
return data;
}
void MAX30003_Reg_Write (const Registers_e address, unsigned long data) {
byte dataToSend = (address << 1) | WREG;
digitalWrite(MAX30003_CS_PIN, LOW);
delayMicroseconds(IO_DELAY);
SPI.transfer(dataToSend);
SPI.transfer(data >> 16);
SPI.transfer(data >> 8);
SPI.transfer(data);
digitalWrite(MAX30003_CS_PIN, HIGH);
delayMicroseconds(IO_DELAY);
}
void max30003_sw_reset(void) {
MAX30003_Reg_Write(Registers_e::SW_RST, 0x000000);
}
void max30003_synch(void) {
MAX30003_Reg_Write(Registers_e::SYNCH, 0x000000);
}
void max30003_fifo_rst(void) {
MAX30003_Reg_Write(Registers_e::FIFO_RST, 0x000000);
}
void MAX30003_Reg_Read(const Registers_e address) {
digitalWrite(MAX30003_CS_PIN, LOW);
delayMicroseconds(IO_DELAY);
uint8_t SPI_TX_Buff = (address << 1 ) | RREG;
SPI.transfer(SPI_TX_Buff);
for (int i = 0; i < 3; i++) {
buff[i] = SPI.transfer(0xff);
}
digitalWrite(MAX30003_CS_PIN, HIGH);
delayMicroseconds(IO_DELAY);
}
void readConfig(const Registers_e address, uint32_t& all) {
all = MAX30003_Read_uint32(address);
}
void MAX30003_begin() {
max30003_sw_reset();
max30003_fifo_rst();
GeneralConfiguration_u CNFG_GEN_r;
setupGeneralCfg(CNFG_GEN_r);
MAX30003_Reg_Write(Registers_e::CNFG_GEN, CNFG_GEN_r.all);
CalConfiguration_u CNFG_CAL_r;
setupCalCfg(CNFG_CAL_r);
MAX30003_Reg_Write(Registers_e::CNFG_ALL, CNFG_CAL_r.all);
MuxConfiguration_u CNFG_MUX_r;
setupManageCfg(CNFG_MUX_r);
MAX30003_Reg_Write(Registers_e::CNFG_EMUX, CNFG_MUX_r.all);
ECGConfiguration_u CNFG_ECG_r;
setupECGCfg(CNFG_ECG_r);
MAX30003_Reg_Write(Registers_e::CNFG_ECG, CNFG_ECG_r.all);
RtoR1Configuration_u CNFG_RTOR_r;
setupRtoRCfg(CNFG_RTOR_r);
MAX30003_Reg_Write( Registers_e::CNFG_RTOR1 , CNFG_RTOR_r.all);
EnableInterrupts_u EN_INT_r;
setupInterruptsCfg(EN_INT_r);
MAX30003_Reg_Write( Registers_e::EN_INT , EN_INT_r.all);
ManageDynamicModes_u MNG_DYN_r;
setupDynamicCfg(MNG_DYN_r);
MAX30003_Reg_Write( Registers_e::MNGR_DYN , MNG_DYN_r.all);
ManageInterrupts_u MNG_INT_r;
setupManageCfg(MNG_INT_r);
MAX30003_Reg_Write( Registers_e::MNGR_INT , MNG_INT_r.all);
max30003_synch();
}
void printConfigs() {
GeneralConfiguration_u CNFG_GEN_r;
setupGeneralCfg(CNFG_GEN_r);
Serial.print("CNFG_GEN: ");
Serial.print(CNFG_GEN_r.all, HEX);
Serial.print(" ");
readConfig(Registers_e::CNFG_GEN, CNFG_GEN_r.all);
Serial.println(CNFG_GEN_r.all, HEX);
CalConfiguration_u CNFG_CAL_r;
setupCalCfg(CNFG_CAL_r);
Serial.print("CNFG_CAL: ");
Serial.print(CNFG_CAL_r.all, HEX);
Serial.print(" ");
readConfig(Registers_e::CNFG_ALL, CNFG_CAL_r.all);
Serial.println(CNFG_CAL_r.all, HEX);
MuxConfiguration_u CNFG_MUX_r;
setupManageCfg(CNFG_MUX_r);
Serial.print("CNFG_EMUX: ");
Serial.print(CNFG_MUX_r.all, HEX);
Serial.print(" ");
readConfig(Registers_e::CNFG_EMUX, CNFG_MUX_r.all);
Serial.println(CNFG_MUX_r.all, HEX);
ECGConfiguration_u CNFG_ECG_r;
setupECGCfg(CNFG_ECG_r);
Serial.print("CNFG_ECG: ");
Serial.print(CNFG_ECG_r.all, HEX);
Serial.print(" ");
readConfig(Registers_e::CNFG_ECG, CNFG_ECG_r.all);
Serial.println(CNFG_ECG_r.all, HEX);
RtoR1Configuration_u CNFG_RTOR_r;
setupRtoRCfg(CNFG_RTOR_r);
Serial.print("CNFG_RTOR: ");
Serial.print(CNFG_RTOR_r.all, HEX);
Serial.print(" ");
readConfig(Registers_e::CNFG_RTOR1, CNFG_RTOR_r.all);
Serial.println(CNFG_RTOR_r.all, HEX);
ManageInterrupts_u MNG_INT_r;
setupManageCfg(MNG_INT_r);
Serial.print("MNGR_INT: ");
Serial.print(MNG_INT_r.all, HEX);
Serial.print(" ");
readConfig(Registers_e::MNGR_INT, MNG_INT_r.all);
Serial.println(MNG_INT_r.all, HEX);
EnableInterrupts_u EN_INT_r;
setupInterruptsCfg(EN_INT_r);
Serial.print("EN_INT: ");
Serial.print(EN_INT_r.all, HEX);
Serial.print(" ");
readConfig(Registers_e::EN_INT, EN_INT_r.all);
Serial.println(EN_INT_r.all, HEX);
ManageDynamicModes_u MNG_DYN_r;
setupDynamicCfg(MNG_DYN_r);
Serial.print("MNG_DYN: ");
Serial.print(MNG_DYN_r.all, HEX);
Serial.print(" ");
readConfig(Registers_e::MNGR_DYN, MNG_DYN_r.all);
Serial.println(MNG_DYN_r.all, HEX);
}
void setupGeneralCfg(GeneralConfiguration_u& CNFG_GEN_r) {
CNFG_GEN_r.all = 0;
CNFG_GEN_r.bits.rbiasn = 0;
CNFG_GEN_r.bits.rbiasp = 0;
CNFG_GEN_r.bits.rbiasv = 0b00;
CNFG_GEN_r.bits.en_rbias = 0;
CNFG_GEN_r.bits.vth = 0b00;
CNFG_GEN_r.bits.imag = 0b00;
CNFG_GEN_r.bits.ipol = 0;
CNFG_GEN_r.bits.en_dcloff = 0;
CNFG_GEN_r.bits.en_ecg = 1;
CNFG_GEN_r.bits.fmstr = 0;
CNFG_GEN_r.bits.en_ulp_lon = 0;
}
void setupCalCfg(CalConfiguration_u& CNFG_CAL_r) {
CNFG_CAL_r.all = 0;
CNFG_CAL_r.bits.thigh = 0;
CNFG_CAL_r.bits.fifty = 0;
CNFG_CAL_r.bits.fcal = 0b000;
CNFG_CAL_r.bits.vmag = 0;
CNFG_CAL_r.bits.vmode = 0;
CNFG_CAL_r.bits.en_vcal = 0;
}
void setupManageCfg(MuxConfiguration_u& CNFG_MUX_r) {
CNFG_MUX_r.all = 0;
CNFG_MUX_r.bits.calp_sel = 0;
CNFG_MUX_r.bits.caln_sel = 0;
CNFG_MUX_r.bits.openn = 0;
CNFG_MUX_r.bits.openp = 0;
CNFG_MUX_r.bits.pol = 0;
}
void setupECGCfg(ECGConfiguration_u& CNFG_ECG_r) {
CNFG_ECG_r.all = 0;
CNFG_ECG_r.bits.dlpf = 0b01;
CNFG_ECG_r.bits.dhpf = 1;
CNFG_ECG_r.bits.gain = 0b00;
CNFG_ECG_r.bits.rate = 0b00;
}
void setupRtoRCfg(RtoR1Configuration_u& CNFG_RTOR_r) {
CNFG_RTOR_r.all = 0;
CNFG_RTOR_r.bits.wndw = 0b0011;
CNFG_RTOR_r.bits.rgain = 0b1111;
CNFG_RTOR_r.bits.pavg = 0b10;
CNFG_RTOR_r.bits.ptsf = 0b0011;
CNFG_RTOR_r.bits.en_rtor = 1;
}
void setupManageCfg(ManageInterrupts_u& MNG_INT_r) {
MNG_INT_r.all = 0;
MNG_INT_r.bits.samp_it = 0;
MNG_INT_r.bits.clr_samp = 1;
MNG_INT_r.bits.clr_rrint = 1;
MNG_INT_r.bits.clr_fast = 0;
MNG_INT_r.bits.efit = 0;
}
void setupInterruptsCfg(EnableInterrupts_u& EN_INT_r) {
EN_INT_r.all = 0;
EN_INT_r.bits.intb_type = 0b11;
EN_INT_r.bits.en_pllint = 0;
EN_INT_r.bits.en_samp = 0;
EN_INT_r.bits.en_rrint = 1;
EN_INT_r.bits.en_loint = 0;
EN_INT_r.bits.en_dcloffint = 0;
EN_INT_r.bits.en_fstint = 0;
EN_INT_r.bits.en_eovf = 1;
EN_INT_r.bits.en_eint = 1;
}
void setupDynamicCfg(ManageDynamicModes_u& MNG_DYN_r) {
MNG_DYN_r.all = 0;
MNG_DYN_r.bits.fast_th = 0;
MNG_DYN_r.bits.fast = 0;
}
Configs I took from here: The best configuration - Question | Mbed
In plotter I see sinusoid:
If I connect it to human, then I get something like that:
Also, I have a 47Hz signal generator, If I connect the generator to MAX30003:
When I touch contacts signal is changing, but after that, it’s stabilizing.
Can anybody clarify what I did wrong?