project
Ghost Hand
Public Unreviewedby John Lauer
A small battery gadget that keeps an automatic sink faucet running while you use the sink: it learns the faucet's timeout, re-arms with the shortest blip, and stops after 10 minutes or when picked up.
main
John Lauer
Rev 2: two IR emitters (850 nm at 8.2 ohm, 940 nm at 4.7 ohm), battery 40 / 74 / 170 days, new resistor pages
795559a
1d ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
{
"title": "Ghost Hand calcs",
"rev": "2",
"date": "2026-11-08",
"charger": {
"rprog_ohm": 13000.0,
"i_reg_mA": 76.9,
"c_rate": 0.51,
"charge_time_h": 2.44,
"p_worst_W": 0.135,
"rise_minimal_copper_C": 31.0,
"note": "0.51 C: inside the pack's 1 C quick-charge limit (QA.S.0228 form 1), and 4 x less heat in U2 than rev 1"
},
"stat_divider": {
"r_top": 68000.0,
"r_bot": 100000.0,
"v_at_4v75": 2.83,
"v_at_5v0": 2.98,
"v_at_5v5": 3.27,
"vih_ok": true,
"abs_max_ok": true
},
"vbus_sense_divider": {
"r_top": 100000.0,
"r_bot": 150000.0,
"v_at_4v75": 2.85,
"v_at_5v0": 3.0,
"v_at_5v5": 3.3,
"vih_ok": true,
"abs_max_ok": true
},
"ldo": {
"iq_nA": 25,
"i_rail_peak_mA": 48.1,
"dropout_at_peak_mV": 64.9,
"min_vbat_for_3v3": 3.365,
"note": "the firmware stops at 3.45 V, above the dropout point"
},
"vbat_monitor": {
"divider": "4.7M / 4.7M to GND, always on",
"v_adc_full": 2.1,
"ref_V": 2.5,
"lsb_mV_at_vbat": 4.88,
"sleep_leak_uA": 0.45,
"settle_ms": 235,
"note": "VBAT/2 stays under 2.1 V, inside the 3.3 V rail; C6 (100 nF) holds it for the ADC sample"
},
"receiver": {
"tia_rf_ohm": 150000.0,
"tia_cf_F": 4.7e-12,
"tia_bw_kHz": 225.8,
"hp_corner_kHz": 1.59,
"stage2_gain": 11,
"comparator": "AC0 AINP0 (PA7) vs DACREF, threshold RX_REF + 60 mV by default, adapted to the noise floor",
"cases": [
{
"distance_in": 3,
"off_axis_deg": 0,
"irradiance_mW_cm2": 0.8611,
"photo_uA": 12.056,
"tia_mV": 1808.3,
"rx_sig_mV": 3000.0
},
{
"distance_in": 3,
"off_axis_deg": 30,
"irradiance_mW_cm2": 0.6097,
"photo_uA": 8.536,
"tia_mV": 1280.4,
"rx_sig_mV": 3000.0
},
{
"distance_in": 5.5,
"off_axis_deg": 0,
"irradiance_mW_cm2": 0.2562,
"photo_uA": 3.587,
"tia_mV": 538.0,
"rx_sig_mV": 3000.0
},
{
"distance_in": 5.5,
"off_axis_deg": 30,
"irradiance_mW_cm2": 0.1814,
"photo_uA": 2.54,
"tia_mV": 381.0,
"rx_sig_mV": 3000.0
},
{
"distance_in": 12,
"off_axis_deg": 0,
"irradiance_mW_cm2": 0.0538,
"photo_uA": 0.753,
"tia_mV": 113.0,
"rx_sig_mV": 1243.0
},
{
"distance_in": 12,
"off_axis_deg": 30,
"irradiance_mW_cm2": 0.0381,
"photo_uA": 0.534,
"tia_mV": 80.0,
"rx_sig_mV": 880.0
}
],
"assumed": "faucet emitter 50 mW/sr peak; real units vary 10 to 200 mW/sr, the firmware sets the threshold from what it sees"
},
"echo": {
"emitters": {
"VSMY2853SL_850nm": {
"vf_at_pulse_V": 1.8,
"r_series_ohm": 8.2,
"i_peak_mA": [
200,
292
],
"ie_mW_sr": [
100,
146
],
"limit": "IFSM 1 A at tp = 100 us; pulses are 25 us at under 2 % duty"
},
"VSMB2948SL_940nm": {
"vf_at_pulse_V": 1.7,
"r_series_ohm": 4.7,
"i_peak_mA": [
371,
531
],
"ie_mW_sr": [
74,
106
],
"limit": "IFSM 1 A at tp = 100 us; pulses are 25 us at under 2 % duty"
}
},
"pulse_us": 25,
"total_peak_mA_at_full": 823,
"hand_return_W_m2": 0.1045,
"echo_850_W_m2_at_12in": 1.0764,
"echo_940_W_m2_at_12in": 0.7965,
"margin_vs_hand_at_12in_850": 10.3,
"margin_vs_hand_at_12in_940": 7.6,
"note": "the echo arrives inside the faucet's own pulse, so a synchronous receiver reads it as a strong reflection"
},
"battery_life": {
"battery": "Adafruit 1317, 150 mAh 1S LiPo",
"usable_mAh": 128,
"stop_V": 3.45,
"sleep_uA": {
"TPS7A0233 IQ": 0.025,
"ATtiny1616 power-down, pin-change wake on PA2 and PB2": 0.1,
"LIS2DW12 LP mode 1, 12.5 Hz, wake-up detection": 1.0,
"MCP73831 reverse discharge (no VBUS)": 0.15,
"VBAT monitor divider, 9.4 Mohm": 0.42,
"WS2812B rail switched off (Q3)": 0.0,
"TLV9062 unpowered (PA4 low)": 0.0,
"LiPo pack protection IC S-8261AAJMD (3 uA assumed)": 3.0
},
"sleep_total_uA": 4.7,
"sleep_only_years": 3.1,
"active_mA": {
"ATtiny1616 standby with OSC20M at 5 MHz for AC + TCB (idle 0.6 mA at 3 V) plus wake-ups": 0.8,
"TLV9062 two channels (538 uA each typ)": 1.08,
"receiver bias divider 3.3 V / 110 k": 0.03,
"IR echo pulses (850 + 940 nm emitters, 25 us at 20 Hz)": 0.411,
"status dot: breathing at 2 % average white, 20 % rail duty": 0.6,
"LIS2DW12 LP 50 Hz (pick-up and tilt watch)": 0.004
},
"active_total_mA": 2.93,
"hours_of_running": 44.0,
"mAh_per_10min_session": 0.488,
"sessions_per_charge": 261,
"days_per_charge": {
"1 session a day": 170,
"3 sessions a day": 74,
"6 sessions a day": 40
},
"self_discharge": "3.0 %/month assumed (0.15 mAh/day), larger than the sleep current",
"charge_time_h": 2.44,
"days_per_charge_min_capacity": {
"6 sessions a day": 38,
"3 sessions a day": 70
},
"once_a_month_bar": {
"sessions_per_day_for_30_days": 8.2
},
"pulse_supply": "the 0.93 A, 25 us echo pulse comes mostly from C15 (100 uF); the pack's average load is about 3 mA, far under its 150 mA (1 C) continuous rating",
"note": "typical datasheet currents at 25 C; the faucet's pulse rate and the light pattern are the two big unknowns"
},
"timing": {
"session_cap_s": 600,
"settle_after_set_down_s": 1.5,
"listen_before_echo_s": 2.0,
"default_rearm_s": 8.0,
"blip_start_ms": 600,
"blip_min_ms": 120,
"blip_step": 0.85,
"rearm_margin_s": 1.5,
"timeout_window_s": [
10,
60
],
"pickup_g": 0.25,
"tilt_deg": 30,
"low_battery_V": 3.45,
"note": "re-arm proactively at (learned timeout - margin); shorten the blip by 15 % each time the faucet stays on, lengthen 30 % when it misses"
},
"hot": {
"U2": {
"W": 0.135,
"why": "MCP73831 linear charger at 77 mA, VBUS 5.25 V, cell 3.5 V"
},
"U3": {
"W": 0.0433,
"why": "LDO at the peak light current"
}
}
}