Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
suhail jr
Published © CC BY

OXGROW: Smart Aquaponics System

It's an integrated cultivation of fish and plants. Co-operating a living ecosystem to help each other to grow based on NXP Rapid IoT.

AdvancedFull instructions provided20 hours1,512

Things used in this project

Hardware components

Raspberry Pi 3 Model B
Raspberry Pi 3 Model B
×1
DC motor (generic)
×1
5 mm LED: Red
5 mm LED: Red
×1
Power MOSFET N-Channel
Power MOSFET N-Channel
×1
Grove - OLED Display 1.12'' V2
Seeed Studio Grove - OLED Display 1.12'' V2
×1

Hand tools and fabrication machines

CNC Machine
Laser cutter (generic)
Laser cutter (generic)

Story

Read more

Schematics

Architecture

data flow diagram

Code

NXP_Main.c

C/C++
#include "callbacks.h"

//HEADER START

//HEADER END

void ATMO_Setup() {

}


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


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

    Backlight_SetLevel(ATMO_PROPERTY(Backlight, initialSetting));
	return ATMO_Status_Success;
	
}


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

    Backlight_SetLevel(BLIGHT_LEVEL_OFF);
	return ATMO_Status_Success;
    
}


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

    Backlight_SetLevel(BLIGHT_LEVEL_LOW);
	return ATMO_Status_Success;
	
}


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

    Backlight_SetLevel(BLIGHT_LEVEL_MEDIUM);
	return ATMO_Status_Success;
    
}


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

    Backlight_SetLevel(BLIGHT_LEVEL_HIGH);
	return ATMO_Status_Success;
	
}


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


ATMO_Status_t Light_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
	ATMO_TSL2572_Config_t config;
	config.address = ATMO_PROPERTY(Light, i2cAddress);
	config.i2cDriverInstance = ATMO_PROPERTY(Light, i2cInstance);

	return ( ATMO_TSL2572_Init(&config) == ATMO_TSL2572_Status_Success ) ? ATMO_Status_Success : ATMO_Status_Fail;

}


ATMO_Status_t Light_setEnabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_TSL2572_SetEnabled(true);
return ATMO_Status_Success;
}


ATMO_Status_t Light_setDisabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_TSL2572_SetEnabled(false);
return ATMO_Status_Success;
}


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


ATMO_Status_t Light_readAmbientLight(ATMO_Value_t *in, ATMO_Value_t *out) {
    float lightLux;
    if(ATMO_TSL2572_GetAmbientLight(&lightLux) != ATMO_TSL2572_Status_Success)
    {
        ATMO_CreateValueVoid(out);
        return ATMO_Status_Fail;
    }
    ATMO_CreateValueInt(out, (int)lightLux);
    return ATMO_Status_Success;
}


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


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

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

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

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


ATMO_Status_t BLE_Light_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(BLE_Light, readDataType), in);

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


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

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


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


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


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


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

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


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


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


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

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

}


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


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


ATMO_Status_t CO2_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 CO2_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 CO2_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 BLE_CO2_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
	return ATMO_Status_Success;
}


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

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

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

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


ATMO_Status_t BLE_CO2_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(BLE_CO2, readDataType), in);

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


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

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


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


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


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


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

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

}


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


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


ATMO_Status_t TVOC_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 TVOC_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 TVOC_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 BLE_TVOC_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
	return ATMO_Status_Success;
}


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

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

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

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


ATMO_Status_t BLE_TVOC_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(BLE_TVOC, readDataType), in);

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


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

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


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


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


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


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

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

}


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


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


ATMO_Status_t Temperature_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 Temperature_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 Temperature_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 Humidity_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
	return ATMO_Status_Success;
}


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

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

}


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


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


ATMO_Status_t Humidity_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 Humidity_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 Humidity_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 Pressure_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
	return ATMO_Status_Success;
}


