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.

























TypeFunction CallDescription
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:




















TypeFunction CallDescription
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:




















TypeFunction CallDescription
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:




















TypeFunction CallDescription
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:



































TypeFunction CallDescription
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:















TypeFunction CallDescription
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:













































TypeParameterDescription
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:















TypeFunction CallDescription
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:




















TypeFunction CallDescription
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:













































StateDescription
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:






























TypeFunction CallDescription
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:




















TypeFunction CallDescription
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 TypeSensor TypeProfile #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:








































TypeFunction CallDescription
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:






























TypeFunction CallDescription
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 TypeNameRaw ValueFormatted 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.