Previously related posts:
ModusToolbox Intro:
Part 1 link:
PSoC 6 BLE Pioneer Kit with Honeywell SEK002: Part 1
Topics Covered
- Honeywell SEK002 Sensor Evaluation Kit for Arduino
- Honeywell Sensors Tested
- Cypress PSoC 6 BLE Pioneer Kit (CY8CKIT-062-BLE)
- ModusToolbox IDE configuration
- i2C
- CapSense
- Debug UART
- Pump / Valve config.
5. Blood Pressure Pump Board
Honeywell SEK002 Sensor Evaluation Kit for Arduino
https://my.element14.com/honeywell/sek002/eval-kit-board-mount-pressure/dp/2849208?COM=Cypress
The Honeywell SEK002 Sensor Evaluation Kit for Arduino is designed to assist in the evaluation of Honeywell ABP, MPR, HPM, and Humidicon sensors using the popular Arduino Header form factor. The SEK002 provides multiple on board solder pads for various surface mount devices as well as a DIP Header for a ABP sensor (S3) and a through hole SIP option for a Humidicon sensor (S7) as well as a header to plug in a cable from a HPM sensor (P4). The board offers both SPI and I2C to most sensors and UART with HPM sensors with the signals being mapped to the associated Arduino Header pins. Each sensor location on the board has an independent enable jumper and associated set of jumpers to enable either SPI of i2C for the sensor block on the board. However, there is no separate Chip Enable for the SPI interface and the Pressure sensors tend to have the same I2C address of 0x28 (40) which means that only a single Pressure sensor can be tested at a time with the board. There is an option where the customer can request to have a custom address assigned to a device, but the default for the Pressure Sensor is 0x28. The Humidicon sensor has an i2C address of 0x27 (39) so this sensor can be tested along with a Pressure sensor, but still only one Humidicon sensor can be tested at a time as an I2C device. Combining a I2C and a SPI sensor may be possible but this was not tested during this exercise. Instead of mounting sensors on the board directly, wires were attached the Humidicon and MPR sensor used in the test and attached to the connectors where the associated jumper would be placed for the sensor. This also provides the option to test a sensor that might be in another product or in an environment controlled area where it is not possible to mount the sensor on the SEK002.
As is shown in the top level image of the SEK002, the board is separated in 4 blocks: ABP Series Sensors, Micropressure Sensors (MPR), Humidicon Sensors, and HPM Series sensors.
In the bottom left of the image, there is a ABPDRRT005PG2A5 Pressure Sensor Amplified installed at S3 which is the initial sensor tested in this blog post.
To enable communication to this sensor, a jumper has been placed at J3, and to enable the I2C interface to the sensor jumpers have been placed on the left side of J4 and J5.
The bottom side of the SEK002 board has the Jumper settings to enable the I2C Communication for the HPM Series, ABP Series and Micropressue sensors as well as for the Humidicon SIP and SOIC options. Also, the SPI Communication for the ABP Series and Micropressure sensors is shown.
Quickview Video of the Honeywell SEK002
Honeywell Sensors Tested
MPRLS0015PA0000SA - Pressure Sensor, 15 psi, Digital, Absolute, 3.6 VDC, Single Port, 1.7 mA
For the ABP type,
ABPDRRT005PG2A5 Pressure Sensor Amplified 5 psi Digital Gauge 5 VDC Dual Radial Barbed 3.7 mA
HIH8120-021-001 - Temperature and Humidity Sensor, HumidIcon Series, Digital, 0% to 100% RH, 2 %, SIP, Filter
Cypress PSoC 6 BLE Pioneer Kit (CY8CKIT-062-BLE)
https://www.element14.com/community/roadTests/1862
Honeywell provides evaluation software and custom Firmware for an Arduino UNO to test the SEK002 Sensor Evaluation Kit, however the Cypress PSoC 6 BLE Pioneer Kit (CY8CKIT-062-BLE) will be used to perform the sensor test in the post. The CY8CKIT-062-BLE has Arduino UNO style headers to the SEK002 can plug directly to the CY8CKIT-062-BLE to perform sensor evaluation. Since there is no provided code to test the SEK002 with the Cypress kit, test code will be created utilizing the PSoC 6 features of the CY8CKIT-062-BLE to read sensor values from the Honeywell sensors. Also, rather than use the PSoC Creator to program the PSoC 6 on the Pioneer kit, the ModusToolbox Software Environment will be used instead.
ModusToolbox IDE configuration
To run the test of the SEK002 the ModusToolbox IDE is used instead PSoC Creator. In a preview post. I covered an Overview of ModusToolbox and the i2C Master project from that post will be used as a starter project to test the sensors.
ModusToolbox Intro:
The CE221120 - PSoC 6 MCU SPI Master example is used in this post.
http://www.cypress.com/documentation/code-examples/ce221120-psoc-6-mcu-spi-master
To change the name of a starter project, ModusToolbox has an option available when right clicking on the 'mainapp' part of the project and selecting Rename ModusToolbox Application which will rename all of the files and folders to the new name.
The typical ModusToolbox starter project has 5 parts that make up the complete project.
- Honeywell_Sensor_PSoC6_config - Contains the Design Configurator file design.modus
- Honeywell_Sensor_PSoC6_mainapp - Contains config files specific for the Cortex M4 core
- Honeywell_Sensor_PSoC6_mainapp_cm0p - Contains files specific for the Cortex M0 Plus core
- Honeywell_Sensor_PSoC6_mainapp_cm0p_psoc6pdl - Contains the M0 plus PDL files
- Honeywell_Sensor_PSoC6_psoc6pdl - Contains the M4 PDL files
i2C
The communication between the CY8CKIT-062-BLE and the Honeywell sensors through the SEK002, the i2C interface is used.
- Serial Communication Block
The Serial Communication Block (SCB) from the Device Configurator can be used to quickly configure either a
EZI2C, I2C, SPI or UART interface. The Device Configurator is accessed by double clicking on the
'design.modus' file under the config project folder.
Once the Device Configurator window opens, the SBC configuration is found under the Peripherals tab.
Since the I2C Master starter project was used, both a Master and Slave I2C SBC still exist.
However, the Master interface was moved to SBC 3 since this is tied to the main I2C interface on the
Arduino headers and thus the I2c interface used to communicated with the sensors.
Port 6 Pin 0 - Master SCL
Port 6 Pin 1 - Master SDA
- Sensor Communication
To communicate with the Honeywell sensors, a buffer is created and set with 2 ACK and an NACK to be sent
to the sensor via the I2C Master interface.
uint8 tmpBuffer[TMP_PACKET_SIZE]; float pressureValue = 0.0; uint16 cntVal = 0; /* create packet to be sent to slave. */ tmpBuffer[PACKET_SOP_POS] = CY_SCB_I2C_ACK; tmpBuffer[PACKET_CMD1_POS] = CY_SCB_I2C_ACK; tmpBuffer[PACKET_CMD2_POS] = CY_SCB_I2C_NAK;
The Master I2C is initialized and the status is checked to ensure the I2C interface initialized properly.
status = initMaster(); if(status == I2C_FAILURE) { handle_error() }
Then the Slave status is checked to ensure it is online and communicating,
if (TRANSFER_CMPLT == checkSlaveStatus()) { gpioState(&ledStates[RGB_RED], LED_ON); gpioState(&gpioStates[GPIO_MOTOR], ON); Cy_SysLib_Delay(START_PUMP_DELAY); }
checkSlaveStatus
uint32_t checkSlaveStatus(void) { uint32_t masterStatus; masterStatus = Cy_SCB_I2C_MasterSendStart(mI2C_HW, PRESS_SENSOR_ADDR, CY_SCB_I2C_WRITE_XFER, 100, &mI2C_context); if (CY_SCB_I2C_SUCCESS == masterStatus) { CyDelay(100); masterStatus= Cy_SCB_I2C_MasterSendStop(mI2C_HW, 100, &mI2C_context); } return masterStatus; }
If the slave status is true, then the RED RGB Led will be lit and the Pump motor is turned on.
- Read Sensor Value
Then the sensor is read using the I2C Master Write interface. While the converted sensor value is less then 1,
the program will loop and read the sensor again until the value '1.00' is reached. The Pump motor is then turned off
and delays to normalize the reading. The Red RGB Led will blink while the sensor is being read.
while (pressureValue < 1.0) { if (TRANSFER_CMPLT == readPressure(tmpBuffer, TMP_PACKET_SIZE, &pressureValue)) { UpdateLEDs(&ledStates[RGB_RED]); DEBUG_PRINTF("Pressure value = %2.4f \r\n", pressureValue); } if (BUTTON1_TOUCHED == getTouch()) { break; } Cy_SysLib_Delay(RUN_PUMP_DELAY); } DEBUG_PRINTF("\r\n\nPump Motor Stopping now \r\n"); gpioState(&ledStates[RGB_RED], LED_OFF); gpioState(&gpioStates[GPIO_MOTOR], OFF);
readPressure Function
uint32_t readPressure(uint8_t* buffer, uint32_t bufferSize, float *pressValue) { uint32_t masterStatus; uint8_t tempBuffer[TEMP_PACKET_SIZE]; static const uint8_t pressureMask = 0xC0; uint8_t pressureStatus = 0; volatile uint32_t pressRawData = 0; uint8_t* cmdBuffer = buffer; // Read the Pressure data Cy_SCB_I2C_MasterSendStart(mI2C_HW, PRESS_SENSOR_ADDR, CY_SCB_I2C_READ_XFER, 500, &mI2C_context); for (int bufNum = 0; bufNum < bufferSize; bufNum++) { masterStatus = Cy_SCB_I2C_MasterReadByte(mI2C_HW, cmdBuffer[bufNum], &tempBuffer[bufNum], 100, &mI2C_context); if(masterStatus != CY_SYSINT_SUCCESS) { return I2C_FAILURE; } } CyDelay(100); masterStatus = Cy_SCB_I2C_MasterSendStop(mI2C_HW, 100, &mI2C_context); if (masterStatus != CY_SCB_I2C_SUCCESS) { return I2C_FAILURE; } pressureStatus = tempBuffer[0] & pressureMask; switch (pressureStatus) { case 0: masterStatus = 0; break; case 1: masterStatus = 1; break; case 2: masterStatus = 2; break; case 3: masterStatus = 3; break; default: break; } // Convert the 2 byte data to 14-bits value pressRawData = (((uint32_t) (tempBuffer[0] & 0x3f)) << 8) | ((uint32_t) tempBuffer[1]); *pressValue = SSC_PRESSURE(pressRawData); return masterStatus = 0; }
Pressure Sensor value convertion
#define SSC_PRESSURE(v) ((float)(v) * 1.6 / 16383)
CapSense
For user input, the CapSense interface was added to the project. The CapSense interface on the CY8CKIT-062-BLE
includes a Slider, 2 Buttons as a presence sensor. Only the 2 Buttons were used for the testing of the sensor at this time.
- CSD Config
To add CapSense to a ModusToolbox project, the first step is to enable the CapSense Peripherals System option
from Device Configurator.
Once CapSense is enabled, multiple pins must be enabled and configured.
In this instance, the CSX Sensing Mode is used with the following pin mapping.
Name | Port[Pin] |
---|---|
Cmod | P7[7] |
CintA | P7[1] |
CintB | P7[2] |
Button0_Rx0 | P8[1] |
Button0_Tx | P1[0] |
Button1_Rx0 | P8[2] |
LinearSlider0_Sns0 | P8[3] |
LinearSlider0_Sns1 | P8[4] |
LinearSlider0_Sns2 | P8[5] |
LinearSlider0_Sns3 | P8[6] |
LinearSlider0_Sns4 | P8[7] |
From the Device Configurator, this will look like the following.
From the Pins tab in the Device Configurator, the individual pins can be configured.
Note where the P7[7] Terminals are set to CSD CapSense amuxbus_a and amuxbus_b.
A Clock will have to be enabled and configure for CapSense functionality which can be added
from the Peripheral Clocks tab. The 8-bit Divider 2 was added for CapSense.
- Button Config
Going back the Peripherals tab, the ModusToolbox also includes a CapSense Configurator
and CapSense Tuner to fine tune the CapSense configuration. These are added as
separate tool that can be launch from command line, but in ModusToolbox these have separate
Launch selections under External Tools. Selecting Launch CapSense Configurator will
open the CapSense Configuator tool.
From the BasicTab in the CapSense Configurator window, the CapSense devices can be added
and the Sensing mode set.
Here Button0 Button1 and LinearSlider0 have been added. The Buttons have the Sensing Mode
to CSX (Mutual-cap) where the Buttons can share the cap config.
From the Advanced Tab, the Widget Details can be accessed where the device settings can be fine
tuned and each port can be individually configured.
The Pins Tab will display the Signal and Port/Pin Mappings.
Once the settings are complete, clicking Save will save the config data and update the necessary
project files. This can be seen from the Code Preview window under Peripherals.
The required libraries to support the CapSense Interface can either be added manually or via the
ModusToolbox Middleware Selector by right clicking on the mainapp folder. Here the capsense library
was added to the mainapp folder psoc6sw-1,0->components->psoc6mw.
Borrowing code from another starter project, the CapSense interface can be initialized as follows:
void initCapSense(void) { /*Initialize CapSense Data structures */ Cy_CapSense_Init(&cy_capsense_context); /* Initialize CapSense interrupt */ Cy_SysInt_Init(&CapSense_ISR_cfg, &CapSense_Interrupt); NVIC_ClearPendingIRQ(CapSense_ISR_cfg.intrSrc); NVIC_EnableIRQ(CapSense_ISR_cfg.intrSrc); /* Start CapSense block and perform first scan to set up sensor baselines */ Cy_CapSense_Enable(&cy_capsense_context); }
Example of reading a Button press from the CapSense interface
/* Check if CapSense is busy with a previous scan */ if (CY_CAPSENSE_NOT_BUSY == Cy_CapSense_IsBusy(&cy_capsense_context)) { /* Process all widgets and read touch information */ Cy_CapSense_ProcessAllWidgets(&cy_capsense_context); gestureStatus = Cy_CapSense_DecodeWidgetGestures( CY_CAPSENSE_LINEARSLIDER0_WDGT_ID, &cy_capsense_context); /* Button0 is active */ if (Cy_CapSense_IsWidgetActive(CY_CAPSENSE_BUTTON0_WDGT_ID, &cy_capsense_context)) { currentTouchData = BUTTON0_TOUCHED; }
Debug UART
To show output of the Sensor reading, the serial Debug UART option was enabled.
- ModusToolbox Middleware Selector
- Retarget I/O
To enable the Debug UART on the CY8CKIT-062-BLE, the Retarget I/O Middleware software must be added.
This is done by right clicking on the mainapp project folder and selecting the ModusToolbox Middleware Selector
option. This adds the Retarget I/O library files 'stdio_user.h' and stdio_user.c' to the project files.
Retarget I/O provides a means to send standard I/O commands such as 'printf' out a user defined Target such as the Debug UART
From the Middleware Selector window, ensure the checkbox for Retarget I/O is selected.
- UART SBC
To enable the SBC UART for the Debug port (KIT_UART), open Device Configurator and
enable a SBC set to UART-1.0. SBC 5 was used in this instance.
From the Parameters pane, the UART Baud Rate, Comm Mode, etc can be set.
Also from the Parameters pane, the PIn mapping for Tx and Rx can be set as well as the
appropriate clock.
Name | Connect |
---|---|
Clock | 16 bit Divider 2 clk |
RX | P5[0] |
TX | P5[1] |
The UART SBC can be assigned to the Tx and Rx from the Parameter pane.
Once the Debug UART has been configured, the code preview for the SBC can be viewed
from the Parameters tab.
Macros borrowed from another starter project were used to send commands to the serial port.
#include "cy_scb_uart.h" /*************************************** * Macros ***************************************/ #define UART_DEBUG_HW KIT_UART_HW cy_stc_scb_uart_context_t KIT_UART_context; __STATIC_INLINE void UART_DEBUG_START(void) { (void) Cy_SCB_UART_Init(KIT_UART_HW, &KIT_UART_config, &KIT_UART_context); Cy_SCB_UART_Enable(UART_DEBUG_HW); } #define DEBUG_PRINTF(...) (printf(__VA_ARGS__)) #define UART_DEBUG_GET_TX_BUFF_SIZE(...) (Cy_SCB_GetNumInTxFifo(UART_DEBUG_HW) + Cy_SCB_GetTxSrValid(UART_DEBUG_HW)) #define DEBUG_WAIT_UART_TX_COMPLETE() while(UART_DEBUG_GET_TX_BUFF_SIZE() != 0);
To send a string or data to the Debug serial port, the DEBUG_PRINTF macro is used.
UART_DEBUG_START(); DEBUG_PRINTF("\r\n\nWait for User input to start \r\n");
DEBUG Uart output example:
Debug output while reading pressure sensor
Pump / Valve config.
To test the pressure sensor capabilities, a Mini Pump and Solenoid Valve along with a modified manual
Sphygmomanometer were used.
Mini Air Pump Motor Model : KPM12A
Solenoid Electromagnet Valve
A circuit board to power the Pump and Valve was created using 2 TIP120 transistors.
The following Pin Mapping were used to control the Motor, Valve and RGB LEDs.
Name | Port[Pin] |
---|---|
VALVE_OUT | P6[3] |
MOTOR_OUT | P9[7] |
RGB_RED | P0[3] |
RGB_GREN | P1[1] |
RGB_BLUE | P11[1] |
To enable the configurator devices, the 'init_cycfg_all' function is called.
init_cycfg_all();
A set of enums and struct/struct arrays are used to control the states of the Motor and Valve and the LEDS.
typedef enum {LED_OFF = 1u, LED_ON = 0u} LED_STATE; typedef enum {RGB_RED, RGB_GREEN, RGB_BLUE, KIT_LED2_RED} RGB_COLOR; typedef enum {GPIO_MOTOR, GPIO_VAVLE} GPIO_STATE; typedef struct Gpios{ GPIO_PRT_Type* portNum; uint32 pinNum; uint32 pinState; }Gpio; Gpio ledStates[4] = { {RGB_RED_PORT, RGB_RED_PIN, LED_OFF}, {RGB_GREEN_PORT, RGB_GREEN_PIN, LED_OFF}, {RGB_BLUE_PORT, RGB_BLUE_PIN, LED_OFF}, {KIT_LED2_PORT, KIT_LED2_NUM, LED_OFF} }; Gpio gpioStates[2] = { {MOTOR_OUT_PORT, MOTOR_OUT_NUM, OFF}, {VALVE_OUT_PORT, VALVE_OUT_NUM, OFF} };
Functions to control the state of the GPIO devices and LEDs.
void UpdateLEDs(Gpio *ledState) { ledState->pinState = (LED_OFF == ledState->pinState) ? LED_ON : LED_OFF; Cy_GPIO_Write(ledState->portNum, ledState->pinNum, ledState->pinState); } void gpioToggle(Gpio *gpioVal) { gpioVal->pinState = (OFF == gpioVal->pinState) ? ON : OFF; Cy_GPIO_Write(gpioVal->portNum, gpioVal->pinNum, gpioVal->pinState); } void gpioState(Gpio *gpioVal, uint8 gpioState) { gpioVal->pinState = gpioState; Cy_GPIO_Write(gpioVal->portNum, gpioVal->pinNum, gpioVal->pinState); }
To turn off a GPIO device such as the Motor or Valve, the device enum value and state is sent to the gpioState function.
gpioState(&gpioStates[GPIO_MOTOR], OFF); gpioState(&gpioStates[GPIO_VAVLE], OFF);
The code waits for the user to press Button0 on the CapSense interface to start the pump and read the pressure sensor.
DEBUG_PRINTF("\r\n\nWait for User input to start \r\n"); while (BUTTON0_TOUCHED != getTouch()) { Cy_SysLib_Delay(500UL); UpdateLEDs(&ledStates[RGB_BLUE]); } gpioState(&ledStates[RGB_BLUE], LED_OFF); DEBUG_PRINTF("\r\n\nPump Motor Turning on \r\n"); if (TRANSFER_CMPLT == checkSlaveStatus()) { gpioState(&ledStates[RGB_RED], LED_ON); gpioState(&gpioStates[GPIO_MOTOR], ON); Cy_SysLib_Delay(START_PUMP_DELAY); }
The Pump will run until the pressure sensor reading reaches 1, and then the pump state is set to OFF.
while (pressureValue < 1.0) { if (TRANSFER_CMPLT == readPressure(tmpBuffer, TMP_PACKET_SIZE, &pressureValue)) { UpdateLEDs(&ledStates[RGB_RED]); DEBUG_PRINTF("Pressure value = %2.4f \r\n", pressureValue); } if (BUTTON1_TOUCHED == getTouch()) { break; } Cy_SysLib_Delay(RUN_PUMP_DELAY); } DEBUG_PRINTF("\r\n\nPump Motor Stopping now \r\n"); gpioState(&ledStates[RGB_RED], LED_OFF); gpioState(&gpioStates[GPIO_MOTOR], OFF); Cy_SysLib_Delay(CMD_TO_CMD_DELAY);
After the pump state is set to OFF, the sensor value is checked again and the pump is used to attempt to keep the
the pressure value at 1 for 10 iterations.
for (cntVal = 0; cntVal < 10; cntVal++){ if (TRANSFER_CMPLT == readPressure(tmpBuffer, TMP_PACKET_SIZE, &pressureValue)) { UpdateLEDs(&ledStates[RGB_GREEN]); DEBUG_PRINTF("Pressure value = %2.4f \r\n", pressureValue); if (pressureValue < 1.0 ) { gpioState(&gpioStates[GPIO_MOTOR], ON); } else { gpioState(&gpioStates[GPIO_MOTOR], OFF); } Cy_SysLib_Delay(RUN_PUMP_DELAY); } }
The last part of the test is to release the pressure from the cuff.
DEBUG_PRINTF("\r\n\nRelease Pressure \r\n"); gpioState(&ledStates[RGB_GREEN], LED_ON); gpioState(&gpioStates[GPIO_MOTOR], OFF); gpioState(&gpioStates[GPIO_VAVLE], ON); for (cntVal = 0; cntVal < 3; cntVal++) { Cy_SysLib_Delay(START_VAVLE_DELAY); } gpioState(&gpioStates[GPIO_VAVLE], OFF); gpioState(&ledStates[RGB_GREEN], LED_OFF); Cy_SysLib_Delay(CMD_TO_CMD_DELAY);
Video of the ModusToolbox config used and a running example of reading the ABP sensor from the SEK002 board using a Cypress PSoC BLE Pioneer kit.
Summary
The Honeywell SEK002 is a handy board that can be used to quickly test the Honeywell line of SPI and I2C and HPM sensors, or other related sensors. The board has multiple options for the various mounting footprints which include both surface mound and DIP. The Arduino Headers allow the board to be used with low cost Arduino style dev kits where testing can be rapidly prototyped. One consideration is that the default address for many of the Honeywell sensors have an I2C address of 0x28(40) so only 1 sensor can be tested at a time. However, if the sensors support both SPI and I2C, then at least 2 can be tested with each other. Also, considering the small form factor of some of the Surface Mount pads, it is unclear as to how a sensor could be mounted to the board in this manner since heating the board could cause the components on the bottom side of if to either move or fall off. A Hot Air tool might be an option in this case. Overall, it is a nice platform to quickly evaluate Honeywell sensors in a common Arduino config.
Next Step
To see about adding FreeRTOS and BLE and the E-Ink Display and mobile reading of the sensor.
Top Comments