12/14/2015 at 19:40 •
After a few months of competing priorities, I have finally cut the case and installed some of the bits and pieces. The correct buttons just arrived this morning, so I can take out the placeholder buttons and actually wire up the fully-functional Darktimer v1.
Minimal testing suggests the code works fine with the power-saving features turned on -- primarily turning off pieces of the processor which aren't being used. I haven't measured current consumption yet, but now that I"ve got the code blown onto the Arduino Pro Mini, I expect it to be much lower.
The project page is more or less done, and can be previewed here: http://dangerpants.com/labs/darktimer/
Once I have the prototype fully built up, I'll be taking pictures and finalizing the project page. Looks like v1 is code-complete, and the first prototype is only an hour or two from being finished.
Feature ideas for future versions:
- Temperature-aware timers for precise timing of development (this may be a completely different project, too)
- "Repeat" setting for timers when doing repetitive tasks
- Configurable timer series: one for developing film, one for developing paper, etc.
- Upgraded sounds: moving beyond the tone() function
09/25/2015 at 05:52 •
The prototype and code are in good shape. Knocked out all the bugs I could find, and I've been updating the project page. It's practically a real thing!
Loaded up Fritzing for the first time, and made up a wiring diagram with it. Not very hard to figure out, which was nice. The output certainly looks nice, for the breadboard view.
Once I get a chance to load the latest code onto the processor and see if my latest tweaks have broken anything (hopefully they've knocked down the power consumption a little bit -- 45 mA at rest!), I think this thing is ready to publish.
I still have to put together the encased prototype, but this code is feeling pretty much ready.
Cool new feature idea: adding a temperature probe, and adding a temperature compensation factor per timer: you program the correct time at a given temperature, and a ratio of time change per degree (probably by inputting temps vs. times rather than having to do any calculations on your own) and the timer automatically adjusts time to match temperature. That's for a future version, but I really like it, and it would allow me to stop being so fanatical about chemistry temperature.
08/26/2015 at 22:50 •
With various appendages crossed, I'm ready to call the code bug-free. I haven't tested absolutely everything, but all the big stuff is fixed, and all seems to be working the way I expect it to. Just pushed the "final" commit for this set of features, though I have one more useful thing to implement: hold-and-repeat on the + and - buttons. It shouldn't represent much code or even coding time, but will be a big leap forward in useability.
There's an order from Mouser winging its way my direction, containing the bits and pieces I didn't already have (mostly a suitable LCD, and an enclosure). Once that arrives, I can make the (admittedly very hacky-looking) physical object. There are still a number of questions to answer as to the physical build (mostly whether I want a volume control so I can go from silent to just-audible, and whether I want to have an external contrast adjustment), but it'll be nice to break out the mill and do some LCD and button mounting.
At this rate, I could have a working widget within a month or two. That's pretty cool.
08/24/2015 at 05:23 •
The prototype phase is nearly complete. Rejiggering things so the buttons are just read instead of generating interrupts worked with minimal effort. I was able to get the code running, almost completely bug-free, on the hardware this weekend. The board, buttons and LCD are still terribly jury-rigged, but things are generally looking good.
The one snag is that the code doesn't work quite the same way on the board as it does in the test run. I'm not sure if my test is incorrect (most likely scenario), or the code actually runs differently on the 328, but in a situation where there are multiple timers saved, deleting the first one then resetting the processor causes the program to claim there are no timers available. Testing for this exact scenario works perfectly, with no errors.
Of course, one of the things the tests don't do very well is test what happens when multiple operations are strung together, so it may be that I'm running into bad EEPROM state after adding and deleting timers -- the tests are all very precisely focused, and reset "EEPROM" each time. I may have to add a couple more larger-scale tests.
However, this one problem aside, it's pretty cool to see code that has only existed as a series of tests for many sporadically-active months actually work the way it's supposed to (mostly) on the hardware.
08/23/2015 at 00:11 •
I started out this project assuming I would be using interrupts to register button presses. A previous project had done that, and it had worked well, but I didn't consider it very hard in my coding. That was a detail for hardware implementation.
This weekend, I actually did the research on it, and realized that using interrupts like that will not work the way I want. So, although I thought I was close to done, I'm now having to rejigger the way all the button interactions were tested (and there are a *lot* of tests around button interaction). Fortunately, I was clever enough to make a function to handle button presses for the majority of uses, so it will be a matter of updating that one function rather than touching a zillion tests.
It's a bit silly having to go back and rework things, but this is pretty much the heart of iterative design: do it the way you think will work, then when you discover it won't, go back and rework things until it works the way it has to. Try to keep yourself from having to do too much of an about-face with changes like this, and design in such a way that the rework will be as minimally awful as possible.
I was able to get the LCD hooked up properly last night, and got the display I was expecting, after some trouble with a doubled-up pin. No button handling meant I couldn't see anything happening, but it was pretty cool to see the opening screen looking like it should.
08/19/2015 at 18:44 •
This is a minor update, but I was able to get the Arduino IDE to compile the code successfully late last night. It was too late to try actually moving the code to hardware (and hardware isn't set up yet), but it was a nice milestone to pass.
For those who question my interest in compiling with the IDE vs. going deeper with avr-gcc and friends (such as myself), I counter that this is intended to be a lightweight project that's easy to use. Setting up the Arduino IDE is about as simple as they come. I want to get to the point of compiling with gcc and uploading with avrdude, but that's for later.
Up next: building up the hardware on a breadboard, and seeing if any of this stuff actually runs!
08/17/2015 at 23:05 •
This weekend saw the "feature complete" stage for logic code. 1283 lines of code, and 1709 lines of test code. With any luck, those 1283 lines will compile down into something that will still fit in the flash storage of an ATMega328P, though I haven't tried yet. It gives me a good appreciation for how much code surrounds us: this timer is pretty straightforward, and it still took many hours to write, and occupies (an admittedly somewhat sparse) 1283 lines.
The logic code is basically everything that can be written without having the hardware in front of me. All the display stuff, timer manipulation, beep manipulation, button presses (via interrupt variables), etc. The hardware layer will be its own challenge, although there are only 8 function calls that will hook up to hardware (read and write EEPROM, tone on and off, start and stop a 1 second timer, get millis, and set a line on the display). These are all things that I've dealt with before, but never all at once.
I know the Arduino Tone library (which I'm hoping to use) takes up a timer, and I believe the millis() function takes up another, which should fill up the timers available on the 328. So I'm not sure if I'm going to have trouble trying to set a 1s interrupting timer.
One thing I'd like to do, but may not be able to just yet, is to put the CPU to sleep until the next interrupt comes in. The buttons and 1s timer are all designed as interrupts with this in mind, but I've never done any low-power work on a microcontroller, so I expect to have some challenges getting that to work. The battery will last a whole lot longer if the CPU can sleep between ticks and button presses.