NXP Rapid IoT Prototyping Kit - Review

Table of contents

RoadTest: NXP Rapid IoT Prototyping Kit

Author: gam3t3ch

Creation date:

Evaluation Type: Development Boards & Tools

Did you receive all parts the manufacturer stated would be included in the package?: True

What other parts do you consider comparable to this product?:

What were the biggest problems encountered?: Calibration of temp sensor (indoor/outdoor) variance. no undo button on web based gui Battery would run out before I could test things.

Detailed Review:

 

 

Where to start with this unit.

First off thank you to Element14 and NXP for putting on this Roadtest.

It is a real love/hate relationship I have started to have with this unit even despite the faults of the unit I have to say I still keep playing with it every chance I get.  For no apparent reason it just keeps calling me.  Try me....Test me... So I do.

So I made a short......under 30 minute video below which goes into some detail on the unit and my experience so far.

 

 

 

 

 

 

 

But wait there is more.  I really didn't get into the software side of it too much on the video....what better way to get people to come check out my roadtest eh?

So like I said I was working on my own design.  Did pretty good at it still playing around with it and probably will even after this because for some strange reason this thing is great to play with. "Play" I don't see myself going further with it maybe some major updates will happen to software or hardware design before I start going out and buying add-ons for the unit.

My main issue being unable to save multiple instances in https://rapid-iot-studio.nxp.com/  which really put me in a grumpy mood at times but I just keep playing with it like a small child a his first computer.  Eventually something has to work.

I re-designed a few times but this is one I will share.

I started with a graphic in mind and what I wanted to have on it designing the template was the first thing then making it work was the second part.

 

 

Now I have my template designed I wanted to see if I could get well most of them working which I managed to get a few of them working correctly and more the attempt before but then I broke it.  Then started again.

 

I decided I would go with Bluetooth this time as I was quite impressed with the distance I was able to acquire with the unit was much better then anything I have found to date so this was the only saving grace.  I have used awesome products and then connectivity is just garbage and I slowly loose interest because there has to be something better.

 

So at first I thought I would piggy back off each sensor and get the readings I wanted from each then playing around I was getting temp in my humidity and didn't matter what I changed it just kept displaying the temp.  so on to plan b lets do 2 intervals and see what happens.

 

So on both the application page and the main page I set two intervals changed all my stuff as much as I could to see if I could get everything working and still nothing.

I was only getting temp, pressure, and tvoc. So I guess its back to the drawing board.  This has been a great learning experience I really hope that they resolve a few of the issues and setup more functionality for the workflow on the web gui as it really makes you want to play but I can certainly see how some could get discouraged quite quickly with it as well.

 

How does it look on my phone? Something like this.

 

 

first one is indoor actual indoor temp is 21oC    right one is external temp with an actual temp of -1oC so as you can see there is still more calibration that is needed.

The time it took for it to go from indoor to outdoor temp I actually had a nap waiting for it to get to 1oC.

 

 

But at this point I must say I learnt a trick as well.  I was able to use the top right button with bottom left the reverse program mode buttons to turn the screen off this was great temps dropped a bit.

But nothing major as the heat was still high from the battery.

 

Here is the code from my https://rapid-iot-studio.nxp.com/  project

 

#include "callbacks.h"

//HEADER START

//HEADER END

void ATMO_Setup() {

}