ATMO_Status_t Pressure_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
	ATMO_MPL3115_Config_t config;
	config.address = ATMO_PROPERTY(Pressure, i2cAddress);
	config.i2cDriverInstance = ATMO_PROPERTY(Pressure, 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(Pressure, pressureOffset);	// Offset pressure correction = 4*-128 = -512Pa (8 bits signed integer)
	config.MPLsettings.altitudeOffset = ATMO_PROPERTY(Pressure, altitudeOffset);	// Offset altitude correction = 128m (signed 8 bits integer)
	config.MPLsettings.tempOffset = ATMO_PROPERTY(Pressure, 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 Pressure_setEnabled(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_MPL3115_SetEnabled(true);
return ATMO_Status_Success;
}


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


ATMO_Status_t Pressure_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 Pressure_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 Pressure_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 Pressure_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 BLE_Pressure_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
	return ATMO_Status_Success;
}


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

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

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

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


ATMO_Status_t BLE_Pressure_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(BLE_Pressure, readDataType), in);

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


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

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


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


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


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


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

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

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

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


ATMO_Status_t BLE_Temperature_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(BLE_Temperature, readDataType), in);

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


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

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


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


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


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


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

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

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

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


ATMO_Status_t BLE_Humidity_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(BLE_Humidity, readDataType), in);

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


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

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


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


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


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


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

	ATMO_UI_Page_DisplayPageByCoord(ATMO_PROPERTY(OXGROW, x), ATMO_PROPERTY(OXGROW, y), false);
	return ATMO_Status_Success;
	
}


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

	return ATMO_Status_Success;
    
}


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

	return ATMO_Status_Success;
	
}


