Soldering and Board Test of the Healthy pH -> MCP3901 ADC



This isn’t a great time to read this post.  I am in the middle of writing it.  I post now because I will be reviewing with others.

Healthy pH Shield With Probes

On to the MCP3901.  I continue to be challenged in soldering this SSOP-20 chip.


at this point for the most part I favor solder paste and a hot air gun to solder on the parts.  Particularly for the capacitors and resistors.  For the SSOP-20 I need more practice and better technique.  Happily, I see many more opportunities to practice soldering an SSOP in the near future!

What to Solder

The components to solder are shown in the DigitalAccess kicad schematic (GitHub repository).

Digital Access Schematic


Read/Write to Config 1

It worked, it worked!  I ran a simple test program that reads CONFIG1 and CONFIG2, then writes to CONFIG1, and then sets CONFIG1 back to the defaults.  Here are the results I get on a serial monitor:

**** Read CONFIG registers ****

->Bits in config 1 register: 00010000| 0X10

->Bits in config 2 register: 00001100| 0XC

 Register values: 100C

**** Change the ADC width from 16 bytes to 24 bytes for CH0 and CH1 (set in CONFIG 1 – see datasheet ****

**** Read CONFIG registers ****

->Bits in config 1 register: 00011100| 0X1C

->Bits in config 2 register: 00001100| 0XC

*** Reset CONFIG registers to default ****

->Bits in config 1 register: 00010000| 0X10

->Bits in config 2 register: 00001100| 0XC

the values are what I expected based on the MCP3901 data sheet

Digital Voltage Values

In the last post I discussed using an AWG to generate an analog signal with a Vpp close to the values that would be returned by a pH probe.  Here is an image of the AWG generated pH signal (TP1)  relative to TP18:

pH Signal from Rigol relative to TP18

and the same signal relative to AGND:

pH signal from Rigol relative to AGND

The difference is because of VGND.  V+_Wallwart’s voltage = 5.0V.  

Rigol V+_WallWart relative to AGND

VGND is at .459V and is noisier that the V+_Wallwart signal.

VGNDTP18 relative to AGND


VGND is doing it’s thing – raising V(min) from -416mV to ~ 40m (-416mV + 459mV = 43mV.

I am using the AWG to simplify testing.  This way I can look at all incoming values.  If the analog -> digital works correctly, I expect to get values from the ADC that closely represent their analog counterparts.

Calculating the Digital Value for the Voltage

To calculate the voltage:

  • figure out which division the reading fits into.  I am using the MCP3901 at a 16 bit width.  That means there are 2^16 = 65536 divisions.
  • set the value relative to VREF.  The data sheet notes the typical value for VREF is 2.37V.  This means the voltage values must be within +/-2.37V.  I am expecting values +/- .440V – so the VREF range works.
The calculation is then: ((value read from CH0 of the ADC)/65536)*2.37

    const char register_read = 1;

    const byte address_CH0_msb = 0x00;  //address of MSB of CH0

    unsigned int readaddress = address_CH0_msb | register_read;

    //we’re using the SPI bus so set CS pin to LOW



    adc_value_bytes[0] = SPI.transfer(0xFF);

    adc_value_bytes[1] = SPI.transfer(0XFF);

    //we’re done using the SPI bus so set CS pin to HIGH


    adc_value = adc_value_bytes[0] << 8 | adc_value_bytes[1];

    float volts = (((float)adc_value/65536)*vRef);



Results currently in spreadsheet (TBD).

Additional Cleanup

A few more changes in Dev-Rev3.

Get Rid of Multiple Test points

Each additional test point adds complexity to the layout and debugging process.  Multiple places to insert a probe for the same reading include:

  • Remove TP2, TP3, TP4, TP5:  These test points are for SPI testing.  It is easier to just connect probe wires to the SPI pins on the stackable headers.




Soldering and Board Check of Healthy pH Dev-Rev 2 -> The pH Circuit


, ,

Moving right along, it is time to test the pH circuit.  The pH circuit is in the pH.sch kicad file (GitHub repository).  

Virtual Ground

The first thing I tested was the voltage divider used to provide a .45 VGND to the op amp so that a single source power source can be used.


Easy-peasy.  Soldered on the two resistors…measured on TP18.  Read .45V.  YIPPEE…

pH Analog Signal

Now on to the heart of this circuit.  Getting a reading from a pH probe.  Besides the op amp, I soldered on the  8 position terminal block (data sheet).  As shown on the HealthypH kicad schematic, the pH probe uses the first two pins of the terminal block



Minor Change – Enlarge Terminal Block Pins

I’m going to change the footprint of the terminal blocks such that the through holes allow the terminal blocks to be smoothly placed versus the snug fit which made me need to apply a bit of force to get the terminal block flush to the PCB.  It should take much – it just needs a little wiggle room.

Reading the pH

I simulated a probe by using the AWG feature of the Gabotronics XMiniLab.  While I use a Rigol scope as my main scope, I am very glad to have the XMinilab.  It is not only great for on-the-go but the AWG feature has come in spectacularly handy.  I fed in a sine way of roughly +/-.42V:

AWG XMini Lab



The test points I looked at and then took readings at test points 17 and 1 relative to TP 18 (VGND).  Here is an image of the test points on the pH schematic:


And..YIPPEE! The scope saw a sine wave with a Vpp of 848mV.  This is very close to the AWG sine wave I use as input into pins 1 and 2 of the terminal block.


pH Test pins 17 and 18

  Probe in Test Pin 17 Relative to Test Pin 18

pH TestPins 1 and 18  Probe in Test Pin 1 Relative to Test Pin 18

THAT was TOTALLY exciting. Wow, it seems to be working.  I’ll come back to this and look at it more closely.  For now, I’m going to journey on to circuits not yet explored…

I was surprised with how quickly I was able to get this part of the Healthy pH Shield working.  On the one hand, the circuit is simple.  On the other hand, I might be missing something.

What’s Next

Time to enter the place where analog and digital collide or cross – depending on your point of view.  On to digital access through the MCP3901 ADC and the Arduino.




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

Soldering and Boardcheck of Healthy pH Shield Dev-Rev2 Voltage Regulator Circuit


, ,

A YIPPEE moment yesterday…delivery of a purple envelope containing 3 Healthy pH Dev-Rev2 PCBs… so….how’d it go?  What works what does’t?  As a process check – how long was the turn around time from Gerber submission to having the PCBs in hand?

The Goal

The goal of this post is to start the debug process of the Healthy pH Dev-Rev2.  This post will focus on the Voltage Regulator Circuit.

Thanks to Those That Went Before

  • Chris Gammell – I took Chris’s unique/fantastic Contextual Electronics course.  It is unique because it truly is like going to the deep end of the pool, jumping in, and then having to figure out how to swim.  Only, Chris is swimming right along with us showing how to move forward and what pitfalls to avoid.  Since taking this class, I have benefited greatly from his additional guidance.  Besides all this, Chris is passionate about electronics, how we learn electronics, and has always been a person of excellence.  I recommend his courses and podcast.  Not because I get any monetary benefit – because I do not.  But because they have allowed me to make what I consider incredible (by my past history) progress in learning electronics.
  • Laen and his company OshPark – I can’t build a prototype without a PCB.  Thank goodness for OshPark and how simple they make it to submit Gerbers.  In addition, their service and support is excellent.  Not only does the person responding to a question respond within 24 hours, but they take time to explain stuff in more detail.  Also, folks answering my questions have been extremely positive – which makes for an overall very positive experience.

Cost and Turn Around Time

The more I can test and faster I can iterate on a rev means the sooner I can have a V1.  The long pole in the iteration is fabrication.  Typically, from submitting Gerbers to receiving the PCBs took around 15 days.  OshPark offers a Super Swift service so I tried it for the rev of the Healthy pH PCB.  The turn around time was cut in 1/2 for roughly 4x the cost.  Besides the cost of the PCB, shipping needs to be thought through.  With free shipping, it took four days to arrive.  Paying $5 for a better shipping option skimmed off two days from shipping.

Takes longer, Costs Less

I sent Dev-Rev1 out on Thursday PM.  I received them 15 days later at a cost of $28.50.

3 boards at $28.50 per batch of three. $28.50
Sub total $28.50

United States: Free Shipping $0.00
TOTAL (paid) $28.50

Faster, Costs More

My current experience with OshPark’s SuperSwift service / USPS priority mail is 9 days at a cost of $122.50.

I sent the Gerbers in on a Monday in the afternoon.  I wanted to try out the Super Swift Service as well as some for shipping to see what the time difference is.

3 boards at $28.50 per batch of three. $28.50
Super Swift Service $89.00
Sub total $117.50

USPS – Priority Mail $5.00
TOTAL (paid) $122.50

It took 2 days for shipping.  I received the boards 9 days later on Wednesday.

According to the great folks at OshPark, panels go out each day at 11AM.  If I had been able to submit the Gerbers prior to 11AM Monday, there is a good chance I would have received the boards two days earlier.  Perhaps if I paid for overnight shipping I would receive the PCBs on Saturday – a total of 6 day turnaround.

Circuit to Supply a Regulated 5V

The voltage regulation circuit is in the WallWart.sch kicad schematic (GitHub link). So what worked and what didn’t?  Time to solder and test.

D’OH: Barrel Jack’s Drill Holes are Too Small

Simpson DOHThis is embarrassing.  AGAIN?  Are you kidding me???  Now the pads are larger but the drill holes are STILL too small.  **D’OH!**  I double checked the holes on Dev-Rev2.  Chris pointed out the darn holes still looked too small…but……I was sure I corrected this.  WRONG.   

Looking at the layout in PCBnew (kicad files are at this GitHub repository)


compared with the test points, they do look rather small.  Um…this was the exact feedback Chris gave me on review of this layout.  I clearly didn’t get this right!  Here’s an image of the barrel jack part next to the pads and holes on the board: 

Here’s what I have for the pad properties:
Barrel Jack Pad Properties
From the mechanical drawings of the barrel jack’s through hole (data sheet), I come up with the length and height of the barrel jack’s footprint to be (NOTE: values are in inches):
Length and Height of Barrel Jack Footprint
The X / Y locations for the pads work out to be:
XY Loc Of Pads
From trying to “force” one of the barrel jack pins into a test point, the length of the barrel jack pin needs to be slightly bigger than the diameter of the test point.  But – hmmm… the test point’s are .4”…seems to me the mechanical drawing is incorrect based on the barrel jack I am holding and the test point comparison.  I am widening the length and height by 150%
Here are the pad settings for Dev-Rev3 barrel jack:



I was able to solder wires to the barrel jack pads.  YIPPEE!  I got Power, which I set to 10V.  The fun part was using the hot air gun to connect longer wires so that I could attach the ends to my power source.  It is so much more fun to use the air gun than a lighter!


 I soldered on the components (yes, I need practice!):

Voltage Regulator Components

D’OH: Wrong Wiring of Voltage Regulator Pins

 Here is a drawing I made of this part of the Healthy pH Shield:


Hmmm…I expected to see 5V on Vout …what’s with this punky .63V (.68V when the green LED was attached).  I expected to see closer to 5V.  Checking the wiring of the pins on the MC78L05ACHX Voltage regulator (data sheet).


Voltage Regulator Pins

Simpson DOH

**D’OH!** Pins 1 and 2 are swapped. Excuse me for a bit while I bang my head on a wall…clearly nothing is going to be hurt…



I skipped over using the voltage regulator by soldering a wire between pin 1 of the barrel jack and pin 2 of the Wall Wart extension pins (P2):

Skip Voltage Regulator

YIPPEE! I Saw the Light

The board works, the green LED turns on.  This is great because it is a visual indicator that the power supply is on…which is most inconvenient when I’m soldering on parts!


PCB Testing Through Wall Wart Schematic

Not very pretty, but at least I can move past the voltage regulator circuit. 

Additional Cleanup

There are a few additional changes I will be making to Dev-Rev3.  These changes became obvious after playing around with Dev-Rev2.

Get Rid of Multiple Test points

Each additional test point adds complexity to the layout and debugging process.  Multiple places to insert a probe for the same reading include

  • Remove TP19 and TP10:  There are three holes where a DMM or scope probe can go to get to AGND: TP19, TP10, pin 1 of P2 (closest to edge of board).  Since there is a through hole (pin 1) available, I will get rid of TP19 and TP10 and use pin 1 of P2 to probe AGND.
  • Remove TP8.  TP8 is on the same node as the through holes for P2.  Bah Bye.

To Add: Text and Logo

I have not added any additional text or art to the PCB.  The text is the most important.  It will be the way I can tell the differences between revs of the boards.  Right now I look for the epic fails between boards.  While – sadly – there are many epic fails to help identify the board, it will be easier with identifying text like “Dev-RevX.”  I plan to add a sacrificial draft of a logo.  Creating artwork that identifies my work is really hard so I thought I’d start the iterations now just to start getting visuals in my mind for behind the brain processing. 

Closing Thoughts/What’s Next

I am glad to have the test points scattered throughout the PCB.  This has made it easier to map expected values from the schematic to circuit location in the layout.  I started studying electronics in January, 2014.  I need more time to absorb basic circuit design concepts.  I like this way of building, measuring, comparing to ideal/expected behavior.  It is an incredible learning opportunity.  I’m excited to press forward…although I seem to be losing out on sleep in anticipation of figuring out why something doesn’t work and then learning from it.

I plan to go through the pH schematic/circuit after this….until then…



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

Testing the RGB LED Light on the Healthy pH Shield


, ,

I’m adding testing the RGB LED on the Healthy pH Shield.  I added the RGB  LED to provide a visual indication when the Healthy pH Shield is working or not working.  Given all the layers that come together in order to adjust the pH, a visual indication can go a long way in helping debug an uncooperating piece of hardware/software!

The Goal

The goal of this post is to provide text behind the RGB LED diagnostics tests to be run starting with Dev-Rev2 of the Healthy pH Shield.

Thanks to Those that Went Before

  • ReadASCIIString Tutorial – I used some of the code to get the R,G,B values from the serial monitor.  Google is our friend! is a great resource.  Thanks folks on the Arduino team for the useful content and excellent hardware.  You have dramatically simplified my ability to poke around and see how this stuff works.

Additional Material

  • Design: I am currently working on Dev-Rev2 of the Healthy pH Shield.  The RGB LED is located on the Arduino schematic within the Healthy pH Shield schematic.  The kicad files are available at this GitHub location.
  • Test code: I am continuing my test harness to include an RGB LED test.  The code is located in LEDDiags.cpp.  The firmware source is located at this GitHub location.  

Common Anode RGB LED

RGB LEDs come in either common anode or common cathode.  The one used in the design of the Healthy pH Shield is a common anode RGB LED.  The reason for this was the ready availability of the LED that is used (link to BoM).  I’m used to common cathode RGB LEDs where the color red – for example – is 255,0,0.  Since the anode RGB LED shares V+, the RGB values for red is the reverse: 0, 255,255.  This could be a spot confusing to get used to at first.

The Test

The diagnostic test is simple:

  • turn on the RGB LED passing in an RGB value in the form 0-255(red),0-255(green),0-255(blue).  For example, to turn the light green, 255,0,255 is entered on the serial monitor.
  • turn off the light.

The code is found in LEDDiags.cpp (link).  It is straightforward so I won’t detail it here.

What’s Next

The RGB LED diagnostic test is very simple.  It is included in a post for completeness.  The next test diagnostics will be for the temperature sensor.  I’m also hoping the Healthy pH PCBs arrive very soon so that I can solder on the parts and start testing!



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

Testing the SPI Bus on Healthy pH Shield Dev-Rev2



As I wait for a purple package from OshPark containing the Dev-Rev2 Healthy pH PCBs, I’m getting ready for diagnostic testing of the Healthy pH Shield.  I should have defined these tests prior to board layout.  It is a great way to see if the circuit functionality and test points exist to get to what the goal of the Shield – reading the pH value – actually is!  For example, instead of randomly putting in test points where I think it is a good idea to do so, I’m putting them in because they are a requirement to run a test.  Another benefit of doing this first is not duplicating test points or having unnecessary test points.

The Goal

The goal of this post is to identify tests that I will run to determine if the Healthy pH Shield works.

Additional Material

The SPI test that I plan to run on Dev-Rev2 can be found at the Healthy pH Dev-Rev2 GitHub repository.  This post revolves around the SPIDiagTests.cpp file.  Hopefully I commented it enough!

Thanks to Those That Went Before

  • Jon Black wrote a menuing system for the Arduino that supports multiple layers of menus.  Each menu can have multiple items.  His code (available at this github repository) made it extremely easy to add a structure to running the tests through the serial monitor.  That folks like Jon make their code available is a testimonial to his talents as well as one of the (many) benefits of using the Arduino platform.  Thank you Jon.
  • Chris Gammell for all that I have learned about electronics from him as well as walking us through the MCP3901’s SPI interface during the Contextual Electronics course.  I had been intimidated by going into the MCP3901 data sheet and reading/writing over SPI. Chris walked us through this and now I feel confident to be able to read/write to any device that supports SPI by reading the data sheet.

The Tests

The tests I want to define and run should tell me what doesn’t work in the shortest amount of time.  Tools to be used include a DMM, Oscilloscope,Logic analyzer, and Arduino Sketches.  

Tabel of Tests

The first thing I did was to create a spreadsheet identifying the diagnostic tests I will run.  

Schematic Name Tool Test Expected
Arduino shield sees Ard 5V&3.5V Power relative to Ard GND DMM Shield stacked on Ard. pos probe in Ard pwr pins of shield. neg probe in Ard GND ~5V and ~ 3.5V reading
  RGB LED works Sketch Sketch turns on RGB LED to a few colors RGB LED lights up when sketch turns on a color
WallWart Power from WallWart relative to AGND – before diode scope Shield plugged into WallWart (6-12V). pos Probe in TP20 (pre-volt reg) neg in TP10 or TP19 voltage in jumping around value of the (6-12V) wall wart
  Power from WallWart relative to AGND – after diode scope pos Probe in TP 9 neg in TP10 or TP 19 same as above.
  Regulated power V+_WallWart Scope pos Probe in TP8 neg in TP10 or TP19 smooth 5V
SPI SPI Read config Sketch,logic analyzer Sketch r/w config data config bytes match expected values from MPC3901 data sheet
Temperature AC signal relative to AGND Scope pos Probe in TP11 neg probe in TP10 or TP19  
  SPI Read thermistor Sketch Sketch reads data channel for therm and translates to C and F temp readings around 60 – 80˚F
pH pH Probe GND (VGND) relative to AGND DMM pos Probe in TP18 neg probe in TP10 or TP19
  pH probe non-inverting input signal relative to VGND scope ph probe connected to TB. pH probe submersed in ph 7 calibration solution pos Probe in TP17 neg probe in TP18
  output from pH Op Amp relative to VGND scope (pH probe same as above) pos Probe in TP1 neg probe in TP18 same signal as above (buffer applied)
  SPI Read pH Sketch (pH probe same as above) Sketch reads data channel for pH and translates to a pH value Something within range of pH 7.
Pumps 5V from Ard relative to GND DMM pos probe in TP14 neg probe in Ard GND smooth 5V
  Down Pump HIGH relative to GND Sketch,scope pH Down pump hooked up to TB and ready to pump. Sketch sends analogWrite() to pump the pH DOWN…pos probe in TP12 neg probe in Ard GND I’m thinking I should see a digital 1 in the scope
  When down pump HIGH relative to GND, current flows Sketch, scope using the same setup and sketch as above, pos probe goes into TP15 neg probe goes to Ard GND  
  repeat two tests above for Up Pump      
  Turn on/off down pump Sketch using the same setup and sketch as above, validate that the pump turns on and off pumps for the amount of seconds specified by sketch
  Turn on/off up pump      

The test in yellow will be my starting point when running the diagnostics (and where I must eventually end up!)  I do not expect reading the pH will pass on the first try.  Most likely one or more of the circuits was not designed correctly.  Once I figure out what doesn’t work (and why), I’ll update the Healthy pH Shield design and layout to fix what I have found doesn’t work.  That effort will be the start of Dev-Rev3.

Analog Tests

The analog tests rely on readings from either a DMM or Oscilloscope and the test points.  Viewing test points from the schematic (versus the layout/pcbnew in kicad) gives a better feeling for what is being tested (and hopefully why).

Digital Tests

My work in progress is under the firmware directory of the Healthy pH Shield GitHub repository (link).  I am using Xcode 5 for my IDE.  In order to do this, I use embedXCode (link).  The Arduino IDE is fine when I want to write a sketch that has a few functions.  XCode is terrific as the firmware gets more complex.  I find menuing/UI to be tedious without a framework, so I use Jon Black’s Arduino menuing system (GitHub link).

Once I set up the menu framework for the diagnostic test harness, I started coding the tests for transmitting data over the SPI bus.


The SPI bus is well documented within the MCP3901 data sheet (link).  The test harness will read the current settings contained in the CONFIG1 and CONFIG2 registers, change some of the values, read the modified contents, then reset the registers to their default values.


Prototype Testing

breadboard proto side view MCP3901     pins On SSOP-20

 Previously I soldered an MCP3901 with a 20-SSOP footprint  onto a SSOP-to-DIP adapter I had bought from Sparkfun (link)… I had put this on a breadboard with the crystal and caps which are needed by the clock.  

Crystal on MCP3901 schematic

Now this is frustrating!  It used to work (honest really….) and now I transmit the right command over MOSI, but do not receive what I expect from MISO. 

Setting up the SPI pins

First thing I did was review the wiring of the SPI pins going to<->from the Arduino<->MCP3901.

from Table 3-1 of the MCP3901 data sheet (link),

SPI pins from Table 3-1

pin 20 = SDI, pin 19 = SDO, pin 18 = SCK, and pin 17 – CS.  These are the pins I will need to test the part of the test harness that reads and writes to the CONFIG1 and CONFIG2 registers of the MCP3901.

Sadly, I can’t remember which Arduino pins are defined for SPI, so once again I go to a handy-dandy picture:
picture of Arduino SPI pins

Now I can wire the Arduino and MCP3901 together.

Checking SPI traffic

What command ‘is really’ being transmitted on the MOSI line?  The best way to see this is using a Logic Analyzer.  I really like Saleae’s logic analyzer (which I discussed earlier in this post).  After hooking up the logic analyzer, I send a control byte (see the MCP3901 data sheet, section 6.2):

MCP3901 Control Byte

All the info needed to figure out how I came up with a control byte value of 0X15 for reading CONFIG1 and 0x17 for reading CONFIG2 is contained in the MCP3901 data sheet.  I expected to get the default values defined in section 7.6 of the data sheet:

Config Values

Based on the table above – for CONFIG1, I’d expect 0001 0000  (0x10).  For CONFIG 2, I’d expect 0000 1100 (0X0C)

Results from Logic Analyzer

At first I was not able to get any values from the Logic Analyzer.  It turns out I needed to slow down the clock, so added:


before SPI.begin().

Here is the traffic I get when I try to read CONFIG1:

SPI Output FF Miso

CS looks right (pulled down while data is transmitted for this device), clock looks great, MOSI looks right…but…sigh…0XFF for MISO.

And GUESS WHAT – ARGH!!! I did not have pin 11 (digital GND pin) attached.  OK, I get confused easily… and now….my YIPPEE! moment…here is a screen shot of MISO for Config2:

Config 2 SPI Works

One thing that seems weird to me (but then again, it took me a l-o-n-g time to figure out about pin 11 :-) ) was sending to SPI.Transfer().  In order to get the 0X0C, I had to:


    char register_value = SPI.transfer(0XFF);

Given that this is a transfer (read and write at the same time), I was expecting:

char register_value = SPI.transfer(SPIReadControlByte);

to work…hmmm….


Whew!  Well that was exciting…a breadboard prototype using the MCP3901 and required crystal.  Now I can finish writing Arduino tests for the MCP3901.

SPI Write Test 

The test will change the ADC width bit from the default of 16 bit to 24 bit by setting the CH0 and CH1 width bits of CONFIG2 to 1.  Thus, the value in the CONFIG2 registry goes from 0x10 (0001 0000) to 0x1C  (0001 1100) (see register 7-6 in the data sheet ).                                                                                        



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












Dev Rev 1 of the Healthy EC Shield



 I want to get going on the schematic of the Healthy EC Shield while I wait to get fabricated PCBs of the Healthy pH Shield from OshPark.  The job of the Healthy EC Shield is to read the nutrients in the bath and determine if more nutrients are needed.  If so, pump in the amount of nutrients needed.  Schematics are located in this GitHub repository.  CAUTION – THE DESIGN and LAYOUT ARE NOT FINISHED.

The Goal

The goal is similar to the goal when I posted the design of the Dev-Rev 2 of the Healthy pH Shield (link).  I will walk through the Healthy EC Shield’s circuits.

Thanks to Those That Go Before

I can’t help smiling when I think about how amazing it is to be able to learn something each day.  What has been occurring recently has been like a zap to my head!  Just when I thought I understand something, Chris Gammell or Ryan (SparkysWidgets) – maker of many very cool boards – like the minipH and miniEC) kindly nudge what I think I know into the right direction of how something (in this case an EC Circuit) actually works.  Both Chris and Ryan have been instrumental in my understanding of an EC Circuit and electronics.  I highly recommend the offerings from both!

