main/task_apds9930.c

changeset 12
bb72d448e282
child 16
b3e96bbe4ce4
equal deleted inserted replaced
11:bdc123ae7b49 12:bb72d448e282
1 /**
2 * @file task_apds9930.c
3 * @brief The FreeRTOS task to query the APDS9930 sensor.
4 */
5
6
7 #include "config.h"
8
9
10 static const char *TAG = "task_apds9930";
11
12 SemaphoreHandle_t xSemaphoreAPDS9930 = NULL; ///< Semaphore APDS9930 task
13 EventGroupHandle_t xEventGroupAPDS9930; ///< Events APDS9930 task
14 APDS9930_State *apds9930_state; ///< Public state for other tasks
15
16 float ambient_light;
17 uint16_t ch0 = 0;
18 uint16_t ch1 = 1;
19 uint16_t ALS_maxcount; ///< Maximum ADC value
20 uint16_t ALS_mincount; ///< Threshold to increase gain
21
22
23 extern apds9930_t apds9930_dev;
24
25 const int TASK_APDS9930_REQUEST_DONE = BIT0; ///< All requests are done.
26 const int TASK_APDS9930_REQUEST_LIGHT = BIT1; ///< Request Ambient Light
27
28
29
30 void request_apds9930(void)
31 {
32 xEventGroupClearBits(xEventGroupAPDS9930, TASK_APDS9930_REQUEST_DONE);
33 xEventGroupSetBits(xEventGroupAPDS9930, TASK_APDS9930_REQUEST_LIGHT);
34 }
35
36
37
38 bool ready_apds9930(void)
39 {
40 if (xEventGroupGetBits(xEventGroupAPDS9930) & TASK_APDS9930_REQUEST_DONE)
41 return true;
42 return false;
43 }
44
45
46
47 /*
48 * Task to read APDS9930 sensor on request.
49 */
50 void task_apds9930(void *pvParameter)
51 {
52 int tries;
53 esp_err_t err = ESP_OK;
54 uint8_t l_gain = 0, l_aglbit = 0;
55
56 ESP_LOGI(TAG, "Starting task APDS9930 sda=%d scl=%d", CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL);
57 apds9930_state = malloc(sizeof(APDS9930_State));
58
59 apds9930_state->valid = false;
60 apds9930_state->fake = (apds9930_dev.i2c_dev.addr == 0) ? true:false;
61 apds9930_state->address = apds9930_dev.i2c_dev.addr;
62 apds9930_state->error = APDS9930_ERR_NONE;
63
64 /* event handler and event group for this task */
65 xEventGroupAPDS9930 = xEventGroupCreate();
66 EventBits_t uxBits;
67
68 /*
69 * Task loop forever.
70 */
71 ESP_LOGI(TAG, "Starting loop APDS9930 sensor 0x%02x %d", apds9930_state->address, apds9930_state->fake);
72 while (1) {
73
74 uxBits = xEventGroupWaitBits(xEventGroupAPDS9930, TASK_APDS9930_REQUEST_LIGHT, pdFALSE, pdFALSE, portMAX_DELAY );
75
76 if (uxBits & TASK_APDS9930_REQUEST_LIGHT) {
77
78 if (! apds9930_state->fake) {
79 /* Real sensor is present */
80 apds9930_enablePower(&apds9930_dev);
81 apds9930_enableLightSensor(&apds9930_dev, false);
82 apds9930_disableProximitySensor(&apds9930_dev);
83 if (xSemaphoreTake(xSemaphoreAPDS9930, 25) == pdTRUE) {
84 l_gain = apds9930_state->gain;
85 l_aglbit = apds9930_state->aglbit;
86 xSemaphoreGive(xSemaphoreAPDS9930);
87 }
88 if (l_gain > 3)
89 l_gain = 0;
90 apds9930_setAmbientLightGain(&apds9930_dev, l_gain);
91 apds9930_setAmbientGainLevel(&apds9930_dev, l_aglbit);
92 vTaskDelay(200 / portTICK_PERIOD_MS);
93 tries = 6;
94 err = ESP_OK;
95
96 while (tries) {
97 err = apds9930_readAmbientLightLux(&apds9930_dev, &ambient_light);
98 if (err == ESP_OK) {
99 err = apds9930_readCh0Light(&apds9930_dev, &ch0);
100 if (err == ESP_OK) {
101 err = apds9930_readCh1Light(&apds9930_dev, &ch1);
102 }
103 }
104 if (err != ESP_OK) {
105 ESP_LOGE(TAG, "read APDS-9930 values error '%s'", esp_err_to_name(err));
106 break;
107 }
108
109 /*
110 * Check ranges
111 */
112 if (((ch0 == ALS_maxcount) || (ch1 == ALS_maxcount)) && ((l_gain > 0) || (l_aglbit == 0))) {
113 /* Looks like an internal overflow */
114 if (l_gain > 0) {
115 l_gain--;
116 } else {
117 l_aglbit = 1;
118 }
119 apds9930_setAmbientLightGain(&apds9930_dev, l_gain);
120 apds9930_setAmbientGainLevel(&apds9930_dev, l_aglbit);
121 vTaskDelay(200 / portTICK_PERIOD_MS);
122 ESP_LOGI(TAG, "Gain decreased to %d AGL: %d", l_gain, l_aglbit);
123 } else if ((ch0 < ALS_mincount) && (ch1 < ALS_mincount) && (l_gain < 3)) {
124 /* Looks like low resolution of the ADC. */
125 if ((l_gain == 0) && l_aglbit) {
126 l_aglbit = 0;
127 } else {
128 l_gain++;
129 }
130 apds9930_setAmbientLightGain(&apds9930_dev, l_gain);
131 apds9930_setAmbientGainLevel(&apds9930_dev, l_aglbit);
132 vTaskDelay(200 / portTICK_PERIOD_MS);
133 ESP_LOGI(TAG, "Gain increased to %d AGL: %d", l_gain, l_aglbit);
134 } else {
135 if ((ch0 == ALS_maxcount) || (ch1 == ALS_maxcount)) {
136 ambient_light = -1;
137 } else if (l_aglbit) {
138 ambient_light = ambient_light / 0.1666;
139 }
140 ESP_LOGI(TAG, "Ambient: %.3f Ch0: %d Ch1: %d Gain: %d AGL: %d", ambient_light, ch0, ch1, l_gain, l_aglbit);
141 break;
142 }
143 tries--;
144 }
145 if (tries == 0) {
146 ESP_LOGW(TAG, "tries = 0");
147 }
148 apds9930_disableLightSensor(&apds9930_dev);
149 apds9930_disablePower(&apds9930_dev);
150
151 if (xSemaphoreTake(xSemaphoreAPDS9930, 25) == pdTRUE) {
152 if (err == ESP_OK) {
153 apds9930_state->error = APDS9930_ERR_NONE;
154 apds9930_state->valid = true;
155 apds9930_state->ambient_light = ambient_light;
156 apds9930_state->gain = l_gain;
157 apds9930_state->aglbit = l_aglbit;
158 } else {
159 apds9930_state->error = APDS9930_ERR_READ;
160 apds9930_state->valid = false;
161 apds9930_state->ambient_light = 12.34;
162 apds9930_state->gain = 2;
163 apds9930_state->aglbit = 0;
164 }
165 xSemaphoreGive(xSemaphoreAPDS9930);
166 }
167 } else {
168 /* Use fake values */
169 if (xSemaphoreTake(xSemaphoreAPDS9930, 25) == pdTRUE) {
170 apds9930_state->error = APDS9930_ERR_NONE;
171 apds9930_state->valid = true;
172 apds9930_state->ambient_light = 12.34;
173 apds9930_state->gain = 2;
174 apds9930_state->aglbit = 0;
175 xSemaphoreGive(xSemaphoreAPDS9930);
176 }
177 }
178
179 xEventGroupClearBits(xEventGroupAPDS9930, TASK_APDS9930_REQUEST_LIGHT);
180 xEventGroupSetBits(xEventGroupAPDS9930, TASK_APDS9930_REQUEST_DONE);
181 #if 1
182 ESP_LOGI(TAG, " Light: %.2f, gain: %d, error: %d", apds9930_state->ambient_light, apds9930_state->gain, apds9930_state->error);
183 #endif
184 }
185 }
186 }

mercurial