diff --git a/examples/Example5_fast_print/Example5_fast_print.ino b/examples/Example5_fast_print/Example5_fast_print.ino new file mode 100644 index 0000000..51ca2c5 --- /dev/null +++ b/examples/Example5_fast_print/Example5_fast_print.ino @@ -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 +#include + +// 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); +} diff --git a/src/SparkFun_Bio_Sensor_Hub_Library.cpp b/src/SparkFun_Bio_Sensor_Hub_Library.cpp index f266e56..f721ff3 100644 --- a/src/SparkFun_Bio_Sensor_Hub_Library.cpp +++ b/src/SparkFun_Bio_Sensor_Hub_Library.cpp @@ -43,9 +43,12 @@ uint8_t SparkFun_Bio_Sensor_Hub::begin( TwoWire &wirePort ) { // _i2cPort->begin(); A call to Wire.begin should occur in sketch // to avoid multiple begins with other sketches. + digitalWrite(_resetPin, HIGH); + delay(30); + digitalWrite(_mfioPin, HIGH); digitalWrite(_resetPin, LOW); - delay(10); + delay(30); digitalWrite(_resetPin, HIGH); delay(1000); pinMode(_mfioPin, INPUT_PULLUP); // To be used as an interrupt later @@ -85,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 } @@ -708,7 +711,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; } @@ -1043,7 +1046,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(1)); uint8_t statusByte = _i2cPort->read(); @@ -1062,7 +1065,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(4)); uint8_t statusByte = _i2cPort->read(); @@ -1089,7 +1092,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(4)); uint8_t statusByte = _i2cPort->read(); @@ -1116,7 +1119,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(4)); uint8_t statusByte = _i2cPort->read(); @@ -1278,7 +1281,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(1)); @@ -1301,7 +1304,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(1)); @@ -1327,7 +1330,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(1)); @@ -1350,7 +1353,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(1)); @@ -1380,7 +1383,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(1)); @@ -1419,7 +1422,7 @@ uint8_t SparkFun_Bio_Sensor_Hub::writeBytes(uint8_t _familyByte, uint8_t _indexB // 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; @@ -1429,7 +1432,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(sizeof(returnByte) + sizeof(statusByte))); statusByte = _i2cPort->read(); @@ -1438,13 +1441,54 @@ 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(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(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 parameter. It starts a request by writing the family byte, index byte, and +// 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 // the MAX32664 retrieves the requested information. A I-squared-C request is // then issued, and the information is read. @@ -1460,7 +1504,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, static_cast(sizeof(returnByte) + sizeof(statusByte))); statusByte = _i2cPort->read(); @@ -1482,12 +1526,13 @@ uint8_t SparkFun_Bio_Sensor_Hub::readFillArray(uint8_t _familyByte, uint8_t _ind _i2cPort->write(_familyByte); _i2cPort->write(_indexByte); _i2cPort->endTransmission(); - delay(CMD_DELAY); + //delayMicroseconds(CMD_DELAY*1000); - _i2cPort->requestFrom(_address, static_cast(_numOfReads + sizeof(statusByte))); - statusByte = _i2cPort->read(); - if( statusByte ){// SUCCESS: 0x00 - for(size_t i = 0; i < _numOfReads; i++){ + _i2cPort->requestFrom(_address, static_cast(arraySize + sizeof(statusByte))); + statusByte = _i2cPort->read(); // Got it + //if( (statusByte!=0) && (statusByte!=255) ){// SUCCESS (0x00) + if( statusByte!=0 ){// SUCCESS (0x00) + for(uint8_t i = 0; i < arraySize; i++){ array[i] = 0; } return statusByte; @@ -1517,7 +1562,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(sizeof(returnByte) + sizeof(statusByte))); statusByte = _i2cPort->read(); @@ -1549,7 +1594,7 @@ uint8_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(sizeof(int32_t) * _numOfReads + sizeof(statusByte))); statusByte = _i2cPort->read(); @@ -1584,7 +1629,7 @@ uint8_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(_numOfReads + sizeof(statusByte))); statusByte = _i2cPort->read(); diff --git a/src/SparkFun_Bio_Sensor_Hub_Library.h b/src/SparkFun_Bio_Sensor_Hub_Library.h index 0679adc..68cf951 100644 --- a/src/SparkFun_Bio_Sensor_Hub_Library.h +++ b/src/SparkFun_Bio_Sensor_Hub_Library.h @@ -728,6 +728,9 @@ class SparkFun_Bio_Sensor_Hub // information. An I-squared-C request is then issued, and the information is read and returned. uint8_t readByte(uint8_t, uint8_t); + uint8_t readByte_fast(uint8_t _familyByte, uint8_t _indexByte); + uint8_t readByte_fast(uint8_t _familyByte, uint8_t _indexByte, uint8_t _writeByte); + // This function is exactly as the one above except it accepts a Write Byte as // a paramter. It starts a request by writing the family byte, index byte, and // write byte to the MAX32664, delays 60 microseconds, during which