The Schematics

I am calling this build of the Healthy EC Shield Dev-Rev1.  The (kicad) files for the schematic are located at this GitHub repository.

The design shares design choices with the Healthy pH Shield.  They both

  • use the MCP3901 as the ADC.  This way, the same firmware functions will be needed and I there will be twice as many needed which increases my chances of buying at the less expensive bulk rate.
  • use the same design for pumps.  There is only one pump circuit on the Healthy EC Shield to pump nutrients.
The Healthy EC Shield assumes the Healthy pH Shield is stacked below.  This allows the Healthy EC Shield to use the Healthy pH Shield’s temperature sensor, Wall Wart power source, and RGB LED (for debugging purposes).

The Sub Circuits

As with the Healthy pH Shield, I use Kicad’s hierarchical schematic feature to logically represent the sub circuits.  I’ll only detail the EC circuit since the others are pretty much the same as found on the Healthy pH Shield (link).

EC Circuit

The key thing to know about the EC circuit is the EC probe acts as a variable resistor within the gain loop segment of the EC Circuit.  I’ve walked through this circuit several times (and every time I do – just when I think I understand it, there is something I don’t understand!  Fascinating) (link).

EC Circuit Picture

The EC circuit schematic explains what EC_GND and the AC power source as input into the non-inverting input pin of the op amp (link in GitHub).  I’ll include the “important snippets” below.  But it is perhaps best to look at the schematic to get a better feel for the circuit.

