Skip to content

Commit 2423c78

Browse files
EBF_STTS22H_TemperatureSensor updated to use the interrupt processing.
1 parent 6cd38a0 commit 2423c78

File tree

3 files changed

+253
-10
lines changed

3 files changed

+253
-10
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#include <Arduino.h>
2+
#include "wiring_private.h" // pinPeripheral() function
3+
4+
#include "EBF_Products.h"
5+
6+
// That example shows how to use STTS22H with an interrupt line connected to
7+
// Digital Input, which will notify when the temperature goes out of configured
8+
// thresholds, so there is no need to poll the sensor every time.
9+
// In order to enable interrupts for the EBF environment, you have to uncomment
10+
// the EBF_USE_INTERRUPTS flag in your EBF_Config.h file.
11+
// Using interrupts allow the EBF to use very low current while sleeping (when
12+
// sleep functionality enabled), and free the CPU for other tasks.
13+
14+
// Timers enumeration
15+
enum {
16+
TIMER1 = 0,
17+
18+
NUMBER_OF_TIMERS
19+
};
20+
21+
// In that example we will use SERCOM2 on the SparkFun SAMD21 Mini board
22+
TwoWire Wire2(&sercom2, 4, 3);
23+
24+
// EBF objects creation, should be global
25+
EBF_Core EBF;
26+
27+
// EBF_I2C instance will use SERCOM2 assigned to Wire2 instance
28+
EBF_I2C i2c(Wire2);
29+
// If you would like to use the default Wire instance, on Arduino UNO for eaxmple:
30+
//EBF_I2C i2c;
31+
32+
// EBF serial object will use the Arduino's Serial USB for communication
33+
EBF_Serial serial;
34+
35+
// Initialize STTS22H temperature sensor communicating via EBF_I2C instance
36+
EBF_STTS22H_TemperatureSensor tempSensor(i2c);
37+
38+
void onTemperatureHigh()
39+
{
40+
float tempC;
41+
42+
serial.println("Temperature high alert");
43+
44+
tempC = tempSensor.GetValueC();
45+
serial.print("temperature (C): ");
46+
serial.println(tempC);
47+
}
48+
49+
void onTemperatureLow()
50+
{
51+
float tempC;
52+
53+
serial.println("Temperature low alert");
54+
55+
tempC = tempSensor.GetValueC();
56+
serial.print("temperature (C): ");
57+
serial.println(tempC);
58+
}
59+
60+
void onTimer()
61+
{
62+
serial.println(tempSensor.GetValueC());
63+
64+
EBF.StartTimer(TIMER1);
65+
}
66+
67+
void setup()
68+
{
69+
EBF.Init(NUMBER_OF_TIMERS, 16);
70+
71+
// Timer will just print current temperature for debug
72+
EBF.InitTimer(TIMER1, onTimer, 1000);
73+
EBF.StartTimer(TIMER1);
74+
75+
// Default Init is enough for printouts via Serial on 115200 boud speed
76+
serial.Init();
77+
78+
// Using I2C with EBF products requires a stand-alone initialization since several products
79+
// might use the same I2C interface, hence there is no need to do multiple initializations
80+
// from within the product's Init
81+
i2c.Init();
82+
i2c.SetClock(400000);
83+
84+
// PIN re-assignment is required since SERCOM2 lines were configured for other usage by the Arduino code
85+
// You don't need those calls if you're using the defauld Wire instance
86+
pinPeripheral(4, PIO_SERCOM_ALT);
87+
pinPeripheral(3, PIO_SERCOM_ALT);
88+
89+
// Initialize the temperature sensor on I2C address 0x3C
90+
tempSensor.Init(0x3C);
91+
// Interrupt line is connected to pin 10 on SparkFun'x SAMD21 Mini board
92+
tempSensor.AttachInterrupt(10);
93+
94+
// Register high and low thresholds callbacks
95+
tempSensor.SetOnThresholdHigh(onTemperatureHigh);
96+
tempSensor.SetOnThresholdLow(onTemperatureLow);
97+
98+
// Set threshold levels
99+
tempSensor.SetThresholdHigh(29.0);
100+
tempSensor.SetThresholdLow(27.0);
101+
102+
// The operation mode can be changed any time during the execurion
103+
// Polling interval will be set accordingly to the operation mode
104+
// For example, for 1Hz mode, polling will be 1000mSec
105+
tempSensor.SetOperationMode(EBF_STTS22H_TemperatureSensor::OperationMode::MODE_1HZ);
106+
// We will use the interrupt line to trigger the threshold level notifications, so no polling is needed
107+
tempSensor.SetPollInterval(EBF_NO_POLLING);
108+
}
109+
110+
void loop()
111+
{
112+
// Let EBF to do all the processing
113+
// Your logic should be done in the callback functions
114+
EBF.Process();
115+
}

