Charter 27 · count · reserve project

The Ballot Bug

Anonymous Preference Counter

Ask one small garden question and publish only the total.

Difficulty
★☆☆
Prefix
bb
Zone
entrance
Type
ballot-node
Device
bb-01
Build time
6 hours

Mission

Build this

Build a robust one-question voting object that confirms each accepted press and publishes an aggregate count without identities.

One kit, one team repository.

Borrowed parts are labelled below and have a fallback. The registered device ID is fixed; sensing and behaviour decisions remain yours.

Bill of materials

Parts

SourcePartFallback
○ fablabLarge push buttonsUse two labelled kit push buttons
● kitOLED or four-digit display—
● kitSG90 servo—

Disconnect USB before rewiring. Motors, the relay, and the servo need appropriate power and a shared ground. Never drive an actuator from the ESP32 3V3 pin.

Backup assignment · your invitation

Ask one small question and make every press count once

A cheerful button can be surprisingly demanding. People tap, hold, lean, change their mind, press together, and wonder whether the machine noticed. The Ballot Bug must make one simple public question feel clear and fair.

Your device offers two reviewed choices, accepts deliberate presses, acknowledges each accepted vote, and publishes only an aggregate total. It does not identify voters, build profiles, or pretend that a playful garden prompt is a scientific opinion poll.

The ballot promise

No identity, camera, device address, timestamp trail, or individual response leaves the object. Publish the aggregate total, not a history of people.

Meet the idea

A press is a physical interval, not one perfect electrical pulse

When metal contacts meet, they often bounce apart and together for a few milliseconds. A held button then remains electrically active for far longer. Code that counts every LOW reading can turn one finger into hundreds of votes.

A useful press has a beginning, an accepted moment, and a release before the same button can vote again. This is both debounce and rearming.

Two buttons create another question: what happens if they are pressed nearly together? Decide before testing. You may accept the first stable choice, reject both as ambiguous, or use another documented rule.

Candidate press

A button has changed, but the device is still checking that the contact remains stable.

Accepted vote

One deliberate press passed the rule and may increment the aggregate total once.

Rearmed

All required buttons have been released long enough for the next visitor.

Signal chainHow one finger becomes one anonymous total
  1. in the worldA visitor pressesA finger may tap, hold, or press near another choice.
  2. the partButton contactsMechanical movement creates noisy HIGH and LOW edges.
  3. electricalStable candidateTimers reject bounce and recognise ambiguity.
  4. in the codeAccepted totalExactly one is added after the fixed rule succeeds.
  5. on the spinecountOnly the aggregate accepted-vote count is published.

The selected button can control local feedback; the registered garden message contains only the growing aggregate event count.

The lovely trick

Acknowledgement is part of the measurement

Without immediate feedback, a visitor may press again because they do not know whether the first vote worked. That makes the interface create the double counts it is supposed to prevent.

Use one short, accessible acknowledgement after acceptance—not while the press is merely a candidate. Make it visible as well as physical or audible so more visitors can understand it.

Decision flowOne accepted vote from press to release
  1. 01ReadyBoth buttons are released and the bug invites one choice.
    then, one button begins,
  2. 02CandidateOne input remains active through the debounce interval.
    then, stable and unambiguous,
  3. 03AcceptedIncrement once and acknowledge the choice locally.
    then, gesture completes,
  4. 04Wait for releaseIgnore the held contact until the rearming rule succeeds.

Back to the start: Return to ready only after the required release interval.

The gesture happens once after acceptance. A held button cannot return directly to candidate.

A total is not a representative survey.

Some people may vote twice, some may never approach, and button placement can influence choices. Present the result as interactions with this object during a documented period—not what all garden visitors believe.

Wiring

Make both buttons boring before making the bug charming

Print raw button states, then accepted events. Test long holds and simultaneous presses before adding the display or servo. The physical labels should remain next to their buttons even when the screen is asleep.

The power rule: Each button closes an ESP32 input to ground and uses the internal pull-up. The OLED uses 3V3. Power the servo from a separate 5 V supply and join grounds.

Bench referenceOpen the exact wiring map
WiringTwo anonymous choices, local display, and one acknowledgement
ESP32GPIO 25Choice A buttonone sideGNDChoice A buttonother sideGPIO 26Choice B buttonone sideGNDChoice B buttonother side3V3OLED (SSD1306)VCCGNDOLED (SSD1306)GNDGPIO 21OLED (SSD1306)SDAGPIO 22OLED (SSD1306)SCLGPIO 18SG90 servosignal (orange)external 5 VSG90 servopower (red)GNDSG90 servoground (brown)
ESP32 pinPartPart markingCarries
GPIO 25Choice A buttonone sideDigital in/out — configure INPUT_PULLUP
GNDChoice A buttonother sideGround
GPIO 26Choice B buttonone sideDigital in/out — configure INPUT_PULLUP
GNDChoice B buttonother sideGround
3V3OLED (SSD1306)VCC3V3 power
GNDOLED (SSD1306)GNDGround
GPIO 21OLED (SSD1306)SDAI²C bus
GPIO 22OLED (SSD1306)SCLI²C bus
GPIO 18SG90 servosignal (orange)PWM to actuator — one acknowledgement gesture
external 5 VSG90 servopower (red)5V power — separate supply
GNDSG90 servoground (brown)Ground — join servo and ESP32 grounds