EC_GND is a virtual ground so that a single (5V) power supply can be used for the op amp rails:


The AC signal is generated by shrinking down an AC Signal created by a Wien Bridge Oscillator:

Created AC Signal


Calculating the EC Value

I went through how to calculate the EC value in this post.  Looking back at the picture I’ll redraw the R’s and V’s as:



  • Vout = EC_Signal
  • R1 = 3K
  • R2 = 1/S = 1/EC

That is, this is part of a variable gain loop in which the only unknown is the value for R2.  Once that is figured out, conductivity (EC) is the inverse of resistance. 

Like I said, the explanation and example calculation are in this post.

Just One More Thing – Changes to Healthy pH Layout Prior to Sending Gerbers



Just sent Dev-Rev2 Gerbers to OshPark for Fabrication (~2PM on 9/15/2014).  But before I did I fixed a few things from my last post.  I have updated all schematic/layout/gerber files on the GitHub repository for Dev-Rev2 of the Healthy pH Shield.  Since I barely (and perhaps that is questionable?) know what I am doing, I crave your thoughts on how I can improve on the design/layout.

The Goal

The goal of this post is to walk through the errors on the Healthy pH Shield Dev-Rev2 layout.

Thanks to Those That Go Before

Every day I am thankful for the many amazing people that I interact with.  

