Standing Automation
Wed 13 April 2016
I've had a standing desk at work for a long time, but I've always felt that I wasn't using it enough, that I still spent most of my timing sitting.
This week I finally decided to do something about it.
I bought a small sonar sensor (LV-MaxSonar-EZ1), hooked it up to an Arduino and added a little Python script to sample the sensor once a minute.
The sonar is mounted to my table and measures the distance to the floor, and with ~3 cm accuracy it's very easy to distinguish whether I'm sitting or standing.
Since the Sonar happily runs of 5V, I just connected its power input pins directly to the VCC and GND pins of my Arduino. Conveniently it also provides the measured distance as analog voltage on a pin, I just connected that to A0 on the Arduino.
The Arduino code to regularly sample the sonar is then very simple, even with basic smoothing included:
void setup() { Serial.begin(9600); } const float sample_duration = 500; void loop() { // Protect against timer overflow. unsigned long start = millis(); const unsigned long deadline = start + sample_duration; double cumulative_sensor_value = 0; unsigned long steps = 0; while (millis() < deadline && millis() >= start) { cumulative_sensor_value += analogRead(A0); steps++; } // Sonar values are (Vcc/512) per inch, Arduino sensor range is [0, 1023]. float distance_inch = (cumulative_sensor_value / steps) / 2.0; float distance_m = distance_inch * 2.54 / 100; Serial.println(distance_m); }
The Arduino includes a USB serial interface, so I can just connect it directly to my computer and it's straightforward to read its output with Python:
import serial import sys import time desk_height = None deadline = time.time() + 30 with serial.Serial(port='/dev/ttyUSB0', timeout=1) as ser: while desk_height is None: line = ser.readline().strip() if line: try: desk_height = float(line) except ValueError: pass if time.time() > deadline: print "failed to read desk height" sys.exit(1) print 'standing' if desk_height > 0.5 else 'sitting'
At this point I can do whatever I want with the data - create daily or weekly graphs, send automated email reminders if I haven't been standing in the last 2 hours, etc.
To ignore periods where I'm not actually at my computer, I use xprintidle
, which prints the time in milliseconds since the last user activity, i.e. mouse or keyboard input.
Tags: misc
italics | surround text with *asterisks* |
bold | surround text with **two asterisks** |
hyperlink | [hyperlink](https://example.com)or just a bare URL |
code | surround text with `backticks` |
surround text with ~~two tilde characters~~ | |
quote | prefix with > |
Loading comments...