#include <stdio.h>
#include <stdlib.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);
struct sensor_value data[3];
/* Convert to s/m2 depending on the maximum measured range used for adxl362. */
#if IS_ENABLED(CONFIG_ADXL362_ACCEL_RANGE_2G)
#define ADXL362_RANGE_MAX_M_S2 19.6133
#elif IS_ENABLED(CONFIG_ADXL362_ACCEL_RANGE_4G)
#define ADXL362_RANGE_MAX_M_S2 39.2266
#elif IS_ENABLED(CONFIG_ADXL362_ACCEL_RANGE_8G)
#define ADXL362_RANGE_MAX_M_S2 78.4532
#endif
static uint32_t work_time_minutes = 0;
static bool is_working = false;
static const struct device *adxl1362_sens = DEVICE_DT_GET(DT_ALIAS(adxl362));
#define ADXL362_THRESHOLD_RESOLUTION_DECIMAL_MAX 2000
static int ext_sensors_accelerometer_threshold_set(double threshold, bool upper);
static void configure_triggers(void);
static void trigger_handler(const struct device *dev, const struct sensor_trigger *trig);
static void print_sensor_data(const struct device *dev)
{
if (sensor_channel_get(dev, SENSOR_CHAN_ACCEL_XYZ, data) < 0)
{
LOG_ERR("Cannot read sensor channels");
return;
}
LOG_INF("X: %f m/s², Y: %f m/s², Z: %f m/s²",
sensor_value_to_double(&data[0]),
sensor_value_to_double(&data[1]),
sensor_value_to_double(&data[2]));
}
static void trigger_handler(const struct device *dev, const struct sensor_trigger *trig)
{
if (sensor_sample_fetch(dev) < 0)
{
LOG_ERR("Sample fetch error");
return;
}
if (trig->type == SENSOR_TRIG_MOTION)
{
LOG_INF("Activity detected");
//print_sensor_data(dev);
is_working = true;
}
else if (trig->type == SENSOR_TRIG_STATIONARY)
{
LOG_INF("Inactivity detected");
print_sensor_data(dev);
is_working = false;
}
}
static void configure_triggers(void)
{
struct sensor_trigger trig_motion = {
.chan = SENSOR_CHAN_ACCEL_XYZ,
.type = SENSOR_TRIG_MOTION,
};
if (sensor_trigger_set(adxl1362_sens, &trig_motion, trigger_handler))
{
LOG_ERR("SENSOR_TRIG_MOTION set error");
}
struct sensor_trigger trig_stationary = {
.chan = SENSOR_CHAN_ACCEL_XYZ,
.type = SENSOR_TRIG_STATIONARY,
};
if (sensor_trigger_set(adxl1362_sens, &trig_stationary, trigger_handler))
{
LOG_ERR("SENSOR_TRIG_STATIONARY set error");
}
}
static int ext_sensors_accelerometer_threshold_set(double threshold, bool upper)
{
int err, input_value;
double range_max_m_s2 = ADXL362_RANGE_MAX_M_S2;
if ((threshold > range_max_m_s2) || (threshold <= 0.0))
{
LOG_ERR("Invalid %s threshold value: %f", upper ? "activity" : "inactivity", threshold);
return -ENOTSUP;
}
threshold = (threshold * (ADXL362_THRESHOLD_RESOLUTION_DECIMAL_MAX / range_max_m_s2)) + 0.5;
input_value = (int)threshold;
if (input_value >= ADXL362_THRESHOLD_RESOLUTION_DECIMAL_MAX)
{
input_value = ADXL362_THRESHOLD_RESOLUTION_DECIMAL_MAX - 1;
}
else if (input_value < 0)
{
input_value = 0;
}
const struct sensor_value data = {
.val1 = input_value
};
enum sensor_attribute attr = upper ? SENSOR_ATTR_UPPER_THRESH : SENSOR_ATTR_LOWER_THRESH;
err = sensor_attr_set(adxl1362_sens, SENSOR_CHAN_ACCEL_X, attr, &data);
if (err)
{
LOG_ERR("Failed to set accelerometer threshold value");
LOG_ERR("Device: %s, error: %d", adxl1362_sens->name, err);
return err;
}
return 0;
}
void work_time_counter(struct k_work *work)
{
if (is_working)
{
work_time_minutes += 1; // 1 dakika ekle
LOG_INF("Total work time: %u minutes", work_time_minutes);
is_working = false;
}
// Tekrar 1 dakika sonra çalışacak şekilde zamanlayıcıyı ayarla
k_work_schedule((struct k_work_delayable *)work, K_MINUTES(1));
}
K_WORK_DELAYABLE_DEFINE(work_time_task, work_time_counter);
int main(void)
{
if (!device_is_ready(adxl1362_sens))
{
LOG_ERR("sensor device %s not ready", adxl1362_sens->name);
return -1;
}
configure_triggers();
ext_sensors_accelerometer_threshold_set(9.6133, true);
// İlk zamanlayıcı çalışmasını 1 dakika sonra başlat
k_work_schedule(&work_time_task, K_MINUTES(1));
while (1)
{
k_sleep(K_SECONDS(1));
}
return 0;
}
# ADXL362 CONFIG_SENSOR=y CONFIG_ADXL362=y #CONFIG_ADXL362_TRIGGER_GLOBAL_THREAD=y CONFIG_ADXL362_TRIGGER_OWN_THREAD=y CONFIG_ADXL362_INTERRUPT_MODE=1 CONFIG_ADXL362_ABS_REF_MODE=1 CONFIG_ADXL362_ACCEL_RANGE_4G=y CONFIG_ADXL362_ACCEL_ODR_400=y
&spi3 {
compatible = "nordic,nrf-spim";
status = "okay";
cs-gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;/* ,<&gpio0 7 GPIO_ACTIVE_LOW>;*/
pinctrl-0 = <&spi3_default>;
pinctrl-1 = <&spi3_sleep>;
pinctrl-names = "default", "sleep";
adxl362: adxl362@0 {
compatible = "adi,adxl362";
spi-max-frequency = <8000000>;
reg = <0>;
int1-gpios = <&gpio0 9 0>;
};
};
Hi , on this code there are not any problems, ,it runs good. but the problem is current.it is 36uA. it is more than ecpectation. because in datasheet.
adxl362 current consumption is up tu 3uA. I hane another LTE project with psm mode. when I did not initilize adxl362. the power consumption
is 6 uA. but when initilizing the sensor the current is 42. actually 6uA + 36uA = 42uA. why it consumes more. in datasheet adxl362 current
consumption is up tu 3uA. my expectation is 6uA + 3uA = 9uA.
It feels like I'm setting it up wrong.I would like to get at least 3uA when not triggered.For example, how do I switch to standby mode?
My goal is to consume low power