Work In Progress
Please note that this blog post is still a work in progress. I've used CTRL+S shortcut to save the draft, but instead of saving it as a draft, the blog got published.
AnyCloud_BLE_Environmental_Sensing_Service
I've imported AnyCloud_BLE_Environmental_Sensing_Service as it already has integration with BLE and is not using I2C communication.
Resolving MTB Semantic Error
Once the project has been imported I've run the build, I've noticed an error message "Symbol 'xxx' could not be resolved".
I've identified missing includes by using "Project->Index->Search for Unresolved Includes"
And then I've added them to the project includes:
RTOS Task Stack Size
It is required to define the stack size for RTOS task. The only working way I'm aware of is an emerical. It requires to identify available memory after the task gets loaded, RTOS provides function uxTaskGetStackHighWaterMark.
But it is not available unless it is configured. So I've got the following error: uuxTaskGetStackHighWaterMarkxTaskGetStackHighWaterMark
/home/vlasov01/airq/AnyCloud_BLE_Environmental_Sensing_Service//main.c:391: undefined reference to `uxTaskGetStackHighWaterMark'
The solution as per RTOS document is to enable it in FreeRTOSConfig.h https://www.freertos.org/FreeRTOS_Support_Forum_Archive/April_2012/freertos_uxTaskGetStackHighWaterMark_5161498.html
Enabling Floating Point
ZMOD4510 algorithm to calculate Air Quality is using floating-point calculations. FPU can accelerate these calculations. The PSOC board comes with FPU, but it needs to be enabled. I've modified Makefile to enable them.
VFP_SELECT=hardfp # Additional / custom C compiler flags. # # NOTE: Includes and defines should use the INCLUDES and DEFINES variable # above. CFLAGS= # Hardware Floating Point Unit flags # 1. Constants are interpreted as "single-precision" float, not double CFLAGS += -fsingle-precision-constant # 2. Set the float binary interface to "hardware" CFLAGS += -mfloat-abi=hard -mthumb # 3. Set the exact model of the hardware FPU CFLAGS += -mfpu=fpv4-sp-d16
And then it is required to initiate it in the program:
Cy_SystemInitFpuEnable();
ModusToolbox Bluetooth Configurator
I've started the ModusToolbox Bluetooth Configurator using a shortcut in Quick Pan. It opened existing configuration for the I've imported AnyCloud_BLE_Environmental_Sensing_Service project,
I left as is General LE settings:
But I need to adjust GATT Settings, The temperature element came with the project.
I need to add several new elements:
- Humidity
- O3, ppb
- Fast AQI a 1-minute average of the Air Quality Index according to the EPA standard based on ozone
- EPI AQI the Air Quality Index according to the EPA standard based on ozone.
I've added them. Humidity is included in the Environmental Sensing service. The other characteristics I've added under a custom Air Quality service.
I've set the device name as Air Quality Monitor and left the appearance value as is.
After I've saved changes in Bluetooth Configurator and the Generated Sources were updated.
RTOS Task
I've wrapped my ZMOD4510 loop as the RTOS task. I'm measuring uxTaskGetStackHighWaterMark to make sure the task has enough memory allocated to the stack.
void task_zmod4510(void *parameter) { UBaseType_t uxHighWaterMark; /* Inspect our own high water mark on entering the task. */ printf("INFO *****ZMOD4510 measurements************\r\n\n"); for (;;) { uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL); printf("INFO *****uxTaskGetStackHighWaterMark %ld\r\n", uxHighWaterMark); loop(); //psoc6_i2c_write(i2c_addr, reg_addr, buf, len); /* Give delay between commands. */ //cyhal_system_delay_ms(CMD_TO_CMD_DELAY); /* Read adc value */ //psoc6_i2c_read(i2c_addr, reg_addr, buf, len); } printf("Ending ZMOD4510 task\r\n"); vTaskDelete( NULL); }
And I've added it to the RTOS scheduler. The stack size is set to TASK_BLE_STACK_SIZE value. TASK_BLE_STACK_SIZE
if (pdPASS != xTaskCreate(task_zmod4510, "Air Quality Task", TASK_BLE_STACK_SIZE, NULL, TASK_BLE_PRIORITY, NULL)) { printf("Failed to create the Air Quality task!\r\n"); CY_ASSERT(0u); } printf("completed\r\n"); /* Start the FreeRTOS scheduler */ vTaskStartScheduler();
Initial Test
I've uploaded the code to the board. ZMOD4510 got initialized and start producing results:
>> Enabling FPU..... Done >> Configuring I2C Master..... Done ************************* PSoC 6 MCU I2C ZMOD4510 ************************** *****ZMOD4510 read the sensor info************ *****ZMOD4510 read the tracking number************ sensor tracking number: x400DE4AE348A sensor trimming data: 184 6 134 174 70 221 78 5 1 0 *****ZMOD4510 prepare the sensor************ INFO *****ZMOD4510 the library initialization************ *********AnyCloud Air Quality************** ****** Environmental Sensing Service ****** Bluetooth Stack Initialization Successful Setting the Air Quality task... completed INFO *****ZMOD4510 measurements************ INFO *****uxTaskGetStackHighWaterMark 454 adc[0]=18 [1]=169 [2]=237 [3]=6 [4]=136 [5]=23 [6]=123 [7]=10 [8]=121 [9]=164 [10]=120 [11]=215 [12]=120 [13]=203 [14]=120 [15]=99 [16]=120 [17]=10 Measurement[1] Rmox[0]=7590.5k [1]=238.7k [2]=190.2k [3]=185.6k [4]=183.0k [5]=182.9k [6]=181.6k [7]=180.5k O3_ppb= 0.0 Fast AQI=0 EPA AQI=0 Warmup! INFO *****uxTaskGetStackHighWaterMark 354
Then Bluetooth tasks got started as well:
Unhandled Bluetooth Management Event: 22 BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT This application implements Bluetooth LE Environmental Sensing Service and sends dummy temperature values in Celsius, humidity, ozone concentration and air quality indexes every 5000 milliseconds over Bluetooth Discover this device with the name:Air Quality Monitor My Bluetooth Device Address: E8:E8:B7:A0:1D:95 Bluetooth Management Event: BTM_ENABLED_EVT gatt_register status: WICED_BT_GATT_SUCCESS Bluetooth Management Event: BTM_BLE_ADVERT_STATE_CHANGED_EVT Advertisement state changed to BTM_BLE_ADVERT_UNDIRECTED_HIGH Unhandled Bluetooth Management Event: 21 BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT Unhandled Bluetooth Management Event: 21 BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT INFO *****uxTaskGetStackHighWaterMark 354
Now my air quality monitor is ready for the final test.