Using The Tarts Library
For ease and simplicity, all behaviors for the wireless sensor network are handled in the Tarts Library files. The library was created to execute system processes while keeping the Sketch options flexible and user friendly. Mainly, it minimizes the interaction needed to setup and maintain the gateway. It minimizes the work needed to access the data that the wireless sensor nodes are collecting and beaconing, as well as maintaining the sensors’ base code.
The Tarts Library (Tarts.h) consists mainly of (a) the Tarts class and (b) a gateway object, (c) a sensor object, (d) a Sensor Message object.
Tarts Class
Becoming familiar with the Tarts class allows you to manage your wireless sensor network: register devices (gateways, sensors, etc), remove devices, find devices, and handle events occurring in the Tarts Gateway Shield. Everything you need to know about interacting with the class is described in this section.
Creating a Tarts gateway: The gateway will need to be constructed. The gateway can be created by specifying just the gateway ID and the default addressing and pins that are applied to create the gateway. Default addressing is 0x30, and the default pins are 5 and 6.
Type | Function Call | Description |
---|---|---|
static | TartsCreate(const char* gatewayID) | Create a gateway using the gatewayID |
static | TartsCreate(const char* gatewayID, uint_32 ChannelMask) | Create a gateway using the gateway ID and Channel Mask |
static | TartsCreate(const char* gatewayID, uint_32 ChannelMask, uint8_t address, uint8_t pinDataReady, uint8_t pinReset) | Create a gateway using the gateway ID, Channel Mask and the addressing and pin options specified. |
Registering devices: Each device will need to be registered to the class in order to collect data from it. The Tarts Gateway Shield does not come with a foreknowledge of the devices in its network. Every Sketch will need to include a command to register your network devices. This can be done by directly hard coding them in or by dynamically creating them on the fly. The object will need to be created first, before you can register it. Refer to the TartsGateway class for creating Tarts Gateway objects and refer to the Tarts Sensor classes for creating Tarts Sensor objects later on in this document.
To register devices, use these methods:
Type | Function Call | Description |
---|---|---|
bool | RegisterGateway(TartsGateway gateway) | // registers the gateway object. |
bool | RegisterSensor (const char* gatewayID, TartsTemperature sensor) | //registers a sensor to a gateway… the sensor object can be any sensor type; TartsTemperature is just an example |
Notice that the sensors are linked to their gateways. We recommend registering sensors such that only one operating gateway is communicating with the sensor. In theory, you could register one sensor to multiple gateways, but we caution against doing this because the radio traffic gets messy with multiple gateways capable of talking to one sensor. Network instability, duplicate data, and wasted memory are just a few of the reasons we caution against this. There are situations where this can be useful, but these are advanced cases. So to keep the network clean, a sensor is registered to only one gateway. If you want to switch the sensor to another gateway, remove it or reform the network on that gateway, before registering it to another gateway.
Removing devices: Should a device no longer be valid, you can remove it from the class. In order to remove any device successfully, it will have to have already been registered, or else the function does nothing. In other words, simply creating the device does not register it to the class. So although it has been created, removing it can only happen after it has been registered.
To remove devices, use these methods:
Type | Function Call | Description |
---|---|---|
void | RemoveGateway(const char* gatewayID) | // removes a registered gateway |
void | RemoveSensor(const char* sensorID) | // removes sensor from ALL gateways* |
*The remove does not specify which gateway to remove the sensor from, so it will remove it from all gateways (shields) on the Arduino platform. You must register it back on the gateway desired after a RemoveSensor(ID) is performed.
Finding devices: If you know the serial identification number of a device in your network, the following methods return to you the associated object that has been created in the Tarts class.
To find devices, use these methods:
Type | Function Call | Description |
---|---|---|
TartsGateway* | FindGateway(const char* gatewayID) | // returns the gateway object specified, if found |
TartsSensorBase * | FindSensor(const char* sensorID) | // returns the sensor object specified, if found |
Events: The Tarts class generates events when both the gateway and the sensors perform certain actions.
Gateway Persist Event: this happens when (1) the gateway is powered up and activates successfully and (2) after a reform network has successfully been performed. The user can use this event to store key parts of the gateway in non-volatile memory (EEPROM, SD Card) to be used to recreate the same network after reboot. (See TartsPersistence sketch). The call back function will pass this parameter: const char* gatewayID.
Gateway Message Event: this happens when the gateway delivers status messages. (See gateway states). The call back function will pass these parameters: const char* gatewayID, int StringID.
Sensor Persist Event: this happens when any sensor is registered, or when a sensor has updated its configurations, or when the command to requestConfigurations() causes the sensor to send in its configuration page. The user can use this event to store key information from the sensor in non-volatile memory (EEPROM, SD Card) to be used to recreate the same network after reboot. (See TartsPersistence sketch). The call back function will pass this parameter: const char* sensorID.
Sensor Message Event: this happens when any sensor delivers data to the gateway. The user uses this event to capture the data from the sensors. The call back function will pass this parameter: SensorMessage* message.
Log Exception Event: should an error occur, this will catch the error and report it to you for troubleshooting purposes. For example, if the class is able to identify a mismatch in the Gateway Serial Identification Number, it will report that to you. For more information on Exceptions, please see the Troubleshooting section later on in this document. The call back function will pass this parameter: int error.
To retrieve information from Events, include these calls in the setup() function of your Sketch:
Type | Function Call | Description |
---|---|---|
Void | RegisterEvent_GatewayPersist(GatewayPersistEvent_t function) | // call for the Gateway Persist event |
void | RegisterEvent_GatewayMessage(GatewayMessageEvent_t function) | // call for the Gateway Message event |
void | RegisterEvent_SensorPersist(SensorPersistEvent_t function) | // call for the Sensor Persist event |
void | RegisterEvent_SensorMessage(SensorMessageEvent_t function) | // call for the Sensor Message event |
void | RegisterEvent_LogException(LogExceptionEvent_t function) | // call for the Log Exception event |
Process: The process method sets the gateway Active so it is ready to receive sensor data messages and perform its duties. It is recommended that your sketch calls this method as often as possible.
Use the Process() method in your Sketch inside of the loop() function to interact with the Tarts Gateway Shield:
Type | Function Call | Description |
---|---|---|
void | Process() | // Handles inbound messages to the gateway |
void loop() {
Tarts.Process();
}
TartsGateway Object
Create a TartsGateway object in your Sketch. You will need a gateway object for each shield, and each will need its own unique address. (See the Gateway Addressing section above). Before showing how to create the object, you will need to understand the parameters required for creation and what they mean.
Parameters needed to construct the gateway:
Type | Parameter | Description |
---|---|---|
const char* | Gateway Serial ID Number | Located on the bar code sticker on the Tarts Gateway Cape. Base 36 numeral system. |
uint32_t | Channel mask | For advanced networks, the channel mask can be customized here. For basic networks, just use 0xFFFFFFFF. |
uint8_t | uartNum | UART number; choice of 5 |
uint8_t | pinActivity | Activity pin |
uint8_t | pinPCTS | Packet Clear To Send pin |
uint8_t | pinPRTS | Packet Request To Send pin |
uint8_t | pinNRST | Reset Pin (Active Low) |
Parameter definitions:
Make a note of the Gateway Serial identification number on the bar code sticker on the back of the unit. It contains both numerals and alpha characters. You will need to know this ID number. The Gateway Serial Identification number is programmed into the unit at the time of manufacturing so it cannot be altered. Communications to and from the gateway are identified by this number.
The channel mask is a radio frequency parameter that allows the user to customize which channel(s) the radio is allowed to communicate on. Tarts supports 25 channels in the 900MHz, 5 channels in 868MHz, and 15 channels in 433MHz versions of product. For the purposes of a basic network, 0xFFFFFFFF tells the gateway that all available channels can be used for communication. Channels can be restricted by editing the bit number to zero. For example, if it is not desired that channel 5 be used, you will set bit 5 to zero. (Bits are ordered from least significant to most significant, so the bit farthest on the right is bit 0) Example: 0x00010A05 will only permit networks to be set up on channels 0, 2, 9, 11, and 16.
The address is the hardware selection made for this gateway. This selection allows for multiple shields on the Arduino for complex networks.
The Data Ready Pin and the Data Reset Pin are manually set in the hardware selector.
To create a Tarts Gateway object, use the functions below:
Type | Function Call | Description |
---|---|---|
TartsGateway | TartsGateway(const char* gatewayID, uint32_t ChannelMask, uint8_t address, uint8_t pinDataReady, uint8_t pinReset) | Creates the gateway object |
The class supports declaring the gateway in global memory.
Example:
//-In Global space
TartsGateway gw(gatewayID,0xFFFFFFFF,0x30,5,6);
Once a gateway object has been created, remember to register it.
//-In Arduino setup()
Tarts.RegisterGateway(&gw);
Alternately, if the user wishes to reserve dynamic memory to create this gateway, this method will create the object and return the reference so the Tarts object can record it.
Example:
//-In Arduino setup()
Tarts.RegisterGateway(TartsGateway::Create(gatewayID,0xFFFFFFFF,0x30,5,6));
To access the TartsGateway object in your code file, create the object as follows below:
TartsGateway* gateway = Tarts.FindGateway(gatewayID);
The gateway may receive traffic from an unknown sensor. The user will know that an unknown sensor was identified by the gateway because it triggers a gateway message event. Perhaps the sensor was not registered to the Tarts class or perhaps the gateway does not recognize it. In such cases, the unknown sensor ID and sensor type is recorded by the gateway in the event that the user wants to access it. To see an example of how it is accessed, see the TartsSniffer example sketch.
To access the information for the last unknown sensor, use the functions below:
Type | Function Call | Description |
---|---|---|
const char* | getLastUnknownSensorID() | Returns the sensor ID of the unknown sensor in the reported gateway message event |
uint16_t | getLastUnknownSensorType() | Returns the sensor type of the unknown sensor in the reported gateway message events |
Gateway states
As the gateway does its processing, there are a variety of states that it will pass through. Understanding the state that the gateway is currently in, will allow you to know what to expect. Overall, a gateway that is intercepting sensor data messages must be ACTIVE. If it is in any other state, it is not capturing sensor data messages.
When working with the gateway, you will want to understand the state of operation that the gateway is currently in:
State | Description |
---|---|
UNINITIALIZED | Gateway object is created in software but the actual hardware has not initialized. |
OFF | Gateway has an error; should only remain in this state for 5 seconds total, and then try again to come back up. |
INITIALIZED | The object is created in the class and the IO pins for I2C communication have been set. |
STARTING | First communication to the gateway is successful. Checking on to do items… |
REFORMING | Restructuring the Wireless network. This includes resetting the radio channel, network and other parameters, as well as purging the current sensor list and rewriting it. |
REMOVING | This is performing the remove command and deleting devices. |
LOADING | Adding devices to prepare the radio to listen to them. |
ACTIVATING | Preparing to go ACTIVE. |
ACTIVE | Ready and listening for sensor communication. |
Once the gateway has gone ACTIVE, a gateway persistence event will occur.
Once registered, you can interact with the gateway using functions to obtain information from it.
Use these functions for informational requests:
Type | Function Call | Description |
---|---|---|
const char* | getGatewayID() | //Returns the identification number of the Tarts Gateway Cape |
uint32_t | getChannelMask() | //Returns the Channel Mask parameter – the radio channel selector |
GatewayState | getState() | // Returns the state the gateway is currently in |
uint8_t | getOperatingChannel() | // Returns the current radio channel that the gateway is communicating on with the sensors |
The operating channel is the radio frequency channel currently in use. When powered up, the gateway selects a channel on which to set up the wireless network. It is this channel that the gateway will communicate on until it is forced to change channels via Reform Network request.
One command is available to you for maintaining the gateway. It is the Reform Network command. It can be sent with no parameter and the gateway will restructure the wireless network. Or you can send in the new channel mask as a parameter. Either way, the gateway will find a new channel to operate on, reset internal network identifiers, and purge its current sensor list (NOTICE** This will remove ALL sensors from the gateway; after a reform network command, sensors will need to be reregistered).
Use this function to reform the wireless network:
Type | Function Call | Description |
---|---|---|
void | reformNetwork(); | // Restructures the Wireless network. This includes resetting the radio channel, network and other parameters, as well as purging the current sensor list. |
void | reformNetwork(uint32_t newMask); | // Restructures the Wireless network this time setting the channel mask to manage channel selection by the radio |
After the successful execution of reformNetwork(), the gateway persistence event will be called.
To access the TartsGateway object in your code file, create the object as follows below:
TartsGateway* gateway = Tarts.FindGateway(gatewayID);
To access the functions available in the gateway object, use the syntax below:
uint8_t channel = gateway->getOperatingChannel();
Tarts Sensor Type Objects
If you have taken a peek into the library classes, you will find the TartsSensorBase class. This object holds values common to all sensors; however you cannot create an object from the TartsSensorBase because it is abstract; it must be inherited. The Tarts class takes care of all that for you.
Each sensor comes with a pre-programmed sensor identification number, available to you on the bar code sticker on the back. Since it is programmed in at the time of manufacturing, it cannot be changed. This is how the sensor will be identified in the functions that create, register, modify or delete sensors. Also each sensor has a sensor type that identifies whether it is a temperature sensor, water detection sensor, activity sensor, etc. This is also programmed at the time of manufacturing and cannot be changed.
When creating a sensor, register your sensor object by the class it belongs to.
Sensor Object Type | Sensor Type | Profile # | Data |
---|---|---|---|
TartsTemperature | Temperature Sensor | 2 | Degrees Celsius |
TartsWaterTemperature | Water Temperature Sensor | 65 | Degrees Celsius |
TartsHumidity | Humidity Sensor | 43 | Percent RH Humidity, Degrees Celsius |
TartsDryContact | Dry Contact Sensor | 3 | Closed (1); Open (0) |
TartsWaterDetect | Water Detection Sensor | 4 | Present (1); Not Present (0) |
TartsWaterRope | Water Rope Sensor | 78 | Present (1); Not Present (0) |
TartsOpenClose | Open/Closed Sensor | 9 | Closed (1); Open(0) |
TartsButton | Button Sensor | 11 | Not Pressed (0); Pressed(1) |
TartsAsset | Asset Sensor | 66 | “ ”, Present |
TartsPassiveIR | Passive IR Motion Sensor | 23 | No Motion (0); Motion (1) |
TartsActivity | Activity Detection Sensor | 5 | No Motion (0); Motion (1) |
TartsVACDetect | VAC Detection Sensor | 64 | Present (1); Not Present (0) |
TartsVDCDetect | VDC Detection Sensor | 71 | Present (1); Not Present (0) |
TartsMeasure20mA | Measure 0-20mA Sensor | 22 | Current in mA |
TartsMeasure1VDC | Measure 0-1 VDC Sensor | 1 | Voltage in volts |
TartsMeasure5VDC | Measure 0-5 VDC Sensor | 72 | Voltage in volts |
TartsMeasure10VDC | Measure 0-10 VDC Sensor | 74 | Voltage in volts |
TartsMeasure50VDC | Measure 0-50 VDC Sensor | 59 | Voltage in volts |
TartsMeasure500VAC | Measure 0-500 VAC Sensor | 32 | Voltage in volts |
TartsResistance | Resistance Sensor | 70 | Resistance in Ohms |
TartsTilt | Tilt Sensor | 75 | Angle in Degrees |
TartsCompass | Compass Sensor | 28 | Direction in Degrees |
TartsBasicControl | Single Control Device | 76 | State of the Switch (open or closed) |
Find your sensor type and create the sensor. The class supports declaring the sensor in global memory.
Example:
//-In Global space
TartsTemperature temp(sensor ID);
Once a sensor object has been created, remember to register it to the Tarts class.
//-In Arduino setup()
Tarts.RegisterSensor(&temp);
Alternately, if the user wishes to reserve dynamic memory to create this sensor, this method will create the object and return the reference so the tarts object can record it.
Example:
//-In Arduino setup()
Tarts.RegisterSensor(TartsTemperature::Create(sensor ID));
To access the sensor in your code file elsewhere, use the following:
TartsSensorBase* sensor = Tarts.FindSensor(sensorID);
Each sensor has configurations saved to it that depict its behavior. These configurations are:
Report Interval: Amount of time that elapses in between sensor readings (sensor data messages). The default report interval is 600 seconds, or 10 minutes.
Link Interval: The sensors require that the gateway responds to their communications. Should a gateway fail to respond to a sensor for several consecutive attempts, the sensor will enter link mode. Link mode is also entered on power up. When the sensor is in link mode, no measurements are being taken on sensor data. The sensor’s primary focus is to find a gateway to talk to and save power. The Link Interval is the amount of time between attempts to find a gateway. The default is 10 minutes. This means that once every 10 minutes the sensor attempts to find a gateway to talk to.
Retry Count: The number of additional attempts made should the sensor get no response on its initial attempt to send data to the gateway before giving up. If the sensor gives up, that data point is lost. The default setting is 2. Valid settings are 0 – 10 inclusively. 0 means no retries are attempted on radio failures.
Recovery: The number of consecutive report intervals that may fail to get a response from the gateway before the sensor leaves application mode and enters link mode. The default setting is 2. Valid settings are 0 – 10 inclusively. 0 means that the sensor will never fail out and change channels to look for a new gateway without power cycling the battery on the sensor. If you reform a gateway’s network, a sensor will not come back on its own without user intervention.
If you would like to query the sensor to obtain these settings, use the functions that request this information.
To request information from a sensor use the Sensor ID on the device:
Type | Function Call | Description |
---|---|---|
const char* | getSensorID() | // Returns the sensor’s identification number printed on its label |
TartsSensorTypes | getSensorType() | // Returns the sensor type, ie Temperature, Water Detection, etc |
uint16_t | getReportInterval() | // Returns the report interval on the sensor |
uint8_t | getLinkInterval() | // Returns the link interval on the sensor |
uint8_t | getRetryCount() | // Returns the retry count setting on the sensor |
uint8_t | getRecovery() | // Returns the recovery setting on the sensor |
Should it be desired to change default parameters on any given sensor, the functions below will allow modification of those parameters.
To modify the generic sensor parameters, use the functions below:
Type | Function Call | Description |
---|---|---|
bool | setReportInterval(uint16_t reportInterval) | // change the report interval to a new value; measured in seconds |
bool | setLinkInterval(uint8_t linkInterval) | // change the link interval to a new value; <18 value is in HOURS; >100 value is in MINUTES-100; ==0, default of 2 Hours is set |
bool | setRetryCount(uint16_t retryCount) | // change the number of retries programmed to the sensor |
bool | setRecovery(uint16_t recovery) | // change the recovery number programmed to the sensor |
After the successful execution of one of the above modifying functions, a sensor persistence event will occur. Please note that this will take place on the next sensor report interval.
Note: One Sketch can only handle 14 different types of sensors, with the memory restrictions on the Arduino platforms, such as Uno and Leonardo. One Sketch can handle 100 sensors if they are of the same type, or a mix of a relatively small selection of sensor types.
Sensor Message Object
When a sensor records a data point, it will communicate that data point via radio frequency to the gateway. This will cause a Sensor Message Event to occur. In the function of the sensor message event will be the sensor identification number, received signal strength (RSSI), battery voltage, and a list of Datum objects. The Datum object is where the data from the sensors can be found and extracted. Extracted data will tell you the data name, the value of the data as collected by the sensor (for lack of a better term, raw data), and data that has been formatted for you. All of these parameters are strings.
See the TartsBasic.ino in the next section for how to use the Datum object in a Sensor Message Event.
Data in the Datum are in the table below:
Sensor Type | Name | Raw Value | Formatted Value |
---|---|---|---|
Temperature | TEMPERATURE | 236 | 23.6 C |
Water Temperature | TEMPERATURE | 236 | 23.6 C |
Humidity | RH / TEMPERATURE | 3455 / 25O1 | 34.55% 25.01 C |
Dry Contact | CONTACT | 0 or 1 | OPEN or CLOSED |
Water Detection | DETECT | 0 or 1 | NOT PRESENT or PRESENT |
Water Rope | DETECT | 0 or 1 | NOT PRESENT or PRESENT |
Open Close | CONTACT | 0 or 1 | OPEN or CLOSED |
Button | BUTTON | 0 or 1 | NOT PRESSED or PRESSED |
Asset | ASSET | PRESENT | |
Passive IR | PIR | 0 or 1 | NO MOTION or MOTION |
Activity | ACTIVITY | 0 or 1 | NO MOTION or MOTION |
VAC Detection | DETECT | 0 or 1 | NOT PRESENT or PRESENT |
VDC Detection | DETECT | 0 or 1 | NOT PRESENT or PRESENT |
Measure 0-20mA | CURRENT | 565 | 5.65 mA |
Measure 0-1 VDC | VOLTAGE | 1005 | 1.005 VDC |
Measure 0-5 VDC | VOLTAGE | 5241 | 5.241 VDC |
Measure 0-10 VDC | VOLTAGE | 8952 | 8.952 VDC |
Measure 0-50 VDC | VOLTAGE | 12313 | 12.313VDC |
Measure 0-500 VAC | VOLTAGE | 1106 | 110.6 VAC |
Resistance | RESISTANCE | 8096 | 809.6 Ohms |
Tilt | PITCH / ROLL | 9552 / 4226 | 95.52 DEG / 42.26 DEG |
Compass | HEADING | 124 | 124 DEG |
Basic Control | SWITCH | 0 or 1 | OPEN or CLOSED |
Strings
The Library includes a message string header file (TartsStrings.h). This is to make the readout more understandable. However, it is not needed. You can save code space by not including the table in your code file.