Basil Using my Latest DIY LED Setup

In a previous post, I discussed why/how I built an LED lamp for growing leafy herbs and vegetables.  All this in an quest to grow the happiest and tasty plants.  This post is about my practice with a bunch of basil plants.  I love basil.  I put it in my salads, tomato sauces, and just love the smell.  I am very grateful to go into our kitchen and be greeted by a happy, great smelling plants.  More to come!

The Goal

The goal of this post is to chronicle the growing of basil plants using the LED lamp setup.  

September 20, 2016

The plants are not using the LED lamp setup.  I have them under an older LED lamp setup as I built the new one.

9 20 2016 Basil

I am using nutrients I had got awhile back.  At this point I am not doing a good job tracking pH and EC.  Dr. Paul Fisher‘s Nutrient Management 2 (Advanced) was extremely helpful in giving me a stronger grasp of how to best use pH and EC readings as well as keeping plants healthy through visual clues.

I am concerned about the color of the leaves.  They appear to show signs of chlorosis pointing to a nutrient deficiency.  I plant on changing to a different nutrient so I’ll reset at this point.  Next week’s photo should show positive growth signs.

September 28, 2016

After course lectures on quantity/quality of nutrients, I read this Cornell University paper.  One of the recommended fertilizers is Jack’s Hydro FeEd.  I got some from Amazon, but won’t put the link here because I was unhappy with the delivery.  The nutrient packs were mushy instead of dry, making it impossible to use a little dry mix in a couple of gallons of water.  Instead, I called JR Peter’s support and was told to mix one of the nutrient packs in two gallons of water.  This is wonderful.  Now I use a measuring cup to measure out exactly how much of the diluted nutrients to add to every gallon of water.  This is a really easy and relatively inexpensive way to deliver a high quality nutrient mix.  I plan to use Jack’s Hydro FeEd for all my leafy plant growing needs.

Here’s the basil plants after a week sipping up Jack’s Hydro FeEd’s nutrient mixture and use the DIY LED lamp:

9 28 2016 Basil

 While there appears to be a minor amount of inter veinal chlorosis on one or two of the leaves, I am very happy with the growth and color of the leaves.

The roots look to be coming along nicely:

 9 28 2016 BasilRoots

I’m experimenting with a lamp neck and base fixture.  I’m using a gooseneck iPad stand I got on Amazon


This attempt is a “sacrificial draft prototype.”  I hope / plan to evolve the lamp neck and base.  

October 8, 2016

We went on a mini-vacation and when we came back I was thrilled with the growth.  Leaves look healthy:

10 8 2016

Roots look to be growing well:

Roots 10 8 2016

October 9, 2016

A YIPPEE! moment…first time using – basil growing about two feet away from stove:


October 14, 2016

I have started to use the basil leaves on my salads.  I typically have two salads a day.  I started using about 2-3 leaves each time but then decided the leaves were very big.  The large size of the leaves is expected given what I have learned about the effect of red dominant light wavelengths on plant leaves.

BasilLeaf 10 14 2016

I see some “little white dots” particularly on the upper part of the leaf.  I am not sure what is causing this.  I’ll monitor to see if this spreads/gets worse.

Little White Dots on Basil

October 17, 2016

The “bucket” I was using was higher than I liked.  So I moved the plants to a different container.  I’ve been picking one or two basil leaves about twice a day.

10 17 2016 Basil

I waited a bit over a week to change the nutrients.  The upper leaves look a tad yellow.  I’m thinking it is best to change nutrients every week.  Here is an image of the roots:

10 18 2016 BasilRoots

Roots appear to be growing ok.  They are starting to connect together…which is probably suboptimal, caused by the smallish container.  I’m not going to do anything about this since I don’t see it risking my basil harvest.

Here’s a few PAR values:

Par Values taken 10/27/2016

There is enough (high level) of PAR smacking into the leaves.

Detecting Chlorosis Using Image Processing.


, ,

I woke up awhile back extremely excited to answer the question if I could use a picture and image processing to help isolate nutrient deficiencies or toxicities.  All the while thinking if I mentioned this to my family they would say something…”can’t you just look at the leaf?”  Yes family.  You are indeed right….and yet…I bumble onward in this effort.  Still – ever grateful (seriously) that my family cares enough to ask!  I crave the thrill of learning how to do something I am clueless about.  And who knows…down the road this knowledge might come in handy.

The Goal

While plants are poor communicators, they do offer visual clues when they are getting not enough or too much of a nutrient.  One of the big visual clues is when all or part of a leaf turns yellow.  

This is known as chlorosis.  The goal of this post is to take an image of a leaf and have my Mac tell me the overall and localized level of chlorosis.  The code will work but probably just barely.  It will be a sacrificial draft.

Thanks To Those That Went Before

The folks behind the ImageJ and Fiji software, especially  Wayne Rasband, the NIH, and the large community of folks that improve on this valuable resource.

Dr. Mark Chopping, Montclair State University and Dr. Ved Sharma, Albert Einstein College of Medicine.  These two wonderful folks answered a question I had on how to create selections based on quadrants of the images.  Dr. Chopping led me to understand how getting the bounding rectangle (i.e.:  run(“Set Measurements…”, “area bounding redirect=None decimal=2”);) is critical to finding these quadrants.  Dr. Sharma pointed out to get only the leaf pixels in the quadrant is a simple task of taking the intersection of the leaf selection with a quadrant.

Dr. Paul Fisher for teaching the excellent University of Florida’s Nutrient Management 2 (Advanced).  This post uses the knowledge I gained within the course.

Open Source

The ImageJ macro and images used in this post are located at this Github location.


The color analysis algorithm I will use was proposed in the article Smart Sensor for Real-Time Quantification of CommonSymptoms Present in Unhealthy Plants .

My biggest challenge with implementing the algorithm described in the document was a lacking in how to interpret the math language as well as my general fear of math.  Ah…but why stop because someone else (Oh alright – several folks) said I can’t do math…

The code on my Mac will:

  • Divide an RGB image of a leaf into four quadrants at the leaf’s centroid.
  • Figure out how yellow each quadrant is.
  • Figure out if the yellow is localized to a quadrant or is all over the leaf.

I will use the definition of Yellow that was proposed in the paper:  Yellow = The average of the pixel’s (.5)Red + (.5)Green values.

Figure 13 and the text around it in the paper

 gives an example of the chlorosis detection algorithm in action.

Getting an Image

If You Have a Moment…


I’d like to run as many leaf images as possible.  It would be very helpful to get images from you.  If you are interested, please send the images to using the image capturing technique described in this section.  I will send you back results values from the analysis.


It took me a few tries at different techniques in order to create an image.  I ended up using the white screen of an iPad as background.  It is important to get the screen as clean as possible!  I opened the Notepad app on the iPad and got most of the iPad’s screen to show a note on white background.  Next I put the leaf on the iPad.  I put some care into flattening the leaf so that the leaf laid relatively flat on the screen.


After turning off the overhead lights and minimizing any reflections, I took a picture of the leaf with my iPhone.


This technique provided a contrast between the background as well as a backlight to bring out the leaf’s color.

Processing The Image

There is a super amazing open source software tool available to all of us – ImageJ –  thanks to the excellent work by Wayne Rasband, the NIH, and the community.  I used ImageJ as well as Fiji to get the yellow values needed to figure out the amount of chlorosis.  I preferred Fiji for the majority of the programming.  Unlike the ImageJ editor, the Fiji editor is language aware which makes editing much easier.  On the other hand, ImageJ has a source level debugger that lets me step through the code.  Stepping through the code is an immense help in understanding what is going on as well as where an error is lurking.  Yet, Fiji has bundled in a lot of great things into the development environment that make it much easier to get stuff done because the additional plug-ins and such are part of Fiji’s installation.

I almost always used Fiji except when debugging.  The challenge here is if I modify the script in ImageJ, Fiji won’t read the file.  I got around this painful challenge by copy/pasting the code between the two editors.  The ideal environment would have ImageJ’s debugger part of the Fiji environment.

I’ll refer to both packages as ImageJ during discussions.

ImageJ Processing Steps

I used ImageJ’s macro language and GUI.  The experience is messy since windows with images at various processing states appear and then are closed.  I would imagine if I evolve this project that I will move off any GUI to a command line execution.

The steps below are a high level discussion of the ImageJ macro code found at this Github location.

