This is my third design of an RPM Letterboard. To better understand its application, the write-up of the second design is the best guide. And just for comparison, the first prototype also provides some insights (and perspective on how it has evolved).
In a nutshell, it's a mobile & programmable whiteboard with capacitive touch and, acting as a Bluetooth keyboard, sends output to a text-to-speech capable device (i.e., an iPad). Also providing on-board visual (LED) and audio (Piezo) feedback of touched letters & symbols as they are drawn on the whiteboard.
It would have been orders of magnitude easier to write code for an App on iOS/Android, but some autistic individuals find the light emitted by a screen as sensory noise, thus making it much harder to maintain focus during purposeful communication.
This guide encompasses the things I learned, both as a reference to others (hopefully) and for my future self.
Functional DescriptionThe letterboard consists of a 22x14 matrix of “Touch Electrodes” (TE). Each “TE” in turn, consists of a 2x3 matrix of copper pads. The pads are small enough so that a finger will touch at least 2 of the copper pads, providing the row and column that allow for its usage as a 2D touchpad (albeit with a 22x14 “pixel” resolution. Since this is only for letters, this is fine)
Each row and column of the TE’s connect to one channel of the three 12-Key Capacitive Touch Sensor Breakouts (Adafruit MPR121) for a total of 36 channels (22 columns + 14 rows = 36 channels). These 3 breakout boards use I2C to connect to the MCU and each has a distinct I2C address. The breakout boards are added to the PCB using SMD header pins (datasheet)
The MCU is an ESP32 (Adafruit ESP32 Feather). Because the MCU’s USB port will also serve as the letterboard’s battery charger port, it is added to the PCB using through-hole pins (to create a solid union that can withstand the multiple connect/disconnects of a USB charger).
The letterboard also has a 10x6 LED matrix interspersed in the TE matrix. The LEDs are controlled by two 74HC595 Shift Registers (datasheet), the first controlling the 6 rows as current source (each with a 1206 250mW 110-ohm SMD resistor - datasheet) and the second controlling the 10 columns as current sinks. The LEDs are 1204 SMD reverse mounted color Amber with a max forward voltage of 2.4V and max forward current of 20mA (datasheet). The LEDs serve as confirmation of a touch, so only one LED will be ON at any given time (by driving HIGH one row and LOW one column, making the intersection light up) and only for 500ms or less. Because of this, there should be no problem by driving the LED with the 3.3v regulated output of the MCU. Each of the Shift Registers has a 0805 0.01uF SMD decoupling capacitor (datasheet).
There is also a 2016 SMD piezo buzzer (datasheet) and 5 THT slide SPDT switches (Model EG1218 datasheet) for turning on/off specific functions of the letterboard (i.e., as DIP switches). These connect to individual pins in the MCU (plus power & GND).
Finally, there’s another THT slide switch that serves as the system’s general On/Off. This switch receives the Power cable from a LiPO battery (datasheet) which is not added on the PCB but resides inside the letterboard’s case and delivers power to the MCU’s VBAT pin.
PCB - Design & BuildBeing my first PCB ever, I started learning with KiCad Like a Pro 3rd edition in Udemy. I then went further down the rabbit hole with San Francisco Circuits' PCB School and consulted a couple more sources like The Hitchhiker's Guide to PCB Design and Sierra Circuit's PCB Knowledge Base. A good reference site is Tech Explorations' YouTube Channel.
To create a first draft of a prototype and then, to validate my near-final design, I hired Kasun E. via Upwork, again a first for me and I must say, an extraordinary experience. This helped me a lot in producing the final PCB design.
Capacitive Touch Sensing Electrodes
- An outline of common challenges and provision of solutions and guidance: Capacitive Touch Sensor Design Guide (AN2934) from Microchip including pitch & separation for surface sensor (aka 2D, self vs mutual capacitance)
- Critical concepts: Designing Touch Sensing Electrodes (AN3863) from NXP. (Focused on Items 3.1 Traces for clearance, width & routing, 3.2 Electrode Pattern Design, 3.3 Electrode Placement, 3.4 Correct use of Planes, 3.6 Virtual Ground and Considerations in Battery Operated Applications, and 4.5 Electrode Patterns: Touchpad
(The KiCad 6 files are available to anyone upon simple request)
Touch Matrix
- The letterboard operates with a single-finger touch, so it's designed to have a minimum of 1 and a maximum of four TE's touched at any one time and always at least one row and one column. Any other case is filtered out in code (i.e. multitouch or touch at the edges)
- To start designing custom symbols, see a basic tutorial from Atomic14 and then my own discussion on the KiCad forum to use SMD pads as capacitive touch sensing electrodes.
- There are two kinds of TE's in the matrix: labeled EVEN and ODD for the number of the copper pad that's connected on the top layer and the copper pad that's connected using Via's in the bottom layer.
- To keep distances to a minimum, odd columns connect to the top MPR121 and even columns to the bottom MPR121 with the rows connecting to the middle MPR121.
- Details of copper pads on the finished PCB
LED Matrix
- The Basics: LED Circuit Design (forward current & voltage, voltage drop, resistors) from The Engineering Mindset
- The Basics: 74HC595 & 74HC165 Shift Registers from DroneBot Workshop
- About LED matrices: LED Matrix Introduction, Daisy Chain Shift Registers, and An 8x8 LED Matrix
- 74HC595 Datasheet (incl. pinout of different layouts, operating conditions like voltage and current limits).
- Reverse Mount SMD LED 1204 Datasheet (incl. dimensions to fit in PCB hole, color voltage & current ratings) to be driven by 3.3v
- As an option (not used, better but more expensive) 8x8 Dot Matrix with MAX7219
Manufacture
- Discussions on surface finish. HASL vs ENIG and Final Finish Comparison Table. In short: HASL has lowest cost, but not recommended for lead pitches less than 0.64mm (.025 inch) due to solder bridging and uneven thickness.
- JLCPCB: PCB Manufacturing Capabilities.PCB & Stencil Nuances when Ordering
- SMD soldering and equipment used. SMD Soldering Tutorial, SMD Stencil Reflow Soldering Tutorial, PCB Key Terms (from Learn KiCad 6)
- To learn Fusion360, I first hit wermy's Crash Course, then purchased Designing for 3D Printing with Fusion 360 from Udemy, then practiced with Product Design Online's various videos. Needless to say, this is like painting or writing: I'll have to practice for the rest of my life.
- I sent for manufacture in JLCPCB a resin version and a filament version. Interesting to see the differences in texture and weight. Note to self: now that my Prusa is on its way, I must circle back to compare and assess pricing in Craftcloud.
- Resin resulted is a better finish, but a much higher weight and less precise dimensions. The filament enclosure was printed as separate parts and then glued together.
- To cover the PCB copper pads (i.e., the "Touch Electrodes") and create the visual user interface, I tested various options and settled on Post-it Dry Erase Whiteboard Film Surface, which allows to draw the three different keyboard layouts in the letterboard.
(The Fusion360 files are available to anyone upon simple request)
- There are three letterboard formats: Large, Medium and QWERTY. Each can be selected by entering Config Mode (putting all Functional Switches to OFF) and touching the first, middle or last third of the board, respectively. To assist in identifying the selected format, that third of the LED Matrix is flashed and a distinct tune is played for each.
- The selected format is then drawn using standard whiteboard markers
- The voice can be selected from the iOS device's Accessibility configuration. Using the Functional Switches, the user can choose to send letters, and/or words and/or sentences to be read out loud.
- Erasing and drawing a different format is just as easy
- MPR121. Having gone through Adafruit’s learning guide (a good starting point), I reached the limit of what can be done with the Set Thresholds public method of the MPR121 library. I created a program for calibration of individual electrode sensitivity using baseline filtering, touch filtering & debounce, and the MPR121's autoconfigure feature, all during program execution, thus avoiding the need to recompile & reload with each scenario being tested. Its objective is finding the optimal calibration parameters to be later implemented in the appropriate production program. I posted the summary of the MPR121 capabilities, the NXP application notes, the changes made to the MPR121 library in a tutorial on the Arduino Forum. The code is on Github.
- Interrupts. Reading the SPDT switches could be done in the main loop(), but I wanted to use Interrupts (to learn about them and to avoid using loop() cpu time, although now I see its overkill, but that's what makes it fun!). I went through Function Pointers in Gammon's Forum, but my comprehension ability hit a wall. Passing arguments to Interrupt Routines was the solution (the forum discussion includes advanced topics like compile-time recursion and lambda functions both of which I did not use). Also useful: the Espressif Docs on GPIO: Interrupts
- BLE Keyboard. The only ESP32-BLE Keyboard library I've found is T-vK's. To minimize memory usage, it can use NimBLE-Mode albeit with some mods to compile in Arduino. Some tinkering is necessary to compensate the speed at which iOS can receive and Text-To-Speech characters and words. Also, the library handles only standard US keyboard, to special characters (like "ñ") have to be sent using the equivalent keyboard character (like ";"),
- Debug Output. A nifty method I found for managing debug output is creating a DEBUG variable and redirecting the Serial.print() commands to the bleKeyboard (for wireless serial outout), to themselves (for standard serial monitor) or to null (for production versions).
- Permanent Data Storage. To store the selected configuration parameters, I use the Preferences library (unique to arduino-esp32, the replacement for the Arduino EEPROM library). Works best for storing many small values, rather than a few large values (in that case, better to useLittleFS as file system library instead). Don't miss Random Nerd Tutorials' take on the subject.
- LED Matrix. Core references include Serial to Parallel Shifting-Out with a 74HC595 and Advanced IO > ShiftOut. This being a 10x6 matrix (columns 1 thru 10, rows 1 thru 6) managed by two 74HC595 shift registers (see schematic), specific bytes had to be assembled for letterboard configurations using one or two LEDs per letter. These bytes are assembled in Declarations.h as seen here:
- Letterboard Configuration Mode. When the user sets all 5 switches to OFF (i.e., no letter, word or phrase output and no LED nor Buzzer feedback), the system enters config mode. At this point, all touch detection and management routines are focused on the three possible letterboard configurations: touching anything on the rightmost third of the board (column > 14), sets layout #3, touching anything on the middle of the board (columns > 7), sets layout #2 and touching anything on the first third of the board sets layout #1, saving these changes in permanent memory via Preferences.
- Note to self: Always circle back ro the ESP32 Arduino Core documentation
All of these routines allow for a short, sweet & simple loop()
- The SPDT switches are affected by ground bounce. When using interrupts, the ISR is triggered continuously when more than 2 pins are LOW. The issue is currently managed in code and could be further mitigated (albeit not eliminated) by not using interrupts. Must read more on decoupling and possibly test using Wokwi.
- PCB can benefit from using 3 distinct types of ground (for analog, digital, and power circuits) with their respective cap separators.
- The MCU's antenna is placed over the ground plane which can badly detune the antenna and impair the WiFi / Bluetooth performance. Beginner's luck: I placed the MCU over headers, creating a 2mm air gap that mitigated (but not eliminated) the issue.
- Increase Copper Weight of Outer Layers to possibly increase capacitance of the touch pads (albeit nearly double the cost if 2oz copper weight), Look at Trace Resistance Calculator from AllAboutCircuits,
- Use a connector instead of soldering the battery cables directly to holes in the PCB: with a little manipulation, it breaks off.
- In the 3D printed enclosure, I missed how the different height of all the PCB elements would affect accessibility to the config switches. Will have to redesign this portion.
- The smallest SMT were the caps @ 0805. Consider using bigger components since we don't really have am issue with available real-estate on the PCB.
- ESP32 Usable Flash Memory: the ESP32 development boards from non-Espressif manufacturers usually can't use the full on-board memory because their partition schemes on Espressif's Arduino ESP32 core are limited. A quick (manual) fix is to put a partition.cvs in the sketch: it will be picked up instead of the one in the menu. Adafruit has "...a PR to Espressif to fix the partition scheme for 8MB. It may take a while for them to review and merge...".
- Consider the latest generation of touch sensing technology from Microchip.
There are 5 files (I name them.h to bypass the alphabetical order assigned by the Arduino IDE if they were all named.ino):
- RC3.ino (i.e. Release Candidate 3) is the main program and contains the setup() and loop() functions.
- Declarations.h has the variables, constants & #includes, all grouped by function
- MPR121.h is the modified & simplified version of the standard MPR121 library contained now in a single file (i.e., no.cpp file)
- fCore.h contains the core functionality routines (programming mode, read & output touched data, manage config switches & interrupts)
- fSupport.h contains the supporting functionality routines (buzz, LEDs, symbol tables, battery).
- tunes.h contains the melodies and routines used in the config mode and at system startup to identify which mode is selected.
Comments
Please log in or sign up to comment.