This post would not be possible without the guidance and knowledge shared by Chris Gammell.  Just when I think I understand something, I go over it with Chris…and…whoa – I truly was clueless.  While he has every right to do so, Chris has not laughed at my learning foibles.  Rather he has patiently explained (and re-explained) something I just don’t get.

Results From freeDFM

In the post where I discussed the design and initial layout of the Healthy pH Shield (link), I noted freeDFM – a utility from Advanced Circuits (here is the link) I like to run prior to submitting Gerbers to a fab house – pointed out errors that I couldn’t read.  The first problem I had was the coordinate system.  What the heck origin was freeDFM using?  I mean, I had entered X=2.7” and Y=2.1”….then did freeDFM report an error at X=8.5277987″, Y=-3.2543901”?

DOH! I have ignored actually LOOKING at the Gerber files, relying on the layout view in Kicad’s PCBNew.  Um..yah, not good.  Considering what actually going on is shown in the Gerbers…. so opening up the Gerber files notice where the origin is:

Gerber Showing Origin

The origin is way to the upper left.  So yes indeed, TP9 (circled) is at X=6.9975″, Y=-4.355″

…and yes, indeed there is a double drill hit:

Double Drill Hit

…and the other based on the coordinates / location in the Gerbers:

2nd Double Drill Hit


