Trying to understand typedef struct enum

I'm working with the Interrupts Example in Sparkfun's STHS34PF80 library. I need to set the interrupt that the STHS34PF80 generates to Active LOW. The default is active HIGH. To achieve active LOW, the INT_H_L bit of the CTRL3 register must be set to 1.

Here is the setup function from the "SparkFun_STHS34PF80_Arduino_Library.h"

void setup()
{
    Serial.begin(115200);
    Serial.println("STHS34PF80 Example 2: Interrupts");

    // Begin I2C
    Wire.begin(4, 5);
    // if(Wire.begin() == 0)
    // {
    //   Serial.println("I2C Error - check I2C Address");
    //   while(1);
    // }

    // Establish communication with device 
    if(mySensor.begin() == false)
    {
      Serial.println("Error setting up device - please check wiring.");
      while(1);
    }

    // Set INT pin to be triggered on rising and falling edges of INT pin
    pinMode(intPin, INPUT);
    // Attach interrupt to the pin as a digital pin that triggers on a change
    attachInterrupt(digitalPinToInterrupt(intPin), isr1, CHANGE);

    // Route all interrupts from device to interrupt pin
    mySensor.setTmosRouteInterrupt(STHS34PF80_TMOS_INT_OR);

    // Enable the presence interrupt source 
    // (see page 17 of application note AN5867 for more information)
    mySensor.setTmosInterruptOR(STHS34PF80_TMOS_INT_PRESENCE);

    // Set interrupt value to pulsed on the INT pin
    mySensor.setInterruptPulsed(0);

    mySensor.setInterruptMode(sths34pf80_int_mode_t val);

    delay(500);
}

The function prototype mySensor.setInterruptMode(sths34pf80_int_mode_t val); is where I'm having problems.

From the sths34pf80_reg.h file

typedef struct
{
  enum {
    STHS34PF80_PUSH_PULL = 0x0,
    STHS34PF80_OPEN_DRAIN = 0x1,
  } pin;

  enum {
    STHS34PF80_ACTIVE_HIGH = 0x0,
    STHS34PF80_ACTIVE_LOW = 0x1,
  } polarity;
} sths34pf80_int_mode_t;
int32_t sths34pf80_int_mode_set(stmdev_ctx_t *ctx, sths34pf80_int_mode_t val);
int32_t sths34pf80_int_mode_get(stmdev_ctx_t *ctx, sths34pf80_int_mode_t *val);

What is the format of the parameter that the
mySensor.setInterruptMode( )
function takes to set the STHS34PF80_ACTIVE_LOW?
Any help or suggestions gratefully received.

is there some example code for the library you're using that will demonstrate how to invoke those functions?

SparkFun_STHS34PF80_Arduino_Library/examples/Example2_Interrupts/Example2_Interrupts.ino at main · sparkfun/SparkFun_STHS34PF80_Arduino_Library · GitHub

Unfortunately it returns an error

sths34pf80_int_mode_t myMode;
myMode.pin = 0;  // or 1
myMode.polarity = 1; // or 0

mySensor.setInterruptMode(myMode);

Compilation error: 'myMode' does not name a type

Any more thoughts?

That's a function prototype, not a function call. You need to get rid of the type specification to call the function:

mySensor.setInterruptMode(val);

val must be a variable of type sths34pf80_int_mode_t.

I made a mistake. I didn't put the lines

myMode.pin = 0;  // or 1
myMode.polarity = 1; // or 0

within the setup function.
Here's the full sketch.

/******************************************************************************
  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 <http://www.gnu.org/licenses/>.
******************************************************************************/

#include "SparkFun_STHS34PF80_Arduino_Library.h"
#include <Wire.h>

STHS34PF80_I2C mySensor;

// Values to fill with presence data
int16_t presenceVal = 0;

// Change the pin number to the pin that has been chosen for your setup
int intPin = 2;

sths34pf80_int_mode_t myMode;

// Star the flag as false
bool volatile interruptFlag = false;

// ISR to set the triggered interrupt
void isr1()
{
  interruptFlag = true;
}

