YIPPEE! I just received my purple package of 3 Healthy pH Dev-Rev3 Shields.  And just before that – my order after my shopping spree at Digikey arrived…time for another round of soldering, testing, and iteration on the design and layout. 

The Kicad schematic and board layout files are located at this GitHub location.

The Goal

The goal of this post is to walk through the testing of the Healthy pH Dev-Rev3 shield.

Thanks to Those That Went Before

I will always be extremely grateful to Chris Gammell and his Contextual Electronics course.  Prior to taking Chris’s course, I didn’t understand how wires on a bread board could be wired together into a workable circuit…even though I dabbled in doing so.  I didn’t have a conceptual model around key electronic concepts.  Thanks to Chris, I am able to push forward learning electronics and tools such as Kicad to a point where I can build – and make work – a PCB.  This to me is amazing.

Power Source

Here is an image of the chips on the shield that take the voltage from a wall wart and clean it up for the power source used by the analog circuits on the shield:


Simpson DOH

Hmmm…silly me…D’OH…now the througholes are large enough for the barrel jack…but the middle hole is backward.  Not my finest hour.  



and an image of the schematic:

Voltage Regulator Circuit

The data sheet gives characteristics based on an incoming non-regulated power source of 10V.  The range can be anywhere from 8V to a maximum of 30V.  Working back from the 5V out, the MC7805 has a dropout voltage of 1.7V.  In addition, the 4004 diode (D2) contributes a voltage drop of .64V.  5V + .64V + 1.7V = 7.34.  So I lied.  In this configuration, the absolute minimum is 7.3V.  Given the common wall wart voltage, I will recommend 9V or 12V wall warts.

Noise on Power Lines

The first test will check the level of noise on the V+_WallWart (+5V/AGND) and VGND (VGND/AGND) signals.

Using TP20 for the probe and pin 1 of P2 for AGND, turning on AC coupling on the scope, the incoming noise looks like:


the Vpp ~= 4.6mV.  Chris noted less than 10mV can be considered clean.  The power coming in from the bench power supply is nicely regulated.

Noise on V+_WallWart (through pin 2 and pin 1 of P2) looks like:


Incoming power is coming from my bench power supply, which is providing regulated power. 

VGND is built using a voltage divider:



The noise that comes from VGND relative to AGND looks like:



The noise for VGND shows a Vpp ~= 3mV.  Close but smaller than V+_Wallwart.  I don’t understand the characteristics of decoupling capacitors well enough but assume the slightly smaller Vpp is due to the addition of C10 – a .1µF capacitor placed closed to the resistors used for the voltage divider.

Analog pH Readings

The part of the circuit to test is the op amp used to capture the voltage measurement of the pH probe:


The chips as they are soldered on the shield are shown in an earlier image.

Testing the Analog pH Voltage Value

I’ll be putting the probe’s scope in TP1 relative to VGND.

The pH Voltage Value

I pointed out in this post, the easiest way to test the pH analog values is to send in various DC voltage values representing what might be coming from a pH probe.  I do this by setting up the power source to provide 5V to the pH circuit as well as a voltage divider  with a potentiometer to adjust the DC value simulating a result from a pH probe.  


In an earlier post, I showed a table that mapped pH values to their voltage values (link).  The table shows that a pH voltage value is a function of the pH value:  pHv =  .414-pH*.05916 – where 59.16mV is the change in voltage (slope) between two pH values.

I adjusted the POT such that the incoming DC is listed in the Bread Board column.  The measurements taken after going through the op amp are pretty much the same:

Bread Board TP1/relative to VGND
0.44 0.44
0.703 0.702
0.273 0.271

YIPPEE! This part of the circuit is working.

From Analog to Digital

Moving to digital is all about the ADC and the Arduino.


Schematic View With Oops on CH0…

Testing SPI Traffic

