Design Philosophy
SwadgePass is a feature where Swadges can transmit and receive small packets of data while idle. This feature was inspired by Nintendo's StreetPass. SwadgePass data may include things like avatar data or high scores from all Swadge Modes.
SwadgePass uses ESP-NOW, not WiFi or Bluetooth. See hdw-esp-now.h.
Transmission and Reception
Packets are transmitted with sendSwadgePass(). To preserve battery life, this should only be called when the Swadge is idling in it's LED animation mode (dance.c
). In this state, the Swadge will transmit every 7.5s, +/- 1.875s. Randomness ensures two Swadges don't get locked out-of-sync while transmitting and receiving. After transmitting, the Swadge stays awake and listening for 700ms. While not transmitting or listening, the Swadge light sleeps for 100ms increments, updating the LEDs ten times per second.
The receiver is initialized with initSwadgePassReceiver() and packets are received with receiveSwadgePass(). Any incoming packet may be passed to this function, including from modes which are using ESP-NOW for other purposes, as long as the receiver was initialized. deinitSwadgePassReceiver() frees memory allocated for the receiver.
During normal operation, if not explicitly used the WiFi radio is turned off and SwadgePass data is neither transmitted nor received.
Usage
Transmission and reception of SwadgePass data is automatic in dance.c
and does not need to be managed by each SwadgeMode (see Transmission and Reception). Other modes may transmit and receive SwadgePass data, but it is discouraged for battery reasons.
Building a Packet for Transmission
A swadgePassPacket_t is built with the function fillSwadgePassPacket(), which calls each mode's swadgeMode_t.fnAddToSwadgePassPacket function. Each mode may add data to swadgePassPacket_t, and modes must not modify data which is not their own. The total packet size must be less than 250 bytes, which is the largest possible ESP-NOW packet.
- Warning
- swadgeMode_t.fnAddToSwadgePassPacket is called when the Swadge Mode is not initialized, so it must not rely on memory allocated or data loaded in swadgeMode_t.fnEnterMode
Using Received SwadgePass Data
Swadge Modes may check received SwadgePass data by giving an empty list_t to getSwadgePasses() to fill. getSwadgePasses() may fill the list with all received SwadgePass data, or only SwadgePass data which has not been used by the given mode yet. After being filled, the list contain pointers to swadgePassData_t and may be iterated through. swadgePassData_t.key is the string representation of the source MAC address. SwadgePass data will not change during Swadge Modes (aside from dance.c
), so the data should be loaded once and saved for the mode's lifetime. getSwadgePasses() should not be called repeatedly.
If the Swadge Mode wants to use each SwadgePass data from a source only once, it can be checked with isPacketUsedByMode(). This may be useful for an RPG game where each received SwadgePass gets to make one action. Once the data is used, it can be marked as such with setPacketUsedByMode(). This will save the used state to non-volatile storage, which persists reboots.
When the Swadge Mode is finished with the SwadgePass data, it must be freed with freeSwadgePasses().
Example
Building a Packet for Transmission Example
swadgeMode_t.fnAddToSwadgePassPacket would be set to this example function.
{
packet->myHighScore = 9001;
}
A SwadgePass packet which is transmitted over ESP NOW.
Definition swadgePass.h:120
Using Received SwadgePass Data Example
while (spNode)
{
{
ESP_LOGI("SP", "Receive from %s. Preamble is %d", spd->key, spd->data.packet.preamble);
}
}
struct node * next
The next node in the list.
Definition linked_list.h:79
struct node node_t
A node in a doubly linked list with pointers to the previous and next values (which may be NULL),...
void * val
A pointer to the data for this node.
Definition linked_list.h:78
node_t * first
The first node in the list.
Definition linked_list.h:88
A doubly linked list with pointers to the first and last nodes.
Definition linked_list.h:87
void getSwadgePasses(list_t *swadgePasses, const struct swadgeMode *mode, bool getUsed)
Fill a list with SwadgePass data. The list should be empty before calling this function.
Definition swadgePass.c:246
bool isPacketUsedByMode(swadgePassData_t *data, const struct swadgeMode *mode)
Return if a given mode has used this SwadgePass data yet.
Definition swadgePass.c:314
void setPacketUsedByMode(swadgePassData_t *data, const struct swadgeMode *mode, bool isUsed)
Set if a given mode has used this SwadgePass data yet.
Definition swadgePass.c:329
SwadgePass data that is received from another Swadge.
Definition swadgePass.h:152