STHS34PF80 set threshold problem

I have been trying to set the presence threshold value to a number bigger than 255 but it seems to truncate the new setting value to just one byte (> 256 decimal). The sths34pf80_presence_threshold_set takes a 16 bit unsigned value (which must be 15 bits or less).

If I set the presence threshold to 400 (0x0190) and then read (get) the presence threshold it returns 144 (0x0090). It would appear that the device only accepts or stores the low byte of the set value.

The ST documentation states that the PRESENCE_THS register takes two bytes, first byte is bits 7 - 0 and the second byte is bits 14 - 8, for a total of 15 bits unsigned.

I get the same results with the other two threshold set functions, namely motion_set and ambient_shock_set.

Has anyone else tried setting the thresholds to a value greater than 255? Just wondering if I am doing something wrong.

We’re gonna see about grabbing one for testing and might be able to give a better answer shortly…in the mean time, maybe try testing a value more than 144 but less than the default 200? (so, like 185) https://github.com/sparkfun/SparkFun_ST … #L648-L664

Thanks Russell.

I have tested the three set threshold functions with values less than 255, back to the default 200 (for two of them) and down to 100 and 50. They all work. But anything bigger than 255 gets truncated to just the low byte of the 16 bit value.

What I have not tried yet is to only set the high byte of presence threshold alone. If you look at the source code for setting or reading those embedded function registers the process is kind-a weird. First enable access to the registers, then enable write access and then set the register address and finally write the value. I wonder if that multi-step process has to be followed for both the low and the high byte writing individually.

Unfortunately the ST data sheet and app note do not describe the process for writing to a 16 bit (2 byte) embedded function register. The AN5867 app note describes the procedure well for a single byte (“YYh”) write in section 2.1.1.

No go!. Writing the low byte of a new threshold value to STHS34PF80_PRESENCE_THS_L (0x20) and then writing the high byte to STHS34PF80_PRESENCE_THS_H (0x21) results in only the low value value changing in the STHS34PF80. The high byte is stuck at 0x00 value.

I just wonder…

in sths34pf80_reg.c in the function that writes to the embedded registers (sths34pf80_func_cfg_write()) it assumes an automatic increment on writing, BUT not on reading sths34pf80_func_cfg_read()). Maybe it only expects ONE write after setting the address? Attached is a changed version of that file, where starting line 1518 I have made some changes with the remark special to apply that change. Also, some changes in sths34pf80_presence_threshold_set() as that is double what is already happening.

Try to replace it with the one that is currently in src/ths34pf80_api (first make a safety copy of the original)

who knows …

sths34pf80_reg.zip (5.71 KB)

Thanks Paul. Yes, reading the embedded function registers one byte at a time did the trick, namely your modified sths34pf80_func_cfg_read() fixed the problem. The sths34pf80_func_cfg_write() is ok without a change as the auto-increment of STHS34PF80_FUNC_CFG_ADDR writing seems to work. To recap the auto-incrementing of STHS34PF80_FUNC_CFG_ADDR when reading those registers does not happen, it must be done one byte address as a time.

I did hack the sths34pf80_func_cfg_write() method to be something like yours. Why didn’t I think of doing the same with the sths34pf80_func_cfg_read() method!

All is good. You can push your changes to github .

Thanks, again.

Hi there, I’m experiencing a similar issue with setting the motion threshold. For example, when I set it to 256, it reads as 0. I tried following your instructions to fix this issue, but unfortunately, it didn’t work. Could you please advise me? Thank you! Here is my code for your reference if you need to test it:

#include “SparkFun_STHS34PF80_Arduino_Library.h”

#include <Wire.h>

STHS34PF80_I2C mySensor;

void setup()

{

Serial.begin(115200);

Serial.println(“STHS34PF80 Example: Setting and Reading Motion Threshold”);

// Begin I2C

Wire.begin();

// Establish communication with device

if (!mySensor.begin())

{

Serial.println(“Error setting up device - please check wiring.”);

while (1);

}

delay(1000);

// Set the motion threshold

uint16_t newThreshold = 256; // Set your desired threshold value

int32_t setError = mySensor.setMotionThreshold(newThreshold);

Serial.print("Motion Threshold set to: ");

Serial.println(newThreshold);

delay(1000);

// Read and print the current motion threshold

uint16_t motionThreshold;

int32_t getError = mySensor.getMotionThreshold(&motionThreshold);

if (getError == 0)

{

Serial.print("Current Motion Threshold: ");

Serial.println(motionThreshold);

}

else

{

Serial.println(“Error reading motion threshold.”);

}

}

void loop()

{

// Nothing in the loop function for this example

}

When I looked at the github repo for the Arduino sths34pf80 driver I see that it has not been touched in serval months. Unfortunately they have not fixed this bug.

However, the setting of the thresholds do work, the problem is reading them as you only receive the low byte of the two byte threshold value. So for actual use you do not need to read them back, just set them.

You can download the github repo and modified the driver source code yourself according to the
instruction from sparkfun support in this blog (a zip of source file).

My actual use was to create a sths34pf80 driver Rust crate (which is at crates.io if interested), and when I ran into this bug I switched over to C++ to test it.

1 Like