diff --git a/.github/workflows/add_issue_to_project.yml b/.github/workflows/add_issue_to_project.yml
new file mode 100644
index 0000000..6b60cc3
--- /dev/null
+++ b/.github/workflows/add_issue_to_project.yml
@@ -0,0 +1,18 @@
+name: Add new issue to our main project
+
+on:
+ issues:
+ types:
+ - opened
+
+jobs:
+ add-to-project:
+ name: Add issue to project
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/add-to-project@main
+ with:
+ # You can target a project in a different organization
+ # to the issue
+ project-url: https://github.com/orgs/sparkfun/projects/19
+ github-token: ${{ secrets.DEFECT_ADD_TO_PROJECT }}
diff --git a/README.md b/README.md
index fed3d77..7abf646 100644
--- a/README.md
+++ b/README.md
@@ -19,8 +19,8 @@ Documentation
--------------
* **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library.
-* **[Hookup Guide](https://docs.sparkfun.com/SparkFun_IoT_Brushless_Motor_Driver)** - Basic hookup guide for the SparkFun IoT Motor Driver Breakout (ESP32, TMC6300).
-* **[Product Repository](https://github.com/sparkfun/SparkFun_IoT_Brushless_Motor_Driver)** - Main repository for the IoT Motor Driver (including hardware files)
+* **[Hookup Guide](https://docs.sparkfun.com/SparkFun_Qwiic_Human_Presence_Sensor-STHS34PF80/introduction/)** - Basic hookup guide for the SparkFun Qwiic STHS34PF80.
+* **[Product Repository](https://github.com/sparkfun/SparkFun_Qwiic_Human_Presence_Sensor-STHS34PF80)** - Main repository for the SparkFun Qwiic STHS34PF80 (including hardware files)
Products that use this Library
diff --git a/examples/Example1_BasicReadings/Example1_BasicReadings.ino b/examples/Example1_BasicReadings/Example1_BasicReadings.ino
index de71b2e..857d18d 100644
--- a/examples/Example1_BasicReadings/Example1_BasicReadings.ino
+++ b/examples/Example1_BasicReadings/Example1_BasicReadings.ino
@@ -1,3 +1,49 @@
+/******************************************************************************
+ Example1_BasicReadings.ino
+
+ Read human presence detection values from the STHS34PF80 sensor, print them
+ to terminal. Prints raw IR presence (cm^-1), if motion was detected, and
+ temperature in degrees C.
+
+ SparkFun STHS34PF80 Arduino Library
+ Madison Chodikov @ SparkFun Electronics
+ Original Creation Date: September 19th, 2023
+ https://github.com/sparkfun/SparkFun_STHS34PF80_Arduino_Library
+
+ Development environment specifics:
+
+ IDE: Arduino 2.2.1
+ Hardware Platform: SparkFun RedBoard Qwiic
+ SparkFun Human Presence and Motion Sensor - STHS34PF80 (Qwiic) Version: 1.0
+ SparkFun Qwiic Mini Human Presence and Motion Sensor - STHS34PF80 Version: 1.0
+
+ Do you like this library? Help support SparkFun. Buy a board!
+
+ SparkFun Human Presence and Motion Sensor - STHS34PF80 (Qwiic)
+ https://www.sparkfun.com/products/22494
+
+ SparkFun Qwiic Mini Human Presence and Motion Sensor - STHS34PF80
+ https://www.sparkfun.com/products/23253
+
+ Hardware Connections:
+ Use a Qwiic cable to connect from the RedBoard Qwiic to the STHS34PF80 breakout (QWIIC).
+ You can also choose to wire up the connections using the header pins like so:
+
+ ARDUINO --> STHS34PF80
+ SDA (A4) --> SDA
+ SCL (A5) --> SCL
+ 3.3V --> 3.3V
+ GND --> GND
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+******************************************************************************/
+
#include "SparkFun_STHS34PF80_Arduino_Library.h"
#include
@@ -15,14 +61,10 @@ void setup()
Serial.println("STHS34PF80 Example 1: Basic Readings");
// Begin I2C
- if(Wire.begin() == 0)
- {
- Serial.println("I2C Error - check I2C Address");
- while(1);
- }
+ Wire.begin()
// Establish communication with device
- if(mySensor.begin() != 0)
+ if(mySensor.begin() == false)
{
Serial.println("Error setting up device - please check wiring.");
while(1);
diff --git a/examples/Example2_Interrupts/Example2_Interrupts.ino b/examples/Example2_Interrupts/Example2_Interrupts.ino
index ef2167b..9026d1d 100644
--- a/examples/Example2_Interrupts/Example2_Interrupts.ino
+++ b/examples/Example2_Interrupts/Example2_Interrupts.ino
@@ -1,3 +1,50 @@
+/******************************************************************************
+ Example2_Interrupts.ino
+
+ Read human presence detection value from the STHS34PF80 sensor, print them
+ to terminal using the interrupt flag instead of the typical data ready flag.
+ Prints raw IR presence values (cm^-1).
+
+ SparkFun STHS34PF80 Arduino Library
+ Madison Chodikov @ SparkFun Electronics
+ Original Creation Date: September 19th, 2023
+ https://github.com/sparkfun/SparkFun_STHS34PF80_Arduino_Library
+
+ Development environment specifics:
+
+ IDE: Arduino 2.2.1
+ Hardware Platform: SparkFun RedBoard Qwiic
+ SparkFun Human Presence and Motion Sensor - STHS34PF80 (Qwiic) Version: 1.0
+ SparkFun Qwiic Mini Human Presence and Motion Sensor - STHS34PF80 Version: 1.0
+
+ Do you like this library? Help support SparkFun. Buy a board!
+
+ SparkFun Human Presence and Motion Sensor - STHS34PF80 (Qwiic)
+ https://www.sparkfun.com/products/22494
+
+ SparkFun Qwiic Mini Human Presence and Motion Sensor - STHS34PF80
+ https://www.sparkfun.com/products/23253
+
+ Hardware Connections:
+ Use a Qwiic cable to connect from the RedBoard Qwiic to the STHS34PF80 breakout (QWIIC).
+ You can also choose to wire up the connections using the header pins like so:
+
+ ARDUINO --> STHS34PF80
+ SDA (A4) --> SDA
+ SCL (A5) --> SCL
+ INT (2) --> INT
+ 3.3V --> 3.3V
+ GND --> GND
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+******************************************************************************/
+
#include "SparkFun_STHS34PF80_Arduino_Library.h"
#include
@@ -7,7 +54,7 @@ STHS34PF80_I2C mySensor;
int16_t presenceVal = 0;
// Change the pin number to the pin that has been chosen for your setup
-int intPin = 12;
+int intPin = 2;
// Star the flag as false
bool volatile interruptFlag = false;
@@ -24,14 +71,10 @@ void setup()
Serial.println("STHS34PF80 Example 2: Interrupts");
// Begin I2C
- if(Wire.begin() == 0)
- {
- Serial.println("I2C Error - check I2C Address");
- while(1);
- }
+ Wire.begin()
// Establish communication with device
- if(mySensor.begin() != 0)
+ if(mySensor.begin() == false)
{
Serial.println("Error setting up device - please check wiring.");
while(1);
diff --git a/examples/Example3_EmbeddedFunctions/Example3_EmbeddedFunctions.ino b/examples/Example3_EmbeddedFunctions/Example3_EmbeddedFunctions.ino
index 88fa295..e1fa9b8 100644
--- a/examples/Example3_EmbeddedFunctions/Example3_EmbeddedFunctions.ino
+++ b/examples/Example3_EmbeddedFunctions/Example3_EmbeddedFunctions.ino
@@ -1,3 +1,49 @@
+/******************************************************************************
+ Example3_EmbeddedFunctions.ino
+
+ Set the hysteresis values for the presence and motion detection, read human
+ presence detection values from the STHS34PF80 sensor, print them to terminal.
+ Prints raw IR presence (cm^-1) and if motion was detected.
+
+ SparkFun STHS34PF80 Arduino Library
+ Madison Chodikov @ SparkFun Electronics
+ Original Creation Date: September 19th, 2023
+ https://github.com/sparkfun/SparkFun_STHS34PF80_Arduino_Library
+
+ Development environment specifics:
+
+ IDE: Arduino 2.2.1
+ Hardware Platform: SparkFun RedBoard Qwiic
+ SparkFun Human Presence and Motion Sensor - STHS34PF80 (Qwiic) Version: 1.0
+ SparkFun Qwiic Mini Human Presence and Motion Sensor - STHS34PF80 Version: 1.0
+
+ Do you like this library? Help support SparkFun. Buy a board!
+
+ SparkFun Human Presence and Motion Sensor - STHS34PF80 (Qwiic)
+ https://www.sparkfun.com/products/22494
+
+ SparkFun Qwiic Mini Human Presence and Motion Sensor - STHS34PF80
+ https://www.sparkfun.com/products/23253
+
+ Hardware Connections:
+ Use a Qwiic cable to connect from the RedBoard Qwiic to the STHS34PF80 breakout (QWIIC).
+ You can also choose to wire up the connections using the header pins like so:
+
+ ARDUINO --> STHS34PF80
+ SDA (A4) --> SDA
+ SCL (A5) --> SCL
+ 3.3V --> 3.3V
+ GND --> GND
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+******************************************************************************/
+
#include "SparkFun_STHS34PF80_Arduino_Library.h"
#include
@@ -16,14 +62,10 @@ void setup()
Serial.println("STHS34PF80 Example 3: Using Embedded Functions");
// Begin I2C
- if(Wire.begin() == 0)
- {
- Serial.println("I2C Error - check I2C Address");
- while(1);
- }
+ Wire.begin()
// Establish communication with device
- if(mySensor.begin() != 0)
+ if(mySensor.begin() == false)
{
Serial.println("Error setting up device - please check wiring.");
while(1);
diff --git a/examples/Example4_SPIFunctionality/Example4_SPIFunctionality.ino b/examples/Example4_SPIFunctionality/Example4_SPIFunctionality.ino
index 63aebc2..92bb700 100644
--- a/examples/Example4_SPIFunctionality/Example4_SPIFunctionality.ino
+++ b/examples/Example4_SPIFunctionality/Example4_SPIFunctionality.ino
@@ -1,3 +1,51 @@
+/******************************************************************************
+ Example4_SPIFunctionality.ino
+
+ Read human presence detection values from the STHS34PF80 sensor, print them
+ to terminal using SPI communication instead of I2C.
+ Prints raw IR presence (cm^-1), if motion was detected, and temperature
+ in degrees C.
+
+ SparkFun STHS34PF80 Arduino Library
+ Madison Chodikov @ SparkFun Electronics
+ Original Creation Date: September 19th, 2023
+ https://github.com/sparkfun/SparkFun_STHS34PF80_Arduino_Library
+
+ Development environment specifics:
+
+ IDE: Arduino 2.2.1
+ Hardware Platform: SparkFun RedBoard Qwiic
+ SparkFun Human Presence and Motion Sensor - STHS34PF80 (Qwiic) Version: 1.0
+ SparkFun Qwiic Mini Human Presence and Motion Sensor - STHS34PF80 Version: 1.0
+
+ Do you like this library? Help support SparkFun. Buy a board!
+
+ SparkFun Human Presence and Motion Sensor - STHS34PF80 (Qwiic)
+ https://www.sparkfun.com/products/22494
+
+ SparkFun Qwiic Mini Human Presence and Motion Sensor - STHS34PF80
+ https://www.sparkfun.com/products/23253
+
+ Hardware Connections:
+ Wire the SPI Connections from the RedBoard Qwiic to the STHS34PF80 Breakout
+ with a resistive divider using the header pins like so:
+
+ ARDUINO --> STHS34PF80
+ SCK/SCL (13) --> Clock
+ SDI/SDA (12) --> Data in
+ !CS (10) --> Chip Select
+ 3.3V --> 3.3V
+ GND --> GND
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+******************************************************************************/
+
#include "SparkFun_STHS34PF80_Arduino_Library.h"
#include
@@ -8,7 +56,7 @@ int16_t presenceVal = 0;
float temperatureVal = 0;
// Set your chip select pin according to your setup
-uint8_t chipSelect = 12;
+uint8_t chipSelect = 10;
void setup()
{
@@ -23,7 +71,7 @@ void setup()
SPI.begin();
// Establish communication with device
- if(mySensor.begin(chipSelect) != 0)
+ if(mySensor.begin(chipSelect) == false)
{
Serial.println("Error setting up device - please check wiring.");
while(1);
@@ -36,7 +84,6 @@ void loop()
{
sths34pf80_tmos_drdy_status_t dataReady;
mySensor.getDataReady(&dataReady);
- Serial.println(dataReady.drdy);
// Check whether sensor has new data - run through loop if data is ready
if(dataReady.drdy == 1)
diff --git a/examples/Example5_ArduinoPlotterOutput/Example5_ArduinoPlotterOutput.ino b/examples/Example5_ArduinoPlotterOutput/Example5_ArduinoPlotterOutput.ino
index 8b56397..2958c18 100644
--- a/examples/Example5_ArduinoPlotterOutput/Example5_ArduinoPlotterOutput.ino
+++ b/examples/Example5_ArduinoPlotterOutput/Example5_ArduinoPlotterOutput.ino
@@ -1,3 +1,49 @@
+/******************************************************************************
+ Example5_ArduinoPlotterOutput.ino
+
+ Read human presence detection values from the STHS34PF80 sensor, print them
+ to Arduino Serial Plotter.
+ Prints raw IR presence values (cm^-1).
+
+ SparkFun STHS34PF80 Arduino Library
+ Madison Chodikov @ SparkFun Electronics
+ Original Creation Date: September 19th, 2023
+ https://github.com/sparkfun/SparkFun_STHS34PF80_Arduino_Library
+
+ Development environment specifics:
+
+ IDE: Arduino 2.2.1
+ Hardware Platform: SparkFun RedBoard Qwiic
+ SparkFun Human Presence and Motion Sensor - STHS34PF80 (Qwiic) Version: 1.0
+ SparkFun Qwiic Mini Human Presence and Motion Sensor - STHS34PF80 Version: 1.0
+
+ Do you like this library? Help support SparkFun. Buy a board!
+
+ SparkFun Human Presence and Motion Sensor - STHS34PF80 (Qwiic)
+ https://www.sparkfun.com/products/22494
+
+ SparkFun Qwiic Mini Human Presence and Motion Sensor - STHS34PF80
+ https://www.sparkfun.com/products/23253
+
+ Hardware Connections:
+ Use a Qwiic cable to connect from the RedBoard Qwiic to the STHS34PF80 breakout (QWIIC).
+ You can also choose to wire up the connections using the header pins like so:
+
+ ARDUINO --> STHS34PF80
+ SDA (A4) --> SDA
+ SCL (A5) --> SCL
+ 3.3V --> 3.3V
+ GND --> GND
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+******************************************************************************/
+
#include "SparkFun_STHS34PF80_Arduino_Library.h"
#include
@@ -12,14 +58,10 @@ void setup()
Serial.println("STHS34PF80 Example 5: Arduino Serial Plotter Output");
// Begin I2C
- if(Wire.begin() == 0)
- {
- Serial.println("I2C Error - check I2C Address");
- while(1);
- }
+ Wire.begin()
// Establish communication with device
- if(mySensor.begin() != 0)
+ if(mySensor.begin() == false)
{
Serial.println("Error setting up device - please check wiring.");
while(1);
diff --git a/library.properties b/library.properties
index 69ef2f0..54c6b36 100644
--- a/library.properties
+++ b/library.properties
@@ -1,9 +1,9 @@
name=SparkFun STHS34PF80 Arduino Library
-version=1.0.0
+version=1.0.4
author=SparkFun Electronics
maintainer=SparkFun Electronics
sentence=A library to drive the STMicroelectronics infrared sensor STHS34PF80.
paragraph=The STHS34PF80 is a low-power, high-sensitivity infrared sensor for presence and motion detection.
category=Sensors
url=https://github.com/sparkfun/SparkFun_STHS34PF80_Arduino_Library
-architectures=*
\ No newline at end of file
+architectures=*
diff --git a/src/SparkFun_STHS34PF80_Arduino_Library.cpp b/src/SparkFun_STHS34PF80_Arduino_Library.cpp
index a6f9e56..4091fd9 100644
--- a/src/SparkFun_STHS34PF80_Arduino_Library.cpp
+++ b/src/SparkFun_STHS34PF80_Arduino_Library.cpp
@@ -1,30 +1,28 @@
#include "SparkFun_STHS34PF80_Arduino_Library.h"
-int32_t STHS34PF80_I2C::begin(uint8_t devAddr, TwoWire& wirePort)
+
+bool STHS34PF80_I2C::begin(uint8_t devAddr, TwoWire& wirePort)
{
- bus.init(devAddr, Wire);
+ _i2cBus.init(wirePort, false);
sensor.read_reg = STHS34PF80_I2C::read;
sensor.write_reg = STHS34PF80_I2C::write;
sensor.mdelay = STHS34PF80_I2C::delayMS;
- sensor.handle = &bus;
+ sensor.handle = this;
+ deviceAddress = devAddr;
- STHS34PF80::begin();
+ // call super class begin -- it returns 0 on no error
+ return STHS34PF80::begin() == 0;
- return 0; // returns error code here
}
-int32_t STHS34PF80_I2C::read(void* bus, uint8_t addr, uint8_t* data, uint16_t numData)
+int32_t STHS34PF80_I2C::read(void* device, uint8_t addr, uint8_t* data, uint16_t numData)
{
- ((SFE_BusI2C*) bus)->readRegs(addr, data, numData);
-
- return 0; // returns error code here
+ return ((STHS34PF80_I2C*)device)->_i2cBus.readRegisterRegion(((STHS34PF80_I2C*)device)->deviceAddress, addr, data, numData);
}
-int32_t STHS34PF80_I2C::write(void* bus, uint8_t addr, const uint8_t* data, uint16_t numData)
+int32_t STHS34PF80_I2C::write(void* device, uint8_t addr, const uint8_t* data, uint16_t numData)
{
- ((SFE_BusI2C*) bus)->writeRegs(addr, data, numData);
-
- return 0; // returns error code here
+ return ((STHS34PF80_I2C*)device)->_i2cBus.writeRegisterRegion(((STHS34PF80_I2C*)device)->deviceAddress, addr, data, numData);
}
void STHS34PF80_I2C::delayMS(uint32_t millisec)
@@ -32,27 +30,28 @@ void STHS34PF80_I2C::delayMS(uint32_t millisec)
delay(millisec);
}
-int32_t STHS34PF80_SPI::begin(uint8_t chipSelect, SPIClass &spiPort)
+bool STHS34PF80_SPI::begin(uint8_t chipSelect, SPIClass &spiPort)
{
- bus.init(chipSelect, spiPort, false);
+ SPISettings spiSettings = SPISettings(3000000, MSBFIRST, SPI_MODE0);
+ _spiBus.init(spiPort, spiSettings, chipSelect);
sensor.read_reg = STHS34PF80_SPI::read;
sensor.write_reg = STHS34PF80_SPI::write;
sensor.mdelay = STHS34PF80_SPI::delayMS;
- sensor.handle = &bus;
+ sensor.handle = this;
- STHS34PF80::begin();
+ // call super class begin -- it returns 0 on no error
+ return STHS34PF80::begin() == 0;
- return 0; // returns error code here
}
-int32_t STHS34PF80_SPI::read(void* bus, uint8_t addr, uint8_t* data, uint16_t numData)
+int32_t STHS34PF80_SPI::read(void* device, uint8_t addr, uint8_t* data, uint16_t numData)
{
- return ((SFE_BusSPI*) bus)->readRegisterRegion(0, data, numData);
+ return ((STHS34PF80_SPI*)device)->_spiBus.readRegisterRegion(0, addr, data, numData);
}
-int32_t STHS34PF80_SPI::write(void* bus, uint8_t addr, const uint8_t* data, uint16_t numData)
+int32_t STHS34PF80_SPI::write(void* device, uint8_t addr, const uint8_t* data, uint16_t numData)
{
- return ((SFE_BusSPI*) bus)->writeRegisterRegion(0, data, numData);
+ return ((STHS34PF80_SPI*)device)->_spiBus.writeRegisterRegion(0, addr, data, numData);
}
void STHS34PF80_SPI::delayMS(uint32_t millisec)
diff --git a/src/SparkFun_STHS34PF80_Arduino_Library.h b/src/SparkFun_STHS34PF80_Arduino_Library.h
index a6f0cb3..704cf03 100644
--- a/src/SparkFun_STHS34PF80_Arduino_Library.h
+++ b/src/SparkFun_STHS34PF80_Arduino_Library.h
@@ -19,7 +19,7 @@ Distributed as-is; no warranty is given.
#include "sths34pf80_class.h"
-#include "SFE_Bus.h"
+#include "sfe_bus.h"
#include
#include
#include
@@ -28,25 +28,26 @@ Distributed as-is; no warranty is given.
class STHS34PF80_I2C : public STHS34PF80
{
public:
- int32_t begin(uint8_t devAddr = STHS34PF80_I2C_ADD >> 1, TwoWire& wirePort = Wire);
+ bool begin(uint8_t devAddr = STHS34PF80_I2C_ADDRESS, TwoWire& wirePort = Wire);
static int32_t read(void *, uint8_t, uint8_t *, uint16_t);
static int32_t write(void *, uint8_t, const uint8_t *, uint16_t);
static void delayMS(uint32_t millisec);
private:
- SFE_BusI2C bus;
+ sfe_STHS34PF80::QwI2C _i2cBus;
+ uint8_t deviceAddress;
};
class STHS34PF80_SPI : public STHS34PF80
{
public:
- int32_t begin(uint8_t chipSelect, SPIClass &spiPort=SPI);
+ bool begin(uint8_t chipSelect, SPIClass &spiPort=SPI);
static int32_t read(void *, uint8_t, uint8_t *, uint16_t);
static int32_t write(void *, uint8_t, const uint8_t *, uint16_t);
static void delayMS(uint32_t millisec);
private:
- SFE_BusSPI bus;
+ sfe_STHS34PF80::SfeSPI _spiBus;
};
diff --git a/src/sfe_bus.cpp b/src/sfe_bus.cpp
index 8e0bf62..5ac3f69 100644
--- a/src/sfe_bus.cpp
+++ b/src/sfe_bus.cpp
@@ -1,163 +1,389 @@
+// sfe_bus.cpp
+//
+// This is a library written for SparkFun Human Presence Sensor STHS34PF80
+// (Qwiic)
+//
+// SparkFun sells these boards at its website: www.sparkfun.com
+//
+// Do you like this library? Help support SparkFun. Buy a board!
+//
+// SparkFun Human Presence Sensor STHS34PF80 (Qwiic)
+// https://www.sparkfun.com/products/22494
+//
+// Written by Madison Chodikov @ SparkFun Electronics, October 2023
+//
+// Repository:
+// https://github.com/sparkfun/SparkFun_STHS34PF80_Arduino_Library/tree/main
+//
+//
+// SparkFun code, firmware, and software is released under the MIT
+// License(http://opensource.org/licenses/MIT).
+//
+// SPDX-License-Identifier: MIT
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2022 SparkFun Electronics
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions: The
+// above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// The following classes specify the behavior for communicating
+// over the respective data buses: Inter-Integrated Circuit (I2C)
+// and Serial Peripheral Interface (SPI). For ease of implementation
+// an abstract interface (QwIDeviceBus) is used.
+
#include "sfe_bus.h"
+#include
+
+#define kMaxTransferBuffer 32
+#define SPI_READ 0x80
+
+// What we use for transfer chunk size
+const static uint16_t kChunkSize = kMaxTransferBuffer;
-/// @brief Constructor
-/// @param addr Address of the device
-/// @param port Wire port chosen to be used for I2C transactions
-/// @return Error code
-int32_t SFE_BusI2C::init(uint8_t addr, TwoWire& port)
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// Constructor
+//
+
+namespace sfe_STHS34PF80
{
- devAddr = addr;
- devPort = &port;
- return 0;
+QwI2C::QwI2C(void) : _i2cPort{nullptr}
+{
}
-/// @brief Reads a register at the requested address for the requested
-/// number of bytes.
-/// @param regAddress Register address
-/// @param dataBuffer Data buffer
-/// @param numBytes Number of bytes requested from register address
-/// @return Error code (true for success, )
-int32_t SFE_BusI2C::readRegs(uint8_t regAddress, uint8_t* dataBuffer, uint8_t numBytes)
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// I2C init()
+//
+// Methods to init/setup this device. The caller can provide a Wire Port, or
+// this class will use the default
+
+bool QwI2C::init(TwoWire &wirePort, bool bInit)
{
- // Jump to desired register address
- devPort->beginTransmission(devAddr);
- devPort->write(regAddress);
- if(devPort->endTransmission())
+
+ // if we don't have a wire port already
+ if (!_i2cPort)
{
- return 0;
+ _i2cPort = &wirePort;
+
+ if (bInit)
+ _i2cPort->begin();
}
- // Read bytes from these registers
- devPort->requestFrom(devAddr, numBytes);
+ return true;
+}
- // Store all requested bytes
- for(uint32_t i = 0; i < numBytes && devPort->available(); i++)
- {
- dataBuffer[i] = devPort->read();
- }
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// I2C init()
+//
+// Methods to init/setup this device. The caller can provide a Wire Port, or
+// this class will use the default
+bool QwI2C::init()
+{
+ if (!_i2cPort)
+ return init(Wire);
+ else
+ return false;
+}
- return 0;
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// ping()
+//
+// Is a device connected?
+bool QwI2C::ping(uint8_t i2c_address)
+{
+
+ if (!_i2cPort)
+ return false;
+
+ _i2cPort->beginTransmission(i2c_address);
+ return _i2cPort->endTransmission() == 0;
}
-/// @brief Writes to the devices register
-/// @param regAddress Register address
-/// @param dataBuffer Data buffer
-/// @param numBytes Number of bytes requested from register address
-/// @return Error code (false for error, true for success)
-int32_t SFE_BusI2C::writeRegs(uint8_t regAddress, const uint8_t* dataBuffer, uint8_t numBytes)
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// writeRegisterByte()
+//
+// Write a byte to a register
+
+bool QwI2C::writeRegisterByte(uint8_t i2c_address, uint8_t offset, uint8_t dataToWrite)
{
- // Begin transmission
- devPort->beginTransmission(devAddr);
- // Write the address
- devPort->write(regAddress);
-
- // Write all the data
- for(uint32_t i = 0; i < numBytes; i++)
- {
- devPort->write(dataBuffer[i]);
- }
+ if (!_i2cPort)
+ return false;
- // End transmission
- if(devPort->endTransmission())
- {
+ _i2cPort->beginTransmission(i2c_address);
+ _i2cPort->write(offset);
+ _i2cPort->write(dataToWrite);
+ return _i2cPort->endTransmission() == 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// writeRegisterRegion()
+//
+// Write a block of data to a device.
+
+int QwI2C::writeRegisterRegion(uint8_t i2c_address, uint8_t offset, const uint8_t *data, uint16_t length)
+{
+
+ _i2cPort->beginTransmission(i2c_address);
+ _i2cPort->write(offset);
+ _i2cPort->write(data, (int)length);
+
+ return _i2cPort->endTransmission() ? -1 : 0; // -1 = error, 0 = success
+}
+
+int QwI2C::writeRegisterRegion(uint8_t i2c_address, uint8_t offset, uint8_t data, uint16_t length)
+{
+
+ _i2cPort->beginTransmission(i2c_address);
+ _i2cPort->write(offset);
+ _i2cPort->write(data);
+
+ return _i2cPort->endTransmission() ? -1 : 0; // -1 = error, 0 = success
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// readRegisterRegion()
+//
+// Reads a block of data from an i2c register on the devices.
+//
+// For large buffers, the data is chuncked over KMaxI2CBufferLength at a time
+//
+//
+int QwI2C::readRegisterRegion(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t numBytes)
+{
+ uint8_t nChunk;
+ uint16_t nReturned;
+
+ if (!_i2cPort)
return -1;
- }
- return 0;
+ int i; // counter in loop
+ bool bFirstInter = true; // Flag for first iteration - used to send register
+
+ while (numBytes > 0)
+ {
+ _i2cPort->beginTransmission(addr);
+
+ if (bFirstInter)
+ {
+ _i2cPort->write(reg);
+ bFirstInter = false;
+ }
+
+ if (_i2cPort->endTransmission() != 0)
+ return -1; // error with the end transmission
+
+ // We're chunking in data - keeping the max chunk to kMaxI2CBufferLength
+ nChunk = numBytes > kChunkSize ? kChunkSize : numBytes;
+
+ nReturned = _i2cPort->requestFrom((int)addr, (int)nChunk, (int)true);
+
+ // No data returned, no dice
+ if (nReturned == 0)
+ return -1; // error
+
+ // Copy the retrieved data chunk to the current index in the data segment
+ for (i = 0; i < nReturned; i++)
+ {
+ *data++ = _i2cPort->read();
+ }
+
+ // Decrement the amount of data recieved from the overall data request
+ // amount
+ numBytes = numBytes - nReturned;
+
+ } // end while
+
+ return 0; // Success
}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// Constructor
+//
+
+SfeSPI::SfeSPI(void) : _spiPort{nullptr}
+{
+}
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SPI Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+////////////////////////////////////////////////////////////////////////////////////////////////
+// SPI init()
+//
+// Methods to init/setup this device. The caller can provide a SPI Port, or this
+// class will use the default
-/// @brief This function containts the methods to init/setup this device. The caller can provide
-/// a SPI port, or this class will use the default.
-/// @param spiPort SPI port chosen by user
-/// @param ismSPISettings SPI settings for every transaction
-/// @param cs Chip Select Pin
-/// @param bInit True or false for initialization
-/// @return Error code
-int32_t SFE_BusSPI::init(uint8_t cs, SPIClass& spiPort, bool bInit)
+bool SfeSPI::init(SPIClass &spiPort, SPISettings &sthsSPISettings, uint8_t cs, bool bInit)
{
+
// if we don't have a SPI port already
- if( !_spiPort )
+ if (!_spiPort)
{
_spiPort = &spiPort;
- if( bInit )
+ if (bInit)
_spiPort->begin();
}
- // SPI settings are needed for every transaction
- _sfeSPISettings = SPISettings(1000000, MSBFIRST, SPI_MODE0);
+ // SPI settings are needed for every transaction
+ _sfeSPISettings = sthsSPISettings;
- // The chip select pin can vary from platform to platform and project to project
- // and so it must be given by the user.
- if( !cs )
- return -1;
-
- _cs = cs;
+ // The chip select pin can vary from platform to platform and project to
+ // project and so it must be given by the user.
+ if (!cs)
+ return false;
- return 0;
+ _cs = cs;
+
+ return true;
}
-/// @brief This function writes a block of data to a device
-/// @param i2c_address Address to write to
-/// @param offset Offset of register
-/// @param data Data to write to register
-/// @param length Length of data to be written to register
-/// @return Error code
-int32_t SFE_BusSPI::writeRegisterRegion(uint8_t offset, const uint8_t *data, uint16_t length)
+////////////////////////////////////////////////////////////////////////////////////////////////
+// SPI init()
+//
+// Methods to init/setup this device. The caller can provide a SPI Port, or this
+// class will use the default
+bool SfeSPI::init(uint8_t cs, bool bInit)
{
- int i;
- // Apply settings
+ // If the transaction settings are not provided by the user they are built
+ // here.
+ SPISettings spiSettings = SPISettings(3000000, MSBFIRST, SPI_MODE0);
+
+ // In addition of the port is not provided by the user, it defaults to SPI
+ // here.
+ return init(SPI, spiSettings, cs, bInit);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// ping()
+//
+// Is a device connected? The SPI ping is not relevant but is defined here to
+// keep consistency with I2C class i.e. provided for the interface.
+//
+
+bool SfeSPI::ping(uint8_t i2c_address)
+{
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// writeRegisterByte()
+//
+// Write a byte to a register
+
+bool SfeSPI::writeRegisterByte(uint8_t i2c_address, uint8_t offset, uint8_t dataToWrite)
+{
+
+ if (!_spiPort)
+ return false;
+
+ // Apply settings
_spiPort->beginTransaction(_sfeSPISettings);
- // Signal communication start
- digitalWrite(_cs, LOW);
+ // Signal communication start
+ digitalWrite(_cs, LOW);
+
_spiPort->transfer(offset);
+ _spiPort->transfer(dataToWrite);
+
+ // End communcation
+ digitalWrite(_cs, HIGH);
+ _spiPort->endTransaction();
+
+ return true;
+}
- for(i = 0; i < length; i++)
- {
- _spiPort->transfer(*data++);
- }
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// writeRegisterRegion()
+//
+// Write a block of data to a device.
- // End communication
- digitalWrite(_cs, HIGH);
+int SfeSPI::writeRegisterRegion(uint8_t i2c_address, uint8_t offset, const uint8_t *data, uint16_t length)
+{
+
+ int i;
+
+ // Apply settings
+ _spiPort->beginTransaction(_sfeSPISettings);
+ // Signal communication start
+ digitalWrite(_cs, LOW);
+
+ for (i = 0; i < length; i++)
+ {
+ // Increment Address (Device does not do this when using SPI)
+ _spiPort->transfer(offset + i);
+ _spiPort->transfer(*data++);
+ }
+
+ // End communication
+ digitalWrite(_cs, HIGH);
_spiPort->endTransaction();
- return 0;
+ return 0;
}
-/// @brief This function reads a block of data from the register on the device.
-/// @param addr Address chosing to read from
-/// @param reg Register
-/// @param data Data to be filled
-/// @param numBytes Number of bytes to read from
-/// @return Returns the data from the register desired to read from.
-int32_t SFE_BusSPI::readRegisterRegion(uint8_t reg, uint8_t *data, uint16_t numBytes)
+int SfeSPI::writeRegisterRegion(uint8_t i2c_address, uint8_t offset, uint8_t data, uint16_t length)
+{
+
+ // Apply settings
+ _spiPort->beginTransaction(_sfeSPISettings);
+ // Signal communication start
+ digitalWrite(_cs, LOW);
+
+ // ENS160 expects bits [7:1] to be the address and the leading
+ // bit to be a "zero" for a write.
+ _spiPort->transfer(offset << 1);
+ _spiPort->transfer(data);
+
+ // End communication
+ digitalWrite(_cs, HIGH);
+ _spiPort->endTransaction();
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// readRegisterRegion()
+//
+// Reads a block of data from the register on the device.
+//
+//
+//
+
+int SfeSPI::readRegisterRegion(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t numBytes)
{
if (!_spiPort)
return -1;
int i; // counter in loop
-
- // Apply settings
+ // Apply settings
_spiPort->beginTransaction(_sfeSPISettings);
- // Signal communication start
- digitalWrite(_cs, LOW);
- // A leading "1" must be added to transfer with register to indicate a "read"
- reg = (reg | SPI_READ);
+ // Signal communication start
+ digitalWrite(_cs, LOW);
+
+ // ENS160 expects bits [7:1] to be the address and the leading
+ // bit to be a "one" for a read.
+ reg = (reg | SPI_READ);
_spiPort->transfer(reg);
- for(i = 0; i < numBytes; i++)
- {
- *data++ = _spiPort->transfer(0x00);
- }
+ for (i = 0; i < numBytes; i++)
+ {
+ *data++ = _spiPort->transfer(0x00);
+ }
- // End transaction
- digitalWrite(_cs, HIGH);
+ // End transaction
+ digitalWrite(_cs, HIGH);
_spiPort->endTransaction();
- return 0;
+ return 0;
+}
-}
\ No newline at end of file
+} // namespace sfe_STHS34PF80
\ No newline at end of file
diff --git a/src/sfe_bus.h b/src/sfe_bus.h
index 53b5ea3..097deed 100644
--- a/src/sfe_bus.h
+++ b/src/sfe_bus.h
@@ -1,38 +1,125 @@
-#ifndef __SparkFun_Bus_H__
-#define __SparkFun_Bus_H__
+// sfe_bus.h
+//
+// This is a library written for SparkFun Human Presence Sensor STHS34PF80
+// (Qwiic)
+//
+// SparkFun sells these boards at its website: www.sparkfun.com
+//
+// Do you like this library? Help support SparkFun. Buy a board!
+//
+// SparkFun Human Presence Sensor STHS34PF80 (Qwiic)
+// https://www.sparkfun.com/products/22494
+//
+// Written by Madison Chodikov @ SparkFun Electronics, October 2023
+//
+// Repository:
+// hhttps://github.com/sparkfun/SparkFun_STHS34PF80_Arduino_Library/tree/main
+//
+//
+// SparkFun code, firmware, and software is released under the MIT
+// License(http://opensource.org/licenses/MIT).
+//
+// SPDX-License-Identifier: MIT
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2022 SparkFun Electronics
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions: The
+// above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED
+// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// The following classes specify the behavior for communicating
+// over the respective data buses: Inter-Integrated Circuit (I2C)
+// and Serial Peripheral Interface (SPI). For ease of implementation
+// an abstract interface (QwIDeviceBus) is used.
+
+#pragma once
-#include
-#include
#include
+#include
+
+namespace sfe_STHS34PF80
+{
+// The following abstract class is used an interface for upstream
+// implementation.
+class QwIDeviceBus
+{
+ public:
+ virtual bool ping(uint8_t address) = 0;
+
+ virtual bool writeRegisterByte(uint8_t address, uint8_t offset, uint8_t data) = 0;
+
+ virtual int writeRegisterRegion(uint8_t address, uint8_t offset, const uint8_t *data, uint16_t length) = 0;
-#define SPI_READ 0x80
+ virtual int writeRegisterRegion(uint8_t address, uint8_t offset, uint8_t data, uint16_t length) = 0;
-class SFE_BusI2C
+ virtual int readRegisterRegion(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t numBytes) = 0;
+};
+
+// The QwI2C device defines behavior for I2C implementation based around the
+// TwoWire class (Wire). This is Arduino specific.
+class QwI2C : public QwIDeviceBus
{
- public:
- int32_t init(uint8_t addr, TwoWire& port=Wire);
- int32_t readRegs(uint8_t regAddr, uint8_t* data, uint8_t numData);
- int32_t writeRegs(uint8_t regAddr, const uint8_t* data, uint8_t numData);
-
- private:
- uint8_t devAddr;
- TwoWire* devPort;
+ public:
+ QwI2C(void);
+
+ bool init();
+
+ bool init(TwoWire &wirePort, bool bInit = false);
+
+ bool ping(uint8_t address);
+
+ bool writeRegisterByte(uint8_t address, uint8_t offset, uint8_t data);
+
+ int writeRegisterRegion(uint8_t address, uint8_t offset, const uint8_t *data, uint16_t length);
+
+ int writeRegisterRegion(uint8_t address, uint8_t offset, uint8_t data, uint16_t length);
+
+ int readRegisterRegion(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t numBytes);
+
+ private:
+ TwoWire *_i2cPort;
};
-class SFE_BusSPI
+// The SfeSPI class defines behavior for SPI implementation based around the
+// SPIClass class (SPI). This is Arduino specific. Paramaters like "address" are
+// kept although irrelevant to SPI due to the use of the abstract class as
+// interface, QwIDeviceBus.
+class SfeSPI : public QwIDeviceBus
{
- public:
+ public:
+ SfeSPI(void);
+
+ bool init(uint8_t cs, bool bInit = false);
+
+ bool init(SPIClass &spiPort, SPISettings &sthsSPISettings, uint8_t cs, bool bInit = false);
+
+ bool ping(uint8_t address);
+
+ bool writeRegisterByte(uint8_t address, uint8_t offset, uint8_t data);
+
+ int writeRegisterRegion(uint8_t address, uint8_t offset, const uint8_t *data, uint16_t length);
- int32_t init(uint8_t cs, SPIClass& spiPort=SPI, bool bInit=false);
- int32_t writeRegisterRegion(uint8_t offset, const uint8_t* data, uint16_t length);
- int32_t readRegisterRegion(uint8_t reg, uint8_t* data, uint16_t numBytes);
+ int writeRegisterRegion(uint8_t address, uint8_t offset, uint8_t data, uint16_t length);
- private:
+ int readRegisterRegion(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t numBytes);
- SPIClass* _spiPort;
- // Settings are used for every transaction.
- SPISettings _sfeSPISettings;
- uint8_t _cs;
+ private:
+ SPIClass *_spiPort;
+ // Settings are used for every transaction.
+ SPISettings _sfeSPISettings;
+ uint8_t _cs;
};
-#endif
\ No newline at end of file
+}; // namespace sfe_STHS34PF80
diff --git a/src/sths34pf80_class.cpp b/src/sths34pf80_class.cpp
index 7542f15..f656da2 100644
--- a/src/sths34pf80_class.cpp
+++ b/src/sths34pf80_class.cpp
@@ -8,7 +8,7 @@
/// @return Error code (0 no error)
int32_t STHS34PF80::begin()
{
- if (isConnected() == 0)
+ if (isConnected() != 0)
{
return -1;
}
@@ -57,11 +57,11 @@ int32_t STHS34PF80::isConnected()
uint8_t devId = 0;
int32_t err = sths34pf80_device_id_get(&sensor, &devId);
- if (devId == STHS34PF80_ID)
+ if (devId != STHS34PF80_ID)
{
return -1;
}
- return err;
+ return err;
}
/// @brief Checks to see if the data ready flag is high
diff --git a/src/sths34pf80_class.h b/src/sths34pf80_class.h
index 26610f6..14a108f 100644
--- a/src/sths34pf80_class.h
+++ b/src/sths34pf80_class.h
@@ -4,11 +4,17 @@
#include "sths34pf80_api/sths34pf80_reg.h"
#include "sfe_bus.h"
+
+// define a standard i2c address (7 bit) macro
+
+#define STHS34PF80_I2C_ADDRESS (STHS34PF80_I2C_ADD >> 1)
+
class STHS34PF80
{
public:
int32_t begin(); // Resets the device and sets the values needed for sensor use
int32_t isConnected(); // Determines connection to device
+
int32_t getDataReady(sths34pf80_tmos_drdy_status_t *drdy); // Returns if the data is ready to be read or not
int32_t getStatus(sths34pf80_tmos_func_status_t *statusVal); // Returns the status of the device
int32_t reset(); // Set the boot bit, wait 3ms (as per the datasheet), then resets the algorithm