I’ve updated the schematic and board layout of my Healthy pH Shield.  The Healthy pH Shield is an Arduino shield that reads the pH of a bath then adjusts it to the right levels for the plant that is using the bath for nutrients.  For example, growing lettuce hydroponically grows best when the pH level is between 5.5 and 6.5. 

The Goal

The goal of this post is to walk through the Healthy pH Shield and get ready for sending Gerbers off to OshPark.  I also will be documenting where I ordered parts, the time it took to get things done, and the cost.

Thanks to Those That Went Before

Learning – in this case about electronics – brings me endless amounts of joy.  For so many obvious reasons, I would never be able to pick up an IC and figure out what to do with it without the help of someone who knows more.  Whether they wrote a book, an article on a web page, shared their specs, or face-face.  We are blessed to have access to the material sharp folks have willingly provided for us to learn from.  For this section of my projects, I am most thankful for:

  • Chris Gammell – Through Chris’s Contextual Electronics class I was able to make dramatic strides forward in my ability to design a schematic (in kicad), layout the board, solder on the chips, debug.  I also gained a better understanding of the electronics behind the circuits.  Although to be honest, I probably caught the technical details of 20%.  The good news is the material, Chris, and the material make it easy for me to backfill my questionable ability as a “fast” learner.  This is so different than learning in a classroom.  Where once we’re out of the classroom, it is much more difficult to pick up learning where we left off.
  • Ryan – Ryan has created many very useful break out boards – including a pH and EC sensors.  He has also published the schematic and board layout.  I have spent many an hour pouring over his schematic to understand how pH and EC circuits work.  Not only that, but I have been able to reach out to Ryan through twitter @SparkysWidgets – and he has been very helpful.

The Schematics, Board Layout, and BoM

I am on my second build.  I call this the Dev-Rev2 build.  The files for the schematic and board layout are located at this GitHub repository.  They are kicad files.  The BoM is also located there (in the other folder).

The Sub Circuits

I used Kicad’s hierarchical schematic feature to logically represent the sub circuits.



The Arduino sub circuit talks to the Arduino so that firmware can communicate with the other sub circuits.  The main interface is to the SPI bus connected to the ADC (the MCP3901).  There is also an RGB LED that I plan to light different colors depending on tests run by the firmware to detect the health of the circuits. This way I have a visual indication when a sub circuit doesn’t work as it should.  For example, if the firmware can’t get read or write to the MCP3901 over the SPI bus.  At a higher level, if a valid pH reading can be made, etc.   It turns out the least expensive/will work RGB LED is this one.  It is a common anode diode.  So I drew the circuit accordingly.  I need to remember the inverse logic (at least for me) of using a common anode instead of common cathode diode.  The LEDs go on when the signal goes low.  The pumps are controlled by Arduino i/o pins.  

From breadboard prototyping these circuits, I felt the 5V power source of the Arduino would add too much noise to the sensor readings.  This is why there is a barrel jack plug so that a wall wart can be plugged into the shield.  Wallwarts between 6 and 9V should work.  

Wall Wart

The wall wart sub circuit uses a voltage regulator circuit to ensure the amount of voltage to the sensor circuits is a clean (as possible) 5V.  I stuck a green LED on the circuit that will light up when the shield is plugged into the Wall Wart.


Here is where the pH measurements happen.  The schematics reflect this:

When the probe is attached to the BNC connector, the VGND and non-inverting input pins are connected as shown above.  A specific example:  if the pH of the bath = 14, then the voltage across the probe would = -.414V (assume the ideal).  Since VGND is .45,  the input into the non-inverting op amp is .036V.
The BNC connector is not part of the shield.  The BNC connector is connected to the circuit through two wires that are part of the P1 (CONN_8) – see HealthypH.sch.  Input to the MCP non-inverting = output of buffer op amp (the one in the picture above).  Input to the inverting pin of MCP CH0 (or 1) = VGND (i.e.: .45V)

I’ve discussed using a virtual ground to raise up the signal generated by the probe to all positive values such that the op amp has a 0V rail. Also, the op amp I chose had characteristics in the rails and IB (Input Bias) specific to this application. Figuring out which op amp and how to approach virtual ground were the most time consuming aspects of the design. A lot of the time was learning why…. I discuss the op amp choice in previous posts.


pH and E.C. values vary depending on the temperature of the bath.  Readings use the MCP3901 (ADC) CH1.  Here is an image of the circuit:

The Thermistor is the top R of a voltage divider. This is explained well in this Arduino playground writeup.  The Thermistor is coated in water proof epoxy connected to two wires so that it can dangle in the bath.  The wires connect to a terminal block (as do the wires for the BNC of the pH probe and the wires for the pumps). Therm+ is input into the CH1+ (non-inverting pin)  Therm- is input into Ch1- (inverting pin).  I used a blue box to identify in the schematic where the 10K Thermistor would be.  I did not want to add a footprint to the board..the two outputs go to the terminal block.


The design supports two peristaltic pumps in order to adjust both the pH UP and DOWN (addition/dilution of H+ ions).  Here is a drawing of the wiring:

The pumps use the Arduino as their power source and GND.  An Arduino pin is dedicated to sending digitalWrites() to each pump.  E.g.: Turn pump on for 1 second:

digitalWrite(pHDown_pin, 255);



The signal is sent to a transistor (data sheet).  The pump has a diode between its wires to handle the reverse kickback from the pump when it is turned off.

The Layout

As most things, laying out a board gets easier with practice.  I have a long way to go before I feel I have a strong grasp on board layout.  I am able to get a board through DRC in kicad and read OshPark’s track width/via size requirements.  

I use two ground planes: one for the ground plane related to the Wall Wart.  The other for the ground plane related to the Arduino’s 5V power source.

Dev-Rev2 Layout

Tracks Through Ground Planes

Are a bad idea since they cut up the copper.  This “rule of thumb” was used when I went from this layout:

Track Through GND Plane

To this layout:

Track Not In GND Plane

Error Checking

I use kicad’s DRC error checking as the first round.  Once these errors are all gone, I move over to freeDFM provided by Advanced Circuits (link here).  They take and email address – now the marketing is locked and loaded on that email address.  In addition, the Gerbers and drill file are pretty much open to the public.  Since all of this is public domain, I’m ok with that.  There is a small bit of information I have to enter after uploading the Gerbers and drill file such as board width and length, how many layers, and a few others.

FreeDFM Results

The results are located here.  I look at the “Potential Show Stoppers”

freeDFM Potential Show Stoppers

I have trouble reading the results.  When I go to the Double Drill Hits link, I am told: Double hits on layer HealthyPH.drl, at X=6.9975″, Y=-4.355”.  Huh?  I put in the dimensions of x = 2.7” and Y = 2.1” – unless input is in mm?  The X and Y dimension field say input should be in inches. Then why these numbers for X/Y?…


I don’t think these errors matter when submitting to OshPark.  However, I’d like to know why I’m getting these errors.  I’ll update this post once I figure this out.

What’s Next

I hope to figure out where the FreeDFM errors are occurring.  I plan to submit the Gerbers to OshPark on Monday.  That means I should start on writing tests for Dev-Rev2.  I also want to give the rectifying portion of the EC breadboard circuit a twirl.  Everything on the breadboard worked fine.  When I got to this step, the output did not look correct.  There are so many reasons a breadboard doesn’t work.  I find this is a very tedious process to debug – particularly as the circuit gets more complex.  I also want to make progress on the EC schematic.



For now, please find many things to smile about.