The MCP3901 uses SPI to communicate with the Arduino.  Luckily, I wrote test code during my testing of the Healthy pH Dev-Rev2.  The test code I wrote is located at this GitHub location.  When I first ran it on this build, I received:

—> Config 1: 0XFF
—> Config 2: 0XFF

from previous testing, an 0XFF means MOSI is sending out the command, but its not getting anything back on MISO…hmmm….the challenge with debugging this was where to start…the closer I start to the challenge…argh…

I got the debugging tools ready: Logic analyzer and scope.  A DMM can be used in place of a scope.  However, I like to look at the change in voltage over time.  For example, when the Arduino sets a pin to LOW or HIGH.  Immediately hook up the logic analyzer since this is a view into the MOSI, MISO, SCK, and CS lines.

SPI PIns On Arduino

SPI Pins Color Coded to Logic Analyzer UI

  • Hook up the logic analyzer.  Run the test that reads the CONFIG registers.  Is it showing the expected results?  If YES – YIPPEE!! Else, on to the next step…
  • If received 0x0: No traffic is being seen on any of the lines.  At a minimum, I would expect to see SCK beating away and MOSI sending out the command.  Potential reasons:
    • The shield is not receiving traffic from the Arduino. Verify this by pulling off the shield and checking the SPI lines with the logic analyzer.  First thing I do for this is to take off the Shield and check the SPI traffic with just the Arduino running testing reads on CONFIG register.  It could be the Arduino, the connection of the Shield, the connection of the logic analyzer wires…
  • If received 0xFF: SPI traffic is going over the bus – at least the MOSI and CLK lines – check with the logic analyzer.  The MCP3901 is not returning any data (i.e.: no data on MISO).  Check:
    • is the power supply for V+_Wallwart plugged in?  If that is the case, the green LED on the shield should be on.
    • Use the DMM to check continuity.  Is there continuity between the family and friend components?
    • Is the chip getting power?  Pin 3 is connected to V+_WallWart.  Is there a voltage drop because of the power absorbed by the MCP3901?
    • Is the crystal working?  Get out the scope and see if there is an AC Waveform.  Here’s what I measured:
The MCP3901 data sheet (link) notes (section 3.11): The typical clock frequency specified is4 MHz. However, the clock frequency can be 1 MHz to5 MHz without disturbing ADC accuracy. 
The image of the AC Waveform shoes a time period of about 250ns.  The frequency = 1/.000000250s = 4MHz.  So the crystal seems to be correctly creating the AC Waveform needed by the MCP3901’s clock. 
    • Is CS, RESET, DR set to the right pins in the test software? If yes then…
    • Is the RESET line pulled HIGH (view in scope or DMM).  The RESET pin must be high for the MCP3901 to “wake up and hear the request.” (see “Pins to Arduino” below). Make sure this happens!
 …and …and IT WORKS!  YIPPEE!

Pins to Arduino 

Simpson DOH
Hmmm..this took me a better part of a day to figure out.  EVEN THOUGH this exact challenge was noted by Chris Gammell in the Contextual Electronics course.  Besides the SPI lines, the MCP3901 has a RESET and DR line to the Arduino. In section 3.1 of the MCP3901 data sheet (link): This pin [RESET] is active low and places the entire chip in areset state when active.When RESET=0, all registers are reset to their defaultvalue, no communication can take place, no clock isdistributed inside the part.  
I took out my DMM and checked to see if indeed RESET is high…because, after all, I set this pin to HIGH in the code.  In the initialization method for the MCP3901 class I have:

    //RESET_N – first set config to default thent high so that communication can happen with the ADC



which would work just great if indeed the pins I associated with the RESET and DR were correct.  Well wouldn’t yah know? I changed the pins for these two in Healthy pH Dev Rev 3:

MCP3901 adc_mcp3901(10,8,9);

where the initialization method is defined as:

MCP3901::MCP3901(byte cs_n, byte reset_n, byte dr_n);

