Part 1:

 

Introduction

 

The SEK002 Sensor Evaluation Kit consists of an Arduino R3 compatible shield and some software, which includes firmware for an Arduino and a Windows-based software application for reviewing live data on a laptop or PC.

 

But, we all know that an R3 compatible sensor shield is not just for Arduino, as most will work perfectly with the PSoC 6 BLE Pioneer Kit, or with any other development board that uses the R3 compatible pin configuration. It is only the Arduino firmware and the windows software executable that are not compatible with the PSoC 6 straight out the box. Anyhow, this firmware and software is not needed to produce creative PSoC 6 based applications.

 

So let's get started.

 

 

What is the Honeywell SEK002 R3 sensor shield

 

Image source: Honeywell datasheet.

 

The SEK002 R3 sensor shield provides compatible SMD footprints and through-hole SIP/DIP connectors to allow the user to test and evaluate the following Honeywell sensors:

  • HumidIcon™ Digital Humidity/Temperature Sensors (HIH6000, HIH6100, HIH7000, HIH8000, & HIH9000 Series) – which I’ve marked as zone 1 (see below);
  • Particle Sensor (HPM Series) – marked as zone 2;
  • MicroPressure Board Mount Pressure Sensors (MPR Series) – marked as zone 3;
  • Basic Board Mount Pressure Sensors (ABP Series, digital versions only) – marked as zone 4.

 

The area marked as zone 5, is for power selection. Here, the user must use a jumper (shunt) to manually select either 3v3 or 5v as the operating voltage for the shield.

 

If you are unfamiliar with the board, it is worth your while watching this YouTube video from John Lachenmayer (introduces himself as a Honeywell Field Application Engineer). This video provides a nice overview of the Arduino R3 shield and introduces the different sensors that can be attached to the shield. It also demonstrates how to use the shield using an Arduino micro-controller and then focuses on the Honeywell analytical software, which is not applicable in our case.

 

 

 

One thing to note about the shield is that it is designed to allow the user to manually enable any sensor that has been mounted on the board via a jumper (shunt).  The user is then also required to enable and select whether the sensor communicate via I2C or SPI. These are marked as follows:

 

 

Looking at some of the compatible sensors

 

The big surprise I had with the sensors I ordered was how small they all were.

 

 

Let’s look at these sensors in more detail.

 

Honeywell HumidIcon™ Digital Humidity/Temperature Sensor (HIH8000 Series)

 

The Honeywell HumidIcon™ Digital Humidity/Temperature Sensor is a digital output-type relative humidity (RH) and temperature sensor combined in the same package. The sensor provides a ±2.0 %RH accuracy and a ±0.5 °C Temperature accuracy. The temperature sensor has a -40 °C to 125 °C [-40 °F to 257 °F] operating temperature range and the humidity sensor natually operates in the 0% to 100% RH range. The sensor operating voltage is 2.3 Vdc to 5.5 Vdc. The sensor consumes only 1 μA when it goes into sleep mode, following a measurement, versus 650 μA when taking measurements.

 

The user can choose a sensor based on the following options:

  • I2C or SPI bus
  • SIP 4-Pin or SOIC-8 SMD
  • a hydrophobic filter or with no filter

 

The specific sensor I ordered was the HIH8120-021-001 sensor, which operates as an I2C slave (address 0x27 with a 14-bit resolution for both humidity and temperature measurements), it does not have a hydrophobic filter (see photo) and it comes in a SIP 4-pin package.

 

To obtain a measurement from the sensor, you first make a “measurement request”. This is done by simply sending an I2C WRITE command, as illustrated:

 

Image source: Honeywell Technical Note on I2C communication with HumidIcon Sensor

 

The sensor will, according the datasheet, then take 50-60ms from power-up, i.e. when the write request is received, to when data is ready to be read.

 

To read the data, you simply send a READ command and then send an ACK after every byte read and then a NACK and a STOP command to say “that is all, thanks”.

 

Image source: Honeywell Technical Note on I2C communication with HumidIcon Sensor

 