ATMO_Status_t OXGROW_bottomRightButtonPressed(ATMO_Value_t *in, ATMO_Value_t *out) {
...

This file has been truncated, please download it to see its full contents.

NXP_main.bin

BatchFile
No preview (download only).

NXP_main.zip

C/C++
Full Source File
No preview (download only).

BLEtoMQTT.py

Python
Python script that will receve BLE data from NXP and send them to cloud via MQTT
import time
import pygatt
import paho.mqtt.publish as publish
from time import sleep

RPK_ADDRESS = "MAC ID"

MQTT_SERVER = "localhost"

CHAR_UUIDS = {
    "ambient-light" : "2262d1c7-5e0f-447d-bccf-6455c7a901bf",
    "pressure" : "2262d1c7-5e0f-447d-bccf-6455c7a901c2",
    "tvoc" : "2262d1c7-5e0f-447d-bccf-6455c7a901c1",
    "co2" : "2262d1c7-5e0f-447d-bccf-6455c7a901c0",
    "temperature" : "2262d1c7-5e0f-447d-bccf-6455c7a901c3",
    "humidity" : "2262d1c7-5e0f-447d-bccf-6455c7a901c4"
}

adapter = pygatt.GATTToolBackend()

def readData():


    adapter = pygatt.GATTToolBackend()

    try:
        # Connect to the RPK device
        adapter.start()
        conn = adapter.connect(RPK_ADDRESS)

        time_info = int(time.time()*1000000000.0)

        # Get sensor values
        sensor_values = {}
        for sensor in CHAR_UUIDS:
            value = conn.char_read(CHAR_UUIDS[sensor])
            sensor_values[sensor] = float(value.decode("utf-8").rstrip('\x00'))

        light = sensor_values["ambient-light"]
        pressure = sensor_values["pressure"]
        tvoc = sensor_values["tvoc"]
        co2 = sensor_values["co2"]
        temperature = sensor_values["temperature"]
        humidity = sensor_values["humidity"]

    #Print Sensor data 
        print(light)
        print(pressure)
        print(tvoc)
        print(co2)
        print(temperature)
        print(humidity)
    
    #Publish Sensor data 
        publish.single("light",light, hostname=MQTT_SERVER)
        publish.single("pressure",pressure, hostname=MQTT_SERVER)
        publish.single("tvoc", tvoc , hostname=MQTT_SERVER)
        publish.single("co2", co2 , hostname=MQTT_SERVER)
        publish.single("temperature", temperature, hostname=MQTT_SERVER)
        publish.single("humidity", humidity, hostname=MQTT_SERVER)



    except Exception as e:
        print ("Error: ", e)

    finally:
        adapter.stop()



while True: # Run forever
 readData()
 sleep(10)

nodred_flow.json

JSON
[{"id":"ff01a7f3.56cb68","type":"tab","label":"NXP IOT KIT","disabled":false,"info":""},{"id":"d308322d.3289b","type":"mqtt in","z":"ff01a7f3.56cb68","name":"Light","topic":"light","qos":"2","broker":"5b093380.b880ac","x":156,"y":86,"wires":[["6ecef283.37b88c"]]},{"id":"6ecef283.37b88c","type":"ui_gauge","z":"ff01a7f3.56cb68","name":"Light","group":"e7514166.5fc65","order":6,"width":0,"height":0,"gtype":"gage","title":"Light","label":"lux","format":"{{value}}","min":0,"max":"2500","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":433,"y":80,"wires":[]},{"id":"fc213c5f.44924","type":"mqtt in","z":"ff01a7f3.56cb68","name":"Air Quality","topic":"tvoc","qos":"2","broker":"5b093380.b880ac","x":168,"y":172,"wires":[["c5da88b2.54ba88"]]},{"id":"c5da88b2.54ba88","type":"ui_gauge","z":"ff01a7f3.56cb68","name":"Air Quality","group":"dbac2967.6a21f8","order":1,"width":0,"height":0,"gtype":"compass","title":"Air Quality","label":"ppm","format":"{{value}}","min":0,"max":"50","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":442,"y":153,"wires":[]},{"id":"8991d818.804378","type":"mqtt in","z":"ff01a7f3.56cb68","name":"CO2","topic":"co2","qos":"2","broker":"5b093380.b880ac","x":160,"y":237,"wires":[["8ae81fea.31bbf"]]},{"id":"34a44d4e.5320f2","type":"mqtt in","z":"ff01a7f3.56cb68","name":"Pressure","topic":"pressure","qos":"2","broker":"5b093380.b880ac","x":181,"y":306,"wires":[["8283b692.7a15e8"]]},{"id":"c5b9faf1.52a868","type":"mqtt in","z":"ff01a7f3.56cb68","name":"Temperature","topic":"temperature","qos":"2","broker":"5b093380.b880ac","x":197,"y":371,"wires":[["ad51ae16.1fb2b"]]},{"id":"ad51ae16.1fb2b","type":"ui_chart","z":"ff01a7f3.56cb68","name":"Temperature","group":"685cbe20.4604","order":4,"width":0,"height":0,"label":"Temperature","chartType":"line","legend":"false","xformat":"HH:mm","interpolate":"linear","nodata":"","dot":true,"ymin":"0","ymax":"50","removeOlder":"1","removeOlderPoints":"","removeOlderUnit":"86400","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":489,"y":383,"wires":[[],[]]},{"id":"8ae81fea.31bbf","type":"ui_gauge","z":"ff01a7f3.56cb68","name":"CO2","group":"98bd2aec.a0c098","order":3,"width":0,"height":0,"gtype":"compass","title":"CO2","label":"ppm","format":"{{value}}","min":0,"max":"50","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":458,"y":217,"wires":[]},{"id":"8283b692.7a15e8","type":"ui_gauge","z":"ff01a7f3.56cb68","name":"","group":"66e460be.93b9d","order":5,"width":0,"height":0,"gtype":"gage","title":"Pressure","label":"pa","format":"{{value}}","min":0,"max":"300000","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":466,"y":297,"wires":[]},{"id":"5b093380.b880ac","type":"mqtt-broker","z":"","name":"Local","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"e7514166.5fc65","type":"ui_group","z":"","name":"light","tab":"ff785306.eaaf","order":4,"disp":true,"width":"6","collapse":false},{"id":"dbac2967.6a21f8","type":"ui_group","z":"","name":"TVOC","tab":"ff785306.eaaf","order":1,"disp":true,"width":"6","collapse":true},{"id":"685cbe20.4604","type":"ui_group","z":"","name":"Temp","tab":"ff785306.eaaf","order":5,"disp":true,"width":"27","collapse":false},{"id":"98bd2aec.a0c098","type":"ui_group","z":"","name":"CO2","tab":"ff785306.eaaf","order":2,"disp":true,"width":"6","collapse":false},{"id":"66e460be.93b9d","type":"ui_group","z":"","name":"Pressure","tab":"ff785306.eaaf","order":3,"disp":true,"width":"6","collapse":false},{"id":"ff785306.eaaf","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

Credits

suhail jr

suhail jr

8 projects • 75 followers
Maker and electronics enthusiast

Comments