Duet
2022 February 21 18:44 stuartscott 1244231¤ 1971025¤
Duet is a pair of handheld devices that enable two people to collaborate on a drawing, or compete in games like Tic-Tac-Toe and Four-in-a-Row.
At the heart of each device sits an Adafruit Feather M0 with an RFM69HCW Radio, which is attached to a 2.4" 320x240 TFT Touchscreen FeatherWing, and powered by a Lithium Ion Polymer battery, all encapsulated in 3D-Printed case. Creating Duet was an interesting exploration of the intersection of Electronics, 3D Design/Printing, and Software.
-
2022 February 21 18:45 stuartscott 2536¤ 3939515¤
Getting Started
The first step was to create a pair of prototypes where a touch on one screen would be drawn on both displays, this would prove (or disprove) the feasibility of the project and allow rudimentary measurements of performance.
From an electronics perspective this was as simple as plugging the Feather into the FeatherWing - the radio is already mounted on the Feather, and the Feather already has a USB connector for programming, and a JST connector for attaching the battery. The only soldering work required is to attach an antenna for the radio and attach headers to the Feather if they weren't already installed.
From a software perspective this required one device to read the touch coordinates from the touchscreen, write to the display, and transmit the coordinates using the radio, while another device would receive the coordinates from the radio and write to the display.
Fortunately, Adafruit has published many examples and code samples for the Feather ecosystem, and both RadioHead and LowPowerLab have libraries and examples for communicating with the radio.
The communication protocol consisted of a 'D' meaning 'Draw', an integer for the x coordinate, a comma for separation, and an integer for the y coordinate, eg. D024,135.
Packets were delivered unreliably meaning that when one device transmits the information there is no guarantee that the other device receives it. This approach meant the drawing was smooth as there was very little overhead and if one or two packets weren't received there would only be a small pixel difference between the displays - not a big deal.
The RadioHead library was initially used as recommended by Adafruit, but experienced random crashes which were not easy to definitively track down. They may have been caused by SPI bus contention between the FeatherWing and the Radio - the Radio uses interrupts to notify the microprocessor when a packet is received, RadioHead's interrupt service routine uses the SPI bus to read the interrupt flags, Received Signal Strength Indicator (RSSI), and transfer the received payload into a buffer, but if the the radio interrupts when the microprocessor is in the middle of reading from the touchscreen, or writing something to the display, then the system can end up in a bad state.
The interrupt service routine in LowPowerLab's RFM69 library is much simpler - it just sets a boolean field '_haveData = true;' and exits. Thankfully, since switching to LowPowerLab's library there have not been any more spurious crashes.
-
2022 February 21 18:47 stuartscott 3272129¤ 1514742¤
System Indicators
Like many battery-powered devices, it is important to indicate the battery level so the user knows when they should charge the device.
Similarly, a device that communicates wirelessly should indicate the signal level so the user knows when the devices are getting too far apart.
An area in the top-right of the display was reserved for a battery meter, which would periodically update based on battery voltage measurements, and a signal meter which would update after each packet was received with the RSSI.
Each reading is added to a circular buffer from which the average is calculated and used to update the meters, this prevents the meters jumping around too much and appearing glitchy.
It was here that the first problem was encountered - measuring the battery voltage. While the Feather M0 can read the battery voltage from analog pin #7, and Adafruit kindly provided sample code to read and calibrate the value, it turned out that analog pin #7 and digital pin #9, which is the chip select wire for the display, are the same physical pin!
As if the folks at Adafruit had foreseen this exact scenario, the TFT FeatherWing was designed with jumpers on the chip select wires so the display could be reassigned by cutting the trace connecting it to digital pin #9 and soldering on a short wire to connect it to digital pin #11. However this meant that the tiny 105mAh LiPo battery that used to live between the headers connecting the Feather to the FeatherWing would no longer fit and would need to move next to the headers. Though this turned out to be a blessing in disguise because both the display and radio are relatively power-hungry and the new location has more space so to maximum running time the battery could be upgraded to the larger capacity of 260mAh.
-
2022 February 21 18:49 stuartscott 1205703¤ 1823782¤
Adding Games
The next step was to add some games! Tic-Tac-Toe and Four-in-a-Row were chosen due to their ubiquity and simplicity.
The gameplay is quite simple; players take turns touching the screen to make a move which is applied locally to their board and then transmitted to the other device to be applied to that board. Each device will then determine if the game is over, either because a player has won or because there are no more legal moves left.
Since the top-right corner of the display already held the battery and signal meters, it made sense to make a toolbar along the top edge from which the user could select and see the current mode; either Draw, Tic-Tac-Toe, Four-in-a-Row, or System Info (including Player #, Battery Voltage, RSSI, Radio Temperature, Free RAM).
The unreliable communication method that was initially chosen so the drawing was smooth was not sufficient for turn-based games in which each device needs to maintain consistent board state. Both the RadioHead and LowPowerLab library include a reliable communication method in which the receiver acknowledges receipt of each packet and the sender retransmits packets that are not acknowledged within a time limit.
-
2022 February 21 18:52 stuartscott 56630¤ 2525106¤
Designing the Case
First the electronics were measured and modeled in OpenSCAD so the case could fit them well. Extra cutouts were added for the visible area of the display, the USB port, the reset button, and On/Off slider switch.
Next, the Minkowski and hull operations were combined to create a thin shell that could encompass the electronics. Then mounts were added to hold the PCBs, nuts, and bolts.
Initially insets we created so buttons can be accessed, however this was suboptimal - while the reset button was easy to press, the on/off switch was small and difficult to slide.
Since all players would use the on/off switch but only some players would need to use the reset button, a cap was designed to fit onto the on/off switch and enable it to be gripped and slid more easily, and a hole was added so the reset button could be pressed with a paperclip.
-
2022 February 21 18:56 stuartscott 2292219¤ 525¤
Assembly
The case is printed in Polymaker Polylite PLA in four pieces; Front, Center, Back, and the Cap for the On/Off slider switch. It could be printed in three, with the Center and Back combined, but more filament would be wasted on supports.
-
Plug Feather into FeatherWing, then plug the Battery into Feather, and tuck excess wires between the Feather and FeatherWing.
-
Push the Cap onto the On/Off slider switch.
-
Put electronics into the Center/Back case, put front panel on, and tighten the nuts and bolts.
The total package weights 55 grams.
-
2022 February 21 18:57 stuartscott 1051¤
Future Work
The final software only takes up ~21% of the Feather's 256K FLASH, so there is loads of room for more features and improvements!
-
Touchscreen Calibration - while the calibration values provided by Adafruit work well, they are not perfect, particularly towards the edges of the Player 2 (Red) device. An onboard calibration program could get more accurate calibration data by asking the player to touch a series of dots.
-
Backlight Brightness - the FeatherWing includes a PCB pad through which the brightness of the backlight can be controlled with a PWM signal.
-
Light/Dark Mode - a toggle switch could allow a player to choose between a light and dark mode.
-
SD Card - the FeatherWing includes an SD Card slot which could be used to load games from an SD Card, enabling a wider variety of games to be played without needing to reflash the software.
-
Antenna - the antenna could be tuned to improve range.
-
More Players - a future project could create a 4-Player version called Quartet, or an 8-Player version called Octet.
-
-
-
-
-
-
Convey is made available by Aletheia Ware under the Terms of Service and Privacy Policy.
Convey is an open-source project released under the Apache 2.0 License and hosted on Github.
© 2021 Aletheia Ware LLC. All rights reserved.