Inaugural Post: On Wireless Prop Networking

First off, welcome to the initial post of these musings. The intent behind this site is to have someplace better suited than typical social media for rambling about current crafting projects, discussing lessons learned in various projects, possibly posting instructions or the like. For this first post, I intend to discuss what I’ve learned in my first forays into developing electrical prop driven puzzles for a campaign boffer LARP, specifically regarding the networking aspect of the design. How the pieces communicate, how and where the state information resides.

The Initial Project

I had been working with some electrically driven props for a character I play in Cottington. Nothing very complicated, but it did have some basic concept of being in different states, and requiring some user input. A very basic system necessitating the user to ‘synchronize’ a device to start with by adjusting dials, and providing feedback so that the user would be able to recognize their progress on that synchronization. I realized that I wanted to push further and make more interactive and solvable puzzles, something more involved than I could justify as a prop for a player character. It was at this point that I talked with the staff I had been a core NPC for at Madrigal, and soon wound up being, perhaps foolishly, given carte blanche to develop an entire mod. Given the original impetus, a key design goal was to, in effect, have an electronic prop driven escape room style encounter as a mod.

It was from this that the Steps of Sobek mod was born. One of the concepts that drove it was the idea of splitting the players into two groups, and requiring coordination between the groups. This in turn drove a need to be able to have the props communicate wirelessly, in order to enable that design goal.

Hardware

With wireless communication deemed a requirement, one of my first steps was to do a cursory investigation of what wireless communication options were available. At that point in time, all of my experience had been with the actual Arduino ecosystem, using Arduino Uno and Megas. There were three principle options I investigated to begin with. Generic 433mhz RF transmitter and receiver modules, the nrf24l01 wireless transceiver modules, and the esp8266-01 wi-fi module.

  • Generic 433 mhz RF Modules
    • Pros: Individual modules are cheap.
    • Cons: Required two separate modules to both transmit and receive. Required construction of antenna with finicky specific length requirements to optimize range. No channels or the like, only one unit can transmit at a time or signals will be scrambled.
  • nrf24l01
    • Pros: Radio Transceiver, requires only a single module and no need for an access point. Can handle moderate number of channels at once.
    • Cons: Transceiver is potentially limited to only receive or only transmit at any point in time, juggling timing of messages around this while doable would be involved. Antenna for improved range available but somewhat bulky. Number of channels potentially limited to six, which may prove inadequate.
  • esp8266-01
    • Pros: Wi-Fi meant personal experience with network coding could be taken advantage of. With external access point(potentially battery powered router), effectively limitless number of props could be networked. Makes integration of a laptop very easy.
    • Cons: Theoretically higher power draw, since I was working off of batteries. Requires external access point to truly provide limitless prop count(the esp8266-01 can serve as a limited access point for roughly 6 connections, in theory).

The generic 433mhz RF systems would be a huge increase in effort with only a savings in cost to offset it. The nrf24l01 was a reasonable choice, but the flexibility and power of having a full actual network stack by going with wi-fi won out in the end.

In the process of actually developing the props, the ESP32s development boards cropped up as additional tools to use. They combine the wi-fi capabilities of the esp8266-01 with being a full microcontroller with similar capabilities(in fact, far more memory and processing speed) than the Arduino Uno or Mega.

There were some minor tribulations in moving to ESP32s development from Arduino development. There are a number of different ways to actually program the ESP32s, one which is directly based on the Arduino ecosystem, and others which are not. Since I had already developed some libraries within the Arduino style framework, I went with the Arduino style ESP32s programming approach. The fact that the ESP32s space is split between different entire architectures at the software layer, paired with the fact that the ESP32s was not intentionally built as a hobbyist platform in the same way the Arduino family was, leads to a situation where there are a lot of conflicting guides and approaches, and a lot more potential hang-ups when first learning the platform. For anyone interested in learning these things, I feel like starting with Arduino and then moving on is probably a better approach, so as to get the basics understood before having to grapple with the complications and rough edges that get added in when working with the ESP32s.