The second freeDFM error were 5 violations of Insufficient Trace Width.  It turns out an edge of the Arduino GND plane was too close to P1 drill holes:



Zoom In Insufficient Trace Width

So I appended the GND plane to include more surface area around P1:

More Surface Area ARound P1

OK, resubmitted to freeDFM…and…and…


Clean Up

Some uglies I cleaned up:

I had the RGB LED – which uses the 5V+ of the Arduino using digital i/o PWM pins, which was how I’d seen RGB LED examples wired.  The problem with this is it caused me to draw a rather large and ugly track across the board from the 5V+ pin on the Arduino to the digital i/o pins on the other side.  Given this advice (link): 

  • digitalRead() works on all pins. It will just round the analog value received and present it to you. If analogRead(A0) is greater than or equal to 512, digitalRead(A0) will be 1, else 0.
  • digitalWrite() works on all pins, with allowed parameter 0 or 1. digitalWrite(A0,0) is the same as analogWrite(A0,0), and digitalWrite(A0,1) is the same as analogWrite(A0,255)
  • analogRead() works only on analog pins. It can take any value between 0 and 1023.
  • analogWrite() works on all analog pins and all digital PWM pins. You can supply it any value between 0 and 255.The analog pins let you read/write analog values – basically, instead of giving out a voltage of 0 or 5 (as with digital), they can give a range of voltages between 0 and 5 (both as input and output). Note that the voltage during analog output is only the observed voltage with a multimeter. In reality, the analog pins send pulses of 0V and 5V signals to get an output that “looks” analog (this is PWM).