src/Products/EBF_STTS22H_TemperatureSensor.cpp

Lines changed: 125 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "EBF_STTS22H_TemperatureSensor.h"
2-
#include "wiring_private.h" // pinPeripheral() function
3-
2+
#include "../Core/EBF_Logic.h"
3+
#include "../Core/EBF_DigitalInput.h"
44

55
// Part of the code is based on the SparkFun_STTS22H_Arduino_Library
66
// https://github.com/sparkfun/SparkFun_STTS22H_Arduino_Library/tree/main
@@ -14,8 +14,11 @@ extern void EBF_EmptyCallback();
1414
uint8_t EBF_STTS22H_TemperatureSensor::Init(uint8_t i2cAddress, OperationMode mode)
1515
{
1616
uint8_t rc;
17+
StatusRegister_t status;
1718

1819
this->state = InstanceState::STATE_IDLE;
20+
this->interruptAttached = 0;
21+
this->postProcessingFlags = 0;
1922
this->highThresholdSet = 0;
2023
this->lowThresholdSet = 0;
2124
this->i2cAddress = i2cAddress;
@@ -30,6 +33,12 @@ uint8_t EBF_STTS22H_TemperatureSensor::Init(uint8_t i2cAddress, OperationMode mo
3033
return rc;
3134
}
3235

36+
// Reading status register to reset the interrupt line
37+
rc = GetStatusRegister(status);
38+
if (rc != EBF_OK) {
39+
return rc;
40+
}
41+
3342
rc = SetOperationMode(mode);
3443
if (rc != EBF_OK) {
3544
return rc;
@@ -38,6 +47,78 @@ uint8_t EBF_STTS22H_TemperatureSensor::Init(uint8_t i2cAddress, OperationMode mo
3847
return EBF_OK;
3948
}
4049

50+
uint8_t EBF_STTS22H_TemperatureSensor::AttachInterrupt(uint8_t interruptPin)
51+
{
52+
uint8_t rc;
53+
EBF_Logic *pLogic = EBF_Logic::GetInstance();
54+
55+
rc = pLogic->AttachInterrupt(interruptPin, this, EBF_DigitalInput::InterruptMode::MODE_LOW);
56+
if (rc != EBF_OK) {
57+
return rc;
58+
}
59+
60+
interruptAttached = 1;
61+
62+
UpdatePollInterval();
63+
64+
return EBF_OK;
65+
}
66+
67+
void EBF_STTS22H_TemperatureSensor::UpdatePollInterval()
68+
{
69+
uint8_t needPolling = 0;
70+
71+
// No need to poll, unless some callbacks are needed and there is no interrupt attached
72+
pollIntervalMs = EBF_NO_POLLING;
73+
74+
if (onChangeCallback != NULL && onChangeCallback != EBF_EmptyCallback) {
75+
needPolling = 1;
76+
}
77+
78+
if (!interruptAttached) {
79+
if (onThresholdHigh != NULL && onThresholdHigh != EBF_EmptyCallback) {
80+
needPolling = 1;
81+
}
82+
83+
if (onThresholdLow != NULL && onThresholdLow != EBF_EmptyCallback) {
84+
needPolling = 1;
85+
}
86+
}
87+
88+
if (needPolling) {
89+
switch (operationMode)
90+
{
91+
case OperationMode::POWER_DOWN:
92+
pollIntervalMs = EBF_NO_POLLING;
93+
break;
94+
95+
case OperationMode::MODE_ONE_SHOT:
96+
pollIntervalMs = 0;
97+
break;
98+
99+
case OperationMode::MODE_1HZ:
100+
pollIntervalMs = 1000;
101+
break;
102+
103+
case OperationMode::MODE_25HZ:
104+
pollIntervalMs = 1000 / 25;
105+
break;
106+
107+
case OperationMode::MODE_50HZ:
108+
pollIntervalMs = 1000 / 50;
109+
break;
110+
111+
case OperationMode::MODE_100HZ:
112+
pollIntervalMs = 1000 / 100;
113+
break;
114+
115+
case OperationMode::MODE_200HZ:
116+
pollIntervalMs = 1000 / 200;
117+
break;
118+
}
119+
}
120+
}
121+
41122
uint8_t EBF_STTS22H_TemperatureSensor::GetControlRegister(ControlRegister_t &ctrl)
42123
{
43124
uint8_t rc;
@@ -102,6 +183,8 @@ uint8_t EBF_STTS22H_TemperatureSensor::SetOperationMode(OperationMode mode)
102183
uint8_t rc;
103184
ControlRegister_t ctrl = {};
104185

186+
operationMode = mode;
187+
105188
// Any change should be done after the device is moved to power down mode
106189
ctrl.fields.freeRun = 0;
107190
ctrl.fields.mode_1Hz = 0;
@@ -110,31 +193,27 @@ uint8_t EBF_STTS22H_TemperatureSensor::SetOperationMode(OperationMode mode)
110193
return rc;
111194
}
112195

113-
switch (mode)
196+
switch (operationMode)
114197
{
115198
case OperationMode::POWER_DOWN:
116199
state = InstanceState::STATE_IDLE;
117-
pollIntervalMs = EBF_NO_POLLING;
118200
break;
119201

120202
case OperationMode::MODE_ONE_SHOT:
121203
state = InstanceState::STATE_ONE_SHOT;
122-
pollIntervalMs = 0;
123204

124205
ctrl.fields.oneShot = 1;
125206
break;
126207

127208
case OperationMode::MODE_1HZ:
128209
state = InstanceState::STATE_MEASURING;
129-
pollIntervalMs = 1000;
130210

131211
ctrl.fields.mode_1Hz = 1;
132212
ctrl.fields.freeRun = 0;
133213
break;
134214

135215
case OperationMode::MODE_25HZ:
136216
state = InstanceState::STATE_MEASURING;
137-
pollIntervalMs = 1000 / 25;
138217

139218
ctrl.fields.mode_1Hz = 0;
140219
ctrl.fields.freeRun = 1;
@@ -143,7 +222,6 @@ uint8_t EBF_STTS22H_TemperatureSensor::SetOperationMode(OperationMode mode)
143222

144223
case OperationMode::MODE_50HZ:
145224
state = InstanceState::STATE_MEASURING;
146-
pollIntervalMs = 1000 / 50;
147225

148226
ctrl.fields.mode_1Hz = 0;
149227
ctrl.fields.freeRun = 1;
@@ -152,7 +230,6 @@ uint8_t EBF_STTS22H_TemperatureSensor::SetOperationMode(OperationMode mode)
152230

153231
case OperationMode::MODE_100HZ:
154232
state = InstanceState::STATE_MEASURING;
155-
pollIntervalMs = 1000 / 100;
156233

157234
ctrl.fields.mode_1Hz = 0;
158235
ctrl.fields.freeRun = 1;
@@ -161,7 +238,6 @@ uint8_t EBF_STTS22H_TemperatureSensor::SetOperationMode(OperationMode mode)
161238

162239
case OperationMode::MODE_200HZ:
163240
state = InstanceState::STATE_MEASURING;
164-
pollIntervalMs = 1000 / 200;
165241

166242
ctrl.fields.mode_1Hz = 0;
167243
ctrl.fields.freeRun = 1;
@@ -174,6 +250,8 @@ uint8_t EBF_STTS22H_TemperatureSensor::SetOperationMode(OperationMode mode)
174250
SetControlRegister(ctrl);
175251
}
176252

253+
UpdatePollInterval();
254+
177255
return EBF_OK;
178256
}
179257

@@ -237,6 +315,19 @@ uint8_t EBF_STTS22H_TemperatureSensor::Process()
237315
float change;
238316
StatusRegister_t status;
239317

318+
// Process interrupt detected logic
319+
if(postProcessingFlags) {
320+
if(postProcessingFlags & postProcessHighThreshold) {
321+
onThresholdHigh();
322+
}
323+
324+
if(postProcessingFlags & postProcessLowThreshold) {
325+
onThresholdLow();
326+
}
327+
328+
postProcessingFlags = 0;
329+
}
330+
240331
switch (state)
241332
{
242333
case InstanceState::STATE_IDLE:
@@ -282,6 +373,30 @@ uint8_t EBF_STTS22H_TemperatureSensor::Process()
282373
return EBF_OK;
283374
}
284375

376+
void EBF_STTS22H_TemperatureSensor::ProcessInterrupt()
377+
{
378+
StatusRegister_t status;
379+
380+
// Status register is cleared on read
381+
GetStatusRegister(status);
382+
383+
// Set the relevant post-processing flags
384+
if(status.fields.overThreshold) {
385+
postProcessingFlags |= postProcessHighThreshold;
386+
}
387+
388+
if(status.fields.underThreshold) {
389+
postProcessingFlags |= postProcessLowThreshold;
390+
}
391+
392+
if (postProcessingFlags) {
393+
// Pass the control back to EBF, so it will call the Process() function from normal run
394+
EBF_Logic *pLogic = EBF_Logic::GetInstance();
395+
396+
pLogic->ProcessInterrupt(this);
397+
}
398+
}
399+
285400
// Sets high threshold value
286401
uint8_t EBF_STTS22H_TemperatureSensor::SetThresholdHigh(float temp)
287402
{

src/Products/EBF_STTS22H_TemperatureSensor.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class EBF_STTS22H_TemperatureSensor : protected EBF_HalInstance {
2828
uint8_t Init(uint8_t i2cAddress, OperationMode mode = POWER_DOWN);
2929
// Setting polling interval in milli-seconds
3030
void SetPollInterval(uint32_t ms) { pollIntervalMs = ms; }
31+
// Call to attach the device to an interrupt line
32+
uint8_t AttachInterrupt(uint8_t interruptPin);
3133

3234
void SetOnChange(EBF_CallbackType onChangeCallback, uint8_t changePercent = 5)
3335
{
@@ -69,10 +71,19 @@ class EBF_STTS22H_TemperatureSensor : protected EBF_HalInstance {
6971
EBF_I2C &i2c;
7072
uint8_t i2cAddress;
7173
InstanceState state;
74+
OperationMode operationMode;
7275
uint8_t highThresholdSet;
7376
uint8_t lowThresholdSet;
7477
float lastValue;
7578
uint8_t changePercent;
79+
uint8_t interruptAttached;
80+
81+
// Post processing that should be done after interrupt handler
82+
volatile uint8_t postProcessingFlags;
83+
84+
const uint8_t postProcessHighThreshold = 1<<0;
85+
const uint8_t postProcessLowThreshold = 1<<1;
86+
7687

7788
// Callbacks
7889
EBF_CallbackType onChangeCallback;
@@ -81,6 +92,8 @@ class EBF_STTS22H_TemperatureSensor : protected EBF_HalInstance {
8192
EBF_CallbackType onThresholdLow;
8293

8394
uint8_t Process();
95+
void ProcessInterrupt();
96+
void UpdatePollInterval();
8497

8598
private:
8699
// Device registers data

0 commit comments

Comments
 (0)