That said, the increased memory, far faster connection to the network time, ease in not needing to wire in a secondary processor module for every prop(and thus less connections or wires to potentially have hardware failure with at runtime) have lead me to the decision that, moving forward, I intend to use the ESP32s development boards by default. I may look into the esp8266 variants other than the 01, which are less powerful than the ESP32s, but can be used as stand alone modules in a similar fashion as an alternative.

Finite State Machines And Where The State And Logic Live

The implementation of the puzzle state was handled by implementing logic in each prop following your fairly standard finite state machine approach. The one key thing to mention in terms of design which I realized afterwards could use improvement was the fact that each individual prop was it’s own finite state machine, with its own state.

There proved to be two big flaws with the state machines living in the props. First, as part of the development process, I had a very simply console style application for viewing output and providing simple input to the system, and I was able to develop a tool for sending messages to potentially fix or address issues during a live use of the system. The problem was that if a specific prop had significant and complicated state information to convey, it would require a network protocol to send the entire state to the prop in order to ‘reset’ or clear an error during runtime. Second, it is much more difficult to reflash a new program to a prop during an event, with the tools available on site. While this did not directly come up, supporting different mods with different puzzles or logic behind them would be, not impossible, but very awkward if the logic and state data was maintained in the props themselves.

By redesigning the props to be entirely focused around networking, simply taking network inputs to perform actions/provide feedback to players and providing network output for any input from the players, we could make the props reusable in different puzzle configurations without needing to reflash and update the props themselves during an event. And since the props would not be responsible for puzzle logic and state information, any external tools for overriding systems would work without limitations. This does impose the requirement that an external piece would provide all puzzle state tracking and the logic for adjudicating the mechanics, in the form of an application or similar on a laptop. However, since such a tool will likely be wanted for some degree of overrides no matter what, this really is not a significant imposition and will be a net benefit long term.

When reusing the light board and pressure pads from the Steps of Sobek mod for a Crooked House/Red Door mod, I began to implement some of these design changes, and it definitely simplified things during the debugging and development phases, though I still wound up with a very small bit of state information in the light board which I should have avoided. The puzzle mechanics were essentially a Simon game, and the playing of the pattern as an example was managed by the light board. I definitely should have gone to a system where the laptop simply instructed the light board as to what lights to turn on or off, but the network protocol implementation I was working with had some message size limitations which discouraged going all the way with that approach.

Network Protocol

The Arduino build system does provide the capability to develop libraries, and I developed a number of fairly simple ones for the props. In particular, a general network protocol was developed and a library implementation was thrown together so that it could rapidly be reused to develop the different props.

The wi-fi modules did have a networking limitation in that they could only support a limited number of TCP sockets at a time. A low enough number that I decided to employ a broadcast UDP approach with a self implemented message received ‘ack’ response protocol to deal with the non-guaranteed delivery of UDP packets. This also avoided the difficulties in not necessarily knowing the IP addresses that would be assigned to each specific prop, or the connected laptop application. There are actually two different versions of this library, one that works with the Arduinos communicating via separate esp8266-01 modules, and a second for use on the ESP32s development boards. The protocol is the same, but the libraries to access the network differ enough that separate libraries were somewhat easier to manage.

Given the desire to move to a system where all props simply connect to a single control application on a laptop, with the state and puzzle logic living in the application, this means that the TCP socket limitation will no longer actually be an impediment. I have begun the work on a new networking library, as well as computer side server code, to follow this new pattern. By using TCP sockets it will no longer be necessary to rely on responses to verify messages were heard, and I’ll make certain to have a message format with more size flexibility than the previous approach (which was principally limited since memory on an Arduino is very tight, and if you need to have a queue of sent messages so you can track if you’ve received acknowledgement of receipt from the destination, the messages cannot be long).

For reference in case anyone is interested, I have uploaded both the Arduino and the ESP32 versions of the networking libraries.

Leave a Reply

Your email address will not be published. Required fields are marked *