Add tlmConfirm to tlm_dl ota packet-structure (#2991)
[ExpressLRS.git] / src / lib / GSENSOR / gsensor.cpp
bloba8cdf8993bd121f94c7c3c47bfb18241539e275c
1 #include "targets.h"
3 #include "gsensor.h"
4 #include "logging.h"
6 #include "stk8baxx.h"
7 STK8xxx stk8xxx;
9 int gensor_status = GSENSOR_STATUS_FAIL;
11 #define DATA_SAMPLE_LENGTH 20
12 #define QUIET_VARIANCE_THRESHOLD 0.0002f
13 #define QUIET_AVERAGE_THRESHOLD 0.04f
15 #define FLIPPED_ACTION_THRESHOLD 0.2f
17 static float x_buffer[DATA_SAMPLE_LENGTH] = {0};
18 static float y_buffer[DATA_SAMPLE_LENGTH] = {0};
19 static float z_buffer[DATA_SAMPLE_LENGTH] = {0};
20 static int sample_counter = 0;
21 float x_average = 0;
22 float y_average = 0;
23 float z_average = 0;
25 static bool interrupt = false;
27 #ifdef HAS_SMART_FAN
28 extern bool is_smart_fan_control;
29 uint32_t smart_fan_start_time = 0;
30 #define SMART_FAN_TIME_OUT 5000
31 #endif
33 ICACHE_RAM_ATTR void handleGsensorInterrupt()
35 interrupt = true;
38 bool Gsensor::init()
40 int16_t id = -1;
41 if (OPT_HAS_GSENSOR_STK8xxx)
42 id = stk8xxx.STK8xxx_Initialization();
43 else
44 return false;
46 if(id == -1)
48 ERRLN("Gsensor failed!");
49 return false;
51 else
53 DBGLN("Gsensor OK with chipid = %x!", id);
54 gensor_status = GSENSOR_STATUS_NORMAL;
57 if(gensor_status == GSENSOR_STATUS_NORMAL)
59 if (OPT_HAS_GSENSOR_STK8xxx)
61 stk8xxx.STK8xxx_Anymotion_init();
62 pinMode(GPIO_PIN_GSENSOR_INT,INPUT_PULLUP);
63 attachInterrupt(digitalPinToInterrupt(GPIO_PIN_GSENSOR_INT), handleGsensorInterrupt, FALLING);
67 system_state = GSENSOR_SYSTEM_STATE_MOVING;
68 is_flipped = false;
69 return true;
72 float get_data_average(float *data, int length)
74 float average = 0;
75 for(int i=0;i<length;i++)
77 average += *(data+i);
79 average = average / length;
80 return average;
83 float get_data_variance(float average, float *data, int length)
85 float variance = 0;
86 for(int i=0;i<length;i++)
88 float temp = *(data+i) - average;
89 temp = temp * temp;
90 variance += temp;
92 variance = variance / length;
93 return variance;
96 bool Gsensor::hasTriggered(unsigned long now)
98 static unsigned long lastTriggeredMs = 0;
100 if (interrupt)
102 interrupt = false;
103 if (now - lastTriggeredMs > 20)
105 lastTriggeredMs = now;
106 return true;
109 return false;
112 void Gsensor::handle()
114 float x, y, z;
116 getGSensorData(&x, &y, &z);
117 #ifdef HAS_SMART_FAN
118 if(z < -0.5f)
120 is_smart_fan_control = true;
121 smart_fan_start_time = millis();
123 else
125 if(is_smart_fan_control && (millis() - smart_fan_start_time) > SMART_FAN_TIME_OUT)
127 is_smart_fan_control = false;
130 #endif
131 if(z > FLIPPED_ACTION_THRESHOLD)
133 is_flipped = true;
135 else
137 is_flipped = false;
139 if(system_state == GSENSOR_SYSTEM_STATE_QUIET)
141 x = abs(x - x_average);
142 y = abs(y - y_average);
143 z = abs(z - z_average);
144 if((x > QUIET_AVERAGE_THRESHOLD) || (y > QUIET_AVERAGE_THRESHOLD) ||
145 (z > QUIET_AVERAGE_THRESHOLD))
147 system_state = GSENSOR_SYSTEM_STATE_MOVING;
150 else
152 x_buffer[sample_counter] = x;
153 y_buffer[sample_counter] = y;
154 z_buffer[sample_counter] = z;
156 if(sample_counter == DATA_SAMPLE_LENGTH -1)
158 sample_counter = 0;
159 x_average = get_data_average(x_buffer, DATA_SAMPLE_LENGTH);
160 y_average = get_data_average(y_buffer, DATA_SAMPLE_LENGTH);
161 z_average = get_data_average(z_buffer, DATA_SAMPLE_LENGTH);
163 float x_variance = get_data_variance(x_average, x_buffer, DATA_SAMPLE_LENGTH);
164 float y_variance = get_data_variance(y_average, y_buffer, DATA_SAMPLE_LENGTH);
165 float z_variance = get_data_variance(z_average, z_buffer, DATA_SAMPLE_LENGTH);
167 if((x_variance < QUIET_VARIANCE_THRESHOLD) && (y_variance < QUIET_VARIANCE_THRESHOLD) &&
168 (z_variance < QUIET_VARIANCE_THRESHOLD))
170 system_state = GSENSOR_SYSTEM_STATE_QUIET;
173 else
175 sample_counter++;
180 void Gsensor::getGSensorData(float *X_DataOut, float *Y_DataOut, float *Z_DataOut)
182 *X_DataOut = 0;
183 *Y_DataOut = 0;
184 *Z_DataOut = 0;
185 if(gensor_status == GSENSOR_STATUS_NORMAL)
187 if (OPT_HAS_GSENSOR_STK8xxx)
188 stk8xxx.STK8xxx_Getregister_data(X_DataOut, Y_DataOut, Z_DataOut);
190 else
192 ERRLN("Gsensor abnormal status = %d", gensor_status);
196 int Gsensor::getSystemState()
198 return system_state;
201 bool Gsensor::isFlipped()
203 return is_flipped;