The first part – defining the leaf quadrant selections – create selections based on a threshold set on the pixels.  Each selection/ROI can then be analyzed.

Define Leaf Quadrant Selections

The first part divides the leaf pixels into four quadrants at the centroid.

    • Get the GUI focused on processing the leaf image.  If there are any windows open showing images or dialog boxes, close them.
      • closeOpenWindows();
    • Get the path and filename of a leaf image from the user.
      • filepath=File.openDialog(“Select a File”); : openDialog opens the file picker dialog.  Go to the folder holding the image and click on the image.
      • open(filepath);
      • filename = File.getName(filepath);
    • Open the leaf image in a window.
      • selectWindow(filename);
    • Create a mask from the leaf image and figure out an outline around the leaf  – in ImageJ this is called a selection – in which the pixels inside the selection are part of the leaf.  These are the pixels that will be used to figure out the leaf’s yellow amount.
        • selectLeafMask() : A mask is created by setting the threshold color.  The threshold color defines what HSB (HSB is the same as HSV) a pixel needs to be in order to be included within the mask.


      Getting the color threshold “right” for all leaves is an area of further exploration.  There is a good chance for false positives – the case when multiple areas are determined to be within the color threshold.  In the case of multiple selections, I check to see which has the largest area and assume that is the leaf.  I got the macro code by ImageJ’s macro recording feature.  I turned on the macro recorder in Fiji, opened the file, went into the threshold color dialog box.  I then set the Hue, Saturation, Brightness values.  Now that I had the recorded code, I copy/pasted it into the selectLeafMask() function.

    • Create four more selections based on a bounding rectangle of the leaf selection and the centroid of the leaf.  


This gives four quadrants that includes the parts of the leaf but also some of the white background.

    • The pixel calculations should not include any of the white background.  To just have leaf pixels in the selection, create four selections that do not include any of the white background.  This is done by taking the intersection of the leaf selection with each of the four quadrants.
      • roiManager(“Select”,newArray(0,i-4));
      • roiManager(“and”);
      • roiManager(“add”);

Whew! Time to take a breath before we dive into calculating the Yellow values…

The second part calculates the Yellow values.


Finally – it is time to figure out a leaf’s relative amount of generalized or local chlorosis.

As noted in the article where these calculations come from:

    • Rk is the average yellow pixel value of the k selection (where k = 1-4).
    • Rn sums up the four Rks to give a relative value to the amount of chlorosis.
    • Rdiff gives a relative value to the difference in chlorosis values between the four leaf quadrants.

Green Basil Leaf 


Rn = 207, Rdiff = 15

Unhappy Spearmint Leaf 


Rn = 544, Rdiff = 62

 First Leaf Gathered on Walk

First Leaf Gathered On Walk

Rn = 363, Rdiff = 17


 Second Leaf Gathered on Walk

Second Leaf From Walk

 Rn = 421, Rdiff = 21


The Green Basil Leaf has the lowest Rn and Rdiff.  This visually makes sense.  These values are around the range given in the article’s figure 13.a for a low-generalized and low-localized chlorosis.

At an Rn of 544 and Rdiff of 62, the Unhappy Spearmint Leaf analysis gives numbers for a localized chlorosis.

The first leaf gathered on a walk I went on gives numbers for a small amount of generalized chlorosis while the second leaf gathered points to a higher level of generalized chlorosis.

And So On…

That was quite a learning mountain climb for me.  Along the way I was delighted to learn about ImageJ, a potential algorithm for analyzing an image of a leaf for chlorosis, and felt a large amount of gratitude for those that took their time to help.  Will I continue adding other refinements (such as inter veinal chlorosis detection, necrosis, etc.) or evolve the code?  I sure would if there was a practical reason to do so.  I definitely want to test what I have on other leaves to evolve the robustness.



THANKS for reading this far.  Please find many things to smile about.

My Latest DIY LED Lighting Prototype

I’m going to describe how I built the LED light pictured at the bottom of this post.

I have gone through a couple of iterations of this design….this bumbling provides the brain food that inspires me to evolve.  Besides, every once in awhile you make a comment that helps grow my point of view.  I thank you for that.  Your knowledge and wish to share that knowledge inspire me.

Thanks to Those That Went Before

The Materials

Here is the BoM for the LED lamp:

Type MFG Part Quantity 1 Piece Price 1 Piece SKU 100 Piece Price 100 Piece SKU 1,000 Piece Price 1,000 Piece SKU Link
Red LED Cree XPEBRD-L1-R250-00601 9 1.9 17.1 1.679 15.111 1.679 15.111
Blue LED Cree XPEBRY-L1-0000-00J01 2 1.72 3.44 1.518 3.036 1.254 2.508
CPU Heat sink aliexpress Shenzhen JuHome Tech. Co., Ltd. 1 7.98 7.98 7.98 7.98 7.98 7.98
Heat Lamp Woods B001KDVY42 1 12.16 12.16 12.16 12.16 12.16 12.16
DC-DC Buck Converter DROK B00BYTEHQO 1 7.99 7.99 7.99 7.99 7.99 7.99
Silicon wire eBay hdjkhdjk1 0.05 1.62 0.08 1.62 0.081 1.62 0.081
8mm PCBs Micro Commercial Co 1N4448W-TP 11 0.14 1.54 0.0816 0.8976 0.02719 0.29909
Power Supply eBay (Used/HP)0957-2271 32V 1 12.05 12.05 12.05 12.05 12.05 12.05  
LED Driver Meanwell LDD-700H 1 4.99 4.99 4.24 4.24 3.992 3.99
Thermal Heat Sink Tape Amazon   11 0.01 0.10 0.01 0.10 0.01 0.10  
TOTAL         67.33   63.55   62.17  

I didn’t spend time trying to get the “best” prices.  Or find the “best” part for the job at hand.  Rather, I cobbled together a bunch of parts that so far works ok.  Couple of points:

  • I’m reusing what I have on hand.  The CPU heat sink I actually used was equivalent to the one on the list.  I had bought the one I used several years ago.  It is no longer sold.   I have several Meanwell LDD-700H LED drivers with throughole pins. I already had thermal heat sink tape. 
  • The power supply is one used by many of the HP printers.  I got a used one from eBay.
  • The LED lamp needs power for both the CPU heat sink’s fan as well as the LEDs.  I use a DC-DC buck converter so the 32V power supply can provide 12V of power to the CPU heat sink.

The Light


LEDs emit at different wavelengths.  As I discussed in a previous post, red and blue wavelengths provide the most efficient energy for plant growth.  I discussed factors that go into determining how much red versus blue light is needed.  In that post, I decided that 100% red light would be my choice.  Since then, I decided to add some blue with the red, somewhere between 90R:10B and 75R:25B.  I decided to use 3W Cree XP-E2 red and blue LEDs.

Red Cree XP-E2  Cree Blue XP-E2


The number of LEDs to use is dependent on the DLI.

Slide from Michigan State Unit 5 on DLI

I liked the grower’s perspective of DLI given in this postThe grower can think of DLI as the plant’s daily “dose” of lightI’ll modify this perspective: The grower can think of DLI as the plant’s daily “dose” of PAR.  In his article, Light Wavebands & Their Effects on Plants, Dr. Runkle explains the important light wavebands and their effects on a plant’s growth.  There’s a few other concepts to know about before we figure out the DLI we’ll need:

  • PPF:  The quantity of PAR emitted by an LED per second.  The PPF is useful to give an idea of how much PAR is being pumped out by an LED.  However, the amount of PAR that smacks into a plant leaf is depended on the distance the plant leaf is from the LED.   I am grateful to Cree for making the info on PPF available in this document
  • PPFD: Becomes the important quantity number for determining DLI with LEDs because it is the actual measurement of how many photons that are within the PAR wavelength range smack into the plant leaf.

DLI Value To Be Used

Based on the recommendations made in this document,  I decided the DLI should be around 10 mol·m-2·d-1.  As we have been discussing, DLI is the cumulative amount of photons within the PAR wavelength.  How much should the LEDs be on?  24 hours?  Something else?  In the Michigan State class, we learned the time period the light is on (i.e.: the photoperiod) can be a factor in the healthy growth and/or when flowering happens.  I’ve decided on a 20 hour on / 4 hour off time cycle.  After some experimentation, I decided  9 red LEDs and 2 blue LEDs will work with the bucket I am using to hold the nutrients.