In the Healthy pH Dev-Rev2 design, the RESET pin was pin 4 and the DR pin was 2.  I switched these to pins 8 and 9 in Healthy pH Dev-Rev3.



Healthy pH Dev-Rev2 Arduino Pins


Healthy pH Dev-Rev3 Arduino Pins

 YIPPEE!!  Once I changed the RESET and DR pins to the right ones, the SPI worked correctly!  

Digital pH Voltage Readings

Finally I can move on to evaluating results from the ADC.  and…and….

 Simpson DOH
D’OH – somewhere between updating the schematic from Healthy pH Dev-Rev2 to Dev-Rev3, the inputs for the pH analog lines got switched.  

A big OOPS here….ARGH…I am blocked from further testing of pH values. Ah well…Dev-Rev4 better be right! 



Analog Voltage Value

The thermistor is a 10K thermistor.  I changed the resistor from 10K to 1K so that readings would be less than .79V.  The temperature around my desk should point to a voltage that is 1K/11K = .45V.  The reading I got was .368V.  For testing, I am using a 5% thermistor.  The accuracy will be improved.  I am using this thermistor because it is the easiest for me to test with.

Digital Voltage Value

What’s the value seen by the Arduino once it has been transformed into a digital value by the ADC?  The first time I ran the test program, I received what appeared to be random results.  Given that I was getting CONFIG information correctly, I’m betting there is a problem with:

  • The control byte I am sending is not set up correctly.  It could have the address of the register of the read byte incorrect.
  • I am not putting the bytes I get back correctly into a data type understood by the Arduino.
  • If the data channel returned is correct, the function to go from a data channel to a voltage value is not implemented correctly.
Previously, I used the MCP3901’s higher resolution – 24 bit width.  This time, I am going to use 16 bit because the bit manipulation is simpler/easier to understand and a 16 bit accuracy is more than enough.


The Thermistor is on CH1. The address of the 16 bit stored data channel value starts at register 0x03 MSB) and includes 0x04.  

MCP3901 Control Byte

MCP3901 Register Map

the control byte should be 0x03<< 1 | 1 or 0x07.

Reading CH1







Changes for Dev-Rev4

Remove Diode in Voltage Regulator Circuit

As noted earlier, there is no need for diode (D2).  I’ll remove from the schematic.

Barrel Jack

Fix the barrel jack footprint and pick a different barrel jack.   The barrel jack I picked has a very small hole and I want one that will work with the majority of 9V and 12V wall warts.  I should have looked on wikipedia first (link) to learn what the most common barrel jack size is for 9V and 12V Wall Warts.  The most common size is 2.1mm inside/5.5mm outside diameter.  I will use this barrel jack for the next rev.

Label Arduino Pins

I noticed this last time but didn’t think too much about it.  The Shield does not label the Arduino pins.  This makes it difficult to see which Arduino pins do what.  The next rev will include labels for each of the Arduino pins similar to what is on an Arduino Uno.  In addition, I will clean up the Arduino pin model in the schematic so that pin labels align much better to the labels on the Arduino Uno.  When I first started using this model, I was just happy I had something that worked.  Now I am seeing the value in being as clear and obvious as possible early on :-).

Switch ADC Inputs for pH

Clearly the input for CH0+ and CH01 need to be swapped!

Add in a Test Point for VGND

I was having to share the VGND on the 8 pin connector between the circuit and a probe.  Given how much testing used VGND as ground when probing, it deserves its own test point.

TBD: Green LED Indicating Arduino Plugged In

As noted earlier, there is no need for diode (D2).  I’ll remove from the schematic.

Different Thermistor

I thought the thermistor I chose would be great because it was already covered in epoxy (digikey link).  It is too delicate.  I like the thermistors that look and feel more like a big through hole resistor.


The RGB LED is in a “tight” section in the lower right side of the board.  There is a lot of clear space near the logo. Although the RGB LED chip will no longer be near an Arduino pin, the LED will be better positioned.