Time tracker - last update 2021-09-12
THIS IS A WORK IN PROGRESS
Below you will find log entries that describe the design/thinking process.
The goal is to build a device that could allow me to comfortably measure time spent on a project. I want to have a full history of the time spent on particular project. The time log needs to be plain text, easily queried and human readable.
I’ve worked quite a lot on, what many would call, the backend. Since my experience comes mostly from embedded programming, a lot of the concepts around backend infrastructure are new to me. Fortunately I know Docker well enough to be able to spin up a PostgreSQL database on a VPS.
At this point I already had a server, written in Nim, which received the data from the Raspberry Pi or the ESP32 prototype. What I had to add was the Postgres functionality. Fortunately Nim’s standard library already has a module for Postgres. After several days of trying I was able to write Dockerfiles which initialized and started the database and the Nim server. The database schema is still work in progress but it’s very much useable right now.
The next step was to write a web app which would read the data from the database and provide a webpage interface. Once again I chose to write the code using Nim and a community made web framework Jester. The current web interface is pretty simple but it does present useful information.
It’s obvious that the red time segments aren’t that useful just yet. The user can’t tell which project those correspond to and what time did those start exactly. It’s worth pointing out that those SVGs are generated by the server, when it fetches the data from the Postgres database. It might be obvious that its generated (because how else could it work?) but doing that, using code, is very rewarding
At this point in time I can: start time tracking on the Raspberry Pi prototype, recorded stretch of time gets sent to a server which saves that data in the database (with additional information: project ID, user ID and IP, etc.), the web application reads that data, generates the website’s content and serves it as a, decently, readable interface.
I’ve tested the pHat Touch from Pimoroni, attached to a Raspberry Pi. It’s a good prototype of the functionality. It allows for tracking time of 4 projects, thanks to a script written in Python. Again, Python proves to be a great tool for very quick prototyping.
I’ve been thinking a lot about the design of the device. Ideas that I keep coming back to are: keys made from a thin, metal rods, wooden or ceramic (yes, ceramic!) enclosure. Those ideas pose manufacturing challenges, that currently I have no idea how to solve.
After some 3D printing problems I’ve decided to take a step back. I’ve soldered a very simple prototype on a universal PCB. I was trying to take too big of a step. It’s difficult to juggle enclosure design, electronics design and software. Priority should always be given to the parts that matter most to the final goal. Beautiful plane won’t take you anywhere without a functional engine.
Making this prototype allowed me to improve the ESP32 firmware. It handles multiple buttons now and a simple debouncing mechanism has been added. I’ve also added various other improvements. The server code was also significantly improved.
I also realized that a visual feedback is very important. If I press a button, a corresponding LED needs to signal that the ESP32 is logging time for the specific project. I knew it’s important before I built the prototype. After, I’d consider it to be crucial. That forces me to explore the possible pinout configuration. I might learn that squeezing in 5 buttons and 5 LEDs might be diffcult.
Building this prototype proved to be very beneficial. It pushed the entire project several steps forward.
Recent experience with ESP32, working on the ESPotify project, taught me a lot. I feel confident moving in ESP’s ecosystem. This, plus need for a break from other projects, made me start working on the firmware for this project.
During two days I was able to write a significant part of the firmware. Sure, it will need some time to mature, but I’m happy where it’s going. You can find the repository here. I’m using the Lolin D32 PRO board. It has a SD card socket which is super useful for data like AP’s SSID, AP’s password, end server address and port.
I’m also pretty close to 3D printing the enclosure for the first prototype. I still need to get my hands on some basic parts, like tact switches. Those past few days pushed this project quite far.
Using a buttons inspired by the retro tape recorder means that I have to redesign how I want this device to look like. Few uninspired sketches later…
I was thinking about another project that would use an old school tape recorder. Then it hit me that the buttons those use are exactly what a project like this needs.
I’m young enough to not have a lot experience with those, but also old enough to remember how did the buttons on those beautiful devices worked. It’s obvious that you can’t rewind a tape and play it back at the same time. You also can’t have it paused and playing at the same time. That means that when you press one button, the one that’s already pressed in pops out. Those keyboards have a great mechanical feel. I might try to cram this project into a cassette tape recorder. There is plenty of space for the electronics. Unfortunately there are some buttons combinations that don’t conform to this simple idea of “only one button pressed at a time”. I think in order to record you press both Play and Record buttons.
I can obviously replicate this behavior with the tact switches. If the user started tracking time on one project by pressing one button, she can just switch to a different project by pressing another button. That would stop tracking time for the previous project and start doing it for the new one.
The idea of piano like key seems nice. I wonder if I could 3D print a keyboard made out of buttons like the one below:
Part of the fun is designing how this device looks, but a cassette tape recorder is a great inspiration. Also, imagine that when you start working on a project, a tape starts spinning (assuming it’s silent, and if I remember correctly there is a hum coming from the recorder when the tape spins). Wouldn’t that look cool? Unnecessary and excessive? Probably.
Previously I’ve used CircuitLab to draw the schematics. It is pretty good but saving circuits is impossible with a free account. A great alternative is this circuit simulator. As you can see below, the circuit isn’t as aesthetically pleasing.
However, the possibility of saving the circuits to a plain text or in the URL itself is awesome. You can basically copy the text below and import it into the simulator or click this link.
$ 1 0.0000049999999999999996 18.278915558614752 71 5 43 g 176 304 176 352 0 r -32 224 96 224 0 47000 r 176 224 304 224 0 16000 g 304 304 304 352 0 r 304 224 432 224 0 30000 g 432 304 432 352 0 r 432 224 560 224 0 91000 g 560 304 560 352 0 g -48 304 -48 352 0 v -48 304 -48 224 0 0 40 3.3 0 0 0.5 w 112 224 176 224 0 p 96 224 96 304 1 0 g 96 304 96 352 0 w -32 224 -48 224 0 w 96 224 112 224 0 s 176 224 176 304 0 1 false s 304 224 304 304 0 1 false s 432 224 432 304 0 1 false s 560 224 560 304 0 1 false o 11 64 0 4098 5 0.1 0 1
The live drawing of the signal is great. You can easily see the consistently spread voltage values, corresponding to the specific buttons.
Lets update the visual concept with the resistors ladder and the ADC pin.
Looks way easier to assemble and expand.
I’ve planned on explaining how to compute the resistors value. I’ve however found an article that provides all of the necessary information. I need to keep myself in check and focus on what’s most important to finish this project. Even though I belive there is a great value in explaining things from a different perspectives, I decided not to explain the maths behind this in my own words.
The aforementioned article can be found here. I invite you to go through the blog. There is a lot of interesting information there.
The most helpful part for this project is this document.
It basically lists all of the resistor values depending on the buttons count.
You need to edit document the get the resistors values and in order to do that you have to
duplicate it (
File -> Create copy).
Setting the No. Switches to 4 and voltage to 3.3V gives the following results. The resistor values are being rounded to a value that’s actually available on the market (nice!). The ADC values are computed too.
|Computed resistance||Available resistance||ADC reading|
Those values look great. They are almost perfectly linear. Pressing the first button grounds the ADC pin - value is 0. Pressing the second button should output ~260, third ~506 and the fourth ~762.
Of course this gets tricker as you add more buttons, since you have to have finer and finer control over the resistances. This won’t be a problem for a project like that - the first version will use only 4 buttons and I can’t imagine the final version using much more.
With the current configuration, scaling the buttons count is horribly painful. Each button needs its own digital pin. Often used solution is to use a resistor ladder and an ADC.
In the image above the SW2 switch is closed. That makes the current flow through R1 and R2 resistors - that’s basically a voltage divider of 1:1 ratio. That would make a 10-bit ADC read a value of 1024/2 = 512 (well close to…).
Now lets close the SW5 switch instead. That would make a voltage divider with ratio of 1:4. For a voltage value of 3.3V the voltage drop on R1 would be equal to 660mV, while on R2 + R3 + R4 + R5 it would be 2640mV. ADC would output something around 819.
In this solution only one button can be pressed, which is fine for what this keyboard needs to do. What isn’t convenient is that using the same resistors values doesn’t give you a linear numerical values from the ADC. Pushing SW1 would output 1024 (for a 10-bit ADC), pushing SW2 512, SW3 675. Going up from that would mean cramming more into a smaller and smaller values spectrum.
The solution is to compute resistors values to actually compensate for that. Since I want to keep those entries short and simple I’ll explain this next time.
I’ve explored some hardware options for the buttons. The most cost efficient and comfortable option are the big microswitches. I’ve started designing a frame for buttons like that. The design has to be modular. That means that it has to trivial to expand this frame for any number of buttons.
I’m using Blender to experiment with the design. I achieve the modularity with an Array modifier. Increasing the array’s count modifier just adds the next segment. By default the Array modifier makes it so the elements are perfectly spaced - touching it’s ends.
The frame also has to hide the electronic components… or does it. Maybe those can be used to make the whole project look more interesting? Might explore this idea.
For now the wiring and the resistors are located on the bottom. One thing I’ve failed to consider in the sketch above is connecting the buttons back to the GND line. With this layout those connections would collide with the Vcc. It can be solved by moving the Vcc line more towards the middle of the frame. That way the line could go directly below the switches. That way one of the pins, of the pair close to the GND line, can be easily connected to GND. I will show this change in the next update, assuming I won’t find a better way to do it.
Pressing a specific switch will start time logging for a specific project. That needs to be clear for the user. For now I’m thinking of using LEDs for that. That means that the next design should take that into consideration.