ATMO_Status_t BLEConnection_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLEConnection_setup(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_BLE_PairingCfg_t pairingCfg;
    pairingCfg.pairingKey = ATMO_PROPERTY(BLEConnection, pairingKey);
    pairingCfg.type = ATMO_PROPERTY(BLEConnection, pairingType);
    ATMO_BLE_GAPPairingCfg(ATMO_PROPERTY(BLEConnection, instance), &pairingCfg);

    ATMO_BLE_RegisterEventAbilityHandle(ATMO_PROPERTY(BLEConnection, instance), ATMO_BLE_EVENT_Connected, ATMO_ABILITY(BLEConnection, connected));
    ATMO_BLE_RegisterEventAbilityHandle(ATMO_PROPERTY(BLEConnection, instance), ATMO_BLE_EVENT_Disconnected, ATMO_ABILITY(BLEConnection, disconnected));
    ATMO_BLE_RegisterEventAbilityHandle(ATMO_PROPERTY(BLEConnection, instance), ATMO_BLE_EVENT_PairingRequested, ATMO_ABILITY(BLEConnection, pairingRequested));
    ATMO_BLE_RegisterEventAbilityHandle(ATMO_PROPERTY(BLEConnection, instance), ATMO_BLE_EVENT_PairingSuccess, ATMO_ABILITY(BLEConnection, pairingSucceeded));
    ATMO_BLE_RegisterEventAbilityHandle(ATMO_PROPERTY(BLEConnection, instance), ATMO_BLE_EVENT_PairingFailed, ATMO_ABILITY(BLEConnection, pairingFailed));
    
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLEConnection_disconnect(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_BLE_GAPDisconnect(ATMO_PROPERTY(BLEConnection, instance));
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLEConnection_connected(ATMO_Value_t *in, ATMO_Value_t *out) {

    return ATMO_Status_Success;
    
}


ATMO_Status_t BLEConnection_disconnected(ATMO_Value_t *in, ATMO_Value_t *out) {

    return ATMO_Status_Success;
    
}


ATMO_Status_t BLEConnection_pairingRequested(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_CreateValueCopy(out, in);
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLEConnection_pairingSucceeded(ATMO_Value_t *in, ATMO_Value_t *out) {

    return ATMO_Status_Success;
    
}


ATMO_Status_t BLEConnection_pairingFailed(ATMO_Value_t *in, ATMO_Value_t *out) {

    return ATMO_Status_Success;
    
}


ATMO_Status_t Interval_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t Interval_setup(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_INTERVAL_Handle_t intervalHandle;
    ATMO_INTERVAL_AddAbilityInterval(
        ATMO_PROPERTY(Interval, instance), 
        ATMO_ABILITY(Interval, interval), 
        ATMO_PROPERTY(Interval, time), 
        &intervalHandle
    );
    
    return ATMO_Status_Success;
    
}


ATMO_Status_t Interval_interval(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t ENS210TemperatureHumidity_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t ENS210TemperatureHumidity_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
    ATMO_ENS210_Config_t config;
    config.address = ATMO_PROPERTY(ENS210TemperatureHumidity, i2cAddress);
    config.i2cDriverInstance = ATMO_PROPERTY(ENS210TemperatureHumidity, i2cInstance);
    config.tempCalibrationOffset = ATMO_PROPERTY(ENS210TemperatureHumidity, tempCalibrationOffset);

    return ( ATMO_ENS210_Init(&config) == ATMO_ENS210_Status_Success ) ? ATMO_Status_Success : ATMO_Status_Fail;

}


ATMO_Status_t ENS210TemperatureHumidity_setEnabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_ENS210_SetEnabled(true);
return ATMO_Status_Success;
}


ATMO_Status_t ENS210TemperatureHumidity_setDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_ENS210_SetEnabled(false);
return ATMO_Status_Success;
}


ATMO_Status_t ENS210TemperatureHumidity_setEnabledDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
bool enabled = false;
ATMO_GetBool(in, &enabled);
ATMO_ENS210_SetEnabled(enabled);
return ATMO_Status_Success;
}


ATMO_Status_t ENS210TemperatureHumidity_readTemperature(ATMO_Value_t *in, ATMO_Value_t *out) {
    float tempC;
    
    if(ATMO_ENS210_GetTemperatureFloat(&tempC) == ATMO_ENS210_Status_Success)
    {
        ATMO_CreateValueFloat(out, tempC);
    }
    else
    {
        ATMO_CreateValueVoid(out);
    }
    
    return ATMO_Status_Success;
}


