Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
-no more fifo delay issues and no more "unknown error" code
  • Loading branch information
Chris Idema committed Dec 10, 2020
commit 1c887251a90540becd9126d557c89a620ae3708b
175 changes: 175 additions & 0 deletions examples/Example5_fast_print/Example5_fast_print.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*
This example displays a more manual method of adjusting the way in which the
MAX30101 gathers data. Specifically we'll look at how to modify the pulse
length of the LEDs within the MAX30101 which impacts the number of samples
that can be gathered, so we'll adjust this value as well. In addition we
gather additional data from the bioData type: LED samples. This data gives
the number of samples gathered by the MAX30101 for both the red and IR LEDs.
As a side note you can also choose MODE_ONE and MODE_TWO for configSensorBpm
as well.
A summary of the hardware connections are as follows:
SDA -> SDA
SCL -> SCL
RESET -> PIN 4
MFIO -> PIN 5

Author: Elias Santistevan
Date: 8/2019
SparkFun Electronics

If you run into an error code check the following table to help diagnose your
problem:
1 = Unavailable Command
2 = Unavailable Function
3 = Data Format Error
4 = Input Value Error
5 = Try Again
255 = Error Unknown
*/

#include <SparkFun_Bio_Sensor_Hub_Library.h>
#include <Wire.h>

// Reset pin, MFIO pin
int resPin = 32;
int mfioPin = 5;

// Possible widths: 69, 118, 215, 411us
int width = 411;
// Possible samples: 50, 100, 200, 400, 800, 1000, 1600, 3200 samples/second
// Not every sample amount is possible with every width; check out our hookup
// guide for more information.
int samples = 100;
int pulseWidthVal;
int sampleVal;

// Takes address, reset pin, and MFIO pin.
SparkFun_Bio_Sensor_Hub bioHub(resPin, mfioPin);

bioData body;
// ^^^^^^^^^
// What's this!? This is a type (like "int", "byte", "long") unique to the SparkFun
// Pulse Oximeter and Heart Rate Monitor. Unlike those other types it holds
// specific information on the LED count values of the sensor and ALSO the
// biometric data: heart rate, oxygen levels, and confidence. "bioLedData" is
// actually a specific kind of type, known as a "struct". I chose the name
// "body" but you could use another variable name like "blood", "readings",
// "ledBody" or whatever. Using the variable in the following way gives the
// following data:
// body.irLed - Infrared LED counts.
// body.redLed - Red LED counts.
// body.heartrate - Heartrate
// body.confidence - Confidence in the heartrate value
// body.oxygen - Blood oxygen level
// body.status - Has a finger been sensed?

void setup(){

Serial.begin(115200);

#ifdef ARDUINO_ESP32_DEV
delay(2000);//delay for printing after reset
Serial.println("ARDUINO_ESP32_DEV");
#endif

Wire.begin(21,22,400000);
int result = bioHub.begin();
if (result == 0) // Zero errors!
Serial.println("Sensor started!");

Serial.println("Configuring Sensor....");
int error = bioHub.configSensorBpm(MODE_ONE); // Configure Sensor and BPM mode , MODE_TWO also available
if (error == 0){// Zero errors.
Serial.println("Sensor configured.");
}
else {
Serial.println("Error configuring sensor.");
Serial.print("Error: ");
Serial.println(error);
}

// Set pulse width.
error = bioHub.setPulseWidth(width);
if (error == 0){// Zero errors.
Serial.println("Pulse Width Set.");
}
else {
Serial.println("Could not set Pulse Width.");
Serial.print("Error: ");
Serial.println(error);
}

// Check that the pulse width was set.
pulseWidthVal = bioHub.readPulseWidth();
Serial.print("Pulse Width: ");
Serial.println(pulseWidthVal);

// Set sample rate per second. Remember that not every sample rate is
// available with every pulse width. Check hookup guide for more information.
error = bioHub.setSampleRate(samples);
if (error == 0){// Zero errors.
Serial.println("Sample Rate Set.");
}
else {
Serial.println("Could not set Sample Rate!");
Serial.print("Error: ");
Serial.println(error);
}

// bioHub.set_report_period(100);


// Check sample rate.
sampleVal = bioHub.readSampleRate();
Serial.print("Sample rate is set to: ");
Serial.println(sampleVal);

// Data lags a bit behind the sensor, if you're finger is on the sensor when
// it's being configured this delay will give some time for the data to catch
// up.
// Serial.println("Loading up the buffer with data....");
// delay(4000);

}