I ended up moving the RGB LED and associated resistors to analog pins close to the 5V pin:

Layout of RGB LED

Then a few smaller uglies.  The through hole size of the WallWart and Barrel Jack parts were too small.  More like the size of a via than a through hole.  Then the GND planes needed fixing up as well as overlapping labels.  The point of all this minutia is the importance of sanity checks – and most ideally – reviewing with someone far more senior who will point out errors.  So much to learn.


So now I impatiently wait for the PCBs to return from Osh Park.  Then soldering and…maybe…power!


Please find many things to smile about.

Dev – Rev 2 of the Healthy pH Shield



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.




Breadboard Prototype of the 2nd Stage of the E.C. Circuit



Finally – I conquered the Wien Bridge bread board prototype that included a VGND of +2.5V (detailed in this post).  Now on to the 2nd stage – reading the E.C voltage.

The Goal

Add the Second stage of the EC circuit to the breadboard prototype.  Measure the output with an oscilloscope and compare results with the LTSpice IV model.

Bread Board View

The Schematic

Here is an image of the LTSpice IV schematic for the EC Circuit with the second stage within the pink area.

LTSpice EC Circuit


Wien Bridge Oscillator

Here is the output from the Wien Bridge Oscillator stage:



YIPPEE!  The frequency is right where it should be at 1.6KHz.

