I nixie clock build, in an art deco style. My first Nixie project, and I’m fairly happy with the result.

oozey mess
YOU ARE THE REASON

blake kathryn

tannertan36
we're not kids anymore.

@theartofmadeline
Today's Document
Jules of Nature
he wasn't even looking at me and he found me
RMH

pixel skylines
Sweet Seals For You, Always

Origami Around
Mike Driver
One Nice Bug Per Day

Kaledo Art

titsay
KIROKAZE

No title available
let's talk about Bridgerton tea, my ask is open
seen from Canada

seen from United States
seen from Singapore
seen from Malaysia

seen from United Kingdom
seen from T1
seen from United States

seen from T1
seen from Greece

seen from Germany

seen from Malaysia

seen from Canada

seen from South Africa

seen from Singapore
seen from United States

seen from United States
seen from United States
seen from Malaysia

seen from Canada

seen from United Kingdom
@ianspringer
I nixie clock build, in an art deco style. My first Nixie project, and I’m fairly happy with the result.
Adding an Adafruit backlight module to a Spektrum DX6i
Rather than buying a backlight module meant for a DX7 or DX9, I decided to go my own way with it.
I bought a LED backlight module from Adafruit for $2.50
https://www.adafruit.com/product/1622
I then calculated the resistor needed to limit current to 20mA. In this case it was 15 ohms. There are online calculators available to do this as well. Use the current and voltage provided by the manufacturer and the input voltage to get this value.
I decided to use 3.3 volts regulated so the backlight wouldn’t dim as the battery voltage dropped.
Note that the panel has a front and back, with the back being much more reflective! I used a sharpy to mark the back to prevent installing backwards.
My first step was to trim the acrylic diffuser to fit
I then found a regulated 3.3 source. My first location didn’t work, as even the minuscule current from the panel dropped the voltage. I instead found a location right on a large electrolytic capacitor.
I first attempted to trim the LCD brackets to allow the backlight to fit under them, but soon gave that up. I then had issues where any pressure on the LCD itself at all made it not display. I insulated the back of the backlight module, and made sure the LCD wasn’t under any strain, then reassembled.
Once I had the LCD lined up I reassembled, and viola! A backlit DX6e!
WordPress multiple install permalink issues on IIS
I’m working on moving some company sites from a very brittle Dreamweaver setup to Wordpress. We’re using Godaddy, and a singles IIS server to host multiple sites.
I ran in to an issue with using “pretty” permalinks on the site on a sub folder. If I added a web.config file to the sites root folder I got a 500 server error. If I didn’t I’d get 404 errors from any page but the home page.
It turns out there’s a rather simple fix! You need to remove the rule from the top level hosted wordpress web.config file in the new web.config in the sub folder!
Find the rule from your root folder such as
<rule name = "YourRuleName" patternSyntax = "Wildcard">
This rule name needs to be put in your sub folders web.config file as shown below
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <rewrite> <rules> <remove name="YourRuleName"/> <rule name="YourSubFolderRuleName" patternSyntax="Wildcard"> <match url="*"/> <conditions> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/> </conditions> <action type="Rewrite" url="index.php"/> </rule> </rules> </rewrite> </system.webServer> </configuration>
This should allow Wordpress to use the various other options for permalinks.
Changing a corroded tub drain on the cheap
The common tool to repair tub drains works fine on new drains and for installation, but is woefully inadequate for corroded and old drains. It is however cheap (around $10) and can be enough to complete the job.
However many of the people likely to attempt to replace their own have tools that can help! By using a 1 1/4″ or 30mm socket, socket wrench and a large hammer you can almost always remove one, without spending $60 for the expanding tool
The 1 1/4″ didn’t quite work.
I had better luck with the 30mm impact socket
I used my 1/2″ drive ratchet to remove it
Be sure to use some plumbers putty underneath the lip of the new drain to prevent leaks. It typically costs around $5 at your local big box home improvement store. Be sure to clean well before installing the new one, as the dried old putty can prevent a good seal. It may be worth your time to run a piece of wire down and try and pull any hairballs or other nonsense your children (awful creatures!) may have put down it.
Tighten the new drain just past hand tight. I estimate it was around 15 ft/lb’s of torque. Don’t muscle it in, as you can break the center spider easily, and in most cases that web supports the cap.
In the end for about $30 you can replace that corroded (and in my case disgusting) old drain.
Building a Guillows Typhoon for a contest on a group on Facebook.
How to do a marine fish freshwater dip for prophylaxis and as a treatment for ich
With an established marine aquarium, disease prevention is a mandatory task. The typical method to prevent the introduction of diseases is to quarantine new livestock for 4 weeks in a dedicated quarantine tank. This is a tank set aside for this purpose and typically is set up without invertebrates so that medication may be administered if necessary.
However not everyone has the resources to maintain a quarantine tank, and some livestock is too large for any but the most extreme sized quarantines. Additionally you may have issues with your livestock within the display tank picking up a disease or parasite. This is due to a weakened immune system cause by environmental factors.
The puffer shown below has picked up an ich infection due to ammonia poisoning. Note the white cysts on his skin and fins. Puffers are especially susceptible as they have no scales. This also means that most copper based ich medications can be fatal to them.
For these issues the solution is to do a freshwater dip. Fish can osmo-regulate much more effectively than invertebrates can. This means a marine fish can withstand freshwater conditions far longer than most parasites can without long term damage or even ill effects. The freshwater dip is so efficacious that it is standard procedure for most of the larger marine importers.
Material needed
Baking soda (calcium carbonate)
High range pH test kit
RO/DI water
Air pump, tubing and airstone
Container for the dip (tupperware is my preference)
Methylene Blue (optional)
Large container containing mixed saltwater from the display (optional)
I first will aerate the RO/DI water for at least 3 hours using the air pump and an airstone. This will help stabilize the pH of the water.
I then float the RO/DI water in the display tank to equalize the temperature, this could also be accomplished using a heater, but may melt the container if care is not taken.
I'll take a sample of the display tank and measure the pH of the salt water in the tank. I'll use this sample to match the pH of the RO/DI mixture against.
Once the temperature is equalized I will then slowly mix in baking soda one tablespoon at a time to match the pH of the display tank. I let the RO/DI mix sit for 15 minutes between measurements.
It is important to match the pH as closely as possible. This experience will be stressful on the livestock regardless, but it is best to minimize the difference in water conditions. Once the pH is as closely matched as possible you can then add the Methylene Blue (optional).
Once the pH is matched I'll then net the fish and place it in the RO/DI mixture. I'll closely observe the fish to ensure it isn't too distressed. Leave the fish in the RO/DI mixture no longer than 5 minutes! Once the fish starts trying to leap from the container, starts thrashing or breathing very heavily (more than 80 breaths a minute) remove it from the RO/DI mixture and either return it to the display, or if you used the Methylene Blue place it in the rinse container. If the fish is added to the rinse container, let it sit in that container for 2-5 minutes to fully rinse the Methylene Blue traces from the fish.
As you can see with the images below it can be a stressful experience for the fish! It also can be a lifesaving measure however, so it definitively beats the alternative!
The dangers of ammonia based products and marine aquariums
I recently had a near miss with my puffer. The landlord decided that the house needed cleaning and mopped the floor using Pine-Sol. Despite my repeated warnings to the contrary it was assumed that the ammonia on the floor couldn't possibly be dangerous.
I come home to find the porcupine puffer in dire condition. His color was very dark and ashy and he was laying on the sand unmoving. When I tested the water I read .5ppm (parts per million). This small amount is enough to threaten saltwater fish, and puffers are even more susceptible as they have no scales.
A .5ppm level indicates that there was less ammonia than would fit in a bottle cap in the system, yet this level can be fatal. The ammonia entered the system from the surface of the tank from evaporated ammonia. Ammonia is hygroscopic in nature, which means it has a high affinity for water.
I did a crash water change of almost 30 gallons, enough to bring the levels down to .10ppm, and below the fatal level. This is a small enough amount to allow the bacteria in the system to convert it to nitrites and then nitrates.
It is important to avoid any ammonia based cleaners in the vicinity of your tank! In my case I'm banning them from the house, not just the living room area in the future.
DIY low tech automatic top off (ATO) for marine aquariums with sump
One of the issues a saltwater aquarist has to contend with is loss of water through evaporation. As most marine systems employ much higher wattage lighting than freshwater tanks, the rate of loss can be surprising. As an example, my 135 gallon tank can lose up to 1.5 gallons a day in the summer!
Another issue that especially plagues smaller tanks is the change in salinity caused by this loss. As only pure water is lost, the salt remains in the tank, and salinity increases. The loss of 1 gallon of water in a 15 gallon nano reef can shift the specific gravity (SG) from 1.024 to 1.027. This can be stressful on corals and livestock alike.
My (very) low tech approach to this is to use the same float valve that is used within reverse osmosis systems. I purchased this specific float valve from eBay for $9 plus shipping.
Materials Needed
1/4" air-line tubing ($10)
1/4" valve (($1.25)
Scrap plexi-glass/acrylic/plastic (free?)
Float valve ($9)
Nylon hardware ($1.50)
Water container/ 5 gallon bucket/etc. ($3-$15)
Tools needed
Drill
5/8" drill bit
1/4" drill bit
superglue
The first step is to remove the metal hardware in the float valve and replace it with nylon. Drill out the old screw with a 1/8" bit. Thread the new hardware in and tighten it down. You could also simply glue the pieces together instead, and lose the ability to adjust the level. I purchased the nylon hardware at my local Home Depot for roughly $1.50
You then take a scrap of acrylic/plexiglass/plastic and cut it to roughly 2"x4" in size. This is then bent into a 90 degree angle using a heat gun. The plastic can be any sufficiently robust material available. The heat gun can be replaced with a hair-dryer as well, assuming you have patience. The hair dryer adds considerable time to the job.
You then drill out a 5/8" hole into a 5 gallon bucket, and plumb it with a 1/4" line quick release fitting. This will be the RO/DI water reservoir. It could be substituted for a 5 gallon water carrier easily, especially because they have a nipple available to use for this purpose.
5 gallon bucket with plumbed quick release fitting
5 gallon water jug with threaded fitting on top of pic
The float valve is then inserted into the drilled hole and screwed down tightly. Insert about 8" of 1/4" line into the float valve and then a 1/4" valve. Then apply as small quantity of superglue to the vertical face of the plastic (it helps if it is scuffed up somewhat). The angle plastic is then placed at the correct height inside the sump.
Run the 1/4" tubing back to where you placed your reservoir and cut it to length. Fill the reservoir at this point, and find the free end of the tubing. Suck on the tubing until all the air has been displaced, then connect it to the check valve. Turn on the check valve at this point and you're done!
If you are a belt and suspenders sort of person you can add another float valve into the reservoir itself. This valve will be installed upside down, and will use gravity to close the valve. This will prevent the line to the sump from sucking air into it if the reservoir is empty. Not really worth the extra effort in my opinion, but if you are likely to let the reservoir run dry it's not a bad idea.
Images of this setup in operation below.
The float valve glued in place
The ball valve to shut off flow
Wider angle shot of float valve in operation (note the "max fill" marking)
Electrical safety for Marine aquariums
There are a few hazards associated with saltwater tanks that aren't present in freshwater set-ups. One of them involves the conductivity of saltwater.
There are two easy steps that can prevent injury, one of which doesn't even cost a dime!
Install a GFCI outlet
This step should really be done before setting up the tank, but you may be able to retro-fit your outlets depending on clearance or use a GFCI power cord extension. the outlets can be purchased as cheaply as $9, and the extensions go for $15 typically.
A GFCI (Ground Fault Circuit Interrupter) functions differently than a breaker or fuse. Fuses and breakers have a limit on current flow that has to be exceeded before they trip or blow. A GFCI outlet instead uses the presence of as little as 5 milliamps of current flow from the hot line to ground to trip. It can open the circuit in as little time as 30 milliseconds, fast enough to prevent fatal injury in most cases.
Add drip loops to power cords
Once the tank has been set up and the location of power-heads has been decided be sure and put some drip-loops into your cords. These are simply loops of cable that provide an easy path for water to drip from. This prevents water from running into your outlets. As saltwater is both corrosive and conductive it is best to keep it out of your electrical components.
Drip acclimation of aquarium livestock
One of the more contentious topics in fish-keeping is how to acclimate your newly purchased fish for the tank.
The method I prefer for both freshwater and marine fish is drip acclimation. Note that there are a few caveats to this method; if the fish have spent many hours in a shipping bag it is not advisable. As ammonia toxicity decreases with pH it shouldn't be used because the pH will rapidly climb when the bag is open and the water mixes. This is likely harm the fish as the toxicity of the ammonia spikes.
Drip acclimation can be done as elegantly or as simply as you care to do it. The simplest method uses 1/4" tubing and a black metal paperclip. The paperclip is used to crimp the tubing and reduce flow.
Or you can use the same tubing with a suction cup to hold the tubing in place, and a valve to adjust flow. For the more ambitious you can even float the acclimation container in the tank and use a pump for delivery. This will speed up the temperature equalization, though not strictly necessary as the ingress of water from the display tank will do the same.
The use of a valve allows for finer control of drip speed than the metal clip method of crimping the tubing. It is inexpensive to purchase valves intended for use in sprinkler drip systems for the local hardware store as well.
Quite simply drip acclimation is the process of slowly adding water from the tank to the container holding the livestock and the shipping water. This process lets the livestock gradually adjust to the difference between the two. There are always slight differences in mineral content, pH and nitrates as well as the presence of trace materials between two tanks.
I prefer to run my acclimation at roughly a drop per second. Once I've doubled the amount of water I'll scoop out a cupful and continue the process. I'll spend up to an hour with fragile species, but with hardier fish such as Blue/Green Chromis I'll run the drip for 30 minutes.
Once the time frame allotted has passed I then net the fish from the container and evert the net into the water. It is advisable to not empty the shipping water into your system as you can introduce undesirable hitchhikers that way. In a marine tank you could conceivably introduce aiptasia or mojano anemones via small free floating juveniles.
With a saltwater system a further step is required if you don't have a quarantine tank. I strongly recommend using a 4 to 6 week quarantine, but as this is an expensive hobby your resources may not stretch that far.
The final step for a non-quarantine marine system is a freshwater dip. This s a topic worthy of it's own post so will have to wait until I have some new livestock to demonstrate with.
A short clip of my DIY LED moonlighting in action, and a blue/green chromis making a guest appearance.
Acclimating a mail-order cleanup crew
Acclimating new arrivals via mail order is a slightly different process than acclimating livestock from your LFS (Local Fish Store). Additionally there are some differences with the types of livestock purchased. In this post I'll be showing how to acclimate a clean-up crew composed solely of snails. The process would be the same if hermits were included as well as most invertebrates.
Most species utilized for aquarium cleaning are intertidal inhabitants. This means they can accommodate changes in salinity and to an extent pH changes much better than most other livestock. So we'll be more concerned with matching temperature than we will water conditions.
Rather than drip acclimate into a bucket we will float them in the bag they came in; be sure and leave the bag closed! While normally you would open the mouth of the bag for surface area for oxygen exchange, we want to avoid this; while the bag is open the CO2 in the water will be dissipating and the pH will rise.
The water the animals were shipped in has a low pH due to the raised CO2 levels from carbonic acid. This is actually beneficial as it makes the ammonia less toxic. If I were to add water from the display tank, the pH would rise quickly and it would make the ammonia much more toxic. Ammonia toxicity is directly related to pH levels. I'm more likely to lose livestock via ammonia poisoning than I am from the pH and salinity changes. The most important thing is to get the temp matched and get them out of the water they arrived in.
I had my wife bring the package into the house in a warmed area as soon as it arrived. This will bring the temperature up somewhat, and speed the process for me. However I assume most of you will be at the mercy of your employer and the postman and will likely have the package in the weather for a time. No worries though, these are all exothermic animals and as long as the temp doesn't approach freezing they'll survive. For those of you in colder climes I'd advise waiting until spring for your order, or ship overnight with someone ready to receive the package for you. Reefcleaners does ship with a heat pack as shown below.
This particular order is well packed and insulated. Due to the care taken with shipping I expect few losses among these animals. This illustrates an important point too, while I may have spent a bit more by going through reefcleaners.org (well actually I didn't) I'll keep more of my livestock than otherwise. Avoid the false economy of buying in larger lots from a wholesaler who cuts corners. They won't have a high survival percentage, and you will find out why your LFS sells Blue/Green Chromis for $5 and buys them for $1. It's the 50% mortality rate.
Another thing to note is that I won't be quarantining these animals. The tank volume required to feed this many snails in a quarantine would be the same as the display tank! I'll also avoid doing a pH matched freshwater dip as well. These animals are a bit stressed from their trip to San Diego from Florida.
After about 20 minutes have passed I'll net the snails and put them in the display tank. Due to the puffer I'll try and put them in an area away from his normal hangouts. They should be placed in a visible area though. Any snail that loses it's operculum (the trapdoor that closes the shell) is dead, and any that don't move after 24 hours are likely dead as well. It is important to get them out as soon as possible. There is already an increase in bio-load, and the addition of ammonia from decaying snails could induce a mini-cycle and endanger the fish. Be sure and dispose of the water they came in though, as this will minimize the risks of introducing parasites that could harm your fish.
I'll continue to check on them for another week or so. More may have been over-stressed and weakened enough not to survive more than a few days. The Cerith snails are an exception though; they can go dormant and estivate for several days.
While the acclimation process has been completed there are a few ethical points to make here. The large one is sustainability. While these animals were sourced from a vendor who farms their own livestock, most marine animals are wild caught. They suffer terrible conditions during shipment due to the low profit margin, and have obscene mortality rates. As many as 4 out of 5 anemones don't survive more than a month as an example.
Another point to be made regards dumping unwanted livestock into your local ocean. The animals used in marine tanks are tropical species. That means dumping a blue leg hermit from the Caribbean into the Pacific is a bad idea. It can introduce diseases that the local animals have no resistance to, and the hermit will die regardless due to being out of it's preferred habitat. This is actually the best case scenario. For example, Caluerpa is now illegal to have in California as un-thinking hobbyists have allowed it into the wild. It has rapidly become a problem by displacing native species.
So be sure to enjoy your tank, but be responsible as well. I hope that my step-children can enjoy this hobby as much as I do in the future.
A short pic of my marine tank during a huge cyano bloom. I have a booster pack of cleaners coming from www.reefcleaners.org
These guys are flat out the best source for clean-up crews. They harvest the animals themselves and do it sustainably too. Tell John that Ian sentcha' to give me a referral bonus too.
DIY CO2 system
This is a short write up of my DIY low tech CO2 system for a planted aquarium. It has been running for about 2 years now without issue.
Parts list
1/4" airline tubing
2X 2 liter bottles
1X 12 ounce bottle
4X 1/4" fittings
1X 1/4" gang valve
1X bubble counter (optional)
1X diffuser
Equipment List
5/16" drill bit
electric drill
2 part epoxy
Misc. materials needed
Yeast (bakers)
Sugar
Aspirin (optional)
The formula for the yeast mix is simple. I use a pinch of bakers yeast (Red Star in my case) mixed into warm water at 100F to 115F, or roughly hot enough to be uncomfortable but not burn. I'll let it sit for 5 minutes then stir in 3/4 cup of sugar. I'll then leave it uncovered for about an hour to let he yeast fully activate. I then add 1/2 of an aspirin (generic of course) and attach the bottle to the system.
The aspirin is optional, but helps keep bacterial blooms in check and allows you a bit more leeway when cleaning the bottles before reuse.
The tubing being used is the cheap airline tubing available at a hardware store. Over time the CO2 and ambient ultraviolet degrades it and it will need to be replaced. I change my tubing out yearly. You can use the more expensive CO2 rated tubing, but as the airline stuff is so cheap the ROI on the higher quality tubing is about 7 years.
I use a cheap gang valve to enable me to pull one bottle from the system while retaining pressure. This keeps the system running while I clean and fill the bottle.
To build the system I'll first drill a 5/16" hole in the caps for both the 2 liter bottles, and drill 2 5/16" holes in the 12 oz bottle. The 1/4" fittings are squeezed into the holes, then potted thoroughly with epoxy. Let them sit and cure for at least 24 hours before use. I find the white epoxy works better than the clear and is more resistant to degrading from exposure.
I use Pepsi bottles as the caps are constructed without a separate seal and have a molded lip used to retain pressure instead. The actual bottle being used isn't important beyond aesthetics as most can withstand up to 100 psi.
Once the epoxy is dried the system can be set up. Attach a short piece of tubing (3" or so) to the inside of the cap used for the 12 oz. bottle going to the input side. This will act as a trap for vapor and prevent any accident addition of the yeast mixture into the tank. I used an old air diffuser with the stone broken off to weight the end to keep the tubing straight. While this bottle isn't necessary, if your system ever dumps you'll be glad you have it as it will catch the yeast sugar mixture before it pollutes the tank.
I'd advise filling only one bottle at first, then filling the second the following week. At this point a bottle can be recharged weekly and keep a decent level of CO2 in the system.
I'm using a knock-of glass/ceramic diffuser on my system. Note that it may take a day or three to begin seeing bubbles from this style diffuser. They are made to run on systems of +20 psi and the DIY rigs rarely reach that pressure. Be patient however and you will see bubbles from the diffuser in time.
How to quiet a noisy HOB filter
Many new HOB filters (Hang On Back) that come with tank sets are very noisy when first used. It can take weeks for a bio-film to build up on the impeller and quiet the rattle. In some cases, especially with the cheaper models the tank never does stop being noticeably noisy.
The following post shows how to quiet your HOB filter for nothing more than the cost of a small jar of Vaseline.
Note the ingredient, no additives, menthol etc. added. You could possibly even use generic lip-balm if it has nothing more than petroleum jelly. It is inert for all practical purposes in a freshwater tank. I have no experience using this method on a marine system, so use at your own risk in a saltwater tank.
The first step is to pull the lift tube from the u-tube. If this is a filter that's been running a while it is also a good opportunity to give it a good scrub.
Once the lift tube is out the u-tube will pull out vertically, see the side view pic below to illustrate how the u-tube seats.
Simply pull upwards steadily until the u-tube comes free.
Once the u-tube has been removed you should see an impeller, they are typically green or white, but the color may vary and is unimportant.
Use a pair of needle-nose pliers, long tweezers or even chopsticks, pull the impeller from the housing. Pull straight up, but expect a bit of resistance from the magnet of the impeller and the drive coil.
Once the impeller is free wipe it down and remove any debris. this is not necessary with a new filter unit.
Using a small amount of Vaseline apply it evenly to the magnetic cylinder of the impeller.
Using the pliers, tweezers or chopsticks place the impeller back into the drive housing. Then, ensuring it is lined up, replace the u-tube over the impeller. There should be an alignment post or slot on the HOB filters body. Once it's lined up it should seat easily and solidly.
Note the flow control on the u-tube. On occasion this will generate noise as bubbles of air slip by the seal and move through the impeller. This can sound like a can full of rocks if severe. By pulling the adjuster and liberally applying Vaseline around the seal this problem can be fixed as well.
Replace the lift tube. mount the filter on the tank and be sure to prime it before powering it up. A cup full of water should be enough to get it started.
You should now have a whisper quiet filter without spending a fortune on a high end brand.
DIY Desktop aquarium hood with micro-controller
Here is the complete tear-down of my DIY lighting fixture for my 6.6 gallon Endlers tank. I used prototyping board for the LEDs and some left over solar panel strips for the bus. I've attached the schematic for the power board as well.
Be sure to check the older entries for pics of the SBC.
Here is a photo gallery of the hardware. I used 20 gauge aluminum for the cover, and several stand offs to elevate the board from the acrylic tank cover.
I'm planning on replacing one of the NPN transistor outputs on the uC with a FET, and driving the fan directly from that. The built-in 5 volt regulator has spare capacity, and will allow the uC to control the fan. I may add a temperature and humidity sensor ($3 from ebay) and use it to control the fan on/off timing.
The hole for the serial connection is... a bit ragged. I ended up breaking my DB9 punch, so just reamed the hole with a drill bit. Ugly, but I was on the home stretch and wanted it done.
The board is powered from a standard laptop charger/power supply. It could be purchased for around $30 new, but a used one could likely be found for around $8.
I added an external power switch after the fixture was built to complement the over-ride switches on the side. This allows me to turn the entire fixture off when cleaning the tank. There are three over-ride switches installed as well, to allow manual control of the lighting.
Note the transistor driven relay modules, this allows the 8051 to drive the relays, and is well within its 20mA current limit per pin.
The LEDs are mounted onto two prototyping boards with a heavy copper backplane. These are in turn mounted to an aluminum backplate. The backplate has a scrap piece of heatsink added, overkill as the unit has yet to exceed 90 degrees even in the southern California summer.
The timing of the lighting is set via a terminal program over the comm port of a laptop. The serial port is wired as a null modem, so a standard serial cable is all that is needed. If you only have a null modem cable, you will also need a null modem adapter to re-reverse the TX and RX lines.
The power supply board has a heat-sink mounted across the DC-DC convertors, as they do get warm in the summer, although not dangerously so. There is a piece of acrylic covering one end of the cover to force the airflow to pull in past the top mounted heatsink and through the backplane mounted one. This ensures the components all stay cool and should extend the lifetime of the unit. I estimate it has about 5 years before it needs servicing, due to the MTF (mean time to fail) of 14,000 hours for the converters and the 50,000 hour MTF of the LEDs.
The LEDs are a mix of 6500K and 10000K. I noticed a hair algae growth spurt when just the 6500K LEDs were used. The 10000K have less of the red component and has a better PAR for freshwater plants. For a marine tank I'd use 10000K, 12000K and 16000K as saltwater absorbs the red spectrum more readily, so the blue has better penetration.
I initially used lenses on the LEDs, but due to the shallowness of the tank I decided to remove them, as the dispersal of the light isn't a problem. Reading the output view a VU meter shows about 1,500 lumens at 8", equivalent to roughly 45 watts of flourescent lighting. Note that it works out to about 7 watts per gallon effective illumination.
The tank has been thriving now for some months. I can get up to 1" a day on some of the plants, and have to do a weekly trim in order to keep some free areas open for the fish.
The main code loop is provided here. The code is intended for use with the Keil C compiler, and the target platform is the AT89C51RD2.
//--------------------------------------- // Example read and write DS1307 // KEIL C51 v7.5 //--------------------------------------- //#include <AT89C51XD2.H> /* special function registers 8052 */ //#include <stdio.h> //#include "ds1307.h" //#include "delay.h" /* All headers moved to config.h */ #include "config.h" char code menu[] = "1. Set Time:\n" "2. Set Date:\n" "3: Set Day:\n" "4. Set/Show Timers\n" "5. Initialize RTC\n" "6. Enter ISP mode\n" "7. Exit\n"; char code submenu[] = "Select desired light strip\n" "1: Front white strip\n" "2: Rear white strip\n" "3: Moonlight strip\n" "4: Display current settings\n"; char code timerInst[] = "Set start and end times in HH:MM-HH:MM format\n"; unsigned char RTC_ARR[7]; // Buffer for second,minute,.....,year //unsigned int NVRAM_ARR[12]; sbit blue = P0^0; sbit whitefront = P0^1; sbit whiterear = P0^2; //int checkInitRTC; int selection,lightselect; int day, month, year, hour, minute, second; /* int storage for setting time */ //unsigned int wFSh,wFSm,wFEh,wFEm,wRSh,wRSm, wREh,wREm,bSh,bSm,bEh,bEm, FrontStart,FrontEnd,RearStart,RearEnd,BlueStart,BlueEnd; int wFSh,wFSm,wFEh,wFEm,wRSh,wRSm, wREh,wREm,bSh,bSm,bEh,bEm; int scanfErrorCheck; void reset (void) { ((void (code *) (void)) 0x0000) (); } //--------------------------------------- // Initialize serial port //--------------------------------------- void InitSerial(void) { SCON = 0x52; // setup serial port control TMOD = 0x20; // hardware (9600 BAUD @11.05592MHZ) TH1 = 0xFD; // TH1 TR1 = 1; // Timer 1 on } void initializeRTC(void) { ReadRTC(&RTC_ARR[0]); RTC_ARR[0] = 59 & 0x7F; // enable oscillator (bit 7=0) RTC_ARR[1] = 0x59; // minute = 59 RTC_ARR[2] = 0x23; // hour = 05 ,24-hour mode(bit 6=0) RTC_ARR[3] = 0x07; // Day = 1 or sunday RTC_ARR[4] = 0x31; // Date = 30 RTC_ARR[5] = 0x12; // month = August RTC_ARR[6] = 0x99; // year = 05 or 2005 WriteRTC(&RTC_ARR[0]); // Set RTC DelayMs(50); ReadRTC(&RTC_ARR[0]); RTC_ARR[0] = bcd(00); //second RTC_ARR[1] = bcd(00); // minute = 59 RTC_ARR[2] = bcd(14); // hour = 05 ,24-hour mode(bit 6=0) RTC_ARR[3] = bcd(04); // Day = 1 or sunday RTC_ARR[4] = bcd(19); // Date = 30 RTC_ARR[5] = bcd(10); // month = August RTC_ARR[6] = bcd(11); // year = 05 or 2005 WriteRTC(&RTC_ARR[0]); // SRAM addres 0x22 used to store initialization status, 22 = initialized WriteBYTE(0x22,22); } //--------------------------------------- // Main program //--------------------------------------- //addresses 0x8h - 0x3Fh are nvram (while batt attached) void main(void) { //Turn off all LEDs blue = 0; whiterear = 0; whitefront = 0; InitSerial(); // Initialize serial port RI = 0; // clear UART receive interrupt DelayMs(10); // delay about 1/10th second //White front start and end wFSh= ReadBYTE(0x01); wFSm= ReadBYTE(0x02); wFEh = ReadBYTE(0x03); wFEm = ReadBYTE(0x04); //White rear start and end wRSh = ReadBYTE(0x05); wRSm = ReadBYTE(0x06); wREh = ReadBYTE(0x07); wREm = ReadBYTE(0x08); //moonlight start and end bSh = ReadBYTE(0x09); bSm = ReadBYTE(0x10); bEh = ReadBYTE(0x11); bEm = ReadBYTE(0x12); while(1) { ReadRTC(&RTC_ARR[0]); printf("\033[2J"); //clears terminal DOES WORK printf("Day : %s\n",IntDay(decimal(RTC_ARR[3]))); printf("Time: %02d:%02d:%02d\n",decimal(RTC_ARR[2]),decimal(RTC_ARR[1]),decimal(RTC_ARR[0])); printf("Date: %02d-%02d-20%02d\n",decimal(RTC_ARR[5]),decimal(RTC_ARR[4]),decimal(RTC_ARR[6])); //ReadNVRAM(&NVRAM_ARR[0]); //FrontStart = (wFSh*100)+wFSm; //FrontEnd = (wFEh*100)+ wFEh; //RearStart = (wRSh*100) + wRSm; //RearEnd = (wREh*100) + wREm; //BlueStart =(bSh*100) + bSm; //BlueEnd =(bEh*100) + bEm; if(((wFSh*100)+wFSm) == ((decimal(RTC_ARR[2])*100)+(decimal(RTC_ARR[1])))) { whitefront = 1; } if(((wRSh*100)+wRSm) == ((decimal(RTC_ARR[2])*100)+(decimal(RTC_ARR[1])))) { whiterear = 1; } if(((bSh*100)+bSm) ==((decimal(RTC_ARR[2])*100)+(decimal(RTC_ARR[1])))) { blue = 1; } if(((wFEh*100)+wFEm) == ((decimal(RTC_ARR[2])*100)+(decimal(RTC_ARR[1])))) { whitefront = 0; } if(((wREh*100)+wREm) == ((decimal(RTC_ARR[2])*100)+(decimal(RTC_ARR[1])))) { whiterear = 0; } if(((bEh*100)+bEm) == ((decimal(RTC_ARR[2])*100)+(decimal(RTC_ARR[1])))) { blue = 0; } if(RI) { RI=0; //Clear receive interrupt flag in order to grab new values in buffer SBUF=0; // clear buffer (needed due to the occasional error when bad data input) printf("\033[2J"); printf(menu); scanf("%u", &selection); switch(selection) { case 1: printf("Enter time in HH:MM:SS format and hit enter to update\n"); scanfErrorCheck = scanf("%d:%d:%d", &hour, &minute, &second); if (scanfErrorCheck == 3) //verify input has 3 integers { if((hour <=24 && hour >0) && (minute >=0 && minute <=60)&&(second <=60 && second >=0)) // Make sure we have rational inputs { ReadRTC(&RTC_ARR[0]); // Update buffer with current values DelayMs(5); RTC_ARR[0] = bcd(second); RTC_ARR[1] = bcd(minute); RTC_ARR[2] = bcd(hour); WriteRTC(&RTC_ARR[0]); //Write new values } else { printf("Invalid input\n"); SBUF=0; DelayMs(100); } } else { SBUF=0; } RI=0; //Clear receive interrupt flag break; case 2: printf("Enter month, day, and year in MM-DD-YY format and hit enter to update\n"); scanfErrorCheck = scanf("%d-%d-%d",&month, &day, &year); if(scanfErrorCheck == 3) { if((month >0 && month <=12)&&(day > 0 && day <= 31)) // Make sure we have rational inputs { //printf("Date:%02d-%02d-%02d", month, day, year); ReadRTC(&RTC_ARR[0]); // Update buffer with current values DelayMs(5); RTC_ARR[4] = bcd(day); RTC_ARR[5] = bcd(month); RTC_ARR[6] = bcd(year); WriteRTC(&RTC_ARR[0]); //Write new values printf(" Set to %s %02d 20%02d\n",IntMonth(month),day,year); DelayMs(1000); } else { printf("Invalid input\n"); SBUF=0; DelayMs(100); } } else { SBUF=0; } RI=0; //Clear receive interrupt flag break; case 3: printf("\033[2J"); printf("Enter day of week where 1=Sunday then hit enter to update\n"); scanfErrorCheck = scanf("%d", &day); if(scanfErrorCheck == 1) { if(day>0 && day < 8) { ReadRTC(&RTC_ARR[0]); // Update buffer with current values DelayMs(5); RTC_ARR[3] = bcd(day); WriteRTC(&RTC_ARR[0]); //Write new values printf("Day : %s\n",IntDay(day)); DelayMs(1000); } else { printf("Invalid input"); SBUF=0; DelayMs(1000); } } else { SBUF=0; } RI=0; break; case 4: printf("\033[2J"); printf(submenu); scanfErrorCheck = scanf("%u", &lightselect); if(scanfErrorCheck == 1) { switch(lightselect) { case 1: printf(timerInst); scanf("%d:%d-%d:%d",&wFSh,&wFSm, &wFEh,&wFEm); //White front start and end WriteBYTE(0x01,wFSh); WriteBYTE(0x02,wFSm); WriteBYTE(0x03,wFEh); WriteBYTE(0x04,wFEm); DelayMs(5); //White front start and end wFSh= ReadBYTE(0x01); wFSm= ReadBYTE(0x02); wFEh = ReadBYTE(0x03); wFEm = ReadBYTE(0x04); printf("Start time:%02d:%02d, End time:%02d:%02d",wFSh,wFSm,wFEh,wFEm); DelayMs(500); RI=0; break; case 2: printf(timerInst); scanf("%d:%d-%d:%d",&wRSh,&wRSm, &wREh,&wREm); //White front start and end WriteBYTE(0x05,wRSh); WriteBYTE(0x06,wRSm); WriteBYTE(0x07,wREh); WriteBYTE(0x08,wREm); DelayMs(5); //White rear start and end wRSh = ReadBYTE(0x05); wRSm = ReadBYTE(0x06); wREh = ReadBYTE(0x07); wREm = ReadBYTE(0x08); printf("Start time: %02d:%02d, End time: %02d:%02d",wRSh,wRSm,wREh,wREm); DelayMs(500); RI=0; break; case 3: printf(timerInst); scanf("%d:%d-%d:%d",&bSh,&bSm, &bEh,&bEm); // Moonlight start and end WriteBYTE(0x09,bSh); WriteBYTE(0x10,bSm); WriteBYTE(0x11,bEh); WriteBYTE(0x12,bEm); DelayMs(5); //moonlight start and end bSh = ReadBYTE(0x09); bSm = ReadBYTE(0x10); bEh = ReadBYTE(0x11); bEm = ReadBYTE(0x12); printf("Start time:%02u:%02u, End time:%02u:%02u",bSh,bSm,bEh,bEm); DelayMs(500); RI=0; break; case 4: //White front start and end wFSh= ReadBYTE(0x01); wFSm= ReadBYTE(0x02); wFEh = ReadBYTE(0x03); wFEm = ReadBYTE(0x04); //White rear start and end wRSh = ReadBYTE(0x05); wRSm = ReadBYTE(0x06); wREh = ReadBYTE(0x07); wREm = ReadBYTE(0x08); //moonlight start and end bSh = ReadBYTE(0x09); bSm = ReadBYTE(0x10); bEh = ReadBYTE(0x11); bEm = ReadBYTE(0x12); printf("White Front Start time:%02d:%02d\n",wFSh,wFSm); printf("White Front End time:%02d:%02d\n",wFEh,wFEm); printf("White Rear Start time:%02d:%02d\n",wRSh,wRSm); printf("White Rear End time:%02d:%02d\n",wREh,wREm); printf("Moonlight Start time:%02d:%02d\n",bSh,bSm); printf("Moonlight End time:%02d:%02d\n\n",bEh,bEm); DelayMs(2500); SBUF=0; RI=0; break; default: printf("\033[2J"); printf("Unrecognized input, exiting"); SBUF=0; DelayMs(300); RI=0; //Clear receive interrupt flag break; } } else { SBUF=0; } RI=0; //Clear receive interrupt flag DelayMs(10); break; case 5: printf("\033[2J"); initializeRTC(); printf("DS1307 Initialized\n"); DelayMs(500); SBUF=0; RI=0; break; case 6: printf("\033[2J"); printf("Enter 9 to enter ISP mode, any other key to exit\n"); scanfErrorCheck = scanf("%d", &selection); if(scanfErrorCheck == 1) { if(selection == 9) { //printf("Remove serial cable within 5 seconds and then connect via Flip\n"); printf("Power cycle and then connect via Flip\n"); DelayMs(100); __api_wr_SBV(0xFC); __api_wr_BSB(0x55); __api_set_BLJB(); reset (); //((void (code *)(void)) 0) (); //May work also //DelayMs(2500); } } else { SBUF=0; } SBUF=0; RI=0; break; case 7: printf("\033[2J"); printf("Exiting\n"); DelayMs(200); SBUF=0; RI=0; //Clear receive interrupt flag break; default: printf("\033[2J"); printf("Unrecognized input\n"); SBUF=0; DelayMs(100); RI=0; //Clear receive interrupt flag break; } } DelayMs(800); // delay about 1 second //PCON |= 0x01; /* Enter IDLE Mode -- Wake-up every timer interrupt */ } }
New open-hardware project launch!
I've launched an open hardware project to build blue-tooth enabled watches. The goal is to build a watch that is an extension of your smartphone. The prototype model will have a real time clock, a 3 axis compass and a blue-tooth modem. The initial smart-phone software will be developed for the Android platform, with a windows 7 phone release to follow. Currently there are no plans for an iphone app, as development costs are too high.
Check it out at www.blue-pointer.com