Posts from: January '12
Take a programmer, add some electronics, and a poor houseplant. What would you get?
Or, "Gardening meets Programming, ver. 2.0".
As the previous attempt to make the poinsettia blossom didn't succeed, it was time to approach it more gently.
First, let me tell you (in my defence) that it isn't just me who's messing with the poor plant. Its development basically halted long ago, and its stealthy attempts to slip through a little new leaf or appendage would be faced with inevitable trimming, as my mother would trim it anytime she sees anything above the 20cm height-line. You know, riots need to be put down as early as possible :)
However, this summer I changed places, and the flower was now within my guardianship, so I let it grow. And gosh, it did :)
Well, that meant that the Thing's black box had to be upgraded. I also had some difficulty installing the crane in the new appartment.
In the end, I followed another approach: let's just keep the flower in shade, and illuminate it by other means, 10 hours a day.
1. I needed to provide a light source, which would be suitable for photosynthesis. Luckily, NASA had already researched that (f.e.), and they recommend using LEDs for that purpose, for efficiency and resource reasons. LEDs produce very little heat, thus the lighting won't incur any additional evaporation. The optimal light color is also known, this patent recommends red, orange and blue LEDs, in proportions of 12:6:1.
2. I bought some ultra-bright LEDs. Calculating the actual number of LEDs turned out to be a fairly complex deal, as one gets quickly submerged in the miriad of photometric units: lumens, lux, candelas, Watts per steradian... After double-checking my calculations with some other people, I placed 17 red, 8 yellow and two blue LEDs, each having 10000mcd of brightness. The aimed for around 2000 lux at peak, which was achieved (as checked with a dSLR-used-as-a-light-meter).
3. I prototyped on a breadboard:
4. And later moved it on a perfboard:
5. I analized some graphs of the sun's brightness when measured around sunrise. The light intensity shoots up no less than 1000 times (more like 10k in fact). I did some PWM to implement smooth "warming" of my artificial sun (see the video below). I only managed getting ~1000:1 contrast, and the initial part of the "sunrise" sequence is a bit buggy. I also programmed the yellow diodes to be lagging 20 minutes behind the red ones, and similarly for the blue ones, which are offset by an hour. The intent of this was simulating the different light color of the sun around sunrise/sunset. Not very convincing though, to be fair.
6. I cannibalized an old lamp:
and got some screws and plates out of a Meccano set:
... and here I ran a test blink on my strange "lamp":
7. Timekeeping is done with a specialized date/time chip - DS132 - and a quartz resonator. The sunrise/sunset times are correct year-round; they correspond to the actual times in San Antonio, Texas (used this one-year online calculator). These could be calculated algorithmically, but since the PIC is not exactly fit for floating-point math, sines/cosines, etc., I found it better to keep all the sunrise/sunset data in a static array, in a delta-compressed manner.
DS1302 continues to keep accurate time even after a power failure, as it supports backup power. This would normally be a battery, but I chose to just place a big electrolytic cap, which the DS1302 would charge while the main power is OK:
4700µF is more than enough, it can keep the clock alive for a bit more than a day.
8. Finally, I placed the poinsettia in a dark corner, with the "lamp" hanged around 30 cm above it (there has to be some space between them, as the light beam of these LEDs is quite narrow - so the space is needed to get more even illumination on the whole plant).
Finally, it's time to plug the power adapter in the socket, and the lamp follows the programmed daylight cycle, each day on...
And here's the sunrise, captured on video: Youtube.
The whole thing ("project: Daylight" I call it) wastes around a watt. The LEDs don't heat up at all.
The plant doesn't show signs of impendent blossom. It's been hooked up for around a month and a half now.
If flowers were capable of commiting suicide, this one would've been long gone.
• A whole project written in C. Not a single line of assembly for this one, just C, using the Hi-tech compiler. Well, this time I can't account for every last byte of the memory, but as long as the memory still suffices - it's not a problem¹.
• Inter-chip communication, the DS1302 specifically. What I did could classify as writing a driver, albeit a very simple one. Anyhow, a lot of unknown areas, related to hardware communcation, did clear up to me.
• Thinking photometrically: the lux, lumen, candela, and the geometric meaning of all these.
• Non-volatile memory (EEPROM) in projects like this. The PIC has it built-in, and thanks to that, I realized some kind of a zero-button user interface. I wanted to have two functions available: the normal one, and a test "blinker" function. This would have required either a button, or a DIP-switch. Well, the smarter way to convey our intention to the hardware, using only the On/Off switch can be something like that:
1. Turn the switch On.
2. Quickly turn it off again.
3. Turn it on. If the time between 1) and 2) was less than a second, enter in the test function mode, otherwise continue normally. Here's where the non-volatile memory comes into play. At bootup, the software quickly raises some flag in the EEPROM, and a second later turns it down again (if we're still alive). The next power-up can see whether the flag was cleared and decide accordingly.
• The compiler is your friend. Not long ago, I was a big fan of filling my sources with that cute magic-number arrays, which have been conveniently computed by some throwaway script. Well, I'm now for moving as much as possible inside the C/C++ code, wherever practical. The compiler can compute a lot of things all by himself, at compile time. So, no more magic numbers - but code/macros and the like - which derive the said magic numbers. For example: the DS1302 needs power, otherwise it loses track of time and thinks its Jan 1st, 2000. This may happen when placing it initially, or when moving it to the circuit board, or even by mistake. Well, I could've prepped a special build, which initializes it with the correct date/time, but that would be too hacky, as it doesn't leave a track how the DS1302 was ever initialized in the final code. Instead, one can use the __DATE__/__TIME__ pseudovars, which the C compiler is so nice to provide, and derive the correct dates/times from them. Thus, initialization is just a rapid recompile/program/run succession, and, more importantly, code is easier to maintain.
• MPLabX under Linux. Not the greatest IDE on Earth, but it gets work done.
¹ That kind of thinking is, of course, completely flawed, and leads to abominations. You could end up writing in C# if you stick to it for too long :)
Thanks to the second incarnation of the raytracing course in the Uni, I'm having the rare opportunity to experience how it feels to rewrite a modestly-sized (7k sloc) project from scratch. Sounds familiar? Raise your hand, if you, at some point, did have the burning desire to scrap the whole ungodly mess you're currently working on, and restart from Square One. Doing it right™, this time.
Yes, I know. Probably some of you even did that.
Well, it's a known fact, that this could be the worst strategic mistake for any bigger project.
For smaller stuff, it's quite okay though. I feel that we got the sample raytracer a lot better this time. Today, I even decided to compare the global illumination results (with path tracing) against V-Ray (the scene is courtesy of Kevin Beasons's smallpt).
This even poses an opportunity for a small challenge. Can you guess the renderer? V-Ray on top, or the bottom?
Browsing around SmallPT, I stumbled upon something of interest, which made me acknowledge (again) how cool 3D graphics programming could be.
For comparison, imagine you're writing FS stuff. And you've got a bug. What follows next is a kernel panic, reboot, and keeping your fingers crossed that the test partition is not completely invalid, so you can spare the reformat. Oh, and you still have a bug to fix.
Or, you could be writing some web software, and you've got a bug. Three months later, someone figured out how to exploit it, made your site blinking pink, tens of hours of human input are lost, etc. Oh, and you still have a bug to fix.
Or, you could be writing 3D graphics stuff - just went on optimizing some rendering code, which renders the images above. And you've got a bug (you should have seen the trend by now). And the bug manifests itself into this:
The best part is - you can even publish it as is, bugs included.
What else: I'm up for finishing the latest major version of AGG, 0.3.0. After that, I'm going to delve into ucbench and add OpenCL support (which, sadly, this implies a lot of website-related stuff, too).
Every now and then, one can be astonished by human arrogance and ruthlessness. Some genius took the open-source project, AGG, added some copy-protection code, and put a $30 price tag on the resulting product. The GPL is for the losers, who have nothing else to do. Ladies and gentlemen, I present you: SoftOrbits's Html Web Gallery Creator.
Just for example: A gallery, made by AGG, and a take with SoftOrbits's product.
The company that does it is unusually stealthy, specifying nothing about its whereabouts or operations. But the domain still leads to some russian guy, whom I already sent a Cease and Desist letter, coined with the help of this very kind person. And now we wait. I see some interesting days ahead...