Shrink Vpp

Moving right along…here is the output after the voltage divider (to get the input into the non-inverting pin close to a Vpp of 200mA):



YIPPEE! The scope’s readings appear close enough…now onto reading the ECv.

Reading ECv

 I’m going to try both a 200Ω and a 1400Ω resistor for R0 (see image above – R0 represents the input of an E.C. probe.  It acts like a variable resistor within a voltage divider similar to a thermistor sensor).  Here’s what I get from the LTSpice IV model:


The green line is when R = 200Ω.  The black line is when R = 1KΩ.

When R=200Ω, the Vpp ~= 1.4V.  When R=1KΩ, the Vpp != .46V

I added the op amp and resistors to the breadboard then checked out the results on output of the 2nd op amp.  Here I used a 200Ω R:



Another YIPPEE!! The Vpp is “close enough” to the model, off by .1V (1.5V on scope versus 1.4 in LTSpice IV model).


And the breadboard prototype of the EC circuit through stage 2 seemed to work for a 1K resistor.  

What’s Next

On to the last stage – sending the ECv through a rectifier.  Hopefully I have more op amps and diodes around…


Why the Virtual Ground Method used for pH Will Not Work for E.C.



I’ve been bumbling my way through grasping the beauty of using voltage dividers to create virtual grounds so that I can use a single power supply as a power source to the op amps.  In the back of my head, I hear Ryan’s (SparkysWidgets) warning that I’m leaking current into the bath which makes measurement difficult at best and more likely impossible.  But I need to understand all this stuff better, including different configurations for virtual grounds with the goal to use a single power source while handling an AC Signal as it makes its merry way through op amps.