void setup()
{
    Serial.begin(115200);
    Serial.println("STHS34PF80 Example 2: Interrupts");

    // Begin I2C
    Wire.begin(4, 5);
    // if(Wire.begin() == 0)
    // {
    //   Serial.println("I2C Error - check I2C Address");
    //   while(1);
    // }

    // Establish communication with device 
    if(mySensor.begin() == false)
    {
      Serial.println("Error setting up device - please check wiring.");
      while(1);
    }

    // Set INT pin to be triggered on rising and falling edges of INT pin
    pinMode(intPin, INPUT);
    // Attach interrupt to the pin as a digital pin that triggers on a change
    attachInterrupt(digitalPinToInterrupt(intPin), isr1, CHANGE);

    // Route all interrupts from device to interrupt pin
    mySensor.setTmosRouteInterrupt(STHS34PF80_TMOS_INT_OR);

    // Enable the presence interrupt source 
    // (see page 17 of application note AN5867 for more information)
    mySensor.setTmosInterruptOR(STHS34PF80_TMOS_INT_PRESENCE);

    // Set interrupt value to pulsed on the INT pin
    mySensor.setInterruptPulsed(0);

    //myMode.pin = 0;  // or 1
    myMode.polarity = 1 ; // or 0
    mySensor.setInterruptMode(myMode);
    mySensor.setInterruptMode(sths34pf80_int_mode_t val)

    delay(500);
}

void loop() 
{
  // If interrupt is triggered
  if(interruptFlag == true)
  {
    interruptFlag = false;
    
    sths34pf80_tmos_func_status_t status;
    mySensor.getStatus(&status);
    
    Serial.println("Data ready!");
    
    
    // If the flag is high, then read out the information
    if(status.pres_flag == 1)
    {
      // Presence Units: cm^-1
      mySensor.getPresenceValue(&presenceVal);
      Serial.print("Presence: ");
      Serial.print(presenceVal);
      Serial.println("cm^-1");
    }
  }
}

And the error message

C:\Users\richa\AppData\Local\Temp\.arduinoIDE-unsaved2024813-15932-1loif5b.u052\Example2_Interrupts\Example2_Interrupts.ino: In function 'void setup()':
C:\Users\richa\AppData\Local\Temp\.arduinoIDE-unsaved2024813-15932-1loif5b.u052\Example2_Interrupts\Example2_Interrupts.ino:106:23: error: invalid conversion from 'int' to 'sths34pf80_int_mode_t::<unnamed enum>' [-fpermissive]
  106 |     myMode.polarity = 1 ; // or 0
      |                       ^
      |                       |
      |                       int
C:\Users\richa\AppData\Local\Temp\.arduinoIDE-unsaved2024813-15932-1loif5b.u052\Example2_Interrupts\Example2_Interrupts.ino:108:53: error: expected primary-expression before 'val'
  108 |     mySensor.setInterruptMode(sths34pf80_int_mode_t val)
      |                                                     ^~~

Using library SparkFun STHS34PF80 Arduino Library at version 1.0.4 in folder: C:\Users\richa\OneDrive\Documents\Arduino\libraries\SparkFun_STHS34PF80_Arduino_Library 
Using library SPI at version 1.0 in folder: C:\Users\richa\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\SPI 
Using library Wire at version 1.0 in folder: C:\Users\richa\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\Wire 
exit status 1

Compilation error: invalid conversion from 'int' to 'sths34pf80_int_mode_t::<unnamed enum>' [-fpermissive]

See Post #6.

Global
sths34pf80_int_mode_t STHS34PF80_ACTIVE_LOW;

and in setup
mySensor.setInterruptMode(STHS34PF80_ACTIVE_LOW);

Compiles!
I just need to test that it actually does set the interrupt to active LOW.

Thanks to all for your help!

1 Like

I assumed the line
sths34pf80_int_mode_t STHS34PF80_ACTIVE_LOW;

was declaring a type so I placed it before the setup function.
The line
mySensor.setInterruptMode(STHS34PF80_ACTIVE_LOW);

I placed within the setup function and it compiled...

The full code:

/******************************************************************************
  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 <http://www.gnu.org/licenses/>.
******************************************************************************/

#include "SparkFun_STHS34PF80_Arduino_Library.h"
#include <Wire.h>

