Disclaimer: All people described below are fictional and any similarity to friends or family of the author is purely coincidental.
The holidays can be a conversational minefield dominated by a select few who possess an overdeveloped gift of gab, capable of stretching a two-minute thought into a half-hour diatribe. You sit helplessly bored as they drone on about topics you have no interest in. Then, a ray of hope! The conversation shifts to a subject where your nerdy expertise could add just the right comment to make the discussion truly meaningful for everyone listening. You patiently wait for a gap in the chitchat, but there aren't any. Don't these people breathe?
As the words begin to slow down, you sense your opportunity to speak. But then someone cuts you off and changes the subject. Your hopes of meaningful participation are dashed.
But don’t give up. There's hope. BLAB to the rescue!
How it WorksBLAB is the nerdy solution that can turn conversations into fair and balanced exchanges where everyone with a desire to join in is given a chance to speak. It’s "blinky wear" with a purpose. A BLAB-Badge is given to each participant in the conversation. When the LED eyes are both blue, it means you are in listening mode.
If you wish to talk, you hit the button, and one eye turns green, indicating you are waiting to speak. It's your turn to talk when both eyes turn green.
When you are done, simply hit the button again, and both eyes will turn blue again. BLAB then finds the person waiting who has spoken the least and gives them the opportunity to speak.
However, some people are oblivious to others' desire to speak and don't easily yield their turn. BLAB uses its AI (Abbreviated Intelligence) to determine when the talker has gone on long enough and gives them a gentle warning by making both eyes on their badge turn red.
If they still don't get the message, BLAB broadcasts the SHUTUP command, making the eyes on all the badges flash, indicating that this person is the conversational equivalent of a lowlife scoundrel. It also penalizes them, ensuring they are the last to speak for a long time to come.
Here's a short demo of BLAB in action.
Project ReincarnationWith a whole basement full of dead projects, one stood out as a prime candidate for the 'Junk Drawer Competition': GUS - Game for Understanding Social Distancing. This project was initially submitted a few years ago as an entry in a Hackster.io contest to address the COVID pandemic. Sadly, the decline of COVID removed GUS's reason to exist, and it was dispatched to the junk drawer. GUS was a Bluetooth mesh network where each node of the network was a GUS Badge with an nrf52832 processor and two RGB LEDs.
Reincarnation isn’t as easy as it sounds. The SDK was out of date, the code wouldn’t build anymore, several of the hand-built GUS PCBs were no longer functional, and the original producer of the Bluetooth module seemed to have disappeared. However, there were enough remnants of GUS to morph it into BLAB.
HardwareThe hardware modifications were fairly straightforward. I added two switches to the available GPIOs and then 3D-printed a new badge cover. The PCB for the original GUS badge was designed in KiCad.
Sending the gerbers out to have the boards fabricated would have been too easy, so I exported the layout as a .dxf file and used the CarbideCreate application to generate a g-code file. I was able to use my Taig CNC mill to create the PCBs. More details are available in my GUS project write-up.
For the new badge cover design, I used ChatGPT for ideas. Although most of its suggestions were uninspiring, there was one I really liked. I tried to have it refine the one I preferred, but it couldn’t seem to identify which design I was referring to. Ultimately, I used Fusion 360 to create a simple badge design from the image, with the eye holes aligned to match the PCB LEDs. I then exported the design to PrusaSlicer to slice it. The simplicity of the design allowed me to pause the printer halfway through to change the filament and achieve a two-color badge. I also 3D-printed a small bracket to hold the PCB, which was hot-glued to the back. Although it would have been nice to 3D print a single design with the bracket integrated, the two-piece design had no overhangs, and aligning the LEDs was easily done during the hot glue process.
SoftwareThe software is heavily based on the Nordic SDK Bluetooth Mesh Chat example. Initially, the plan was to modify the original GUS software, which was built from the Chat sample. This would have simplified the process as the board configuration was already done. However, the GUS code, built using the Nordic SDK v1.50, failed to compile properly. As a result, Plan B was to utilize code from another project that used SDK v2.2. In hindsight, it would have been better to use the Chat example from the latest SDK.
The chat_cli.c
and model_handler.c
files from the Chat example provide the mechanism to send private and broadcasted messages between the badges. A conversation starts when the master button is pressed on one of the badges. That badge becomes the master and broadcasts a cmd_new_session
message to all badges, putting them into the listening state.
// Commands sent in messages
enum turnz_cmd {
cmd_new_session = 'N', // Broadcast
cmd_listening = 'L', // Private
cmd_waiting = 'W', // Private
cmd_talk_request = 'R', // Private
cmd_talk_start = 'T', // Private
cmd_talk_warning = 'X', // Private
cmd_talk_expired = 'Y', // Broadcast
cmd_talk_expired_reset = 'Z', // Broadcast
};
The only messages the user badges send are talk request messages to the master when their button is pressed. The only action the user badges take is to set or blink the LEDs when a message is received. Hence, the user operation is simple, with the master handling most of the work, such as keeping track of the users' states.
// States of the players
enum turnz_state {
state_startup,
state_listening,
state_waiting,
state_talking,
};
The master also keeps track of how long someone has been talking while another is waiting and their total talking time, which is used to decide who should talk next. One issue with chat messages is that you cannot send a message from a message handler, so the master also tracks talk requests and handles them in the main loop.
// Used by the master player to keep track of players
struct players {
uint16_t addr;
bool talk_request;
int time_talking;
int time_total;
int state;
} players[MAX_PLAYERS];
The rest of the master code implements the conversation rules: selecting who talks next, warning talkers they are running out of time, and sending the dreaded SHUT_UP message when the talk time runs out.
// Warn the talking player if they have been talking for more than WARNING_TIME
// If it has been more than EXPIRED_TIME seconds, send cmd_talk_expired to all players
// After 2 more seconds, set player's state to state_listen and add 2 * EXPIRED_TIME to their time_total
static void check_talk_time() {
// Print the time_talking and time_total for each player every second
if ((get_timer() % (1000 / TICK_INTERVAL_MS)) == 0) {
printk("time: (%d %d), (%d, %d), (%d, %d)\n",
players[0].time_talking, players[0].time_total, players[1].time_talking,
players[1].time_total, players[2].time_talking, players[2].time_total);
}
for (int i = 0; i < MAX_PLAYERS; i++) {
if (players[i].addr != 0 && players[i].state == state_talking) {
if (players[i].time_talking == SHUTUP_TIME) {
broadcast_command(cmd_talk_expired_reset);
private_command(players[i].addr, cmd_listening);
players[i].state = state_listening;
players[i].time_talking = 0;
players[i].time_total += OVERTIME_PENALTY;
printk("shutup issued\n");
} else if (players[i].time_talking == EXPIRED_TIME) {
broadcast_command(cmd_talk_expired);
printk("expired issued\n");
} else if (players[i].time_talking == WARNING_TIME) {
private_command(players[i].addr, cmd_talk_warning);
printk("warning issued\n");
} else {
// printk("time_talking: %d\n", players[i].time_talking);
}
return;
}
}
}
Summary
The BLAB project breathes new life into the GUS project by leveraging the Nordic SDK Bluetooth Mesh Chat example. Despite challenges with outdated SDKs and non-functional PCBs, BLAB successfully integrates new hardware modifications and software refinements. The project employs a master-slave architecture where badges communicate via defined commands, ensuring a balanced conversation. The master badge handles most operations, including tracking talk times and implementing conversation rules. The result is an innovative, fair, and engaging way to manage group discussions.
Comments