Quality of Life Meter
[Note: The Mk.2 is live!]
Harsh new rules at work getting you down? Overtime sucking the life out of you? Or maybe things are great, either way now you can show your co-workers and management exactly how you feel about your job without a single meeting, memo, or team bonding exercise. This is the Quality of Life Meter. Boss take credit for your hard work? Turn it down. Get a bigger bonus than expected? Turn it up.
There is no exact formula for the Quality of Life Meter, the whole idea is that it's a personal thing. That being said on my project we use it as a measure of the groups level. Things like taking a day off, long weekends, cancelled meetings, and getting critical data on time make the meter go up while overtime, useless meetings, server crashes, and management trying to dictate our quality of life make it go down. It's kind of a gut thing and you'll have to decide for your self exactly what factors into moving your meter.
I won't bore you with the story of how this came about but I will be clear that in my work place this is clearly a joke and everyone knows it. If you just show up with this one day and set it low feelings may be hurt and people may take it personally. I'm not saying I'm against using this as a tool to vent your frustrations but just make sure your intentions are clear, joke or otherwise.
Of course Quality of Life isn't the only thing you can use this for, that's the biggest reason there isn't a label directly on the box (at work there is a sign over it but there's a strict no photo rule so I can't show it). It could jazz up a fundraiser, track your exercise, or help you save up for a trip. The Arduino that powers my design is far from working at capacity so there is the possibility for expanding the meter by adding sensors that can directly control the output value or adding WiFi or Bluetooth connectivity allowing your phone or computer to influence the output.
As always, feel free to ask any questions in the comments or via PM and if you make one, or a variation, I love to see pictures.
Materials & Tools
- Small Glass/Plastic Pane - Any material that is clear and stiff will work. Glass or plexiglass are the most obvious solutions.
- Sheet Wood - The type of wood is mostly irrelevant as is the thickness, although I wouldn't go much thinner than 3/8" or 1/4". I used some 3/4" strips that were packed with some toe kicks from IKEA.
- Cardboard/Plastic Sheet - Any thin, presentable looking material will work, even sheet metals.
- Small Knob - This needs to fit your pot and be long enough to make it through the wall of your enclosure. In my build I improvised and used an internally threaded spacer as a knob.
- Screws - Small screws to attach the back sheet to the wood enclosure.
- Frosting Spray Paint; ($4, Lowes) - If you can find a pre-frosted pane then this is unnecessary.
- Regular Spray Paint - I used the same color for the enclosure as well as for the blackout on the pane.
- Wood Filler - When working with particle board (of all varieties) or ply woods using wood filler on the cut edges helps give a uniform texture and look after painting.
- Wood Glue - Holds it all together.
- 2x Small Perfboards
- 1x Arduino Uno
- 1x 6xAA Battery Holder
- 12x 220 Ohm Resistors
- 1x Red Blinking LED
- 3x Red LEDs
- 4x Yellow LEDs
- 3x Green LEDs
- 1x Green Blinking LED
- 2x 74HC595 Shift Registers
- 2x 16 pin IC Sockets
- 1x SPST Switch
- 1x Potentiometer - I honestly don't know the size I used as mine was salvaged. It just needs to have even output across a range of 0-3V.
- Wires
- Batteries
- Table or Circular Saw - A table saw is best but you can make due with a circular or even a hand saw if one isn't readily available.
- Sandpaper
- Clamps
- Masking Tape
- Soldering Equipment
- Drill & Bits
- Utility Knife / Scissors
Circuit Design
The 74HC595's are serial-in-parallel-out shift registers. This means you can use three pins on your microcontroller to send the bytes of data serially (one bit after another) to the 595 which then applies each bit to different output pins and then outputs those bits in parallel (all at once). When you daisy chain 595's you can now send two bytes of data and the first 595 then passes the first byte onto the second 595 and they both execute all 16 bits at once.
*Enough faffing about though, lets break down this circuit. Starting with the Arduino, we are using 3 digital pins to control the 595's. Pin 8 is the latch pin which holds the outputs steady while you write new data and is attached to pin 5 on both 595's. Pin 11 is used to transmit the serial data and is attached to pin 3 on the FIRST 595 ONLY. Pin 12 is the clock which pulses to send each bit and it's attached to pin 6 on both 595's.
The 5V output pin is attached to pins 1 and 7 on both 595's. The GND pin grounds all five "chunks" of the circuit.
*The potentiometer takes 3.3V from the Arduino and runs back to the Arduino ground. The sweep, or output, is connected to the first analog pin on the Arduino, A0. I don't know the value of the pot as it's a salvage but it is pretty small in size and made out of plastic so it can't be anything crazy.
*The power source is 6 AA batteries, providing ~9V, in a holder that uses a 9V battery clip as leads. The positive terminals pass through a push button SPST to the Vin pin on the Arduino. The plan is to use rechargeable batteries to cut running costs.
*On the 595's the pins I haven't addressed are 3, 4, 8, and the outputs. Pin 3 on #1 connects to the Arduino, as discussed above, but on #2 it ties to pin 8 on the first 595. Pin 8 is left unconnected on #2. On both 595's pin 4 connects to GND. The outputs, labeled as Q's, are pretty straight forward. starting with Q0 on #1 and the red flashing LED and ending with the green flashing LED attached to Q3 on #2.
*The LED array is simply a parallel array, one LED and resistor per row. All the resistors tie to the common ground. The size of the resistor needed depends on the specs of your specific LEDs. Use R = V / I, where R is the size of resistor needed, V is the voltage passing through the LED (5V if you use Arduino), and I is the acceptable current for the LEDs. 220 Ohm resistors will work well for most standard 5mm LEDs.
Enclosure Design
To create the thermometer outline I simply scaled free a clip art picture to fit on the window. Before you start finalizing your circuit and soldering it into place you need to know the final size of the image so that you can get the spacing of the LEDs correct.
Firmware
Step 1 is contained in it's own user defined function. First you read in the analog pin attached to the potentiometer. This will result in a reading between 0-682 (remember we're on 3.3V, not 5). Next we want to return a value 0-11, representing the 11 segments on our thermometer, to the main program. To do this you perform an integer on the input using the size of one segment, 62 (682/11 = 62). The use of integer division, which uses only whole numbers, is not a mistake, it allows the function to return a whole number without taking the extra step of rounding the result with another line of code.
Once you output the segment that the pot is indicating the code needs to correlate that number to the binary sequence that will light up the appropriate LEDs. The decimal values that convert to the proper binary strings to control the 595's are stored in an array where their position in the array conveniently is the same as the output from the pot.
The final step is to push the commands to 595's. The order of operations is to deactivate the latch pin, preventing the LEDs from changing while the new commands are written, use the shift out command to send the binary strings through the data pin, which uses the clock pin to differentiate bits, and finally reactivate the latch pin to output the new data across all the pins simultaneously.
//LED TEST 2 w/ 74HC595 //by Bwrussell 2013 //https://www.instructables.com/id/Quality-of-Life-Meter/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ //74HC595-Arduino Interface Pin Definitions //Pin connected to ST_CP of 74HC595 int latchPin = 8; //Pin connected to SH_CP of 74HC595 int clockPin = 12; //Pin connected to DS of 74HC595 int dataPin = 11; //Pin connected to the sweep pin of the pot #define potPin A5 //arrays that hold the LED states for each pot position, one for each 595 int ledStatesA[] = {1,2,6,14,30,62,126,254,254,254,254,254}; int ledStatesB[] = {0,0,0,0,0,0,0,0,1,3,7,15}; //Variable Defs int knobPosition; void setup() { //Start Serial for debuging purposes Serial.begin(9600); //set pins to output because they are addressed in the main loop pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop(){ knobPosition = potRead(); digitalWrite(latchPin, 0); //send data to the second 595 (8-11) shiftOut(dataPin, clockPin, ledStatesB[knobPosition]); //cosend data to the first 595 (0-7) shiftOut(dataPin, clockPin, ledStatesA[knobPosition]); //return the latch pin high to signal chip that it //no longer needs to listen for information digitalWrite(latchPin, 1); } void shiftOut(int myDataPin, int myClockPin, byte myDataOut) { // This shifts 8 bits out MSB first, //on the rising edge of the clock, //clock idles low //internal function setup int i=0; int pinState; pinMode(myClockPin, OUTPUT); pinMode(myDataPin, OUTPUT); //clear everything out just in case to //prepare shift register for bit shifting digitalWrite(myDataPin, 0); digitalWrite(myClockPin, 0); for (i=7; i>=0; i--) { digitalWrite(myClockPin, 0); if ( myDataOut & (1<<i) ) { pinState= 1; } else { pinState= 0; } //Sets the pin to HIGH or LOW depending on pinState digitalWrite(myDataPin, pinState); //register shifts bits on upstroke of clock pin digitalWrite(myClockPin, 1); //zero the data pin after shift to prevent bleed through digitalWrite(myDataPin, 0); } //stop shifting digitalWrite(myClockPin, 0); } // Function for reading and segmanting the pot input int potRead () { int potRaw = 0; //read in the raw pot position, averaging over 5 samples for (int i=0; i<5; i++){ potRaw = potRaw + analogRead(potPin); } potRaw = potRaw/5; //segment the raw data into 12 equal segmants, returns a value 0-11 int potPosition = potRaw / 60; //Use 60 for 3.3V, 93 for 5V across the pot //send the current segment to the main loop return potPosition ; }
The source code is available in the .zip file (the .ino wouldn't upload) and a plain text file.
Just a quick plug: In some of the initial testing I used the fairly new ArduinoDroid app for Android. It's pretty awesome for what it is. It allows you to write Arduino code, with color coding and compiling, anywhere, like on lunch break at work. With a proper USB cable you can also power and upload to an Arduino board. There are some other features I haven't used yet like Bluetooth control and such but for a maker on the go or field work this app is phenomenal. I would highly recommend it especially since it is completely free (ad supported) and unrestricted. If you like it then you can pay a nominal fee to remove the ads and support development. I don't know who the developer is but they rock.
Build the LED Array
I started by placing the resistors since they are on the edge and it sets the spacing for the LEDs. The ground legs of the resistors are all tied to gather. Then solder the LEDs next to the resistors. The sockets for the 595's are placed near the LEDs that they will control. I haven't worked much with PC board and I didn't leave myself very much room. If you have some ribbon cable that would work here I would recommend it. If I were to start over that's what I would use. Before connecting everything together I added long flexible leads, with Arduino header compatible pins, to the board as tie in nodes for GND and +5V. With everything in place follow the circuit diagram and wire up all the 595 connections. Take care when flipping between the back and the front of the PCB. I'd made a couple of connections when I started before I noticed that I'd shifted the pins and had to desolder and start over. The leads for the data, clock, and latch pins should be long and have Arduino header compatible ends.
With the LED circuit complete, decide if the pot and switch can be wired now. If they need to be fit into the enclosure from the outside then you'll probably have to wait until they can be secured in the enclosure to wire them in. If not, attach Arduino leads to the pot and wire the switch to the battery pack. You may need to attach different leads to the switch and power pack to make them Arduino compatible. I was able to add leads to the pot but had to wait to add the switch.
When you're done make sure to test again before moving on.
Enclosure Build
I used a table saw to create the groove that holds the window. Simply lower the blade until it's ~.125" above the table. Set the fence ~.25" from the blade and run each piece through. If you don't have a table saw with a little setup you should be able to cut the groove with a handheld circular saw or even a hand saw.
At this point you need to have a switch, pot and knob picked out so you can prep the enclosure for them. Taking into account where the walls will overlap when assembled, something that nearly bit me, drill holes appropriate for your components. If your walls are thicker than the threads on any panel mounted components then you will need to counterbore the back side of the hole to allow room for either the body or the nut, depending on which way the component mounts to the panel.
Before painting any type of particle board I like to cover the cut faces that will see paint with a wood filler. If you don't do this then those faces will absorb the paint better than the uncut faces and you will struggle to get a uniform. look. Just cover each surface with the filler, let it dry, then sand it smooth. I also used the filler to block the ends of the window groove that were exposed on the two side walls. When the edges are prepped, prime and paint.
Window Painting
Start by cleaning the glass thoroughly and then spray on a couple coats of the glass frosting paint and allow it to dry.
You should already have a template of the thermometer shape that you used to space the LEDs on your circuit board. Using this template cut out a matching template in cardboard. This will act as your mask for painting the outline. Place the mask in the middle of the window and use a couple of small clamps to hold it in place. Lay down a few coats of the dark paint, over the frosting. When the paint is dry carefully remove the mask.
Using masking tape block out the areas you want the light to shine through, leaving strips between each segment. These segments should align with the LEDs on your circuit board. When all the segments are masked apply a couple more coats of the dark paint. This will give you lines between your segments and a place to attach the dividers.
Light Dividers
In addition I made a back plate out of the same cardboard. I put a crease in the middle, horizontally, so that you only have to remove half of the screws to access the battery pack.
Assembly
First, put together three of the enclosures sides. The top, bottom, and edge with the switch and pot are probably your best bet. The walls are simply wood glued together. The easiest way to get everything lined up is to put glue on the two edges you're glueing and then clamp everything together, all four walls and the glass pane. When the glue dries you can remove the unglued edge and start loading components.
The Arduino is screwed to the wall with the switch, near the top. I used velcro to patches to attach the battery box to the back side of the glass pane. A little super glue holds the patches in place nicely. The final major component is the all important circuit board. In a bit of a jury rig I used some Gorilla Tape to secure the circuit in place. It looks a little shoddy but it isn't going anywhere and it allows for easy access if you need to take the circuit off for any reason.
With everything in place make the final connections in the circuit, probably: battery to switch and ground, switch to Arduino, the pot to 3.3V, GND, and A5, and the five circuit board leads (5V, GND, 8, 11, & 12) to the Arduino. With everything connected make sure to test the circuit before buttoning everything up.
If it's all in working order then glue the final wall in place and screw the back plate in place.
Display
Put it somewhere the concerned parties can see it and make sure you label it properly. Just be warned, something you start as just a joke may take on more life than you ever imagined, management has a way of doing that.