Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
|
I have no idea where my cat went during the day and I want to know. So I build a smart collar for cat using the NXP IoT Prototyping Kit. I used the built-in 9 axis IMU (inertial measurement unit) to keep track of the acceleration, orientation and magnetic field of my cat. Then download the raw data points and process them with Kalman filter to get a simple map of x, y positions.
The NXP Rapid IOT Prototyping Kit comes with a development environment NXP Rapid IOT Studio. It is a very easy to use GUI based development tool that I can quickly put together the firmware running on the IOT Prototyping kit, the companion Smartphone application that act as the controller to the IOT kit and the cloud database that stores the data without writing a single line of code.
Figure 1 is the block diagram of the IoT firmware. It has a timer to sample the 9-axis data and stream it to a cell phone via bluetooth connection. It also specified the buttons and page display on the tiny screen on the IoT kit.
Figure 2 is the block diagram of the smart hone app. It has a static page allow me to turn on or off the 9-axis sampling. Display the orientation of the gryoscope to help me debug the IoT firmware. The smartphone app collects the sampled data and send it to the cloud.
Figure 3 is block diagram of the cloud that stores the data. It is pretty simple.
Figure 4 shows the 9-Axis data points collect in the cloud. Now I can download the csv file and post-process it in Python
No schematics
NXP Rapid IOT Studio Project
JSON{
"name": "Smart Cat Collar",
"createVersion": "2017-08-12",
"description": "New Project",
"lastModified": "2019-01-31T16:19:34.391Z",
"created": "2019-01-31T16:19:34.391Z",
"meta": {
"projectTypeName": "NXP Rapid IoT",
"projectTypeId": "NxpRpk"
},
"planes": {
"NXP Rapid IoT": {
"type": "mcuxpresso",
"compilerVersion": "latest",
"variants": [
"NxpRpk"
],
"meta": {},
"elements": [
{
"name": "EmbeddedPageController",
"type": "EmbeddedPageController",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables",
"rpk"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": "\n\tATMO_UI_PAGE_CONTROLLER_Config_t config;\n\tconfig.enableUpDownNavLabels = ATMO_PROPERTY(EmbeddedPageController, upDownNavigationLabelsEnabled);\n\tconfig.enableLeftRightNavLabels = ATMO_PROPERTY(EmbeddedPageController, leftRightNavigationLabelsEnabled);\n\tATMO_UI_Page_SetConfiguration(&config);\n return ATMO_Status_Success;\n\t",
"displayRootPage": "\n\t\n\tATMO_UI_Page_DisplayRootPage();\n\treturn ATMO_Status_Success;\n\t",
"navigateUp": "\n\tATMO_UI_Page_ProcessNavButton(ATMO_UI_PAGE_NAV_UP);\n\treturn ATMO_Status_Success;\n\t",
"navigateDown": "\n\tATMO_UI_Page_ProcessNavButton(ATMO_UI_PAGE_NAV_DOWN);\n\treturn ATMO_Status_Success;\n\t",
"navigateLeft": "\n\tATMO_UI_Page_ProcessNavButton(ATMO_UI_PAGE_NAV_LEFT);\n\treturn ATMO_Status_Success;\n\t",
"navigateRight": "\n\tATMO_UI_Page_ProcessNavButton(ATMO_UI_PAGE_NAV_RIGHT);\n\treturn ATMO_Status_Success;\n\t",
"processTopRightButton": "\n\tATMO_UI_Page_ProcessUserButton(1);\n\treturn ATMO_Status_Success;\n\t",
"processBottomRightButton": "\n\tATMO_UI_Page_ProcessUserButton(2);\n\treturn ATMO_Status_Success;\n\t",
"processTopLeftButton": "\n\tATMO_UI_Page_ProcessUserButton(3);\n\treturn ATMO_Status_Success;\n\t",
"processBottomLeftButton": "\n\tATMO_UI_Page_ProcessUserButton(4);\n\treturn ATMO_Status_Success;\n\t"
},
"variables": {},
"embeddedPropertyConversions": {},
"codeUserChanged": {
"setup": false,
"displayRootPage": false,
"navigateUp": false,
"navigateDown": false,
"navigateLeft": false,
"navigateRight": false,
"processTopRightButton": false,
"processBottomRightButton": false,
"processTopLeftButton": false,
"processBottomLeftButton": false
},
"upDownNavigationLabelsEnabled": true,
"leftRightNavigationLabelsEnabled": true
},
"meta": {
"editorX": 202,
"editorY": 41,
"lastTrigger": "triggered"
},
"triggers": {
"triggered": [],
"navigateUp": [],
"navigateDown": [],
"navigateLeft": [],
"navigateRight": [],
"processTopRightButton": [],
"processBottomRightButton": [],
"processTopLeftButton": [],
"processBottomLeftButton": []
},
"interruptAbilities": {
"trigger": false,
"setup": false,
"displayRootPage": false,
"navigateUp": false,
"navigateDown": false,
"navigateLeft": false,
"navigateRight": false,
"processTopRightButton": false,
"processBottomRightButton": false,
"processTopLeftButton": false,
"processBottomLeftButton": false
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "displayRootPage",
"triggers": []
},
{
"name": "navigateUp",
"triggers": [
"navigateUp"
]
},
{
"name": "navigateDown",
"triggers": [
"navigateDown"
]
},
{
"name": "navigateLeft",
"triggers": [
"navigateLeft"
]
},
{
"name": "navigateRight",
"triggers": [
"navigateRight"
]
},
{
"name": "processTopRightButton",
"triggers": [
"processTopRightButton"
]
},
{
"name": "processBottomRightButton",
"triggers": [
"processBottomRightButton"
]
},
{
"name": "processTopLeftButton",
"triggers": [
"processTopLeftButton"
]
},
{
"name": "processBottomLeftButton",
"triggers": [
"processBottomLeftButton"
]
}
]
},
{
"name": "SX9500Touch",
"type": "EmbeddedSX9500",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": "\tATMO_SX9500_Config_t config;\n\tconfig.address = ATMO_PROPERTY(SX9500Touch, i2cAddress);\n\tconfig.i2cDriverInstance = ATMO_PROPERTY(SX9500Touch, i2cInstance);\n\tconfig.gpioDriverInstance = ATMO_PROPERTY(SX9500Touch, gpioInstance);\n\tconfig.interruptEnabled = ATMO_PROPERTY(SX9500Touch, interruptEnabled);\n\tconfig.interruptPin = ATMO_PROPERTY(SX9500Touch, interruptGpio);\n\tATMO_SX9500_Init(&config);\n\tATMO_SX9500_RegisterTouchedAbilityHandle(SX9500_Touched_Up, ATMO_ABILITY(SX9500Touch, pressUp));\n\tATMO_SX9500_RegisterTouchedAbilityHandle(SX9500_Touched_Down, ATMO_ABILITY(SX9500Touch, pressDown));\n\tATMO_SX9500_RegisterTouchedAbilityHandle(SX9500_Touched_Left, ATMO_ABILITY(SX9500Touch, pressLeft));\n\tATMO_SX9500_RegisterTouchedAbilityHandle(SX9500_Touched_Right, ATMO_ABILITY(SX9500Touch, pressRight));\n\treturn ATMO_Status_Success;",
"getTouchData": "",
"pressUp": "SX9500_TouchState_t touchState;\nATMO_GetBinary(in, &touchState, sizeof(touchState));\nATMO_CreateValueBinary(out, &touchState, sizeof(touchState));\nreturn ATMO_Status_Success;",
"pressDown": "SX9500_TouchState_t touchState;\nATMO_GetBinary(in, &touchState, sizeof(touchState));\nATMO_CreateValueBinary(out, &touchState, sizeof(touchState));\nreturn ATMO_Status_Success;",
"pressLeft": "SX9500_TouchState_t touchState;\nATMO_GetBinary(in, &touchState, sizeof(touchState));\nATMO_CreateValueBinary(out, &touchState, sizeof(touchState));\nreturn ATMO_Status_Success;",
"pressRight": "SX9500_TouchState_t touchState;\nATMO_GetBinary(in, &touchState, sizeof(touchState));\nATMO_CreateValueBinary(out, &touchState, sizeof(touchState));\nreturn ATMO_Status_Success;"
},
"variables": {},
"embeddedPropertyConversions": {},
"codeUserChanged": {
"setup": false,
"getTouchData": false,
"pressUp": false,
"pressDown": false,
"pressLeft": false,
"pressRight": false
},
"i2cInstance": "ATMO_DRIVERINSTANCE_I2C_I2C2",
"gpioInstance": "ATMO_DRIVERINSTANCE_GPIO_GPIO1",
"interruptEnabled": true,
"interruptGpio": "PTA9",
"i2cAddress": "0x28"
},
"meta": {
"editorX": 51,
"editorY": 40,
"lastTrigger": "triggered"
},
"triggers": {
"triggered": [],
"touchDataRead": [],
"upPressed": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "EmbeddedPageController",
"targetAbility": "navigateUp"
}
],
"downPressed": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "EmbeddedPageController",
"targetAbility": "navigateDown"
}
],
"leftPressed": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "EmbeddedPageController",
"targetAbility": "navigateLeft"
}
],
"rightPressed": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "EmbeddedPageController",
"targetAbility": "navigateRight"
}
]
},
"interruptAbilities": {
"trigger": false,
"setup": false,
"getTouchData": false,
"pressUp": false,
"pressDown": false,
"pressLeft": false,
"pressRight": false
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "getTouchData",
"triggers": [
"touchDataRead"
]
},
{
"name": "pressUp",
"triggers": [
"upPressed",
"touchDataRead"
]
},
{
"name": "pressDown",
"triggers": [
"downPressed",
"touchDataRead"
]
},
{
"name": "pressLeft",
"triggers": [
"leftPressed",
"touchDataRead"
]
},
{
"name": "pressRight",
"triggers": [
"rightPressed",
"touchDataRead"
]
}
]
},
{
"name": "EmbeddedSystemStatusDisplay",
"type": "EmbeddedSystemStatusDisplay",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables",
"rpk"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"displayPage": "\n\tATMO_UI_Page_DisplayPageByCoord(ATMO_PROPERTY(EmbeddedSystemStatusDisplay, x), ATMO_PROPERTY(EmbeddedSystemStatusDisplay, y), false);\n\treturn ATMO_Status_Success;\n\t",
"onDisplayed": "\n\treturn ATMO_Status_Success;\n\t",
"setup": "\n ATMO_UI_PAGE_Config_t config;\n config.hidden = ATMO_PROPERTY(EmbeddedSystemStatusDisplay, pageHidden);\n config.activeButtons = ATMO_UI_Page_GetButtonMask(ATMO_PROPERTY(EmbeddedSystemStatusDisplay, topRightButtonEnabled),\n ATMO_PROPERTY(EmbeddedSystemStatusDisplay,bottomRightButtonEnabled), ATMO_PROPERTY(EmbeddedSystemStatusDisplay, topLeftButtonEnabled), ATMO_PROPERTY(EmbeddedSystemStatusDisplay, bottomLeftButtonEnabled));\n config.x = ATMO_PROPERTY(EmbeddedSystemStatusDisplay, x);\n config.y = ATMO_PROPERTY(EmbeddedSystemStatusDisplay, y);\n\tstrncpy(config.topLeftButtonLabel, ATMO_PROPERTY(EmbeddedSystemStatusDisplay, topLeftButtonLabel), ATMO_BUTTON_LABEL_MAXLEN);\n\tstrncpy(config.topRightButtonLabel, ATMO_PROPERTY(EmbeddedSystemStatusDisplay, topRightButtonLabel), ATMO_BUTTON_LABEL_MAXLEN);\n\tstrncpy(config.bottomLeftButtonLabel, ATMO_PROPERTY(EmbeddedSystemStatusDisplay, bottomLeftButtonLabel), ATMO_BUTTON_LABEL_MAXLEN);\n\tstrncpy(config.bottomRightButtonLabel, ATMO_PROPERTY(EmbeddedSystemStatusDisplay, bottomRightButtonLabel), ATMO_BUTTON_LABEL_MAXLEN);\n config.spanX = ATMO_PROPERTY(EmbeddedSystemStatusDisplay, spanX);\n\tconfig.spanY = ATMO_PROPERTY(EmbeddedSystemStatusDisplay, spanY);\n config.title = ATMO_PROPERTY(EmbeddedSystemStatusDisplay, pageTitle);\n config.titleHidden = ATMO_PROPERTY(EmbeddedSystemStatusDisplay, titleHidden);\n ATMO_UI_SYSTEMSTATUS_Init(&config);\n "
},
"variables": {
"pageHandle": {
"type": "ATMO_DriverInstanceHandle_t"
}
},
"embeddedPropertyConversions": {
"pageTitle": "string",
"topRightButtonLabel": "string",
"bottomRightButtonLabel": "string",
"topLeftButtonLabel": "string",
"bottomLeftButtonLabel": "string"
},
"codeUserChanged": {
"displayPage": false,
"onDisplayed": false,
"setup": false
},
"textColor": "GUI_BLACK",
"pageTitle": "",
"titleHidden": false,
"pageHidden": false,
"topRightButtonLabel": "",
"topRightButtonEnabled": false,
"bottomRightButtonLabel": "",
"bottomRightButtonEnabled": false,
"topLeftButtonLabel": "",
"topLeftButtonEnabled": false,
"bottomLeftButtonLabel": "",
"bottomLeftButtonEnabled": false,
"x": 0,
"y": "-1",
"spanX": 1,
"spanY": 1
},
"meta": {
"editorX": 453,
"editorY": 0,
"lastTrigger": "onDisplayed"
},
"triggers": {
"triggered": [],
"onDisplayed": []
},
"interruptAbilities": {
"trigger": false,
"displayPage": false,
"onDisplayed": false,
"setup": false
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "displayPage",
"triggers": []
},
{
"name": "onDisplayed",
"triggers": [
"onDisplayed"
]
},
{
"name": "setup",
"triggers": []
}
]
},
{
"name": "TrackerOnOff",
"type": "EmbeddedOnOffDisplay",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables",
"rpk"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"displayPage": "\n\tATMO_UI_Page_DisplayPageByCoord(ATMO_PROPERTY(TrackerOnOff, x), ATMO_PROPERTY(TrackerOnOff, y), false);\n\treturn ATMO_Status_Success;\n\t",
"onDisplayed": "\n\treturn ATMO_Status_Success;\n ",
"topRightButtonPressed": "\n\treturn ATMO_Status_Success;\n\t",
"bottomRightButtonPressed": "\n\treturn ATMO_Status_Success;\n\t",
"topLeftButtonPressed": "\n\treturn ATMO_Status_Success;\n\t",
"setup": "\n ATMO_UI_PAGE_Config_t config;\n config.hidden = ATMO_PROPERTY(TrackerOnOff, pageHidden);\n config.textColor = ATMO_PROPERTY(TrackerOnOff, textColor);\n\tconfig.activeButtons = ATMO_UI_Page_GetButtonMask(ATMO_PROPERTY(TrackerOnOff, topRightButtonEnabled),\n\t\tATMO_PROPERTY(TrackerOnOff,bottomRightButtonEnabled), ATMO_PROPERTY(TrackerOnOff, topLeftButtonEnabled), ATMO_PROPERTY(TrackerOnOff, bottomLeftButtonEnabled));\n\tconfig.x = ATMO_PROPERTY(TrackerOnOff, x);\n config.y = ATMO_PROPERTY(TrackerOnOff, y);\n\tstrncpy(config.topLeftButtonLabel, ATMO_PROPERTY(TrackerOnOff, topLeftButtonLabel), ATMO_BUTTON_LABEL_MAXLEN);\n\tstrncpy(config.topRightButtonLabel, ATMO_PROPERTY(TrackerOnOff, topRightButtonLabel), ATMO_BUTTON_LABEL_MAXLEN);\n\tstrncpy(config.bottomLeftButtonLabel, ATMO_PROPERTY(TrackerOnOff, bottomLeftButtonLabel), ATMO_BUTTON_LABEL_MAXLEN);\n\tstrncpy(config.bottomRightButtonLabel, ATMO_PROPERTY(TrackerOnOff, bottomRightButtonLabel), ATMO_BUTTON_LABEL_MAXLEN);\n config.spanX = ATMO_PROPERTY(TrackerOnOff, spanX);\n\tconfig.spanY = ATMO_PROPERTY(TrackerOnOff, spanY);\n config.title = ATMO_PROPERTY(TrackerOnOff, pageTitle);\n config.titleHidden = ATMO_PROPERTY(TrackerOnOff, titleHidden);\n ATMO_UI_SELECTICON_Init(&config, 2, true, ATMO_PROPERTY(TrackerOnOff, persist), ATMO_PROPERTY(TrackerOnOff, differentStartup));\n ATMO_VARIABLE(TrackerOnOff, pageHandle) = config.templateInstance;\n ATMO_UI_SELECTICON_SetIcon(config.templateInstance, ATMO_PROPERTY(TrackerOnOff,icon));\n ATMO_UI_SELECTICON_SetOptionText(config.templateInstance, 0, \"Off\", !ATMO_PROPERTY(TrackerOnOff, initialValue));\n ATMO_UI_SELECTICON_SetOptionText(config.templateInstance, 1, \"On\", ATMO_PROPERTY(TrackerOnOff, initialValue));\n ATMO_UI_SELECTICON_RegisterOptionSelectedAbilityHandle(config.templateInstance, 0, ATMO_ABILITY(TrackerOnOff, offSet));\n ATMO_UI_SELECTICON_RegisterOptionSelectedAbilityHandle(config.templateInstance, 1, ATMO_ABILITY(TrackerOnOff, onSet));\n ATMO_UI_SELECTICON_RegisterOptionSelectedStartupAbilityHandle(config.templateInstance, 0, ATMO_ABILITY(TrackerOnOff, offSetStartup));\n ATMO_UI_SELECTICON_RegisterOptionSelectedStartupAbilityHandle(config.templateInstance, 1, ATMO_ABILITY(TrackerOnOff, onSetStartup));\n ATMO_UI_SELECTICON_RegisterButtonAbilityHandle(ATMO_VARIABLE(TrackerOnOff,pageHandle), 1, ATMO_ABILITY(TrackerOnOff, topRightButtonPressed));\n\tATMO_UI_SELECTICON_RegisterButtonAbilityHandle(ATMO_VARIABLE(TrackerOnOff,pageHandle), 2, ATMO_ABILITY(TrackerOnOff, bottomRightButtonPressed));\n\tATMO_UI_SELECTICON_RegisterButtonAbilityHandle(ATMO_VARIABLE(TrackerOnOff,pageHandle), 3, ATMO_ABILITY(TrackerOnOff, topLeftButtonPressed));\n ATMO_UI_SELECTICON_RegisterOnDisplayedAbilityHandle(ATMO_VARIABLE(TrackerOnOff,pageHandle), ATMO_ABILITY(TrackerOnOff, onDisplayed));\n ATMO_UI_SELECTICON_OverlaySaved(ATMO_VARIABLE(TrackerOnOff, pageHandle));\n return ATMO_Status_Success;\n ",
"setOff": "\n ATMO_UI_SELECTICON_SetOption(ATMO_VARIABLE(TrackerOnOff,pageHandle), 0, true);\n ATMO_CreateValueBool(out, false);\n return ATMO_Status_Success;\n ",
"setOn": "\n ATMO_UI_SELECTICON_SetOption(ATMO_VARIABLE(TrackerOnOff,pageHandle), 0, false);\n ATMO_CreateValueBool(out, true);\n return ATMO_Status_Success;\n ",
"offSet": "\n ATMO_CreateValueBool(out, false);\n return ATMO_Status_Success;\n ",
"onSet": "\n ATMO_CreateValueBool(out, true);\n return ATMO_Status_Success;\n ",
"offSetStartup": "\treturn ATMO_Status_Success;",
"onSetStartup": "\treturn ATMO_Status_Success;"
},
"variables": {
"pageHandle": {
"type": "ATMO_DriverInstanceHandle_t"
}
},
"embeddedPropertyConversions": {
"pageTitle": "string",
"topRightButtonLabel": "string",
"bottomRightButtonLabel": "string",
"topLeftButtonLabel": "string",
"bottomLeftButtonLabel": "string",
"label": "string"
},
"codeUserChanged": {
"displayPage": false,
"onDisplayed": false,
"topRightButtonPressed": false,
"bottomRightButtonPressed": false,
"topLeftButtonPressed": false,
"setup": false,
"setOff": false,
"setOn": false,
"offSet": false,
"onSet": false,
"offSetStartup": false,
"onSetStartup": false
},
"textColor": "GUI_BLACK",
"pageTitle": "Smart Collar",
"titleHidden": false,
"pageHidden": false,
"topRightButtonLabel": "",
"topRightButtonEnabled": false,
"bottomRightButtonLabel": "",
"bottomRightButtonEnabled": false,
"topLeftButtonLabel": "",
"topLeftButtonEnabled": false,
"bottomLeftButtonLabel": "Toggle",
"bottomLeftButtonEnabled": true,
"x": 0,
"y": 0,
"spanX": 1,
"spanY": 1,
"icon": "icon_applications_motion",
"initialValue": false,
"persist": true,
"differentStartup": false
},
"meta": {
"editorX": 453,
"editorY": 144,
"lastTrigger": "onSet"
},
"triggers": {
"triggered": [],
"onDisplayed": [],
"topRightButtonPressed": [],
"bottomRightButtonPressed": [],
"topLeftButtonPressed": [],
"offSet": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "OnOffToggle",
"targetAbility": "setValue"
},
{
"mapping": {},
"targetOrder": [],
"targetElement": "FXAS21002Gyroscope",
"targetAbility": "setDisabled"
},
{
"mapping": {},
"targetOrder": [],
"targetElement": "FXOS8700AccelerometerMagnetometer",
"targetAbility": "setDisabled"
}
],
"setOn": [],
"onSet": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "OnOffToggle",
"targetAbility": "setValue"
},
{
"mapping": {},
"targetOrder": [],
"targetElement": "FXAS21002Gyroscope",
"targetAbility": "setEnabled"
},
{
"mapping": {},
"targetOrder": [],
"targetElement": "FXOS8700AccelerometerMagnetometer",
"targetAbility": "setEnabled"
}
],
"offSetStartup": [],
"onSetStartup": []
},
"interruptAbilities": {
"trigger": false,
"displayPage": false,
"onDisplayed": false,
"topRightButtonPressed": false,
"bottomRightButtonPressed": false,
"topLeftButtonPressed": false,
"setup": false,
"setOff": false,
"setOn": false,
"offSet": false,
"onSet": false,
"offSetStartup": false,
"onSetStartup": false
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "displayPage",
"triggers": []
},
{
"name": "onDisplayed",
"triggers": [
"onDisplayed"
]
},
{
"name": "topRightButtonPressed",
"triggers": [
"topRightButtonPressed"
]
},
{
"name": "bottomRightButtonPressed",
"triggers": [
"bottomRightButtonPressed"
]
},
{
"name": "topLeftButtonPressed",
"triggers": [
"topLeftButtonPressed"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "setOff",
"triggers": [
"offSet"
]
},
{
"name": "setOn",
"triggers": [
"setOn"
]
},
{
"name": "offSet",
"triggers": [
"offSet"
]
},
{
"name": "onSet",
"triggers": [
"onSet"
]
},
{
"name": "offSetStartup",
"triggers": [
"offSetStartup"
]
},
{
"name": "onSetStartup",
"triggers": [
"onSetStartup"
]
}
]
},
{
"name": "OnOffToggle",
"type": "EmbeddedBLECharacteristicCustom",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables",
"ble"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": "\n\tATMO_BLE_GATTSAddService(\n\t\tATMO_PROPERTY(OnOffToggle, instance),\n\t\t&ATMO_VARIABLE(OnOffToggle, bleServiceHandle), \n\t\tATMO_PROPERTY(OnOffToggle, bleServiceUuid));\n\t\n\tuint8_t property = 0;\n\tuint8_t permission = 0;\n\t\n\tproperty |= ATMO_PROPERTY(OnOffToggle, read) ? ATMO_BLE_Property_Read : 0;\n\tproperty |= ATMO_PROPERTY(OnOffToggle, write) ? ATMO_BLE_Property_Write : 0;\n\tproperty |= ATMO_PROPERTY(OnOffToggle, notify) ? ATMO_BLE_Property_Notify : 0;\n\n\tpermission |= ATMO_PROPERTY(OnOffToggle, read) ? ATMO_BLE_Permission_Read : 0;\n\tpermission |= ATMO_PROPERTY(OnOffToggle, write) ? ATMO_BLE_Permission_Write : 0;\n\n\tATMO_DATATYPE types[3] = {ATMO_PROPERTY(OnOffToggle, writeDataType), ATMO_PROPERTY(OnOffToggle, readDataType), ATMO_PROPERTY(OnOffToggle, notifyDataType)};\n\t\n\tATMO_BLE_GATTSAddCharacteristic(\n\t\tATMO_PROPERTY(OnOffToggle, instance),\n\t\t&ATMO_VARIABLE(OnOffToggle, bleCharacteristicHandle), \n\t\tATMO_VARIABLE(OnOffToggle, bleServiceHandle), \n\t\tATMO_PROPERTY(OnOffToggle, bleCharacteristicUuid), \n\t\tproperty, permission, ATMO_GetMaxValueSize(3, 64, types));\n\t\n\tATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(\n\t\tATMO_PROPERTY(OnOffToggle, instance),\n\t\tATMO_VARIABLE(OnOffToggle, bleCharacteristicHandle), \n\t\tATMO_BLE_Characteristic_Written, \n\t\tATMO_ABILITY(OnOffToggle, written));\n\t\n\treturn ATMO_Status_Success;\n\t",
"setValue": "\n\t\n\t// Convert to the desired write data type\n\tATMO_Value_t convertedValue;\n\tATMO_InitValue(&convertedValue);\n\tATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(OnOffToggle, readDataType), in);\n\n\tATMO_BLE_GATTSSetCharacteristic(\n\t\tATMO_PROPERTY(OnOffToggle, instance),\n\t\tATMO_VARIABLE(OnOffToggle, bleCharacteristicHandle),\n\t\tconvertedValue.size, \n\t\t(uint8_t *)convertedValue.data,\n\t\tNULL);\n\t\n\tATMO_FreeValue(&convertedValue);\n\t\t\n\treturn ATMO_Status_Success;\n\t",
"written": "\n\tATMO_CreateValueConverted(out, ATMO_PROPERTY(OnOffToggle, writeDataType), in);\n\treturn ATMO_Status_Success;\n\t",
"subscibed": "\treturn ATMO_Status_Success;",
"unsubscribed": "\treturn ATMO_Status_Success;"
},
"variables": {
"bleServiceHandle": {
"type": "ATMO_BLE_Handle_t"
},
"bleCharacteristicHandle": {
"type": "ATMO_BLE_Handle_t"
}
},
"embeddedPropertyConversions": {
"bleServiceUuid": "string",
"bleCharacteristicUuid": "string"
},
"codeUserChanged": {
"setup": false,
"setValue": false,
"written": false,
"subscibed": false,
"unsubscribed": false
},
"instance": "ATMO_DRIVERINSTANCE_BLE_BLE1",
"bleServiceUuid": "1f6a5850-a7a3-4f2c-a860-889142d04d28",
"bleCharacteristicUuid": "1f6a5850-a7a3-4f2c-a860-889142d04d2a",
"read": true,
"write": true,
"notify": true,
"readDataType": "ATMO_DATATYPE_BOOL",
"writeDataType": "ATMO_DATATYPE_BOOL",
"notifyDataType": "ATMO_DATATYPE_BOOL"
},
"meta": {
"editorX": 953,
"editorY": 142,
"lastTrigger": "written"
},
"triggers": {
"triggered": [],
"written": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "EmbeddedComparison",
"targetAbility": "evaluate"
}
],
"subscibed": [],
"unsubscribed": []
},
"interruptAbilities": {
"trigger": false,
"setup": false,
"setValue": "valueSet",
"written": true,
"subscibed": true,
"unsubscribed": true
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "setValue",
"triggers": []
},
{
"name": "written",
"triggers": [
"written"
]
},
{
"name": "subscibed",
"triggers": [
"subscibed"
]
},
{
"name": "unsubscribed",
"triggers": [
"unsubscribed"
]
}
]
},
{
"name": "EmbeddedComparison",
"type": "EmbeddedComparison",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": "\n\treturn ATMO_Status_Success;\n\t",
"evaluate": "\n\tbool conditionTrue = false;\n\n\t// Convert property to same type as input\n\tATMO_Value_t targetStr;\n\tATMO_Value_t targetNum;\n\t\n\tATMO_InitValue(&targetStr);\n\tATMO_InitValue(&targetNum);\n\tATMO_CreateValueString(&targetStr, ATMO_PROPERTY(EmbeddedComparison, target));\n\tATMO_CreateValueConverted(&targetNum, in->type, &targetStr);\n\t\n\tif(ATMO_CompareValues(in, &targetNum, ATMO_PROPERTY(EmbeddedComparison, condition), &conditionTrue) != ATMO_Status_Success)\n\t{\n\t\tATMO_Value_t value;\n\t\tATMO_InitValue(&value);\n\t\tATMO_TriggerHandler(ATMO_TRIGGER(EmbeddedComparison, invalidType), NULL);\n\t\tATMO_FreeValue(&value);\n\t\tATMO_FreeValue(&targetStr);\n\t\tATMO_FreeValue(&targetNum);\n\t\treturn ATMO_Status_Fail;\n\t}\n\n\tATMO_FreeValue(&targetStr);\n\tATMO_FreeValue(&targetNum);\n\n\tif(conditionTrue)\n\t{\n\t\tATMO_Value_t value;\n\t\tATMO_InitValue(&value);\n\t\tATMO_TriggerHandler(ATMO_TRIGGER(EmbeddedComparison, conditionTrue), NULL);\n\t\tATMO_FreeValue(&value);\t\t\n\t}\n\telse\n\t{\n\t\tATMO_Value_t value;\n\t\tATMO_InitValue(&value);\n\t\tATMO_TriggerHandler(ATMO_TRIGGER(EmbeddedComparison, conditionFalse), NULL);\n\t\tATMO_FreeValue(&value);\t\t\t\n\t}\n\n\treturn ATMO_Status_Success;\n\t"
},
"variables": {},
"embeddedPropertyConversions": {
"target": "string"
},
"codeUserChanged": {
"setup": false,
"evaluate": false
},
"condition": "ATMO_EQUAL",
"target": "1"
},
"meta": {
"editorX": 654,
"editorY": 43,
"lastTrigger": "conditionFalse"
},
"triggers": {
"triggered": [],
"conditionTrue": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "TrackerOnOff",
"targetAbility": "setOn"
}
],
"conditionFalse": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "TrackerOnOff",
"targetAbility": "setOff"
}
],
"invalidType": []
},
"interruptAbilities": {
"trigger": false,
"setup": false,
"evaluate": false
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "evaluate",
"triggers": []
}
]
},
{
"name": "FXAS21002Gyroscope",
"type": "EmbeddedFXAS21002",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": "\tATMO_FXAS21002_Config_t config;\n\tconfig.address = ATMO_PROPERTY(FXAS21002Gyroscope, i2cAddress);\n\tconfig.i2cDriverInstance = ATMO_PROPERTY(FXAS21002Gyroscope, i2cInstance);\n\tconfig.samplingRate = ATMO_PROPERTY(FXAS21002Gyroscope, samplingRate);\n\tATMO_FXAS21002_Init(&config);\n\treturn ATMO_Status_Success;",
"setEnabled": "ATMO_FXAS21002_SetEnabled(true);\nreturn ATMO_Status_Success;",
"setDisabled": "ATMO_FXAS21002_SetEnabled(false);\nreturn ATMO_Status_Success;",
"setEnabledDisabled": "bool enabled = false;\nATMO_GetBool(in, &enabled);\nATMO_FXAS21002_SetEnabled(enabled);\nreturn ATMO_Status_Success;",
"getSensorData": "\tATMO_FXAS21002_SensorData_t data;\n\tATMO_3dFloatVector_t atmoVec;\n\n\tif(ATMO_FXAS21002_GetSensorData(&data) != ATMO_FXAS21002_Status_Success)\n\t{\n\t\tATMO_CreateValueVoid(out);\n\t\treturn ATMO_Status_Fail;\n\t}\n\n\tatmoVec.x = data.X;\n\tatmoVec.y = data.Y;\n\tatmoVec.z = data.Z;\n\n\tATMO_CreateValue3dVectorFloat(out, &atmoVec);\n\treturn ATMO_Status_Success;\n",
"getDpsX": "\tATMO_FXAS21002_SensorData_t data;\n\n\tif(ATMO_FXAS21002_GetSensorData(&data) != ATMO_FXAS21002_Status_Success)\n\t{\n\t\tATMO_CreateValueVoid(out);\n\t\treturn ATMO_Status_Fail;\n\t}\n\n\tATMO_CreateValueFloat(out, data.X);\n\treturn ATMO_Status_Success;\n",
"getDpsY": "\tATMO_FXAS21002_SensorData_t data;\n\n\tif(ATMO_FXAS21002_GetSensorData(&data) != ATMO_FXAS21002_Status_Success)\n\t{\n\t\tATMO_CreateValueVoid(out);\n\t\treturn ATMO_Status_Fail;\n\t}\n\n\tATMO_CreateValueFloat(out, data.Y);\n\treturn ATMO_Status_Success;\n",
"getDpsZ": "\tATMO_FXAS21002_SensorData_t data;\n\n\tif(ATMO_FXAS21002_GetSensorData(&data) != ATMO_FXAS21002_Status_Success)\n\t{\n\t\tATMO_CreateValueVoid(out);\n\t\treturn ATMO_Status_Fail;\n\t}\n\n\tATMO_CreateValueFloat(out, data.Z);\n\treturn ATMO_Status_Success;\n"
},
"variables": {},
"embeddedPropertyConversions": {},
"codeUserChanged": {
"setup": false,
"setEnabled": false,
"setDisabled": false,
"setEnabledDisabled": false,
"getSensorData": false,
"getDpsX": false,
"getDpsY": false,
"getDpsZ": false
},
"i2cInstance": "ATMO_DRIVERINSTANCE_I2C_I2C2",
"i2cAddress": "0x20",
"samplingRate": "FXAS21002_CTRL_REG1_DR_12_5HZ"
},
"meta": {
"editorX": 454,
"editorY": 342,
"lastTrigger": "sensorDataRead"
},
"triggers": {
"triggered": [],
"sensorDataRead": [],
"dpsXRead": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "GyroX",
"targetAbility": "setValue"
}
],
"dpsYRead": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "GyroY",
"targetAbility": "setValue"
}
],
"dpsZRead": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "GyroZ",
"targetAbility": "setValue"
}
]
},
"interruptAbilities": {
"trigger": false,
"setup": false,
"setEnabled": false,
"setDisabled": false,
"setEnabledDisabled": false,
"getSensorData": false,
"getDpsX": false,
"getDpsY": false,
"getDpsZ": false
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "setEnabled",
"triggers": []
},
{
"name": "setDisabled",
"triggers": []
},
{
"name": "setEnabledDisabled",
"triggers": []
},
{
"name": "getSensorData",
"triggers": [
"sensorDataRead"
]
},
{
"name": "getDpsX",
"triggers": [
"dpsXRead"
]
},
{
"name": "getDpsY",
"triggers": [
"dpsYRead"
]
},
{
"name": "getDpsZ",
"triggers": [
"dpsZRead"
]
}
]
},
{
"name": "Interval1",
"type": "EmbeddedInterval",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": "\n\tATMO_INTERVAL_Handle_t intervalHandle;\n ATMO_INTERVAL_AddAbilityInterval(\n\t\tATMO_PROPERTY(Interval1, instance), \n\t\tATMO_ABILITY(Interval1, interval), \n\t\tATMO_PROPERTY(Interval1, time), \n\t\t&intervalHandle\n\t);\n\t\n\treturn ATMO_Status_Success;\n\t",
"interval": "\treturn ATMO_Status_Success;"
},
"variables": {},
"embeddedPropertyConversions": {},
"codeUserChanged": {
"setup": false,
"interval": false
},
"instance": "ATMO_DRIVERINSTANCE_INTERVAL_INTERVAL1",
"time": 1000
},
"meta": {
"editorX": 251,
"editorY": 343,
"lastTrigger": "interval"
},
"triggers": {
"triggered": [],
"interval": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "FXAS21002Gyroscope",
"targetAbility": "getDpsX"
},
{
"mapping": {},
"targetOrder": [],
"targetElement": "FXAS21002Gyroscope",
"targetAbility": "getDpsY"
},
{
"mapping": {},
"targetOrder": [],
"targetElement": "FXAS21002Gyroscope",
"targetAbility": "getDpsZ"
},
{
"mapping": {},
"targetOrder": [],
"targetElement": "FXOS8700AccelerometerMagnetometer",
"targetAbility": "getAccelX"
},
{
"mapping": {},
"targetOrder": [],
"targetElement": "FXOS8700AccelerometerMagnetometer",
"targetAbility": "getAccelY"
},
{
"mapping": {},
"targetOrder": [],
"targetElement": "FXOS8700AccelerometerMagnetometer",
"targetAbility": "getAccelZ"
},
{
"mapping": {},
"targetOrder": [],
"targetElement": "FXOS8700AccelerometerMagnetometer",
"targetAbility": "getMagX"
},
{
"mapping": {},
...
This file has been truncated, please download it to see its full contents.
Comments