To test the validity of the data received, you then need to read the Status Register (S1 & S0) values. The following conditions can apply:

  • S0 & S1 are both zero (0) then you have “fresh” data.
  • S0 = 0 & S1 = 1, then you have “stale” data. This can mean two things. The first, which happens if you try to read the data immediately after a Measure Request, is that the sensor did not complete its calculation. The second is that you are reading the data again (as in, its “stale” data).
  • S0 = 1 & S1 = 0, then you are in “command mode”. Command mode allows you to configure the sensor, by writing to sensor EEPROM, alarm threshold values etc. You can refer to Honeywell’s Technical Note on how to use Command mode.
  • S0 = 1 & S1 = 1, is not used – regarded as a diagnostic (failure) condition.

 

As shown in the diagrams above, both the humidity and temperature values are stored in 2 bytes each. You are then required to do some bit match to obtain the 14-bit values. Then it is a matter of applying formulae to covert the 14-bit value in %RH and temperature in degrees Celsius. A further conversion is required for a temperature in degrees Fahrenheit.

 

 

Honeywell Basic Amplified Board Mount Pressure Sensor (digital ABP Series)

 

According to the Honeywell datasheet, the ABP Series sensor is “a piezoresistive silicon pressure sensor offering a ratiometric analog or digital output for reading pressure over the specified full scale pressure span and temperature range. They are calibrated and temperature compensated for sensor offset, sensitivity, temperature effects and accuracy errors (which include non-linearity, repeatability and hysteresis) using an on-board Application Specific Integrated Circuit (ASIC). Calibrated output values for pressure are updated at approximately 1 kHz for analog and 2 kHz for digital.”

 

The user can choose an ABP Series sensor based on the following options:

  • Mounting option (DIP, SMT or leadless SMT)
  • Supply Voltage (3V to 6.6V or 4.75V to 5.25V)
  • Analog or Digital output
  • Digital I2C or SPI bus
  • Differential or gauge output
  • Pressure Port type (e.g. no port, single axial barbed,  single axial barbless, single radial barbed, single radial barbless, dual radial barbed, and dual radial barbless)
  • Specific Pressure Range (scope of options found within the 60 mbar to 10 bar, 6 kPa to 1 MPa, and 1 psi to 150 psi ranges)
  • Transfer function (defines the output of the sensor at a given pressure input)
  • Suitability for substance being measured (e.g. non corrosive dry gases only or non-corrosive liquid media - allows use in applications where condensation may occur)

 

The specific sensors I ordered were:

 

1 The  ABPDRRT005PG2A5ABPDRRT005PG2A5 Dual Radial Barbed Gage Differential Pressure Sensor

 

This sensor has the following properties:

  • 5VDC supply voltage
  • Operating current of 3.7mA
  • Digital I2C bus (address 0x28)
  • Maximum pressure range up to 5 psi
  • Silicone gel coating, suitable for liquid media
  • Transfer function provides 214 counts (measurements) with no temperature output enabled, no diagnostics and no sleep mode

 

 

 

2.      The ABPLANT001PG2A5 Single Axial Barbed Gage Pressure Sensor

 

This sensor has the following properties:

  • 5VDC supply voltage
  • Operating current of 3.7mA
  • Digital I2C bus (address 0x28)
  • Maximum pressure range up to 1 psi
  • Silicone gel coating, suitable for liquid media
  • Transfer function provides 214 counts (measurements) with no temperature output enabled, no diagnostics and no sleep mode

 

 

Unlike the HumidIcon Temperature & Humidity sensor, there is no need to first make a “measurement request” using the WRITE command.  To speed things up all you do is send the sensor a READ request and within 3ms (according to the datasheet) you will receive the answer.

 

The format is as follows:

 

Image source: Honeywell Technical Note on I2C communication with Pressure Sensors

 

Similar, to HumidIcon sensors, to test the validity of the data received, you read the Status Register (S1 & S0) values. The same rules apply:

  • S0 & S1 are both zero (0) then you have “fresh” data.
  • S0 = 0 & S1 = 1, then you have “stale” data. This can mean two things. The first, which happens if you try to read the data immediately after a Measure Request, is that the sensor did not complete its calculation. The second is that you are reading the data again (as in, its “stale” data).
  • S0 = 1 & S1 = 0, then you are in “command mode”. Command mode allows you to configure the sensor, by writing to sensor EEPROM etc. You can refer to Honeywell’s Technical Note on how to use Command mode.
  • S0 = 1 & S1 = 1, is not used – regarded as a diagnostic (failure) condition.

 

