A device that reminds the wearer to stand up and move around every hour.
Overview
Process
Decision Points:
One decision point that occurred fairly early on was the decision to use a rechargeable 9 volt battery not contained within the device itself. In the initial ideation stages, I had planned to use two tiny button batteries in series. I wanted everything to fit inside the main body of the device, which I later realized was quite difficult to achieve. I then made the decision to switch to a rechargeable 9 volt battery with an external battery pack to allot more space, and to avoid burning through too many batteries over extended wear.
Another decision point (also related to the size of the device) was the decision to remake the top half of the device, due to it not being able to fit the electronic components. The original design had the acrylic circle inset into the triangular form. However, the height was too short to fit the electronics, so it was remade so that the circle sat on top. Even though the extruded circle gives the impression of a circle, which is not the intended interaction, it was more important to fit the electronic components.
Process Highlights:
Discussion
Responses:
“It’s a shame that there aren’t smaller batteries to go with it, or it could be even smaller.”
I addressed this for the most part in the decision points of the process section. I definitely agree that it would be more elegant if the design did not include a battery pack and if the device itself was smaller. I think the main benefit of having a battery pack is that the battery can easily be changed when it dies. Since the main device is sealed shut, I would have had to integrate some sort of access point to change the batteries had they been within the device itself; which would have been difficult due to the lack of space and the cluttered electronic components inside.
“Clearly a lot of thought was put into figuring out how the components all fit together functionally and aesthetically.”
I think the plan since the beginning was to make the circuit as small as possible, make the case as spacious as possible (without being obtrusive), and smashing the two together. Soldering all the components to a tiny piece of protoboard was definitely straining. I did have to make an adjustment to the top half of the case when the acrylic indent got in the way. I also ran into some problems when the connections broke because I shoved the circuit too hard. Overall, I think I got lucky that everything fit how I imagined for the most part.
———-
Overall, I am satisfied with the way the project turned out. In the ideation stages, I felt like I underestimated the difficulty of the coding and electronics aspect. I ended up having to spend a lot of time on the two, especially in getting them to synchronize. I feel like I accomplished a lot in terms of the technical aspects of the project because I had very little prior experience with electronics and physical computing in general. I think the aesthetics of the project are below my usual standards, but I am happy with the end result given the time restrictions. With purely design projects, I am able to dedicate 100% of the time to aesthetics and UI, while I had to allocate time to technical aspects in realizing this project. Although I wish I had the time to polish up its outer appearance, I am happy about the opportunity to combine technical and design skills.
Through all this, I delved into some things that I never thought I would. First, I learned not to underestimate the size of electronic components. On the bright side, I was able to learn how to program an ATTINY85. Another thing I learned was how to problem solve. Uniquely in terms of technical problems, I was never aware of how many useful resources can be found online through a simple Google search. I was able to find solutions to many of my hardware and coding problems online. If I were to go through this experience again, I would definitely lower my expectations for how fast things progress. With the type of work I normally do in design, I never really get stuck past the ideation phase; so I found myself getting really frustrated when the code was not working the way I intended, or the circuit was not wired up correctly. I expected everything to go smoothly so this caused me a lot of anxiety. I wish I would have anticipated this and mentally prepared myself for all the mishaps. On the topic of future work, I would be interested in building another iteration of this device. I would like to explore higher quality materials, such as silicone or leather straps. Even though I have already dedicated a lot of effort to the aesthetic qualities of the project, I would be interested in reworking it to the point where it can be useful to me as a showpiece. I would also consider adding a programmable element for the sitting time.
Schematic
Code
/* Get-Up Reminder for Thrombosis Patients * * Description: * The code below takes the input from an accelerometer * to detect whether or not the wearer is sitting or * standing, and vibrates a motor and blinks an LED in * a predetermined pattern to remind them to stand up * if they have been sitting for too long. * * Inputs: * ATTINY85 pin | input * 1 switch * A2 accelerometer (z) * * Outputs: * ATTINY85 pin | output * 0 vibration motor * 3 LED * * Credits: * Programming the ATTINY85: sparkfun tutorial by JIMBLOM * https://learn.sparkfun.com/tutorials/tiny-avr-programmer-hookup-guide/programming-in-arduino * Programming outputs for pancake vibration motor: youtube video by Electronic Clinic * https://www.youtube.com/watch?v=y-Fgm4yYsqg * Debouncing switch inputs: course page tutorial * https://courses.ideate.cmu.edu/60-223/f2019/tutorials/debouncing */ const int BUTTON_PIN = 1; const int MOTOR_PIN = 0; const int Z_PIN = A2; const int LED_PIN = 3; int buttonState; // the current reading from the button input pin int lastButtonState = LOW; // the previous reading from the button input pin bool powerState = false; // is the device on or off unsigned long lastDebounceTime = 0; // the last time the output pin was toggled unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers unsigned long startTime = millis(); // the time at which the user began sitting unsigned long timeElapsed = 0; // the amount of time the user has been sitting void setup() { pinMode(BUTTON_PIN, INPUT); pinMode(Z_PIN, INPUT); pinMode(MOTOR_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT); } void loop() { int reading = digitalRead(BUTTON_PIN); // the state of the button switch int zRead = analogRead(Z_PIN); // the reading from the z input pin of the accelerometer if (reading != lastButtonState) { // if the switch changed during single press instance lastDebounceTime = millis(); // reset debouncing timer } // whatever the reading is at, it's been there for longer than the debounce delay, // so take it as the actual current state: if ((millis() - lastDebounceTime) > debounceDelay) { if (reading != buttonState) { // if the button state has changed buttonState = reading; if (buttonState == HIGH) { // only toggle the on/off state if the new button state is HIGH powerState = !powerState; startTime = millis(); // reset the time the user began sitting to the current time } } } if (powerState) { // if the device is "on": digitalWrite(LED_PIN, HIGH); // turn on the LED if (zRead > 350) { // if the accelerometer indicates that the user is sitting timeElapsed = millis() - startTime; // start counting the amount of time the user has been sitting } else { // if the accelerometer indicates that the user is standing startTime = millis(); // reset the time the user began sitting to the current time } if (timeElapsed > 3600000) { // if the user has been sitting for more than 1 hour // if (timeElapsed > 10000) { // demo case: the user has been sitting for 10 seconds // vibrate and blink LED 3 times: analogWrite(MOTOR_PIN, 255); delay(500); analogWrite(MOTOR_PIN, 0); delay(500); analogWrite(MOTOR_PIN, 255); delay(500); analogWrite(MOTOR_PIN, 0); delay(500); analogWrite(MOTOR_PIN, 255); delay(500); analogWrite(MOTOR_PIN, 0); delay(500); startTime = millis(); // reset the time the user began sitting to the current time } } else { // if the device is "off" digitalWrite(LED_PIN, LOW); // turn the LED off } lastButtonState = reading; // save the reading as lastButtonState for the next loop }
Comments are closed.