Unplug USB while rewiring. Large fablab buttons may have separate lamp terminals or several switch contacts; use only the verified dry-contact pair unless staff approve the lighting circuit.

  • Digital in/out
  • Ground
  • 3V3 power
  • I²C bus
  • PWM to actuator
  • 5V power

This map assumes two normally open momentary switches. Confirm continuity with a meter rather than guessing from terminal position.

Give it character

Design an invitation, not a trap

The question, labels, height, contrast, reach, and feedback all influence whether a person can make an intentional choice. Keep the wording light, reviewed, and answerable without sharing personal information.

Your team decides:

  • What one garden question is appropriate, neutral, and worth asking?
  • How are the two choices labelled in words, shape, and position?
  • What happens when both buttons arrive within the ambiguity window?
  • How does the bug acknowledge acceptance without revealing a lasting individual record?

Write these decisions in plain language before turning them into code. A clear rule is easier to test, explain, and change.

Your field adventure

Does realistic use produce exactly one accepted event?

Treat people as varied users, not noise. Write a press script and invite new testers to use the object naturally after your controlled trials.

  1. Rehearse electrical trouble.

    Run at least fifty labelled single taps, long holds, quick repeats, alternating buttons, and near-simultaneous presses.

  2. Tune once, then freeze.

    Choose debounce, ambiguity, and release rules from the first set. Repeat without changing them.

  3. Test the invitation.

    Ask fresh users to vote without spoken coaching. Record whether they understand the question, labels, and acknowledgement.

  4. Audit privacy and reset.

    List every stored and published field. Demonstrate how staff reset the aggregate without exposing an accidental public control.

Press sceneExpected acceptedObserved acceptedAcknowledged once?Time to feedbackUser / access note
single clear press1___yes / no___ ms___
long hold1___yes / no___ ms___
near-simultaneous choicesteam rule: ______yes / no___ ms___

When it gets dramatic

Most voting errors begin before the total

A held button keeps adding votes

The device is counting a level. After acceptance, enter a wait-for-release state and do not rearm while the contact remains active.

Fast taps are missed

The debounce interval may be too long or the loop may block during feedback. Record press duration and keep the acknowledgement non-blocking.

One press activates both choices

Check wiring, pull-ups, and shared button terminals. Then test whether physical button flex causes genuine near-simultaneous input.

Visitors press again immediately

The acceptance cue is late, subtle, or ambiguous. Improve visible feedback before loosening the count rule.

Anyone can erase the total

A public button must not be the reset control. Use a documented staff-only procedure and show when a new session baseline begins.

Choose your direction

What kind of public-interaction team will you become?

The press detectives

Study bounce, hold, release, and simultaneous inputs until the state machine is exceptionally clear.

The access designers

Make labels, reach, force, contrast, and redundant acknowledgement the main experiment.

The honest pollsters

Explain what the aggregate can and cannot represent, then design the cleanest reset and public caption.

Each direction is real engineering. Pick the question that keeps your team curious.

A calm way through the build

Collect four small wins

  1. bb-01 says hello with no buttons attached.

    Reach the developer view before counting.

  2. Each button produces one accepted event after release.

    Keep feedback disconnected and challenge holds first.

  3. The aggregate count reaches the garden.

    Confirm that no choice history or identifier is included.

  4. A fresh visitor understands the invitation and response.

    Add the display, gesture, labels, and accessibility test.

When a new step fails, return to the last small win. The fault is now somewhere in the few wires or lines you just added.

The garden handshake

Share what you found

These names are the rigid part of the project. They let another team find your work without knowing what you called the variables in your code.

On each accepted vote

Aggregate accepted votes

garden/entrance/ballot-node/bb-01/count

Unit: events

Listen beyond your own device.

garden/entrance/counter/gk-01/count

Entrance count can provide broad context for how many opportunities the ballot may have had. It cannot tell how many unique voters approached, and it must not change acceptance of a button press.

Finish line

Ready to introduce to the garden

  • bb-01 stays online and publishes one aggregate count update per accepted vote.

  • The reject feed stays clear after the final code starts.

  • The device reads Gate Keeper only as aggregate context.

  • No identity or individual vote history is stored or published, and the public controls cannot reset the total.

  • The acknowledgement happens once without blocking input or garden messages.

  • The build log contains fifty controlled trials, frozen rules, fresh-user observations, misses, extras, ambiguity, accessibility limits, and reset policy.

The Ballot Bug is successful when the interaction feels playful, the count behaves rigorously, and the data remains smaller than the people who made it.

Backbone now

Live status

Updates from the same public event stream

Checking bb-01…