ATMO_Status_t ENS210TemperatureHumidity_readHumidity(ATMO_Value_t *in, ATMO_Value_t *out) {
    float humidityPct;

    if(ATMO_ENS210_GetHumidityFloat(&humidityPct) == ATMO_ENS210_Status_Success)
    {
        ATMO_CreateValueFloat(out, humidityPct);
    }
    else
    {
        ATMO_CreateValueVoid(out);
    }
    
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom_setup(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_BLE_GATTSAddService(
        ATMO_PROPERTY(BLECharacteristicCustom, instance),
        &ATMO_VARIABLE(BLECharacteristicCustom, bleServiceHandle), 
        ATMO_PROPERTY(BLECharacteristicCustom, bleServiceUuid));
    
    uint8_t property = 0;
    uint8_t permission = 0;
    
    property |= ATMO_PROPERTY(BLECharacteristicCustom, read) ? ATMO_BLE_Property_Read : 0;
    property |= ATMO_PROPERTY(BLECharacteristicCustom, write) ? ATMO_BLE_Property_Write : 0;
    property |= ATMO_PROPERTY(BLECharacteristicCustom, notify) ? ATMO_BLE_Property_Notify : 0;

    permission |= ATMO_PROPERTY(BLECharacteristicCustom, read) ? ATMO_BLE_Permission_Read : 0;
    permission |= ATMO_PROPERTY(BLECharacteristicCustom, write) ? ATMO_BLE_Permission_Write : 0;

    ATMO_DATATYPE types[3] = {ATMO_PROPERTY(BLECharacteristicCustom, writeDataType), ATMO_PROPERTY(BLECharacteristicCustom, readDataType), ATMO_PROPERTY(BLECharacteristicCustom, notifyDataType)};
    
    ATMO_BLE_GATTSAddCharacteristic(
        ATMO_PROPERTY(BLECharacteristicCustom, instance),
        &ATMO_VARIABLE(BLECharacteristicCustom, bleCharacteristicHandle), 
        ATMO_VARIABLE(BLECharacteristicCustom, bleServiceHandle), 
        ATMO_PROPERTY(BLECharacteristicCustom, bleCharacteristicUuid), 
        property, permission, ATMO_GetMaxValueSize(3, 64, types));
    
    ATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(
        ATMO_PROPERTY(BLECharacteristicCustom, instance),
        ATMO_VARIABLE(BLECharacteristicCustom, bleCharacteristicHandle), 
        ATMO_BLE_Characteristic_Written, 
        ATMO_ABILITY(BLECharacteristicCustom, written));
    
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom_setValue(ATMO_Value_t *in, ATMO_Value_t *out) {

    
    // Convert to the desired write data type
    ATMO_Value_t convertedValue;
    ATMO_InitValue(&convertedValue);
    ATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(BLECharacteristicCustom, readDataType), in);

    ATMO_BLE_GATTSSetCharacteristic(
        ATMO_PROPERTY(BLECharacteristicCustom, instance),
        ATMO_VARIABLE(BLECharacteristicCustom, bleCharacteristicHandle),
        convertedValue.size, 
        (uint8_t *)convertedValue.data,
        NULL);
    
    ATMO_FreeValue(&convertedValue);
        
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom_written(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_CreateValueConverted(out, ATMO_PROPERTY(BLECharacteristicCustom, writeDataType), in);
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom_subscibed(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom_unsubscribed(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t ENS210TemperatureHumidity1_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t ENS210TemperatureHumidity1_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
    ATMO_ENS210_Config_t config;
    config.address = ATMO_PROPERTY(ENS210TemperatureHumidity1, i2cAddress);
    config.i2cDriverInstance = ATMO_PROPERTY(ENS210TemperatureHumidity1, i2cInstance);
    config.tempCalibrationOffset = ATMO_PROPERTY(ENS210TemperatureHumidity1, tempCalibrationOffset);

    return ( ATMO_ENS210_Init(&config) == ATMO_ENS210_Status_Success ) ? ATMO_Status_Success : ATMO_Status_Fail;

}


ATMO_Status_t ENS210TemperatureHumidity1_setEnabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_ENS210_SetEnabled(true);
return ATMO_Status_Success;
}


ATMO_Status_t ENS210TemperatureHumidity1_setDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_ENS210_SetEnabled(false);
return ATMO_Status_Success;
}


ATMO_Status_t ENS210TemperatureHumidity1_setEnabledDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
bool enabled = false;
ATMO_GetBool(in, &enabled);
ATMO_ENS210_SetEnabled(enabled);
return ATMO_Status_Success;
}


ATMO_Status_t ENS210TemperatureHumidity1_readTemperature(ATMO_Value_t *in, ATMO_Value_t *out) {
    float tempC;
    
    if(ATMO_ENS210_GetTemperatureFloat(&tempC) == ATMO_ENS210_Status_Success)
    {
        ATMO_CreateValueFloat(out, tempC);
    }
    else
    {
        ATMO_CreateValueVoid(out);
    }
    
    return ATMO_Status_Success;
}


ATMO_Status_t ENS210TemperatureHumidity1_readHumidity(ATMO_Value_t *in, ATMO_Value_t *out) {
    float humidityPct;

    if(ATMO_ENS210_GetHumidityFloat(&humidityPct) == ATMO_ENS210_Status_Success)
    {
        ATMO_CreateValueFloat(out, humidityPct);
    }
    else
    {
        ATMO_CreateValueVoid(out);
    }
    
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom1_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom1_setup(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_BLE_GATTSAddService(
        ATMO_PROPERTY(BLECharacteristicCustom1, instance),
        &ATMO_VARIABLE(BLECharacteristicCustom1, bleServiceHandle), 
        ATMO_PROPERTY(BLECharacteristicCustom1, bleServiceUuid));
    
    uint8_t property = 0;
    uint8_t permission = 0;
    
    property |= ATMO_PROPERTY(BLECharacteristicCustom1, read) ? ATMO_BLE_Property_Read : 0;
    property |= ATMO_PROPERTY(BLECharacteristicCustom1, write) ? ATMO_BLE_Property_Write : 0;
    property |= ATMO_PROPERTY(BLECharacteristicCustom1, notify) ? ATMO_BLE_Property_Notify : 0;

    permission |= ATMO_PROPERTY(BLECharacteristicCustom1, read) ? ATMO_BLE_Permission_Read : 0;
    permission |= ATMO_PROPERTY(BLECharacteristicCustom1, write) ? ATMO_BLE_Permission_Write : 0;

    ATMO_DATATYPE types[3] = {ATMO_PROPERTY(BLECharacteristicCustom1, writeDataType), ATMO_PROPERTY(BLECharacteristicCustom1, readDataType), ATMO_PROPERTY(BLECharacteristicCustom1, notifyDataType)};
    
    ATMO_BLE_GATTSAddCharacteristic(
        ATMO_PROPERTY(BLECharacteristicCustom1, instance),
        &ATMO_VARIABLE(BLECharacteristicCustom1, bleCharacteristicHandle), 
        ATMO_VARIABLE(BLECharacteristicCustom1, bleServiceHandle), 
        ATMO_PROPERTY(BLECharacteristicCustom1, bleCharacteristicUuid), 
        property, permission, ATMO_GetMaxValueSize(3, 64, types));
    
    ATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(
        ATMO_PROPERTY(BLECharacteristicCustom1, instance),
        ATMO_VARIABLE(BLECharacteristicCustom1, bleCharacteristicHandle), 
        ATMO_BLE_Characteristic_Written, 
        ATMO_ABILITY(BLECharacteristicCustom1, written));
    
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom1_setValue(ATMO_Value_t *in, ATMO_Value_t *out) {

    
    // Convert to the desired write data type
    ATMO_Value_t convertedValue;
    ATMO_InitValue(&convertedValue);
    ATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(BLECharacteristicCustom1, readDataType), in);

    ATMO_BLE_GATTSSetCharacteristic(
        ATMO_PROPERTY(BLECharacteristicCustom1, instance),
        ATMO_VARIABLE(BLECharacteristicCustom1, bleCharacteristicHandle),
        convertedValue.size, 
        (uint8_t *)convertedValue.data,
        NULL);
    
    ATMO_FreeValue(&convertedValue);
        
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom1_written(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_CreateValueConverted(out, ATMO_PROPERTY(BLECharacteristicCustom1, writeDataType), in);
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom1_subscibed(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom1_unsubscribed(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
    ATMO_MPL3115_Config_t config;
    config.address = ATMO_PROPERTY(MPL3115Pressure, i2cAddress);
    config.i2cDriverInstance = ATMO_PROPERTY(MPL3115Pressure, i2cInstance);
    config.MPLsettings.mode = MPL_MODE_PRESSURE;
    config.MPLsettings.oversample = MPL_OS_0;            // oversampling = 1
    config.MPLsettings.autoAcquisitionTime = MPL_ST_0;    // Auto acquisition time = 1s
    config.MPLsettings.pressureOffset = ATMO_PROPERTY(MPL3115Pressure, pressureOffset);    // Offset pressure correction = 4*-128 = -512Pa (8 bits signed integer)
    config.MPLsettings.altitudeOffset = ATMO_PROPERTY(MPL3115Pressure, altitudeOffset);    // Offset altitude correction = 128m (signed 8 bits integer)
    config.MPLsettings.tempOffset = ATMO_PROPERTY(MPL3115Pressure, tempOffset);            // Offset temperature correction -8°C (0.0625°C/LSB)
    config.MPLsettings.fifoMode = FIFO_DISABLED;        // FIFO mode disabled
    config.MPLsettings.fifoWatermark = 5;                // 6 bits to set the number of FIFO samples required to trigger a watermark interrupt.
    config.MPLsettings.fifoINTpin = FIFO_INT1;            // set pin INT1 as output for FIFO interrupt

    return ( ATMO_MPL3115_Init(&config) == ATMO_MPL3115_Status_Success ) ? ATMO_Status_Success : ATMO_Status_Fail;

}


ATMO_Status_t MPL3115Pressure_setEnabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_MPL3115_SetEnabled(true);
return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure_setDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_MPL3115_SetEnabled(false);
return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure_setEnabledDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
bool enabled = false;
ATMO_GetBool(in, &enabled);
ATMO_MPL3115_SetEnabled(enabled);
return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure_readAltitude(ATMO_Value_t *in, ATMO_Value_t *out) {
    uint32_t altitudeMeters;
    if(ATMO_MPL3115_GetAltitude(&altitudeMeters) != ATMO_MPL3115_Status_Success)
    {
        ATMO_CreateValueVoid(out);
        return ATMO_Status_Fail;
    }
    ATMO_CreateValueInt(out, (int)altitudeMeters);
    return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure_readPressure(ATMO_Value_t *in, ATMO_Value_t *out) {
    uint32_t pressurePa;
    if(ATMO_MPL3115_GetPressure(&pressurePa) != ATMO_MPL3115_Status_Success)
    {
        ATMO_CreateValueVoid(out);
        return ATMO_Status_Fail;
    }
    ATMO_CreateValueInt(out, (int)pressurePa);
    return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure_readPressureKpa(ATMO_Value_t *in, ATMO_Value_t *out) {
    uint32_t pressurePa;
    if(ATMO_MPL3115_GetPressure(&pressurePa) != ATMO_MPL3115_Status_Success)
    {
        ATMO_CreateValueVoid(out);
        return ATMO_Status_Fail;
    }
    ATMO_CreateValueInt(out, (int)(pressurePa/1000));
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom2_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom2_setup(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_BLE_GATTSAddService(
        ATMO_PROPERTY(BLECharacteristicCustom2, instance),
        &ATMO_VARIABLE(BLECharacteristicCustom2, bleServiceHandle), 
        ATMO_PROPERTY(BLECharacteristicCustom2, bleServiceUuid));
    
    uint8_t property = 0;
    uint8_t permission = 0;
    
    property |= ATMO_PROPERTY(BLECharacteristicCustom2, read) ? ATMO_BLE_Property_Read : 0;
    property |= ATMO_PROPERTY(BLECharacteristicCustom2, write) ? ATMO_BLE_Property_Write : 0;
    property |= ATMO_PROPERTY(BLECharacteristicCustom2, notify) ? ATMO_BLE_Property_Notify : 0;

    permission |= ATMO_PROPERTY(BLECharacteristicCustom2, read) ? ATMO_BLE_Permission_Read : 0;
    permission |= ATMO_PROPERTY(BLECharacteristicCustom2, write) ? ATMO_BLE_Permission_Write : 0;

    ATMO_DATATYPE types[3] = {ATMO_PROPERTY(BLECharacteristicCustom2, writeDataType), ATMO_PROPERTY(BLECharacteristicCustom2, readDataType), ATMO_PROPERTY(BLECharacteristicCustom2, notifyDataType)};
    
    ATMO_BLE_GATTSAddCharacteristic(
        ATMO_PROPERTY(BLECharacteristicCustom2, instance),
        &ATMO_VARIABLE(BLECharacteristicCustom2, bleCharacteristicHandle), 
        ATMO_VARIABLE(BLECharacteristicCustom2, bleServiceHandle), 
        ATMO_PROPERTY(BLECharacteristicCustom2, bleCharacteristicUuid), 
        property, permission, ATMO_GetMaxValueSize(3, 64, types));
    
    ATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(
        ATMO_PROPERTY(BLECharacteristicCustom2, instance),
        ATMO_VARIABLE(BLECharacteristicCustom2, bleCharacteristicHandle), 
        ATMO_BLE_Characteristic_Written, 
        ATMO_ABILITY(BLECharacteristicCustom2, written));
    
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom2_setValue(ATMO_Value_t *in, ATMO_Value_t *out) {

    
    // Convert to the desired write data type
    ATMO_Value_t convertedValue;
    ATMO_InitValue(&convertedValue);
    ATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(BLECharacteristicCustom2, readDataType), in);

    ATMO_BLE_GATTSSetCharacteristic(
        ATMO_PROPERTY(BLECharacteristicCustom2, instance),
        ATMO_VARIABLE(BLECharacteristicCustom2, bleCharacteristicHandle),
        convertedValue.size, 
        (uint8_t *)convertedValue.data,
        NULL);
    
    ATMO_FreeValue(&convertedValue);
        
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom2_written(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_CreateValueConverted(out, ATMO_PROPERTY(BLECharacteristicCustom2, writeDataType), in);
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom2_subscibed(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom2_unsubscribed(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure1_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure1_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
    ATMO_MPL3115_Config_t config;
    config.address = ATMO_PROPERTY(MPL3115Pressure1, i2cAddress);
    config.i2cDriverInstance = ATMO_PROPERTY(MPL3115Pressure1, i2cInstance);
    config.MPLsettings.mode = MPL_MODE_PRESSURE;
    config.MPLsettings.oversample = MPL_OS_0;            // oversampling = 1
    config.MPLsettings.autoAcquisitionTime = MPL_ST_0;    // Auto acquisition time = 1s
    config.MPLsettings.pressureOffset = ATMO_PROPERTY(MPL3115Pressure1, pressureOffset);    // Offset pressure correction = 4*-128 = -512Pa (8 bits signed integer)
    config.MPLsettings.altitudeOffset = ATMO_PROPERTY(MPL3115Pressure1, altitudeOffset);    // Offset altitude correction = 128m (signed 8 bits integer)
    config.MPLsettings.tempOffset = ATMO_PROPERTY(MPL3115Pressure1, tempOffset);            // Offset temperature correction -8°C (0.0625°C/LSB)
    config.MPLsettings.fifoMode = FIFO_DISABLED;        // FIFO mode disabled
    config.MPLsettings.fifoWatermark = 5;                // 6 bits to set the number of FIFO samples required to trigger a watermark interrupt.
    config.MPLsettings.fifoINTpin = FIFO_INT1;            // set pin INT1 as output for FIFO interrupt

    return ( ATMO_MPL3115_Init(&config) == ATMO_MPL3115_Status_Success ) ? ATMO_Status_Success : ATMO_Status_Fail;

}


ATMO_Status_t MPL3115Pressure1_setEnabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_MPL3115_SetEnabled(true);
return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure1_setDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_MPL3115_SetEnabled(false);
return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure1_setEnabledDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
bool enabled = false;
ATMO_GetBool(in, &enabled);
ATMO_MPL3115_SetEnabled(enabled);
return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure1_readAltitude(ATMO_Value_t *in, ATMO_Value_t *out) {
    uint32_t altitudeMeters;
    if(ATMO_MPL3115_GetAltitude(&altitudeMeters) != ATMO_MPL3115_Status_Success)
    {
        ATMO_CreateValueVoid(out);
        return ATMO_Status_Fail;
    }
    ATMO_CreateValueInt(out, (int)altitudeMeters);
    return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure1_readPressure(ATMO_Value_t *in, ATMO_Value_t *out) {
    uint32_t pressurePa;
    if(ATMO_MPL3115_GetPressure(&pressurePa) != ATMO_MPL3115_Status_Success)
    {
        ATMO_CreateValueVoid(out);
        return ATMO_Status_Fail;
    }
    ATMO_CreateValueInt(out, (int)pressurePa);
    return ATMO_Status_Success;
}


ATMO_Status_t MPL3115Pressure1_readPressureKpa(ATMO_Value_t *in, ATMO_Value_t *out) {
    uint32_t pressurePa;
    if(ATMO_MPL3115_GetPressure(&pressurePa) != ATMO_MPL3115_Status_Success)
    {
        ATMO_CreateValueVoid(out);
        return ATMO_Status_Fail;
    }
    ATMO_CreateValueInt(out, (int)(pressurePa/1000));
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom3_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom3_setup(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_BLE_GATTSAddService(
        ATMO_PROPERTY(BLECharacteristicCustom3, instance),
        &ATMO_VARIABLE(BLECharacteristicCustom3, bleServiceHandle), 
        ATMO_PROPERTY(BLECharacteristicCustom3, bleServiceUuid));
    
    uint8_t property = 0;
    uint8_t permission = 0;
    
    property |= ATMO_PROPERTY(BLECharacteristicCustom3, read) ? ATMO_BLE_Property_Read : 0;
    property |= ATMO_PROPERTY(BLECharacteristicCustom3, write) ? ATMO_BLE_Property_Write : 0;
    property |= ATMO_PROPERTY(BLECharacteristicCustom3, notify) ? ATMO_BLE_Property_Notify : 0;

    permission |= ATMO_PROPERTY(BLECharacteristicCustom3, read) ? ATMO_BLE_Permission_Read : 0;
    permission |= ATMO_PROPERTY(BLECharacteristicCustom3, write) ? ATMO_BLE_Permission_Write : 0;

    ATMO_DATATYPE types[3] = {ATMO_PROPERTY(BLECharacteristicCustom3, writeDataType), ATMO_PROPERTY(BLECharacteristicCustom3, readDataType), ATMO_PROPERTY(BLECharacteristicCustom3, notifyDataType)};
    
    ATMO_BLE_GATTSAddCharacteristic(
        ATMO_PROPERTY(BLECharacteristicCustom3, instance),
        &ATMO_VARIABLE(BLECharacteristicCustom3, bleCharacteristicHandle), 
        ATMO_VARIABLE(BLECharacteristicCustom3, bleServiceHandle), 
        ATMO_PROPERTY(BLECharacteristicCustom3, bleCharacteristicUuid), 
        property, permission, ATMO_GetMaxValueSize(3, 64, types));
    
    ATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(
        ATMO_PROPERTY(BLECharacteristicCustom3, instance),
        ATMO_VARIABLE(BLECharacteristicCustom3, bleCharacteristicHandle), 
        ATMO_BLE_Characteristic_Written, 
        ATMO_ABILITY(BLECharacteristicCustom3, written));
    
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom3_setValue(ATMO_Value_t *in, ATMO_Value_t *out) {

    
    // Convert to the desired write data type
    ATMO_Value_t convertedValue;
    ATMO_InitValue(&convertedValue);
    ATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(BLECharacteristicCustom3, readDataType), in);

    ATMO_BLE_GATTSSetCharacteristic(
        ATMO_PROPERTY(BLECharacteristicCustom3, instance),
        ATMO_VARIABLE(BLECharacteristicCustom3, bleCharacteristicHandle),
        convertedValue.size, 
        (uint8_t *)convertedValue.data,
        NULL);
    
    ATMO_FreeValue(&convertedValue);
        
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom3_written(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_CreateValueConverted(out, ATMO_PROPERTY(BLECharacteristicCustom3, writeDataType), in);
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom3_subscibed(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom3_unsubscribed(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t CCS811AirQuality_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t CCS811AirQuality_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
    ATMO_CCS811_Config_t config;
    config.operatingMode = ATMO_PROPERTY(CCS811AirQuality, operatingMode);
    config.address = ATMO_PROPERTY(CCS811AirQuality, i2cAddress);
    config.i2cDriverInstance = ATMO_PROPERTY(CCS811AirQuality, i2cInstance);

    return ( ATMO_CCS811_Init(&config) == ATMO_CCS811_Status_Success ) ? ATMO_Status_Success : ATMO_Status_Fail;

}


ATMO_Status_t CCS811AirQuality_setEnabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_CCS811_SetEnabled(true);
return ATMO_Status_Success;
}


ATMO_Status_t CCS811AirQuality_setDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_CCS811_SetEnabled(false);
return ATMO_Status_Success;
}


ATMO_Status_t CCS811AirQuality_setEnabledDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
bool enabled = false;
ATMO_GetBool(in, &enabled);
ATMO_CCS811_SetEnabled(enabled);
return ATMO_Status_Success;
}


ATMO_Status_t CCS811AirQuality_readTVOC(ATMO_Value_t *in, ATMO_Value_t *out) {
    uint16_t tvoc;

    if(ATMO_CCS811_GetTVOC(&tvoc) == ATMO_CCS811_Status_Success)
    {
        ATMO_CreateValueUnsignedInt(out, (unsigned int)tvoc);
    }
    else
    {
        ATMO_CreateValueVoid(out);
    }
    
    return ATMO_Status_Success;
}


ATMO_Status_t CCS811AirQuality_readCO2(ATMO_Value_t *in, ATMO_Value_t *out) {
    uint16_t co2;
    
    if(ATMO_CCS811_GetCO2(&co2) == ATMO_CCS811_Status_Success)
    {
        ATMO_CreateValueInt(out, (int)co2);
    }
    else
    {
        ATMO_CreateValueVoid(out);
    }
  
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom4_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom4_setup(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_BLE_GATTSAddService(
        ATMO_PROPERTY(BLECharacteristicCustom4, instance),
        &ATMO_VARIABLE(BLECharacteristicCustom4, bleServiceHandle), 
        ATMO_PROPERTY(BLECharacteristicCustom4, bleServiceUuid));
    
    uint8_t property = 0;
    uint8_t permission = 0;
    
    property |= ATMO_PROPERTY(BLECharacteristicCustom4, read) ? ATMO_BLE_Property_Read : 0;
    property |= ATMO_PROPERTY(BLECharacteristicCustom4, write) ? ATMO_BLE_Property_Write : 0;
    property |= ATMO_PROPERTY(BLECharacteristicCustom4, notify) ? ATMO_BLE_Property_Notify : 0;

    permission |= ATMO_PROPERTY(BLECharacteristicCustom4, read) ? ATMO_BLE_Permission_Read : 0;
    permission |= ATMO_PROPERTY(BLECharacteristicCustom4, write) ? ATMO_BLE_Permission_Write : 0;

    ATMO_DATATYPE types[3] = {ATMO_PROPERTY(BLECharacteristicCustom4, writeDataType), ATMO_PROPERTY(BLECharacteristicCustom4, readDataType), ATMO_PROPERTY(BLECharacteristicCustom4, notifyDataType)};
    
    ATMO_BLE_GATTSAddCharacteristic(
        ATMO_PROPERTY(BLECharacteristicCustom4, instance),
        &ATMO_VARIABLE(BLECharacteristicCustom4, bleCharacteristicHandle), 
        ATMO_VARIABLE(BLECharacteristicCustom4, bleServiceHandle), 
        ATMO_PROPERTY(BLECharacteristicCustom4, bleCharacteristicUuid), 
        property, permission, ATMO_GetMaxValueSize(3, 64, types));
    
    ATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(
        ATMO_PROPERTY(BLECharacteristicCustom4, instance),
        ATMO_VARIABLE(BLECharacteristicCustom4, bleCharacteristicHandle), 
        ATMO_BLE_Characteristic_Written, 
        ATMO_ABILITY(BLECharacteristicCustom4, written));
    
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom4_setValue(ATMO_Value_t *in, ATMO_Value_t *out) {

    
    // Convert to the desired write data type
    ATMO_Value_t convertedValue;
    ATMO_InitValue(&convertedValue);
    ATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(BLECharacteristicCustom4, readDataType), in);

    ATMO_BLE_GATTSSetCharacteristic(
        ATMO_PROPERTY(BLECharacteristicCustom4, instance),
        ATMO_VARIABLE(BLECharacteristicCustom4, bleCharacteristicHandle),
        convertedValue.size, 
        (uint8_t *)convertedValue.data,
        NULL);
    
    ATMO_FreeValue(&convertedValue);
        
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom4_written(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_CreateValueConverted(out, ATMO_PROPERTY(BLECharacteristicCustom4, writeDataType), in);
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom4_subscibed(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom4_unsubscribed(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t CCS811AirQuality1_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t CCS811AirQuality1_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
    ATMO_CCS811_Config_t config;
    config.operatingMode = ATMO_PROPERTY(CCS811AirQuality1, operatingMode);
    config.address = ATMO_PROPERTY(CCS811AirQuality1, i2cAddress);
    config.i2cDriverInstance = ATMO_PROPERTY(CCS811AirQuality1, i2cInstance);

    return ( ATMO_CCS811_Init(&config) == ATMO_CCS811_Status_Success ) ? ATMO_Status_Success : ATMO_Status_Fail;

}


ATMO_Status_t CCS811AirQuality1_setEnabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_CCS811_SetEnabled(true);
return ATMO_Status_Success;
}


ATMO_Status_t CCS811AirQuality1_setDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_CCS811_SetEnabled(false);
return ATMO_Status_Success;
}


ATMO_Status_t CCS811AirQuality1_setEnabledDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
bool enabled = false;
ATMO_GetBool(in, &enabled);
ATMO_CCS811_SetEnabled(enabled);
return ATMO_Status_Success;
}


ATMO_Status_t CCS811AirQuality1_readTVOC(ATMO_Value_t *in, ATMO_Value_t *out) {
    uint16_t tvoc;

    if(ATMO_CCS811_GetTVOC(&tvoc) == ATMO_CCS811_Status_Success)
    {
        ATMO_CreateValueUnsignedInt(out, (unsigned int)tvoc);
    }
    else
    {
        ATMO_CreateValueVoid(out);
    }
    
    return ATMO_Status_Success;
}


ATMO_Status_t CCS811AirQuality1_readCO2(ATMO_Value_t *in, ATMO_Value_t *out) {
    uint16_t co2;
    
    if(ATMO_CCS811_GetCO2(&co2) == ATMO_CCS811_Status_Success)
    {
        ATMO_CreateValueInt(out, (int)co2);
    }
    else
    {
        ATMO_CreateValueVoid(out);
    }
  
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom5_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom5_setup(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_BLE_GATTSAddService(
        ATMO_PROPERTY(BLECharacteristicCustom5, instance),
        &ATMO_VARIABLE(BLECharacteristicCustom5, bleServiceHandle), 
        ATMO_PROPERTY(BLECharacteristicCustom5, bleServiceUuid));
    
    uint8_t property = 0;
    uint8_t permission = 0;
    
    property |= ATMO_PROPERTY(BLECharacteristicCustom5, read) ? ATMO_BLE_Property_Read : 0;
    property |= ATMO_PROPERTY(BLECharacteristicCustom5, write) ? ATMO_BLE_Property_Write : 0;
    property |= ATMO_PROPERTY(BLECharacteristicCustom5, notify) ? ATMO_BLE_Property_Notify : 0;

    permission |= ATMO_PROPERTY(BLECharacteristicCustom5, read) ? ATMO_BLE_Permission_Read : 0;
    permission |= ATMO_PROPERTY(BLECharacteristicCustom5, write) ? ATMO_BLE_Permission_Write : 0;

    ATMO_DATATYPE types[3] = {ATMO_PROPERTY(BLECharacteristicCustom5, writeDataType), ATMO_PROPERTY(BLECharacteristicCustom5, readDataType), ATMO_PROPERTY(BLECharacteristicCustom5, notifyDataType)};
    
    ATMO_BLE_GATTSAddCharacteristic(
        ATMO_PROPERTY(BLECharacteristicCustom5, instance),
        &ATMO_VARIABLE(BLECharacteristicCustom5, bleCharacteristicHandle), 
        ATMO_VARIABLE(BLECharacteristicCustom5, bleServiceHandle), 
        ATMO_PROPERTY(BLECharacteristicCustom5, bleCharacteristicUuid), 
        property, permission, ATMO_GetMaxValueSize(3, 64, types));
    
    ATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(
        ATMO_PROPERTY(BLECharacteristicCustom5, instance),
        ATMO_VARIABLE(BLECharacteristicCustom5, bleCharacteristicHandle), 
        ATMO_BLE_Characteristic_Written, 
        ATMO_ABILITY(BLECharacteristicCustom5, written));
    
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom5_setValue(ATMO_Value_t *in, ATMO_Value_t *out) {

    
    // Convert to the desired write data type
    ATMO_Value_t convertedValue;
    ATMO_InitValue(&convertedValue);
    ATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(BLECharacteristicCustom5, readDataType), in);

    ATMO_BLE_GATTSSetCharacteristic(
        ATMO_PROPERTY(BLECharacteristicCustom5, instance),
        ATMO_VARIABLE(BLECharacteristicCustom5, bleCharacteristicHandle),
        convertedValue.size, 
        (uint8_t *)convertedValue.data,
        NULL);
    
    ATMO_FreeValue(&convertedValue);
        
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom5_written(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_CreateValueConverted(out, ATMO_PROPERTY(BLECharacteristicCustom5, writeDataType), in);
    return ATMO_Status_Success;
    
}


ATMO_Status_t BLECharacteristicCustom5_subscibed(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t BLECharacteristicCustom5_unsubscribed(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t Interval2_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}


ATMO_Status_t Interval2_setup(ATMO_Value_t *in, ATMO_Value_t *out) {

    ATMO_INTERVAL_Handle_t intervalHandle;
    ATMO_INTERVAL_AddAbilityInterval(
        ATMO_PROPERTY(Interval2, instance), 
        ATMO_ABILITY(Interval2, interval), 
        ATMO_PROPERTY(Interval2, time), 
        &intervalHandle
    );
    
    return ATMO_Status_Success;
    
}


ATMO_Status_t Interval2_interval(ATMO_Value_t *in, ATMO_Value_t *out) {
    return ATMO_Status_Success;
}

//FOOTER START

//FOOTER END

So as far as verdict on this unit.

 

Even with all the issues with it the battery and the sensor calibration its a pretty fun unit.  I really enjoyed playing with it and learning the online gui.  I certainly will continue to play with it but that's about it.

Would I recommend it to others? Well sure if they are learning and are aware of some of the issues they face in the process.

 

Focusing on the use of https://rapid-iot-studio.nxp.com/  was my main concern as its what they promote the most with it and should be the one where there is no issues.  I think down the road tho I will have

to give MCUXpresso IDE a go with it.  But for this roadtest it was about the quickest and easiest setup possible to get going and programming something on this unit.

 

So thanks for checking out my roadtest hope you all enjoyed it.

Anonymous