Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MAX30003 max32630fthr DS1307
main.cpp
- Committer:
- kidecha_rahul
- Date:
- 2021-06-11
- Revision:
- 18:101042d225ef
- Parent:
- 17:f0008ebb1040
- Child:
- 19:7a084dc2f09d
File content as of revision 18:101042d225ef:
#include "MAX30003.h"
#include "mbed.h"
#include "max32630fthr.h"
#include "ds1307.h"
//#include <BufferedSerial.h>
#include <string>
//#include <Serial.h>
#include "ds3231.h"
#define TARGET_TX_PIN P3_1
#define TARGET_RX_PIN P3_0
#define SDA P3_4
#define SCL P3_5
Timer timer_fast;
Timer t;
MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
void task_fast(void);
//DigitalOut ledA(LED2);
DigitalOut EN(P1_7);
DigitalOut A0(P1_4);
DigitalOut A1(P7_2);
void ecg_config(MAX30003 &ecgAFE);
//BufferedSerial pc(P3_1,P3_0); // Use USB debug probe for serial link static Unbuffered
static BufferedSerial pc(TARGET_TX_PIN, TARGET_RX_PIN, 230400); // 230400 works well
//Serial uart_1(USBTX, USBRX); // Use USB debug probe for serial link static Unbuffered
//
//Serial pc(P3_1,P3_0);
volatile bool ecgFIFOIntFlag = 0;
volatile bool timerflag = 0;
FileHandle *mbed::mbed_override_console(int fd)
{
return &pc;
}
void ecgFIFO_callback_1() { // Triggered when the ECG FIFO is about to be full
ecgFIFOIntFlag = 1;
}
time_t asUnixTime(int year, int mon, int mday, int hour, int min, int sec) {
struct tm t;
t.tm_year = year - 1900;
t.tm_mon = mon - 1; // convert to 0 based month
t.tm_mday = mday;
t.tm_hour = hour;
t.tm_min = min;
t.tm_sec = sec;
t.tm_isdst = -1; // Is Daylight saving time on? 1 = yes, 0 = no, -1 = unknown
return mktime(&t); // returns seconds elapsed since January 1, 1970 (begin of the Epoch)
}
int main(void)
{
int t=0;
EN=0;
EN=1;
A0=0;
A1=1;
// Constants
const int EINT_STATUS_MASK = 1 << 23;
const int FIFO_OVF_MASK = 0x7;
const int FIFO_VALID_SAMPLE_MASK = 0x0;
const int FIFO_FAST_SAMPLE_MASK = 0x1;
const int ETAG_BITS_MASK = 0x7;
//-------------------------------------------------------------RTC-------------------------------------------------------------//
//instantiate rtc object
Ds3231 rtc(SDA, SCL);
uint16_t rtn_val;
//time = 12:00:00 AM 12hr mode
ds3231_time_t time = {25,20,9,1, 0}; // seconds, min, hours, am_pm, mode
rtn_val = rtc.set_time(time);
//see datasheet for calendar format
ds3231_calendar_t calendar = {6, 11, 6, 21}; // day date month year
rtn_val = rtc.set_calendar(calendar);
//see datasheet for calendar format
ds3231_cntl_stat_t data = {0x1C, 0x08};
rtn_val = rtc.set_cntl_stat_reg(data);
//------------------------------------------------------------------------------------------------------------------------------//
timer_fast.start();
DigitalOut rLed(LED2, LED_ON);
// pc.baud(9600);
//pc.set_baud(115200); // Baud rate = 115200
//pc.set_format(
// /* bits */ 8,
// /* parity */ BufferedSerial::None,
// /* stop bit */ 1 //1
//);
//uart_1.baud(115200);
InterruptIn ecgFIFO_int(P5_4); // Config P5_4 as int. in for the
ecgFIFO_int.fall(&ecgFIFO_callback_1); // ecg FIFO interrupt at falling edge
SPI spiBus(SPI2_MOSI, SPI2_MISO, SPI2_SCK); // SPI bus, P5_1 = MOSI,
// P5_2 = MISO, P5_0 = SCK
MAX30003 ecgAFE(spiBus, P5_3); // New MAX30003 on spiBus, CS = P5_3
ecg_config(ecgAFE); // Config ECG
ecgAFE.writeRegister( MAX30003::SYNCH , 0);
uint32_t ecgFIFO, readECGSamples, idx, ETAG[32], status;
int16_t ecgSample[32];
//bool timerflag = false;
int16_t ecgSample_1sec[200];
uint8_t ecg_1 = 0;
uint8_t ecg_2 = 0;
uint16_t onesec_counter = 0;
uint16_t onesec_counter_temp = 0;
int16_t sample = 300;
uint8_t final[10];
uint16_t checksum_ = 0;
uint16_t mod_checksum = 0;
uint8_t p_1 = 0;
uint8_t p_2 = 0;
uint8_t p_3 = 0;
uint8_t p_4 = 0;
// uint8_t channel_num= 1;
uint8_t channel_num[1]= {1};
uint8_t data_len_1 = 0;
uint8_t data_len_2 = 0;
uint32_t packet_1 = 0;
uint8_t cksm_1 = 0;
uint8_t cksm_2 = 0;
uint8_t header_device_id[3] = {0,0,210};
uint8_t header_packet_type[2] = {0,2};
uint8_t ending[5] = {'@','#','%','!','7'};
bool flip = true;
int sampleps = 0;
char buf[20];//={"1622326341"};
// pc.write("Welcome",8*sizeof(char));
// printf("In the main loop"); //printf("In the main loop");
bool flag_first = false;
bool timestamp_reader = false;
time_t epoch_time;
do {
rtc.get_time(&time);
rtc.get_calendar(&calendar);
epoch_time = rtc.get_epoch();
//printf("seconds since the Epoch: %ld\n", epoch_time);
packet_1 = epoch_time;
}while((epoch_time % 60)!=0); // come out at the start of minute
while(1)
{
if ((onesec_counter>=125))
{
//t.start();
//ledA = !ledA;
pc.write((uint8_t *)header_device_id, sizeof(header_device_id)); // device ID
pc.write((uint8_t *)header_packet_type, sizeof(header_packet_type)); // packet type
epoch_time = rtc.get_epoch();
//time_t seconds = time(NULL); // if remove it the timestamp will be static
packet_1 = epoch_time; //
//packet_1 ++;
// printf("Time as seconds since January 1, 1970 = %d\n", packet_1);
p_1 = packet_1 & 0xff;
p_2 = (packet_1 >> 8) & 0xff;
p_3 = (packet_1 >> 16) & 0xff;
p_4 = (packet_1 >> 24) & 0xff;
// checksum_ = checksum_ + (packet_1 & 0xffff) + ((packet_1 >> 16) & 0xffff) ;
checksum_ = checksum_ + p_1 + p_2 + p_3 + p_4 ;
uint8_t header_packet_id[4] = {p_4,p_3,p_2,p_1};
pc.write((uint8_t *)header_packet_id, sizeof(header_packet_id)); // packet ID
pc.write((uint8_t *)channel_num, sizeof(channel_num));
onesec_counter_temp = onesec_counter * 2;
data_len_1 = onesec_counter_temp & 0xff;
data_len_2 = (onesec_counter_temp >> 8) & 0xff;
checksum_ = checksum_ + data_len_1 + data_len_2;
//pc.write((uint32_t *)packet_1, sizeof(packet_1));
uint8_t header_ecg_datalen[2] = {data_len_2,data_len_1};
pc.write((uint8_t *)header_ecg_datalen, sizeof(header_ecg_datalen));
mod_checksum = checksum_ % 65536 ;
cksm_1 = mod_checksum & 0xff;
cksm_2 = (mod_checksum >> 8) & 0xff;
uint8_t header_ecg_checksum[2] = {cksm_2,cksm_1};
pc.write((uint8_t *)header_ecg_checksum, sizeof(header_ecg_checksum));
pc.write((int16_t *)ecgSample_1sec,onesec_counter * sizeof(int16_t));
// printf("Samples per second %d \n", (onesec_counter));
onesec_counter = 0;
// memset(ecgSample_1sec, 0, sizeof(ecgSample_1sec));
pc.write((uint8_t *)ending, sizeof(ending));
checksum_ = 0;
//t.stop();
// auto us = t.elapsed_time().count();
// float time_taken = us/1000000;
// printf("Timer time: %lu ms \n", (time_taken*100));
// t.reset();
// timer_fast.reset();
}
// Read back ECG samples from the FIFO
else if( (ecgFIFOIntFlag==1))// && (timerflag == 0))
{
ecgFIFOIntFlag = 0;
status = ecgAFE.readRegister( MAX30003::STATUS ); // Read the STATUS register
// Check if EINT interrupt asserted
if ( ( status & EINT_STATUS_MASK ) == EINT_STATUS_MASK )
{
readECGSamples = 0; // Reset sample counter
do {
ecgFIFO = ecgAFE.readRegister( MAX30003::ECG_FIFO ); // Read FIFO
ecgSample[readECGSamples] = ecgFIFO >> 8; // Isolate voltage data
ecgSample[readECGSamples] = ((ecgSample[readECGSamples]<<8)&0xFF00)|((ecgSample[readECGSamples]>>8)&0x00FF);
ETAG[readECGSamples] = ( ecgFIFO >> 3 ) & ETAG_BITS_MASK; // Isolate ETAG
readECGSamples++; // Increment sample counter
// Check that sample is not last sample in FIFO
} while ( ETAG[readECGSamples-1] == FIFO_VALID_SAMPLE_MASK ||
ETAG[readECGSamples-1] == FIFO_FAST_SAMPLE_MASK );
// Check if FIFO has overflowed
if( ETAG[readECGSamples - 1] == FIFO_OVF_MASK )
{
ecgAFE.writeRegister( MAX30003::FIFO_RST , 0); // Reset FIFO
rLed = 1;//notifies the user that an over flow occured
}
//uint8_t header_ecg_checksum[2] = {'%','%'};
//pc.write((uint8_t *)header_ecg_checksum, sizeof(header_ecg_checksum));
//pc.write((int16_t *)ecgSample,readECGSamples * sizeof(int16_t ));
//memcpy(ecgSample_1sec , ecgSample, sizeof(ecgSample));
//memcpy(ecgSample_1sec + (onesec_counter * sizeof(int16_t)), ecgSample, sizeof(ecgSample));
if (flip)
{
sampleps = 12;
//printf("Flipped 12\r\n");
}
else
{
sampleps = 13;
// printf("Flipped 13\r\n");
}
for( idx = 0; idx < sampleps; idx++ )
{
//pc.printf("%6d\r\n", ecgSample[idx]);
ecgSample_1sec[onesec_counter] = ecgSample[idx];
cksm_1 = ecgSample[idx] & 0xff;
cksm_2 = (ecgSample[idx] >> 8) & 0xff;
checksum_ += cksm_1 + cksm_2;
onesec_counter++;
}
flip =!flip;
rLed = ! rLed;
}
}
}
}
void ecg_config(MAX30003& ecgAFE) {
// Reset ECG to clear registers
ecgAFE.writeRegister( MAX30003::SW_RST , 0);
// General config register setting
MAX30003::GeneralConfiguration_u CNFG_GEN_r;
CNFG_GEN_r.bits.en_ecg = 1; // Enable ECG channel
CNFG_GEN_r.bits.rbiasn = 1; // Enable resistive bias on negative input
CNFG_GEN_r.bits.rbiasp = 1; // Enable resistive bias on positive input
CNFG_GEN_r.bits.en_rbias = 1; // Enable resistive bias
CNFG_GEN_r.bits.imag = 2; // Current magnitude = 10nA
CNFG_GEN_r.bits.en_dcloff = 1; // Enable DC lead-off detection
//CNFG_GEN_r.bits.fmstr = 1; //125 sps FMSTR 1
ecgAFE.writeRegister( MAX30003::CNFG_GEN , CNFG_GEN_r.all);
// ECG Config register setting
MAX30003::ECGConfiguration_u CNFG_ECG_r;
CNFG_ECG_r.bits.dlpf = 1; // Digital LPF cutoff = 40Hz
CNFG_ECG_r.bits.dhpf = 1; // Digital HPF cutoff = 0.5Hz
CNFG_ECG_r.bits.gain = 3; // ECG gain = 160V/V
CNFG_ECG_r.bits.rate = 2; // Sample rate = 128 sps
ecgAFE.writeRegister( MAX30003::CNFG_ECG , CNFG_ECG_r.all);
//R-to-R configuration
MAX30003::RtoR1Configuration_u CNFG_RTOR_r;
CNFG_RTOR_r.bits.en_rtor = 1; // Enable R-to-R detection
ecgAFE.writeRegister( MAX30003::CNFG_RTOR1 , CNFG_RTOR_r.all);
//Manage interrupts register setting
MAX30003::ManageInterrupts_u MNG_INT_r;
MNG_INT_r.bits.efit = 0b00011; // Assert EINT w/ 4 unread samples
MNG_INT_r.bits.clr_rrint = 0b01; // Clear R-to-R on RTOR reg. read back
ecgAFE.writeRegister( MAX30003::MNGR_INT , MNG_INT_r.all);
//Enable interrupts register setting
MAX30003::EnableInterrupts_u EN_INT_r;
EN_INT_r.all = 0;
EN_INT_r.bits.en_eint = 1; // Enable EINT interrupt
EN_INT_r.bits.en_rrint = 0; // Disable R-to-R interrupt
EN_INT_r.bits.intb_type = 3; // Open-drain NMOS with internal pullup
ecgAFE.writeRegister( MAX30003::EN_INT , EN_INT_r.all);
//Dyanmic modes config
MAX30003::ManageDynamicModes_u MNG_DYN_r;
MNG_DYN_r.bits.fast = 0; // Fast recovery mode disabled
ecgAFE.writeRegister( MAX30003::MNGR_DYN , MNG_DYN_r.all);
// MUX Config
MAX30003::MuxConfiguration_u CNFG_MUX_r;
CNFG_MUX_r.bits.openn = 0; // Connect ECGN to AFE channel
CNFG_MUX_r.bits.openp = 0; // Connect ECGP to AFE channel
ecgAFE.writeRegister( MAX30003::CNFG_EMUX , CNFG_MUX_r.all);
return;
}