void loop(){

uint16_t t = millis();
static uint16_t t_old = 0;
int16_t t_diff;

// Information from the readSensor function will be saved to our "body"
// variable.

uint8_t samples = bioHub.numSamplesOutFifo();

//read all samples in fifo and use most recent one
while(samples){
body = bioHub.readSensorBpm();
samples--;
}


t_diff = t - t_old;
if(t_diff>=500){
t_old += 500;

// Serial.print(samples);
// Serial.print(",");
Serial.print(body.heartRate);
Serial.print(",");
Serial.println(body.oxygen);

samples = bioHub.numSamplesOutFifo();
}

//clear fifo before delay
while(samples){
body = bioHub.readSensorBpm();
samples--;
}



delay(10);
}
80 changes: 61 additions & 19 deletions src/SparkFun_Bio_Sensor_Hub_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ uint8_t SparkFun_Bio_Sensor_Hub::beginBootloader( TwoWire &wirePort ) {
// The following function checks the status of the FIFO.
uint8_t SparkFun_Bio_Sensor_Hub::readSensorHubStatus(){

uint8_t status = readByte(0x00, 0x00); // Just family and index byte.
uint8_t status = readByte_fast(0x00, 0x00); // Just family and index byte.
return status; // Will return 0x00

}
Expand Down Expand Up @@ -710,7 +710,7 @@ uint8_t SparkFun_Bio_Sensor_Hub::setFifoThreshold(uint8_t intThresh) {
// This function returns the number of samples available in the FIFO.
uint8_t SparkFun_Bio_Sensor_Hub::numSamplesOutFifo() {

uint8_t sampAvail = readByte(READ_DATA_OUTPUT, NUM_SAMPLES);
uint8_t sampAvail = readByte_fast(READ_DATA_OUTPUT, NUM_SAMPLES);
return sampAvail;

}
Expand Down Expand Up @@ -1043,7 +1043,7 @@ bool SparkFun_Bio_Sensor_Hub::eraseFlash() {
_i2cPort->write(BOOTLOADER_FLASH);
_i2cPort->write(ERASE_FLASH);
_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

_i2cPort->requestFrom(_address, static_cast<uint8_t>(1));
uint8_t statusByte = _i2cPort->read();
Expand All @@ -1062,7 +1062,7 @@ version SparkFun_Bio_Sensor_Hub::readBootloaderVers(){
_i2cPort->write(BOOTLOADER_INFO);
_i2cPort->write(BOOTLOADER_VERS);
_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

_i2cPort->requestFrom(_address, static_cast<uint8_t>(4));
uint8_t statusByte = _i2cPort->read();
Expand All @@ -1089,7 +1089,7 @@ version SparkFun_Bio_Sensor_Hub::readSensorHubVersion(){
_i2cPort->write(IDENTITY);
_i2cPort->write(READ_SENSOR_HUB_VERS);
_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

_i2cPort->requestFrom(_address, static_cast<uint8_t>(4));
uint8_t statusByte = _i2cPort->read();
Expand All @@ -1116,7 +1116,7 @@ version SparkFun_Bio_Sensor_Hub::readAlgorithmVersion(){
_i2cPort->write(IDENTITY);
_i2cPort->write(READ_ALGO_VERS);
_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

_i2cPort->requestFrom(_address, static_cast<uint8_t>(4));
uint8_t statusByte = _i2cPort->read();
Expand Down Expand Up @@ -1148,7 +1148,7 @@ uint8_t SparkFun_Bio_Sensor_Hub::enableWrite(uint8_t _familyByte, uint8_t _index
_i2cPort->write(_indexByte);
_i2cPort->write(_enableByte);
_i2cPort->endTransmission();
delay(ENABLE_CMD_DELAY);
delayMicroseconds(ENABLE_CMD_DELAY*1000);

// Status Byte, success or no? 0x00 is a successful transmit
_i2cPort->requestFrom(_address, static_cast<uint8_t>(1));
Expand All @@ -1171,7 +1171,7 @@ uint8_t SparkFun_Bio_Sensor_Hub::writeByte(uint8_t _familyByte, uint8_t _indexBy
_i2cPort->write(_indexByte);
_i2cPort->write(_writeByte);
_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

// Status Byte, success or no? 0x00 is a successful transmit
_i2cPort->requestFrom(_address, static_cast<uint8_t>(1));
Expand All @@ -1197,7 +1197,7 @@ uint8_t SparkFun_Bio_Sensor_Hub::writeByte(uint8_t _familyByte, uint8_t _indexBy
_i2cPort->write((_val >> 8)); // MSB
_i2cPort->write(_val); // LSB
_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

// Status Byte, success or no? 0x00 is a successful transmit
_i2cPort->requestFrom(_address, static_cast<uint8_t>(1));
Expand All @@ -1220,7 +1220,7 @@ uint8_t SparkFun_Bio_Sensor_Hub::writeByte(uint8_t _familyByte, uint8_t _indexBy
_i2cPort->write(_writeByte);
_i2cPort->write(_writeVal);
_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

// Status Byte, 0x00 is a successful transmit.
_i2cPort->requestFrom(_address, static_cast<uint8_t>(1));
Expand Down Expand Up @@ -1250,7 +1250,7 @@ uint8_t SparkFun_Bio_Sensor_Hub::writeLongBytes(uint8_t _familyByte, uint8_t _in
}

_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

// Status Byte, 0x00 is a successful transmit.
_i2cPort->requestFrom(_address, static_cast<uint8_t>(1));
Expand All @@ -1263,7 +1263,7 @@ uint8_t SparkFun_Bio_Sensor_Hub::writeLongBytes(uint8_t _familyByte, uint8_t _in
// requests. It starts a request by writing the family byte an index byte, and
// then delays 60 microseconds, during which the MAX32664 retrieves the requested
// information. An I-squared-C request is then issued, and the information is read.
uint8_t SparkFun_Bio_Sensor_Hub::readByte(uint8_t _familyByte, uint8_t _indexByte )
uint8_t SparkFun_Bio_Sensor_Hub::readByte(uint8_t _familyByte, uint8_t _indexByte)
{

uint8_t returnByte;
Expand All @@ -1273,7 +1273,7 @@ uint8_t SparkFun_Bio_Sensor_Hub::readByte(uint8_t _familyByte, uint8_t _indexByt
_i2cPort->write(_familyByte);
_i2cPort->write(_indexByte);
_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

_i2cPort->requestFrom(_address, static_cast<uint8_t>(sizeof(returnByte) + sizeof(statusByte)));
statusByte = _i2cPort->read();
Expand All @@ -1282,11 +1282,52 @@ uint8_t SparkFun_Bio_Sensor_Hub::readByte(uint8_t _familyByte, uint8_t _indexByt

returnByte = _i2cPort->read();
return returnByte; // If good then return the actual byte.
}

uint8_t SparkFun_Bio_Sensor_Hub::readByte_fast(uint8_t _familyByte, uint8_t _indexByte)
{

uint8_t returnByte;
uint8_t statusByte;

_i2cPort->beginTransmission(_address);
_i2cPort->write(_familyByte);
_i2cPort->write(_indexByte);
_i2cPort->endTransmission();
//delayMicroseconds(CMD_DELAY*1000);

_i2cPort->requestFrom(_address, static_cast<uint8_t>(sizeof(returnByte) + sizeof(statusByte)));
statusByte = _i2cPort->read();
if( statusByte )// SUCCESS (0x00) - how do I know its
return statusByte; // Return the error, see: READ_STATUS_BYTE_VALUE

returnByte = _i2cPort->read();
return returnByte; // If good then return the actual byte.
}

uint8_t SparkFun_Bio_Sensor_Hub::readByte_fast(uint8_t _familyByte, uint8_t _indexByte, uint8_t _writeByte)
{

uint8_t returnByte;
uint8_t statusByte;

_i2cPort->beginTransmission(_address);
_i2cPort->write(_familyByte);
_i2cPort->write(_indexByte);
_i2cPort->write(_writeByte);
_i2cPort->endTransmission();
//delayMicroseconds(CMD_DELAY*1000);

_i2cPort->requestFrom(_address, static_cast<uint8_t>(sizeof(returnByte) + sizeof(statusByte)));
statusByte = _i2cPort->read();
if( statusByte )// SUCCESS (0x00) - how do I know its
return statusByte; // Return the error, see: READ_STATUS_BYTE_VALUE

returnByte = _i2cPort->read();
return returnByte; // If good then return the actual byte.
}


// This function is exactly as the one above except it accepts also receives a
// Write Byte as a paramter. It starts a request by writing the family byte, index byte, and
// write byte to the MAX32664 and then delays 60 microseconds, during which
Expand All @@ -1304,7 +1345,7 @@ uint8_t SparkFun_Bio_Sensor_Hub::readByte(uint8_t _familyByte, uint8_t _indexBy
_i2cPort->write(_indexByte);
_i2cPort->write(_writeByte);
_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

_i2cPort->requestFrom(_address, sizeof(returnByte) + sizeof(statusByte));
statusByte = _i2cPort->read();
Expand All @@ -1326,11 +1367,12 @@ uint8_t* SparkFun_Bio_Sensor_Hub::readFillArray(uint8_t _familyByte, uint8_t _in
_i2cPort->write(_familyByte);
_i2cPort->write(_indexByte);
_i2cPort->endTransmission();
delay(CMD_DELAY);
//delayMicroseconds(CMD_DELAY*1000);

_i2cPort->requestFrom(_address, static_cast<uint8_t>(arraySize + sizeof(statusByte)));
statusByte = _i2cPort->read(); // Got it
if( (statusByte!=0) && (statusByte!=255) ){// SUCCESS (0x00)
//if( (statusByte!=0) && (statusByte!=255) ){// SUCCESS (0x00)
if( statusByte!=0 ){// SUCCESS (0x00)
for(uint8_t i = 0; i < arraySize; i++){
array[i] = 0;
}
Expand Down Expand Up @@ -1361,7 +1403,7 @@ uint16_t SparkFun_Bio_Sensor_Hub::readIntByte(uint8_t _familyByte, uint8_t _inde
_i2cPort->write(_indexByte);
_i2cPort->write(_writeByte);
_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

_i2cPort->requestFrom(_address, static_cast<uint8_t>(sizeof(returnByte) + sizeof(statusByte)));
statusByte = _i2cPort->read();
Expand Down Expand Up @@ -1393,7 +1435,7 @@ uint32_t SparkFun_Bio_Sensor_Hub::readLongByte(uint8_t _familyByte, uint8_t _ind
_i2cPort->write(_indexByte);
_i2cPort->write(_writeByte);
_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

_i2cPort->requestFrom(_address, (sizeof(returnByte) * 3) + sizeof(statusByte) );
statusByte = _i2cPort->read();
Expand Down Expand Up @@ -1427,7 +1469,7 @@ int32_t* SparkFun_Bio_Sensor_Hub::readMultipleBytes(uint8_t _familyByte, uint8_t
_i2cPort->write(_indexByte);
_i2cPort->write(_writeByte);
_i2cPort->endTransmission();
delay(CMD_DELAY);
delayMicroseconds(CMD_DELAY*1000);

_i2cPort->requestFrom(_address, static_cast<uint8_t>(sizeof(int32_t) * _numOfReads + sizeof(statusByte)));
statusByte = _i2cPort->read();
Expand Down
Loading