The Goal

The goal of this post is to better understand the impact of design choices on designing virtual grounds

Thanks to Those That Go Before

Every day I think about the things in my life that I am thankful for.  There are so many things.  One is the sharing of knowledge from exceptionally smart and caring folks.  Today’s thank you goes to:

  • Chris Gammell – Chris is an exceptional teacher/guide who tirelessly walks me through electronic design concepts and implementation.  He has a knack for teaching in a way that makes me passionate to learn more.  I do recommend his Contextual Electronic courses.  I took them and learned a lot.
  • Ryan of SparkysWidgets – If it wasn’t for Ryan’s open source design of the minipH and miniEC, I would not be able to make the progress I have made on the pH and EC Circuits I work on.  Ryan has been exceptional in giving me insight and advice on my circuits.  His stuff is great!


I discussed in this post how I designed for a single power source in order to handle the negative pH readings of the AC Signal.  While this design should work ok for the pH circuit, it will not work for the E.C. circuit.


The Challenge Using the VGND of the pH Circuit

The major difference between the AC signal – in the case of pH, the pH voltage and in the case of EC, the Wien Bridge Oscillator – is shown in this diagram I found from this site:  

Voltage Divider With Load Explained

Recall the (glass) characteristics of a pH probe mean the AC Signal will act as a high impedance load. SpakysWidgets notes: “A typical probe has an impedance of anywhere between 50Ω and 500MΩ.”    The Wien Bridge is built on the wires and components on a PCB or bread board and so acts as a low impedance load.

The pH probe adds pretty much 0 load to the circuit. This is not true for Wien Bridge Oscillator.  The more load, the less the output voltage will be.

Consider this example where this is no load (as is the case with the pH circuit):

No Load Divider

Ach – the more I learn the less I seem to understand.  But just keep swimming..just keep swimming!




Get every new post delivered to your Inbox.