The pressure sensors I am using do not provide temperature information, so only 2 bytes of data need to be read before a NACK and STOP command is sent by the master controller.

 

Then, referring to the HoneyWell Technical Document (I2C Communication with Honeywell Digital Output Pressure Sensors), the following formula is used to calculate a pressure value:

 

 

Parameter:Description:

Example:

a -1 to 1 psi differential sensor with a 10% to 90% calibration and a pressure output of 1657 (decimal) counts

OutputDigital pressure reading [counts]1657 as give in the example description
Output(max)Output at max. pressure [counts]14745 counts (90% of 214 counts or 0x3999)
Output(min)Output at min. pressure [counts]1638 counts (10% of 214 counts or 0x0666)
Pressure(max)Max value of pressure range [bar, psi, kPa, etc.]1psi
Pressure(min)Min value of pressure range [bar, psi, kPa, etc.]-1psi
PressureThe calculated Pressure Reading [bar, psi, kPa, etc.]Calculated as -0.997psi

 

 

 

Setting out my PSoC 6 project application workflow

 

 

 

For my project application, I have set out 7 key steps to completing the PSoC 6 firmware:

  1. I2C register scanning to detect any slave devices
  2. Calculate the relative humidity and temperature values
  3. eInk Display Function
  4. Capsense Functions
  5. Watchdog timer routine
  6. Calculate Pressure values
  7. BLE data transfer services (time permitting)

 