Here is an image of me measuring PAR:


The PAR meter was about 10” from the LEDs.

Spectrum gives us the formula to calculate the DLI when the PAR is fixed:DLI = PAR reading  x (3,600 * photoperiod)/1,000,000

  • The PAR reading’s unit is μmol/m2/s.  The DLI’s unit is mol/m2d.  This means the calculation has to go from µmols to mols and from seconds to days:
    • 3,600 seconds in an hour
    • 1,000,000 µmol / mol
  • photoperiod = 20 hours

These are the (instantaneous) PAR readings and DLI values using a 20 hour photoperiod:


As expected, PAR/DLI readings fall off as the measurements are made away from the center.   

Power Requirements

The fan on the CPU heat sink needs 12V.  The LEDs will be connected together in a series.  The power requirements = 9*FV of Red LEDs + 2*FV of Blue LEDs.  I’ll be running the LEDs with a constant current of 700mA.  From the Cree XP-E2 data sheet:


 The Forward Voltage at 700mA for:
  • blue ~= 3.3V
  • red  ~= 2.4V
Minimum power supply required for LEDs = 9*2.4 + 2*3.3 = 28.2V.
I decided to go with a power supply that comes from a “popular” consumer electronics device.  I also wanted to use a DC-DC buck converter to support the CPU heat sink’s fan also using the power supply. 
This led me to choose the HP 0957-2259.  This power supply can power many HP printers (such as the HP Photosmart 8750, C5100 Series, C5180, C6180, C6188, C7180, D5160, D7100 Series, D7160, D7360 HP DeskJet 6520, 6540Xi, 6543, 6840 HP Deskjet D1668, D2660, D2663, F4200 All-in-One Printer Series: CB656AR, CB656A, CB656BR, CB656B, CB656C, CB656D, CB658A, CB659A, CB661BR, CB661B, CB662C. HP Officejet J4580, J4680 All-in-One Printer Series: CB780AR, CB780A).
I’ve been purchasing used ones on eBay.

Putting the Heat Sink and LEDs Together

I soldered each LED onto an 8mm LED PCB then mounted them onto the heat sink using thermal tape.  I explored making a PCB – and did one to test.  However, I decided to use the 8mm PCBs so that I could easily arrange them onto a heat sink – as many and in whatever pattern I wanted to try.  I used a hot air gun and solder glue when soldering the LED PCB.

LEDs on heat sink

I arranged the red LEDs in a 3 x 3 matrix.  The blue LEDs are placed within the 3 x 3 red matrix.  I then used a soldering iron to solder silicon wire between the LEDs.  I used silicon wire because it can withstand the heat that is generated by the LEDs.

The 8mm LED PCBs have indicators which end is the cathode and which is the anode.

8mm PCB

8mm PCB  

XP-E2 Footprint     

Footprint in XP-E2 Data Sheet

LED_Front_Redback LED Red

Front and back of Red XP-E2

Turn on the light

The LEDs are connected the the LED driver.  The LED driver is connected to the HP power source.  The CPU fan keeps the temperature down around the LEDs.  To run the 12V fan from the 32V power source, the power source is connected to the DC-DC buck converter that adjusts the voltage to the CPU fan plugged into the other end down to 12V..

LED Wiring To Power Source

and here’s the light:

LED Light


Sure is ugly :-)!  But…it has been working.  There is certainly many places for improvement.




Thanks for reading this far.  Please find many things to smile about.

Backyard Automatic Watering using a Feather/Arduino

An Arduino project that automatically waters plants has been done many times.  This summer I finally decided to tackle on my own.  I’m writing up my first attempt at this project in two posts:

  • wirelessly connecting moisture readings from a spot in my garden. (This post)
  • automatically watering areas in the garden based on the moisture readings.
I say first attempt, because as I finish up this attempt I can see several areas where improvements can be made.  I mean, whoa.  I had no idea what the difference between measurements using two galvanized nails versus a sensor used by horticultural researchers….and if the idea is only for watering my backyard vegetables and not a cash crop – how much do I care?   So…what is the best my auto watering solution needs to be?

The Goal

The goals of this post are to:

  • build a moisture sensor gizmo that collects info on the moisture of the dirt it is stuck in and sends it to a receiver hooked up to my Mac.
  • build a receiver that reads the info sent by the moisture sensor gizmo and displays the info on my Mac.
  • identify improvements for the second prototype.

