Mission
Build this
Build a robust one-question voting object that confirms each accepted press and publishes an aggregate count without identities.
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
| Source | Part | Fallback |
|---|---|---|
| ○ fablab | Large push buttons | Use two labelled kit push buttons |
| ● kit | OLED or four-digit display | — |
| ● kit | SG90 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.
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.
- in the worldA visitor pressesA finger may tap, hold, or press near another choice.
- the partButton contactsMechanical movement creates noisy HIGH and LOW edges.
- electricalStable candidateTimers reject bounce and recognise ambiguity.
- in the codeAccepted totalExactly one is added after the fixed rule succeeds.
- 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.
- 01ReadyBoth buttons are released and the bug invites one choice.then, one button begins,
- 02CandidateOne input remains active through the debounce interval.then, stable and unambiguous,
- 03AcceptedIncrement once and acknowledge the choice locally.then, gesture completes,
- 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.
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
| ESP32 pin | Part | Part marking | Carries |
|---|---|---|---|
GPIO 25 | Choice A button | one side | Digital in/out — configure INPUT_PULLUP |
GND | Choice A button | other side | Ground |
GPIO 26 | Choice B button | one side | Digital in/out — configure INPUT_PULLUP |
GND | Choice B button | other side | Ground |
3V3 | OLED (SSD1306) | VCC | 3V3 power |
GND | OLED (SSD1306) | GND | Ground |
GPIO 21 | OLED (SSD1306) | SDA | I²C bus |
GPIO 22 | OLED (SSD1306) | SCL | I²C bus |
GPIO 18 | SG90 servo | signal (orange) | PWM to actuator — one acknowledgement gesture |
external 5 V | SG90 servo | power (red) | 5V power — separate supply |
GND | SG90 servo | ground (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.
- Rehearse electrical trouble.
Run at least fifty labelled single taps, long holds, quick repeats, alternating buttons, and near-simultaneous presses.
- Tune once, then freeze.
Choose debounce, ambiguity, and release rules from the first set. Repeat without changing them.
- Test the invitation.
Ask fresh users to vote without spoken coaching. Record whether they understand the question, labels, and acknowledgement.
- Audit privacy and reset.
List every stored and published field. Demonstrate how staff reset the aggregate without exposing an accidental public control.
| Press scene | Expected accepted | Observed accepted | Acknowledged once? | Time to feedback | User / access note |
|---|---|---|---|---|---|
| single clear press | 1 | ___ | yes / no | ___ ms | ___ |
| long hold | 1 | ___ | yes / no | ___ ms | ___ |
| near-simultaneous choices | team 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
- bb-01 says hello with no buttons attached.
Reach the developer view before counting.
- Each button produces one accepted event after release.
Keep feedback disconnected and challenge holds first.
- The aggregate count reaches the garden.
Confirm that no choice history or identifier is included.
- 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.
Aggregate accepted votes
garden/entrance/ballot-node/bb-01/countUnit: events
Listen beyond your own device.
garden/entrance/counter/gk-01/countEntrance 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.