Step 1 is now complete and this is the basic code hack (code sits in main()) that I came up with to scan for devices and calculate the humidity and temperature values (the formula in the code was taken from an Arduino example found online - I have yet to validate):

 

    const uint8_t ADDR_RANGE[2] = { 0, 127 };


    const uint8_t ADDR_DEVS[3] = {
                                    0x27,           // Honeywell Humidicon sensor
                                    0x28,           // Honeywell Pressure sensor
                                    0x68            // Bosch Sensortec BMI160
                                };
    
    uint8_t I2CAddressReg[3] = {
                                    I2CADDR_NOTFND,
                                    I2CADDR_NOTFND,
                                    I2CADDR_NOTFND
                                };
    
    uint32_t I2C_Status[2];
    uint8_t xx;
    
    uint8_t humidity[2] = {0,0};
    uint8_t temperature[2] = {0,0};
    uint16_t H_dat = 0;
    uint16_t T_dat = 0;
    uint8_t _status;
    
    float RH = 0.0;
    float T_C = 0.0;
    
    // Start SCB's for UART and I2C
    UART_Start();
    I2CM_Start();
    
    
    // Create a zero buffer for the UART
    setvbuf(stdin, NULL, _IONBF, 1);
    
    printf("\r\n");
    CyDelay(1000);
    printf("Starting I2C Register Scan\r\n");
    
    for (xx = ADDR_RANGE[0]; xx <= ADDR_RANGE[1]; xx++) {
    
        /*
        // Old method
        I2C_Status[0] = I2CM_MasterSendStart(xx, I2C_WRITE, 100);
        CyDelay(100);
        I2C_Status[1] = I2CM_MasterSendStop(100);
        */


        I2C_Status[0] = Cy_SCB_I2C_MasterSendStart(I2CM_HW, xx, CY_SCB_I2C_WRITE_XFER, 100, &I2CM_context);
        CyDelay(100);
        I2C_Status[1] = Cy_SCB_I2C_MasterSendStop(I2CM_HW, 100, &I2CM_context);


        if (I2C_Status[0]==CY_SCB_I2C_SUCCESS && I2C_Status[1]==CY_SCB_I2C_SUCCESS) {
            
            if (xx == ADDR_DEVS[0]) {
                printf("I2C Addr: 0x%X (%u) >> Honeywell HumidIcon Sensor Found!\r\n", xx, xx);
                I2CAddressReg[0] = I2CADDR_FOUND;
            }
            else if (xx == ADDR_DEVS[1]) {
                printf("I2C Addr: 0x%X (%u) >> Honeywell Pressure Sensor Found!\r\n", xx, xx);
                I2CAddressReg[1] = I2CADDR_FOUND;
            }
            else if (xx == ADDR_DEVS[2]) {
                printf("I2C Addr: 0x%X (%u) >> Bosch Sensortec BMI160 Found!\r\n", xx, xx);
                I2CAddressReg[2] = I2CADDR_FOUND;
            }
            else printf("I2C Addr: 0x%X (%u) >> Found!\r\n", xx, xx);
            
        }
        
    }
    printf("I2C Scan Completed\r\n");
    printf("===================\r\n");
    
    if (I2CAddressReg[0] == I2CADDR_FOUND) {
        // Now check to see if we can read data -- to do so simply send a Write (0x00) command
        if (Cy_SCB_I2C_MasterSendStart(I2CM_HW, ADDR_DEVS[0], CY_SCB_I2C_WRITE_XFER, 100, &I2CM_context) == CY_SCB_I2C_SUCCESS) {
            // Acknowledge so now send a stop
            if (Cy_SCB_I2C_MasterSendStop(I2CM_HW, 100, &I2CM_context)  == CY_SCB_I2C_SUCCESS) {
                //printf("HumidIcon Data Requested - Let's Not Pause\r\n");
                printf("HumidIcon Data Requested - Pause to wait for calculation\r\n");
                CyDelay(80);
                if (Cy_SCB_I2C_MasterSendStart(I2CM_HW, ADDR_DEVS[0], CY_SCB_I2C_READ_XFER, 500, &I2CM_context) == CY_SCB_I2C_SUCCESS) {
                    printf("Fetch Request of HumidIcon Data Start\r\n");
                    if (Cy_SCB_I2C_MasterReadByte(I2CM_HW, CY_SCB_I2C_ACK, &humidity[0], 100, &I2CM_context) == CY_SCB_I2C_SUCCESS) {
                        if (Cy_SCB_I2C_MasterReadByte(I2CM_HW, CY_SCB_I2C_ACK, &humidity[1], 100, &I2CM_context) == CY_SCB_I2C_SUCCESS) {
                            printf("Humidity Data Fetch Completed\r\n");
                            // Now get the temperature data
                            if (Cy_SCB_I2C_MasterReadByte(I2CM_HW, CY_SCB_I2C_ACK, &temperature[0], 100, &I2CM_context) == CY_SCB_I2C_SUCCESS) {
                                if (Cy_SCB_I2C_MasterReadByte(I2CM_HW, CY_SCB_I2C_NAK, &temperature[1], 100, &I2CM_context) == CY_SCB_I2C_SUCCESS) {
                                    if (Cy_SCB_I2C_MasterSendStop(I2CM_HW, 100, &I2CM_context)  == CY_SCB_I2C_SUCCESS) {
                                        printf("Temperature Data Fetch Completed\r\n");
                                        // Now lets make sense of the data
                                        _status = (humidity[0] >> 6) & 0x03;
                                        switch(_status)
                                        {
                                            case 0:  printf("This is Fresh Data!\r\n");
                                            break;
                                            case 1:  printf("Sorry, Data fetched before completion (or stale data)!\r\n");
                                            break;
                                            case 2:  printf("You're still in command mode!\r\n");
                                            break;
                                            default: printf("Oops. Time for Diagnostics.\r\n"); 
                                            break; 
                                        }
                                        // Convert the 2 bytes of humidity data to 14-bits value
                                        humidity[0] = humidity[0] & 0x3F;
                                        H_dat = ((humidity[0]) << 8) | humidity[1];
                                        RH = (float) H_dat * 6.10e-3;
                                        
                                        // Convert the 2 bytes of temperature data to 14-bits value
                                        T_dat = ((temperature[0]) << 8) | temperature[1];
                                        T_dat = T_dat / 4;
                                        T_C = (float) T_dat * 1.007e-2 - 40.0;
                                        
                                        printf("Your Relative Humidity is: %.1f%%\r\n", RH);
                                        printf("Your Temperature is: %.1f\xB0 C\r\n", T_C);
                                        
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

 

The output from this code is sent to UART for viewing on a Serial Monitor. Here is a short video showing this output, when I have the PSoC 6 EPD Display Shield mounted too:

 

 

 

 

 

So, so far so good...

 

I will update my blog (part 2) once I’ve completed the next steps and hopefully reveal a working medical application.