Thanks To Those That Went Before

  • Felix Rusu (  for his work on the Moteino.  The Moteino is an open hardware Arduino + RFM69HW radio  development board very similar in concept to Adafruit’s Feather series.  In fact, it is Felix’s RFM69xx library that Adafruit – and hence most of us – use within the Arduino IDE to talked with the radio. 
  • Thanks to Adafruit for great development board products like the Feather series.  Adafruit’s support is excellent.  I had a challenge with using a serial port with the feather (see below).  Thanks to Mike in Adafruit support, not only was my issue quickly fixed, but I learned stuff about the micro controller used by the Feather that I hadn’t realized.  THANK YOU MIKE.  I also want to thank Tony DiCola for removing any complexity in using the Watchdog timer by writing Adafruit’s Sleepy Dog library.  THANK YOU TONY.

Open Source

The Arduino and Fusion 360 files are available at this GitHub location.

The Stuff

The stuff I will build for this project include:

TX Box

This is what I’ll be calling the enclosure and the stuff inside that sends moisture readings.  The TX Box includes:

  • Moisture Sensor:  At the risk of stating the obvious, the role of the moisture sensor is to tell the electronics how moist the soil is.  So I ask myself, what probe should I use?  The more I learn about growing healthy plants aided with technology, the more respect I am gaining for the quality of the probes used.  At this point, it is not clear to me if two galvanized nails are good enough – or the accuracy/reliability obtained by using these sensors (particularly the EC5 and/or the 10HS) used by researchers  are required.  POSSIBLE SECOND PROTOTYPE IMPROVEMENT: explore the benefit of a more accurate/reliable sensor.  For this prototype, I am using these inexpensive moisture sensors being sold on eBay

The moisture sensor has three clearly marked pins, one for GND, VCC, and data.  The instructions consist of a sentence on the eBay page: Output voltage :0-2.3 V [2.3V is completely immersed in water] voltage, 5V power supply, humidity, the greater the output voltage increases.

  • A Lithium Ion Battery.  I don’t have active electrical plugs within reach of all areas of our backyard.  This leads me to choosing either solar or battery power.  I felt using a battery would be the simplest solution.  I wanted to recharge rather than replace the battery and I wanted the battery to power the remote measuring sensor for as long as possible.  For these reasons, I chose a lithium ion battery.  POSSIBLE SECOND PROTOTYPE IMPROVEMENT: Determine if solar power will work “better” if it does, replace battery power with solar power.

  • Adafruit’s Feather 32u4 with RFM69HCW:  YIPPEE! for this development board.  It dramatically speeds up how much time it takes to complete this prototype.  Besides having a small and light form factor, it is compatible with the Arduino IDE and Arduino’s pin outs.  It integrates in the terrific RFM69HCW radio that I have played with before – a great solution for home automation tasks that are not suitable for bluetooth or wifi.  A battery connector supports me plugging in a LiPo Battery and there is a micro usb port for communicating with the Arduino IDE.  If that wasn’t enough – like all the other Adafruit development boards – there are a wealth of libraries and documentation.  Add Adafruit’s excellent support, and the price is a bargain over what I’d have to do to bumble my way through putting the chips together.  Perhaps if I get serious about a final future build I might think it worthwhile to design my own PCB.  But for prototyping?  Like I said – YIPPEE!!!!!


  • Waterproof enclosure:  Designed in Fusion 360 and printed on my 3D printer. Here’s some images of the enclosure:


I’m not going to detail the design or printing.  I will however point out some of the “best practices” I am evolving in my knowledge and practice of 3D printing design and print:

    • Have a realistic model for each component. By realistic, I mean not just the dimension of the object in the physical space, but also any room needed for placement on the side or cables, which is the case for the LiPo battery.  The simple models I made were based on measurements I made with my caliper.  When I relied on parameters I measured without a realistic model, I ended up having to reprint/adjust much more often. 

FeatherFusion360ModelMoistureSensorFusion360Model LiPoBatteryFusion360Model

 I found the Fusion 360 model for the Feather here.

    • Given the enclosure is going to be placed outdoors within an irrigation system, minimize any openings.  Now, this sounds obvious.  Yet my original design had an opening for the micro-USB port.  I ended up with two slits for the moisture sensor.  Hmmm… come to think of it, including the moisture probe inside the box is not the best idea.  Much better would be to have small holes for about 22 AWG wire that goes between the enclosure and the moisture probe.  POSSIBLE SECOND PROTOTYPE IMPROVEMENT:  Move the probe to outside the enclosure.  This way, the moisture sensor can be as close to where measuring takes place.  Whereas the box containing the feather and battery can be placed at a close by location.  Notice in the third picture on the right of the enclosure pictures that I ended up placing the enclosure into a ziplock bag and taped it up with waterproof tape.  I also put silicone around the area where the prongs went through the slits within the enclosure.

Receiving Station

When I evolve the prototype to include automatic watering, the receiving station will morph into something similar to the TX box only for receiving the packets from the TX box(es), deciding whether watering is needed, and turning the water hose on/off.  This stuff is reserved for the next stage of this prototype.  Until then, the receiving station is simply:

Arduino Code

A Gotcha – Using Serial Ports

I had no previous experience using a 32u4 based board with the Arduino IDE.  “Those that went before” know there is a hardware difference between the Arduino Uno and the Feather that “bit” me is in the handling of serial ports.  Buried a bit in Adafruit’s documentation is this info gem: “…UNO-type Arduinos have a seperate serial port chip (aka “FTDI chip” or “Prolific PL2303” etc etc) which handles all serial port capability seperately than the main chip. This way if the main chip fails, you can always use the COM port. M0 and 32u4-based Arduinos do not have a seperate chip, instead the main processor performs this task for you. It allows for a lower cost, higher power setup…but requires a little more effort since you will need to ‘kick’ into the bootloader manually once in a while.”

Manually restarting the boot loader is one of the behavioral differences discussed in Adafruit’s documentation .

The other is when the Serial port becomes available.  I wasn’t able to get Serial.print()’s in Setup() until Mike in Adafruit support pointed out:


Are you using:

while ( ! Serial ) { delay( 10 ); }

before you call Serial.begin()?
That will make the code wait until the USB registration has finished before trying to print anything.


This race condition is noted in the if(Serial) Arduino documentation.  Looking back, I should have looked into why the examples that used the Serial functions started in setup() with while (!Serial);  instead of deleting because I didn’t have an understanding why it was there.  A D’OH moment on my part.

The Data Sent

The values to be passed from the TX box to the Receiving Station are stored within the valuesStruct_t structure.  A union data type is then used to map the value view to a string of bytes view.  The string of bytes is then sent to the Receiving Station where the bytes are picked up and then mapped back to values.  The values include:


// Define a struct to hold the values
struct valuesStruct_t
uint8_t firmware_version;
unsigned int reading_number;
float battery_level;
int moisture_reading;
unsigned int sleepMS;
// Define a union type to map from the struct to a byte buffer
union txUnion_t
valuesStruct_t values;
uint8_t b[sizeof(valuesStruct_t)];

  • Firmware Version: This is currently set to 1.  The value of the Firmware Version is used by the Receiving Station to figure out if it understands the valueStruct_t structure.
  • Reading Number: The Reading Number increments each time the data is sent.  This way I can have an idea if data has been dropped as well as how many packets have been sent.  The data type is an unsigned int.  As noted in the Arduino Reference under Coding Tip: “When variables are made to exceed their maximum capacity they “roll over” back to their minimum capacity…”
  • Battery Level: The battery level lets me know how fast the battery is being used up and when I need to recharge it.  Adafruit provides the circuitry and code to easily report on the battery level.  From Adafruit’s documentation under Measuring Battery:  “Lipoly batteries are ‘maxed out’ at 4.2V and stick around 3.7V for much of the battery life, then slowly sink down to 3.2V or so before the protection circuitry cuts it off. By measuring the voltage you can quickly tell when you’re heading below 3.7V.
  • Moisture Reading: This is the reading from the moisture sensor read from one of the Feather’s ADC ports.
  • Sleep (in milliseconds): The amount of time between readings.

The Data Received

The data received is the same as the data sent.  Two additional pieces of info are used that come from the RFM69CHW firmware:

  • RSSI: To get an idea how how strong the signal is between the TX box and the Receiving Station.
  • The Node ID:  In order for a Receiver to know which RFM69* radio sent a packet, a Node ID is sent with the data packet.  In the Receiving Station’s Arduino sketch, the Node ID is set using #define NODEID 2.  In the evolved experience where there are three or more TX boxes, the Receiver will need to know which TX box sent the packet in order to identify where to irrigate.

Power Management

 The experience scatters one or more rechargeable batteries around my garden.  I want to minimize the time between having to recharge the battery (or batteries).  Stuff I want to optimize to meet this goal include:

  • Minimizing the amount of power used by the Feather.
  • Minimizing the power used by the RFM69CHW radio when sending data packets.
  • Minimizing the number of data packets that are sent.

Minimize Power Used By the Feather

Leave it to Adafruit’s document and SleepyDog library to make it easy for me to minimize the power the micro controller gobbles up. Instead of using delay(), the SleepyDog library uses the watchdog timer.  Adafruit’s Feather documentation under Radio Power Drawdoes a great job showing how power use is minimized using the watchdog timer.

int time_Between_Readings_in_ms;

void loop() {
// Since the watchdog timer maxes out at 8 seconds….
int number_of_sleeper_loops = 4; //time between taking a reading is 4 * 8 seconds = 32 seconds.
for (int i = 0; i < number_of_sleeper_loops; i++) {
time_Between_Readings_in_ms = Watchdog.sleep(8000);

The watchdog timer’s max amount of sleep time is 8 seconds. If you set the time between readings to be  >8000 and <= 32767 (the maximum positive value for an int), the watchdog timer is set to 8 seconds. If you set the time between readings to be >8000 and <= 32767 (the maximum positive value for an int), the watchdog timer is set to 8 seconds.  A negative signed int will set the watchdog timer to 15ms.

Minimize Power Used By the Radio

You Are Getting Sleepy….

When transmitting the packet within the transmitReadings() function, I make a call to radio.sleep().

if (radio.sendWithRetry(RECEIVER, txData.b, sizeof(txUnion_t))) {

As noted in Adafruit’s Feather documentation under Radio Power Draw :  “If you put the radio to sleep after transmitting, rather than just sitting in receive mode, you can save more current, after transmit is complete, the average current drops to ~10mA which is just for the micro controller.

The Power Level

This line in the sketch:


where the number (in this case 31) sets the amount of power used for transmission between 5 and 20 dBm.  The value for the power level can be from 0 – 31.  The amount of power increments in steps of 1 dBM.  So for example radio.setPowerLevel(1) = 6 dBm.  If that is the case, I was wondering why values go from 0 – 31 instead of 0 – 15 since radio.setPowerLevel(15) = 20 dBm.

I’m assuming (note: I haven’t validated) the reason given in this post is correct: “…the rfm69hw puts increments power in one db steps from power settings 0 to 15, then starts over at 16 and increments up again from 16 to 31.”

I tried a variety of tests where the radio of the TX box was set at a variety of power levels and determined given the distance, I needed to leave the power level at the highest setting.

Minimize Number of Data Packets

For this prototype, the only thing I am doing to limit the number of data packets sent is to send at a period of 32 seconds (instead – for example – every time through the loop() ).  POSSIBLE SECOND PROTOTYPE IMPROVEMENT: Send a packet only upon request of the Receiving Station.  There is no point to sending packets unless the TX box is asked for an update since the intent is to take action and water (or not) depending on the moisture sensor reading(s). 

Running the Code

ßHere is an image of an example run:

 A moisture reading in the 500’s means the soil does not need watering.  But more on making a decision based on readings in the next post.

Second Prototype Improvements

I’ll collect all the improvements I noted above to be considered for an evolved prototype:

  • Explore the benefit of a more accurate/reliable sensor.
  • Determine if solar power will work “better” if it does, replace battery power with solar power.
  • Move the probe to outside the enclosure.
  • Send a packet only upon request of the Receiving Station.

Thanks for reading this far.  Please find many things to smile about.

Building an LED Grow Lamp – Let There Be Light

I recently finished building a one plant hydro planter (prototype) that includes a built-in air pump and an LED light.  My plan is to write some posts documenting what I learned about building an LED lamp in the process.  The posts I plan to write include:

  • Stuff about the quality of light I need to know in order to choose the LEDs. (This post)
  • Stuff about the quantity of light I need to know.
  • Design of the prototype LED grow lamp including LED chip choice and other implementation implications.
  • Testing the prototype planter by tracking the growth of a basil plant from seed to making pesto.

The Goal

The goal of this post is to get a strong feel for how what light quality means to plants and how that affects the choice of LEDs.  Specifically, gain a firm understanding of the two light enabled processes:  photosynthesis and photomorphogenesis.  Up until this point, I had a fair knowledge about how plants use light for photosynthesis.  However, I didn’t know much about photomorphogenesis.  Folks had kindly (and slowly) tried to explain photomorphogenesis to me…but…the explanations just didn’t stick.  I continued to attribute stuff that happened because of photomorphogenesis to photosynthesis.  Besides, there are a lot of syllables in the word photomorphogenesis.  All those syllables made me think photomorphogenesis was intimidating as a concept to grasp.  If it wasn’t, then wouldn’t it have a more approachable/friendly name?  Most likely many of you are wondering (perhaps in disbelief?) how I could be so challenged in grasping what you consider simple concepts.  If that is the case, this post is a waste of your time!

Thanks to Those That Went Before

I just finished the “Greenhouse and Horticultural Lighting Summer 2016” extension course offered by Michigan State University.  I will be used the knowledge about LED lighting for plants that I learned in the course to build the LED lamp.  THANK YOU to Heidi Wollaege – our teacher.  The content, Heidi’s delivery, and her exceptional answers to my questions made the course well worth the price.

Lighting for Plant Growth (for Dummies Like Me)

Without light, no plants.  Without basil, no pesto.  As I mentioned earlier, the two light processes I needed to have a firm grasp of where light quality is important are photosynthesis and photomorphogenesis.  

But what is light quality?

Light Quality

As noted in Dr. Erik Runkle’s article Light Quality Defined: “…light quality refers to the spectral distribution of light, or the number of photons of blue, green, red, far red and other portions of the light spectrum emitted from a light source.”

now onto two key light enabled processes that go on in a plant – photosynthesis and photomorphogenesis.


I thought this video – Williams Basics Plant Growth Development 4A  1 – does a great job in simply explaining photosynthesis.  Before I found this video, I wrote out my findings on what photosynthesis is.  Like I’ve said before, writing stuff out helps me know what I don’t know.

Since I appreciate stuff like Ohm’s law to simply explain important electronics concepts, I’m starting with the equation that simply explains photosynthesis:

I liked this description:  Chemically speaking, the inputs to photosynthesis are six carbon atoms, 12 hydrogen atoms and 18 oxygen atoms. Glucose uses six carbon, 12 hydrogen, and six oxygen molecules. Simple math shows 12 leftover oxygen atoms, or six oxygen molecules. Interestingly, and not coincidentally, the process of respiration breaks apart the glucose molecule. Respiration occurs in the cells of nearly all living things…” …respiration releases the energy the plant uses to grow.

Photons are absorbed by the plant leaves through the green pigment – chlorophyll.  

Carbon dioxide enters the plant through the stomata (which are on the “underbelly” side of a leaf). 

Water comes into the plant through a plant’s roots.

and there it is..easy schmeazy.

Most Efficient for Photosynthesis

Since chlorophyll is the molecule that absorbs photons,

 Microscopic Image of Chlorophyll

 the most efficient LED color wavelengths for photosynthesis are red and blue.  Dr. Runkle’s article, “Light Wavebands & Their Effects on Plants” provided a nice summary:

  • “…Blue light (400 to 500 nm)… Chlorophyll in plants highly absorbs blue light that is used for photosynthesis.  It also helps regulate the opening of stomata, which are tiny openings in the leaves that regulate the uptake of carbon dioxide…”
  • “…Green light (500 to 600 nm)…Plants appear green because they reflect and transmit slightly more green light than they do blue or red light…. generally, green light is less efficient at stimulating photosynthesis than blue or red light…
  • …Red light (600 to 700 nm)… Most LED arrays  [for plant growth] emit a high percentage (often 75-90 percent) of red light because it is absorbed well by chlorophyll, and the electrical efficiency of red LEDs is high.    

 Notice under the rationale for red light the mention of electrical efficiency.  Looking at a graph from Cree’s XP-E2 data sheet:


the voltage needed to power red LEDs is much less than the voltage needed to power blue or green LEDs.  Since P=IV, the cost of electricity (e.g.: in KW/hour) will be less if there is more red LEDs than blue (or green).

Besides photosynthesis, research has shown red and blue wavelengths of light have a big effect on photomorphogenesis.


Now this just plain out amazes me…plants have light sensors.  Who knew?  Not me…So many times I have built some sort of prototype that uses a light sensor like this one:


I use it to detect simple stuff.  Like how light or dark the light sensor thinks it is.  Here is link to an Instructable that gives an example of an Arduino project that uses this type of simple light sensor.

Plants use of their much more sophisticated light sensors to – as explained in this article to “…manipulate the shape and characteristics of a plant, such as leaf size, branching, and stem length.”  Saying the same thing in a slightly different way, plants use light sensors to detect the light conditions under which they are growing.  The plants use the readings they get from the light sensors to manipulate their size and shape. By manipulating size and shape, the plant can optimize for the light conditions it finds it self under.

Light Sensors Are Detecting Red and Blue Light

Phytochrome and cryptochrome are the pigments found in a plant acting as light sensors.  Phytochrome detects red (and far-red) light.  Cryptochrome detects blue light.  It makes sense there is a close relationship between optimizing the plant’s shape to the light source since light is providing a necessary ingredient to make food.  For more info on these pigments, I found this article interesting.

The Ratio of Blue to Red Light

Given a bunch of LEDs mounted on a PCB, what percentage should be red and what percentage should be blue? The stuff about photosynthesis and photomorphogenesis prepares me to make an informed (first) attempt at setting this percentage.  The factors I use in deciding the percentage include:

  • Red light is more efficient for both photosynthesis and photomorphogenesis
    • photomorphogenesis: from this abstract: “Plants with as little as 10 µmol·m−2·s−1 of B(blue) light were 23% to 50% shorter and had 17% to 50% smaller leaves than plants under only R(red) light.”
    • photosynthesis: Back to  Dr. Runkle’s article, “Light Wavebands & Their Effects on Plants”: “Most LED arrays emit ahigh percentage (often 75-90 percent) of red light because it is absorbed well by chlorophyll”
  • Red light takes less electricity than blue light.  
  • Blue light will help keep the plant stocky.
    • Heidi  Wollaeger – our teacher for Michigan State’s lighting course and co-author of the peer-reviewed article “Growth and acclimation of impatiens, salvia, petunia, and tomato seedlings to blue and red light.”  pointed out to me in an email exchange: “…in a sole-source environment (no sunlight), blue light activates cryptochrome (a photoreceptor in plants) which triggers a change in hormones in the plant which results in reduced stem extension and leaf expansion. You will see that 100% R light (without sunlight) leads to the most elongated plants with the largest leaves. A minimum of 10% B inhibits that excessive stem extension and leaf expansion. What is “ideal” is all a matter of perspective. If you (are) an ornamental plant plug producer and want small compact rooted plants – you will want some B or green in the spectrum. If you a basil grower indoors, you would want those large leaves and might want to have a 100% R.

Blue to Red Ratio for the Prototype

Given I will be growing basil, I will go with 100% Red LEDs

What I’ve Learned After Writing this Post

  • I have a much better feel for photosynthesis and photomorphogenesis.
  • I understand what light quality is.
  • I understand the importance of red and blue light to photosynthesis and photomorphogenesis.
  • I have made an informed choice on the Blue:Red ratio – 0:100 – for prototyping growing basil.

What’s Next

Now that I have a better feel for light quality (the Blue:Red ratio and what it means for photosynthesis and photomorphogenesis), I need a better understanding of light quantity.  Then onto design and implementation of the LED portion of the planter.



Thanks for reading this far.  Please find many things to smile about.

Black Spots on Basil



One of last week’s topic in the UF’s GreenHouse 101 was discovery and identification of plant diseases.  The teachers asked us to explore diseases in the plants we are growing.  I am growing basil.   I love basil.  I put it liberally on my salads, pizza, red sauces…. To meet my cravings, I try to grow as much basil as I can outside starting in early summer months.  

Sadly, one of my basil plants is sick.

The Goal

The goal of this post is to discuss a disease I am seeing on one of the basil plants.  I’ll start with observations and finish with a diagnosis.


Here is a picture of the sick basil plant:

basil in container

Here is the front of the leaf:

basil Front Leaf

the area around the dark spots has a wax-like “look and feel.”

…and the  back:

BasilBottomLeafwhen I first saw this picture of the back, I thought pests might be involved.  However, on closer inspection with a 10x magnifier, the areas that looked like there might be a webbing or small pest turned out to be dirt and/or dust.


The black spots are most likely due to either a bacteria or fungi.  Within the section on Plant Health (week 4) of the Greenhouse 101 course, the teacher (Brian J. Pearson) noted fungi on plants is typically dry whereas bacteria is typically waxy.  In this case, the black spots and area around had a waxy feel.  This leads me to believe the black spots are do to a bacteria infecting the plant.  While there are many posts on the Internet that discuss black spots, I found this post to help me.  This diagnosis makes sense not just because observations appear similar to images provided for black spots on plants that are infected with a fungi or bacteria, but also because it most often occurs in late Spring/early Summer when the plant leaves stay wet longer than they should.  We live in the Pacific Northwest of the US where it rains quite a bit during this period.  

The class material on diseases pointed out those based on bacteria or fungi will find it’s way to other plants since wind, rain, insects… will transmit the bacteria/fungi to other plants.  At this point, this was the only affected plant.  


Not every leaf had the black spots.  I removed those that did from the basil plant, leaving the healthy looking leaves alone.  For now I’ll keep an eye out for other plants that start showing black spots.  If the disease continues, I’ll consider a treatment such as a fungicide.  If that doesn’t work, I’ll assume the soil is contaminated with the disease and will remove the soil where the plants were growing that had leaves with black spots.  I also sterilized the scissors I used to clip off the infected leaves.




Ah yes.  Not a very exciting or technical post.  For me – fascinating and exciting to evolve my understanding of plant disease debugging as part of my seemingly endless effort to grow healthy vegetables and herbs.


Thanks for reading this far.  Please find many things to smile about.

Making a PAR and DLI Meter Using an Arduino


, , ,

I’ve been gratefully enjoying the online Greenhouse 101 course offered by the University of Florida.  This course inspired me to start measuring the Daily Light Integral (DLI) my plants receive.  To do this, I made a PAR (Photosynthetically Active Radiation) and DLI meter using an Arduino Uno, SD Shield, PAR sensor, and LCD.  I used a Fusion 360 to design and 3D printer to make an enclosure.

The Goal

The goal of this post is to describe the PAR and DLI meter that I made.

Thanks to Those That Went Before

Adafruit: I am a fan of Adafruit’s business model.  While their products typically list more than comparable products, Adafruit’s service to the maker community is worth the extra cost.  Often Adafruit’s learning site is the first place I go to when I want to figure out how a sensor or other hardware breakout board works.  The forums are active and include very knowledgable Adafruit employees who tirelessly answer questions from both the first timer to the expert.  Using Adafruit’s libraries and following along with the learning section makes it extremely easy to integrate logging.  Noe’s layer-by-layer series has been a great aid in learning how to make enclosures in Fusion 360.  In particular, I found this video very helpful for this project.  Thank you!

Apogee: I used the SQ-225 PAR sensor from Apogee.  Thank you for making this quality product.  My challenge was the cost at $205 for the PAR sensor.  I probably wouldn’t mind this as much if there was consulting or other service/support included.  

Autodesk: It took me about 6 weeks before I felt fluent enough to make the enclosure in Fusion 360.  Thank goodness for Autodesk’s excellent videos and forums!  I am incredibly grateful for how much more – and how easily – learning can be with good content and an enthusiastic community from the Internet.  Also, Kevin Schneider’s incredibly detailed Fusion 360 model of the Arduino Uno saved me a lot of time. 

MAKEiT: I bought the MAKEiT-PRO 3D printer.  They are located on the west coast of the US which I prefer since I am also located on the west coast of the US.  While on the expensive end, I am ecstatic  with the service/support I have gotten from Russell Singer (director of design and development).  Russell’s insights into 3D design and printer settings to optimize a 3D print more than make up for the extra $$ the printer cost.  Russell has been exceptionally responsive.  His advice constantly brings my 3D printing knowledge and ability leaps forward.  I also like the MAKEiT-PRO because it feels solid and I can dynamically change print settings as the print evolves.  There seem to be a gazillion different 3D printers to choose from.  I don’t have experience with any other printer to compare.  Russell – THANK YOU.  I am very grateful for the encouragement and insight you have shown.  You “know your stuff.”

University of Florida:  As I briefly noted in the intro to this post, I am taking the Greenhouse 101 course from UF.  It has been an incredibly enriching targeted knowledge us students are getting on the effect and control of factors (e.g.: temperature, light, CO2, PGR…) that shape the health of a plant.  Thank you for offering this course.  The instructors have been excellent.  The explanations are easy to follow.  I wish there was more discussion.  However, that has picked up recently.

Open Source

The Arduino sketch, Fusion 360 archive, and a PAR.CSV file with a test run logging data is located at this GitHub location. 

The PAR and DLI meter

I will make and use of this PAR and DLI meter I cobbled together:



I am practicing growing vegetables and herbs hydroponically indoors.  As is commonly known, plants need light for photosynthesis.  

Photosynthesis – light depended reaction

However, not all visible light waves are absorbed by a plant’s leaves.  The wavelengths of light used for photosynthesis is termed the Photosynthetically Active Radiation (PAR). Since I am growing inside with very little light coming from the sun, I need to figure out how much PAR to give a plant within each 24 hour period.  A sum of the total amount of PAR that a plant receives within a period of time is termed it’s Daily Light Integral (DLI).  

For this simple prototype, there are no buttons or other ways to input any settings.  Settings are within the Arduino sketch.  The PAR meter then merrily takes a PAR reading at the time interval I set in the Arduino sketch and then writes the reading as a CSV row into a PAR.CSV file on the SD card.

I’ll start with a brief discussion of the materials I used. 


I was happy to be able to reuse these that had been part of previous projects:

  • Arduino Uno
  • SD Data Shield
  • PAR sensor – I am using the SQ-225 from Apogee Instruments.  I got it in March, 2014 and hadn’t really used it.  I paid a whopping $205 + $6.67 = $211.67 for the SQ-225.  I say whopping because I bet the actual material is sub $50.  My thoughts on why the cost is so high is because there is a lot that goes into R&D, building the units (e.g.: each unit must be calibrated), service, and support.  Also, it seems most purchases of PAR meters are from institutions – academia and large greenhouses – where the cost is more easily absorbed than for hobbyists. There are challenges with the SQ-225 which include the sensor can only be used for indoor lighting and – I didn’t realize this until recently – as noted in this article, “...Apogee quantum sensors and meters for electric lighting are calibrated in a custom chamber filled with T5 cool white fluorescent lamps. LEDs have a very different spectral output than T5 lamps…

            (Image above) 

T5 cool white fluorescent spectrum (lamp used by Apogee for electric light calibration of quantum meters; black line) compared to broadband white LEDs (cool white fluorescent – blue line, neutral white fluorescent – green line, warm white fluorescent – red line) and defined quantum response (gray line).

        Unfortunately, this leads to less than accurate PAR readings:


Electric Calibration Error [%]

Blue (448 nm peak, 10 nm FWHM)


Green (524 nm peak, 15 nm FWHM)


Red (635 nm peak, 10 nm FWHM)


Cool White


Neutral White


Warm White


Red, Blue Mixture


Red, Green, Blue Mixture



Here I am then…using the SQ-225 that cost me a significant amount of money.  If I were buying one today, I’d take a serious look at the NEW! IMPROVED!  SQ-520.  While this baby would set me back an even more whopping $345, it handles reading both LED and outside PAR values and includes the ability to data log PAR values and calculate the DLI.   Sadly, this sensor may not work since moving forward I would rather attach the PAR sensor to a PCB I designed that uses an inexpensive micro controller (like the FRDM-KL25Z).

I was going to include a battery however decided to simplify this initial build and provide power through the power sources supported by the Arduino Uno (i.e.: USB or wall wart).


For some reason, a few months ago I got inspired to make 3D printed “stuff.”  Since then, I have been enthusiastically 3D printing on a MAKEiT-Pro printer I bought from MatterHackers.  I used Fusion 360 to make a 3D model and the MAKEiT-PRO printer to print out an enclosure for the PAR/DLI meter.

Assembling the Electronics

Assembling the Arduino, SD Data shield, PAR sensor, and LCD was easy since I had used each of these components within other projects.  The SD Shield sits on top of the Arduino:



The wiring is hooked up to the power and analog pins that are exposed on the SD shield.

Pasted Image 6 17 16 5 15 AM

  • I used the info on this page to wire up the Funduino ICM1602 LCD.  There are 4 wires – Brown (GND), Red (Power), white(SDA, A5 pin) black (SCL, A4 pin).
  • As noted in the guide for the Apogee SQ-225there are three wires.  The power colors are not the standard red (positive), black (GND) I expected.  White is positive power, clear is GND, and green is hooked up to A3 to get the sensor readings.  The wires are very thin so I ended up soldering wires I usually use to hook up sensors to an Arduino.
  • I used Adafruit’s SD shield for logging PAR values.  

The Enclosure

(TBD: Mention PLA use) The Fusion 360 files I used are available at this GitHub location.  A valuable lesson I learned was to model the components first, then base the enclosure around the models.  Prior to doing this, I was spending A LOT of time printing the enclosure fixing measurements, then reprinting.  Paying more attention to detail on the measurements of the Arduino Uno, SD Shield, LCD significantly lessoned the number of prints I needed to do.  

Components in Fusion 360

  • Arduino Uno – Kevin Schneider has made a remarkably detailed Fusion 360 model of the Arduino Uno.
  • SD Shield – I copied the Arduino Uno files as another component and modified to the shape of the SD Card.
  • LCD – I carefully (well, as carefully as I could) the measurements with a digital caliper.
The steps I took are similar to those taken by Noe in his 3D enclosure printing video available from Adafruit.


My goal was to stay away from using screws.  The biggest challenge was getting the Arduino to play nicely with the mount holes I had printed.

Pasted Image 6 18 16 6 02 AM

Bottom part of enclosure as viewed in Fusion 360

The tap posts broke off when putting the Arduino into the enclosure.  

Pasted Image 6 18 16 12 06 PM


As noted in the Arduino dimensions diagram:

 “All Arduino mounting holes are 3.2mm…”  3.2mm diameter posts are not thick enough for 3D printing.  I ended up adding a piece of plastic that acted as a wedge between the Arduino / SD shield and the inner edge of the bottom enclosure.

For my next enclosure, I’ll use these plastic spacers I ordered from eBay.

Fitting the LCD into the case proved to be easier than I thought it would be.  The rectangle measured for the LCD display was snug to the point the LCD stayed within the top of the enclosure.  Even though the LCD fit, when I do a future enclosure I’d like to have a stronger bind between the top of the enclosure and the LCD.  The LCD’s PCB does have mounting holes which I attempted to use.  However, the taps broke off (as they did for the taps on the bottom part of the enclosure).

The Arduino Sketch

The Arduino sketch is available from this GitHub location.  I’m assuming the sketch is self explanatory.  There are two times the PAR value is read: 1) every time through the loop in order to update the LCD 2) after logging_interval_in_ms milliseconds.  For testing, I set the interval to every 30 seconds.  In use, I set the the time interval to 15 minutes.  While the LCD updates every time through the loop, the date, time, PAR value is written in CSV format to the PAR.CSV file every time period.


The test PAR.CSV is available from this GitHub location.  While I realize the SQ-225 par sensor that I have is for indoor lighting, I tested the light coming in from a sky window above my desk.


 I was interested to see the variability in PAR values – even if the readings were off because the SQ-225 is not calibrated for sunlight –  at given time of day.  After capturing the values into PAR.CSV on the SD card, I uploaded PAR.CSV to a Google doc file. 


 Initial readings in PAR.CSV  

The day was sunny with clouds.  I noted when the clouds covered the sun the PAR value would significantly decrease as it did at 1:47:14 PM.  As the sun went down, the PAR value dropped to 0.The PAR meter took samples from 1:43:40 June 15th until 5:21:32 AM June 16th, for a duration of 15 hours, 37 minutes and 52 seconds.  I used the info on this web page by Licor to calculate the DLI when readings occur every 30 seconds.

Total Time = 12 hours

∆t = 30 seconds 

∑PAR = 4646 µmol/m2 per 1/2 day (note: DLI is typically evaluated within a 24 hours (day) period.  I measured 12 hours)

DLI = 30seconds *4246µmol/m2/1,000,000 µmol/mol = .12738 mol/m2 per 1/2 day.  or ~ .255 mol per day.

I love basil.  The information in this source states: the rate of growth peaked at 500 μmol·m−2·s−1

A page on Apogee’s web site notes to calculate the DLI based on one PAR measurement, multiply the PAR value by 0.0864.

500µmol/m2s-1 = 500*0.0864mol/m2d = 43.2 mol/m2d

Even if the DLI was at the levels discussed within this paper from Purdue

 The DLI I measured was too low for the minimum acceptable quality.  I would have to augment the indoor lighting….which I plan to do with a DIY LED project.

Of course, as I noted earlier, the SQ-225 was not calibrated to measure daylight…so my measurements will carry a significant error to the point of most likely being meaningless.  With that said, I have a better feel for calculating the DLI.

So That’s That

I am very happy to improve my knowledge of growing plants while at the same time flex my maker skills.  It was extremely fun to pull out sensors and other pieces of electronics I had lying around.  I learned A LOT about 3D printing and will continue to evolve printing skills.




Thank you for reading this far.  Please find many things to smile about. 




From Kicad to Digikey -> MakeDigikeyBOM Code Review: The Python Scripts


, ,

I continue my quest to document the MakeDigikeyBOM Python package I built.

The Goal

The goal of this post is to familiarize us with the structure and purpose of the MakeDigikeyBom Python package and individual modules.

Thanks to Those That Went Before

As I noted in my previous post, I could not have gotten this far this quickly without the prior work of debvisme(xesscorp).  He is the author of Kicost – Python that “build(s) cost spreadsheet for a Kicad project.”  Kicost is well worth checking out.  The GitHub location is here.  

Open Source

The MakeDigikeyBom Python project is located at this GitHub location.


I am self-taught when it comes to making flowcharts.  I mention this because flowcharts I make don’t conform to a standard.  This may make them more difficult for you to read.  I apologize for that.  However, I find the method I use to work for me.

Here is the flow chart of MakeDigikeyBOM at the highest level:



I have built two (well, actually three) Python files:

  • : This is where the majority of the high level command/control happens.
  • Takes the bom2csv and JellyBeanPartNumbers files and creates a MadeDigikeyBOM.csv file or a list of errors that must be fixed in either the bom2csv or JellyBeanPartNumbers files before the MadeDigikeyBOM.csv files can be generated.
  • I put this in because it identifies a bunch of Python files as a Package (at least in Eclipse).  I don’t know enough about Python to use it to an advantage.

The first thing is to gather user input.  The pieces of info include:

  • The full name of the bom2csv file.  The bom2csv file was discussed in a previous post.
  • The full name of the csv file that contains the jellybean parts.  As with the bom2csv file, the jellybean parts file was discussed in a previous post.
  • The directory path where MadeDigikeyBOM.csv will be written.
  • Currently the “num_processes” field is not used.  I got this field from the Kicost Python script and thought implementing is probably a good idea.  Having this input argument is a placeholder for a potential future feature.

 Since I run Python within the Eclipse environment, I enter arguments to MakeDigikeyBOM through the debug/run configurations.  Here are the files I used:

Pasted Image 3 14 16 5 32 AM

The code in checks to see if the bom2csv and jelly bean parts files exist.  The script exists if either file does not exist.

If the files exist and the directory to contain MadeDigikeyBOM.csv exist, the calls into makeDigikeyBOM() which is in the file.

That’s all there is to the high level part of the code.  

What’s Next

In the next post I’ll cover the file.






From Kicad to Digikey – Start of MakeDigikeyBoM Code Review – Walk Through of Block Diagram


, ,

In my previous post, I discussed my reason for creating yet another Python script to convert Kicad schematics into a BoM spreadsheet with pricing info from Digikey.  This post is a continuation.  Since the first post I am happy to say I have gotten all the goo to work and was able to use the MadeDigikeyBOM.csv to order parts from Digikey.  So far I am excited with the results.  I find them a terrific time saver (of course, learning python and getting all this to work takes A LOT more time than doing one schematic -> BoM by hand…but YIPPEE! What a learning opportunity…and I plan for plenty more schematics.

The Goal

The goal of this post is to start a code review MakeDigikeyBoM python project.  I’ll cover the block diagram I created to represent the “big picture”.

Thanks to Those That Went Before

I could not have gotten this far this quickly without the prior work of debvisme(xesscorp).  He is the author of Kicost – Python that “build(s) cost spreadsheet for a Kicad project.”  Kicost is well worth checking out.  The GitHub location is here.  The code I used the most was the script that scrapes the Digikey pages.  I learned a lot about the Kicad XML and various Python techniques from other sections of the code.

The folks who created the Beautiful Soup library for Python.  Beautiful Soup is incredibly useful/well done to parse XML files.

Open Source

The MakeDigikeyBom Python project is located at this GitHub location.

Updated Block Diagram

I like to start by doing a fly by of a block diagram.  I had done an initial block diagram in the previous post.  The block diagram evolved as the design and implementation evolved.  Here is the updated block diagram



Input from a Kicad schematic.  The important component Value and PN properties are important to this process.

For example, here is an image of Ladybug Blue’s Schematic with it’s hierarchical sheets:


Each schematic component has a PN field and Value field.  The PN field must contain one of the following:


The schematic component D1 (RED_LED) with a manufacturer part number PN = XPEBRD-L1-R250-0061.  When the PN is a manufacturer or Digikey part number, the value field is not used:



The component C1 has a Jelly Bean PN = C and Value of .1u:


When MakeDigikeyBoM modifies the <outputFrom_bom2csv>.xml file, the created <modified_outputFrom_bom2csv>.xml file replaces the PN field value to the digikey part number CS21F104XZBCNNNC.  This is the part I chose for all .1u capacitors.




The P5 component has None in it’s PN field value:


A component with None in the PN field tells MakeDigikeyBom that this component is not purchased through Digikey.  The Value field is ignored.


Use the bom2csv plug-in to create the “BoM” XML.  The bom2csv plug-in was discussed in my previous post. The XML branch that is the most important to the DIgikey BoM creation process is the <comps> branch.  As the tag suggests, this is where the component info is found.

Here are the <comp> properties for the three types of PN discussed above.

A None <comp>


Here, the PN = None.  The Value=BNC, but that isn’t used by the Digikey BoM process.

A Jelly Bean <comp>


In the above, component C1 is a .1u of part type C.  The Value = .1u is used by the process.

A Manufacturer or Digikey Part Number


As when the PN=None, the Value field is not used.  In this case, the PN number is passed directly into the screen scraping section of the Digikey process.


The first part of the MakeDigikeyBoM Python script takes in the output from bom2csv discussed under “B” above and creates an intermediate file that is then used by another part of the Python script.  The intermediate file is in the same XML format as the file created by bom2csv.  The properties for <comp> components that use a Jelly Bean PN have been replaced by looking up the PN / Value field in the JellyBeanPartNumbers.csv file with the part number that must be should be either the Digikey or manufacturer part.


For the C1 Jelly Bean <comp> listed above, the PN = C and the Value = .1u.  The Python script looks for the row in the JellyBeanPartNumbers.csv file:


in this case, the manufacturer part number = CL21F104ZBCNNNC.  The modified bom2csv file replaces the <comp> tag for C1 with this part number:



The Python script creates a URL with the PN as keyword to the Digikey web site.  The URL is pretty much what we might use when searching for this part:

url = ‘” 

The html is parsed by BeautifulSoup into a fairly easy to access html tree.

There is a whole bunch of Goo in the Python script to scrape through the html and parse it out into the MadeDigikeyBoM.csv file.  If all goes well, the MadeDigikeyBoM.csv file is created.  For example:


I realize the image is rather small…here is the row for .1u capacitors:











There are 12 .1u capacitors.  The price per 1 = $.10, 10 = $.031, 100 = $.0144, and 1000 = $0.0144.  Digikey has 79,269 of these capacitors in stock.  The link to the Digikey page is included.


The challenge is this part of the script will need to be updated when Digikey updates the web page.  This – of course – is true of any web page scraping process.

What’s Next

I’ll start going over the Python modules in the next post.  I’ve posted the Python scripts at this GitHub location.



Thanks for reading this far.  Please find many things to smile about.

From Kicad to Digikey -> Generating a BoM based on eeSchema – Overview



This is my latest ‘sacrificial draft’ to generate a BoM csv file with Digikey prices based on schematic files I create in Kicad.  Once I’m done with layout, creating a BoM from the components in the schematic is tedious and time consuming.  So I jump on the already heavily populated bus of folks using Python to automating the workflow going from eeSchema to ordering parts.

I will refer to this effort as to reflect I pretty much only shop for chips on Digikey and the tool is written in Python.  Since I am fumbling about with Python for my own use and I stick to Digikey for my chip supplier, I have “hard coded” Digikey into the process.  All of this could be expanded and be made more robust.  Right now “it works good enough for me” and really is a sacrificial draft.  

Thanks to Those That Went Before

I wanted to start with saying how very grateful I am to devbisme (xesscorp) for Kicost – Python that “build(s) cost spreadsheet for a Kicad project.”  The GitHub location is here.  There is a very good chance Kicost is all you need.  It is certainly worth checking out if you use Kicad and want to automate BoM creation!  I chose to evolve Kicost to to enhance with two features I feel are important:

  • The ability to not have to enter the part number within the schematic for jelly bean parts (capacitors, resistors,…)
  • Viewing the 1, 10, 100, 1000 unit pricing of parts.  This way I might order more parts even though I need less to lower the price per part.

The Goal

The goal of this post is to provide an overview of my effort.  To do this, I will take a simple schematic created in Kicad:

I call this Kicad project myTestDigikeyBOMCreation.

 … i.e.: a schematic that is just a bunch of components…

and run it through to create  a csv file that provides Digikey pricing info built by scraping the Digikey pages associated with the manufacturer part number:

Block Diagram

The Block diagram gives us a picture of the workflow I have defined to go from components within eeSchema to a csv file with the pricing info from Digikey – as shown in the image above:


Block Diagram


You create your schematic by adding components – these are within the left blue circle of the block diagram.  Each component has a very important field, the PN field.  This is a custom field added to the components.  Kicad lets us add custom fields.  The Kicad documentation at this point gives direction on how to add a custom field like PN.

There are two types of components:

  • Manufacturer
  • Jelly Bean
The RED_LED component is an example of a manufacturer component:


The capacitor is an example of a jelly bean component:

The Value field becomes important when using a jelly bean component.  A Jelly Bean component is reconciled to a manufacturer part number using a Python script that matches the PN value (in this case ‘C”) and the Value in the value field (in this case .1u) to a row in a csv file that maps these two properties to a manufacturer’s part number. 

Jelly Bean Part Numbers

I created a Google spreadsheet that I named JellyBeanPartNumbers.  Here is an image of a few of it’s rows:


I export the rows (which includes the header row) to a file named JellyBeanPartNumbers.csv.  This is the second blue circled area on the Block Diagram.  This csv file is used as input into the script. 


The first step in the process of going from eeSchema to a BoM spreadsheet is running bom2csv.  bom2csv is a plugin for eeSchema that (at least for me!) is included with the Kicad install.  For more info on bom2csv, see the Kicad documentation on eeSchema (see this link, go to section 3.1 “Using eeSchema” then scroll down to #58 – where creating a BoM is discussed).  

bom2csv creates an XML and a csv file.  We’ll be using the XML file as input into  This is the file named <outputFrom_bom2csv>.csv in the above Block Diagram.  I use < filename > to represent a name that will change based on the name of the Kicad project.  In this example, the Kicad project is named myTestDigikeyBOMCreation.  The XML file that is created is named myTestDigikeyBOMCreation.xml.

We’re now ready to run is a bunch of Python Goo that takes in:

  • the XML file created after running bom2csv.
  • JellyBeenPartsNumber.csv.
I’ll discuss in more detail in my next post.
Thanks for reading this far.  Please find many things to smile about.