STHS34PF80_I2C mySensor;

// Values to fill with presence data
int16_t presenceVal = 0;

// Change the pin number to the pin that has been chosen for your setup
int intPin = 2;

sths34pf80_int_mode_t STHS34PF80_ACTIVE_LOW;

// Star the flag as false
bool volatile interruptFlag = false;

// ISR to set the triggered interrupt
void isr1()
{
  interruptFlag = true;
}

void setup()
{
    Serial.begin(115200);
    Serial.println("STHS34PF80 Example 2: Interrupts");

    // Begin I2C
    Wire.begin(4, 5);
    // if(Wire.begin() == 0)
    // {
    //   Serial.println("I2C Error - check I2C Address");
    //   while(1);
    // }

    // Establish communication with device 
    if(mySensor.begin() == false)
    {
      Serial.println("Error setting up device - please check wiring.");
      while(1);
    }

    // Set INT pin to be triggered on rising and falling edges of INT pin
    pinMode(intPin, INPUT);
    // Attach interrupt to the pin as a digital pin that triggers on a change
    attachInterrupt(digitalPinToInterrupt(intPin), isr1, CHANGE);

    // Route all interrupts from device to interrupt pin
    mySensor.setTmosRouteInterrupt(STHS34PF80_TMOS_INT_OR);

    // Enable the presence interrupt source 
    // (see page 17 of application note AN5867 for more information)
    mySensor.setTmosInterruptOR(STHS34PF80_TMOS_INT_PRESENCE);

    // Set interrupt value to pulsed on the INT pin
    mySensor.setInterruptPulsed(0);

    mySensor.setInterruptMode(STHS34PF80_ACTIVE_LOW);
    

    delay(500);
}

void loop() 
{
  // If interrupt is triggered
  if(interruptFlag == true)
  {
    interruptFlag = false;
    
    sths34pf80_tmos_func_status_t status;
    mySensor.getStatus(&status);
    
    Serial.println("Data ready!");
    
    
    // If the flag is high, then read out the information
    if(status.pres_flag == 1)
    {
      // Presence Units: cm^-1
      mySensor.getPresenceValue(&presenceVal);
      Serial.print("Presence: ");
      Serial.print(presenceVal);
      Serial.println("cm^-1");
    }
  }
}

That's still wrong!

This is how it's intended to be done:

#include "SparkFun_STHS34PF80_Arduino_Library.h"
#include <Wire.h>

STHS34PF80_I2C mySensor;

void setup() {
  sths34pf80_int_mode_t myMode;

  myMode.pin = sths34pf80_int_mode_t::STHS34PF80_PUSH_PULL; // or sths34pf80_int_mode_t::STHS34PF80_OPEN_DRAIN
  myMode.polarity = sths34pf80_int_mode_t::STHS34PF80_ACTIVE_LOW;
  mySensor.setInterruptMode(myMode);

}

void loop() {

}

Okay, I understand now.
Thank you for the clarification gfvalvo.
Your code example compiles too. I will use your more correct version :wink:

Here's a more succinct way of doing it:

#include "SparkFun_STHS34PF80_Arduino_Library.h"
#include <Wire.h>

STHS34PF80_I2C mySensor;

void setup() {
  mySensor.setInterruptMode({sths34pf80_int_mode_t::STHS34PF80_PUSH_PULL, sths34pf80_int_mode_t::STHS34PF80_ACTIVE_LOW});
}

void loop() {

}

I like it!
Thanks for your examples. You've given me some good insight in how to access members of a structure.


typedef struct
{
  enum {
    STHS34PF80_PUSH_PULL = 0x0,
    STHS34PF80_OPEN_DRAIN = 0x1,
  } pin;

  enum {
    STHS34PF80_ACTIVE_HIGH = 0x0,
    STHS34PF80_ACTIVE_LOW = 0x1,
  } polarity;
} sths34pf80_int_mode_t;
int32_t sths34pf80_int_mode_set(stmdev_ctx_t *ctx, sths34pf80_int_mode_t val);
int32_t sths34pf80_int_mode_get(stmdev_ctx_t *ctx, sths34pf80_int_mode_t *val);

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.