I just finished testing out the pH probe connection with the shield.

Healthy pH Shield With Probes

The Goal

The goal of this post is to discuss how I tested the MCP3901 and document what I have learned about communicating with it from an Arduino.

Thanks To Those That Go Before

I was more comfortable working with the SPI on the MCP3901 since this is the chip Chris Gammell used in Section 1B of the Contextual Electronics course.  In the course, he walked us through sending/receiving ADC values and converting these to digital volt readings.  Heck, he provided me with all the knowledge I needed!  

I spent a lot of time understanding Ryan’s (Sparkys Widgets) design of the minipH and minieC break out boards for the Arduino.  His schematics got me craving to understand more about electronics.  In addition, Ryan eagerly shares what he knows.  This is totally amazing.  The Healthy Shields are an evolution from the minipH and minieC shields.   It is my way on testing what I have learned from Ryan’s work, with the added benefit that I will use these shields to help grow vegetables (hydroponically).   Ryan really knows his stuff.  I highly recommend his products!

What to Solder

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

Digital Access Schematic


Rather than list code here, I uploaded the code I used for testing to the GitHub repository.  The code is not complete.  The only code that should be considered “working” is the code that tests the SPI bus.

Healthy pH SPI Test Setup

(Rather messy?) Test Setup


Config Registers

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

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

Change Default Config 1 Settings

 Looking at Register 7-6 of the data sheet,

Config Registers Table

Config1’s defaults set the ADC bit width to 16 and the OSR (Over Sampling Ratio) to 64.

I believe I’ll get the “best” readings with an ADC bit width of 24 and an OSR of 256.  Thus, future tests will set Config 1 to 0011 1100 (0x3C).

Digital Voltage Values

I was thinking the “easiest” way to test the analog voltage going in with values going out was to use an AWG (discussed in last post) to generate an incoming sine wave then see what the MCP3901 gave as the digital voltage result. 

Chris recommended a much better testing approach.  Send in various DC values.  So I set 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.  Bummer! The values I was getting were significantly higher than the values read by my DMM.  The reason:

Simpson DOH


D’OH…RTFM.  Now this is doubly sad on my part – Besides being stated in the data sheet, Chris had explained this in Contextual Electronics Session 1B!  Epic failure to research on my part.  HAD I watched the Contextual Electronics videos where Chris was testing the MCP3901 in the BenchBudEE, I would have known that calculating the digital voltage is not what is was for the minipH, e.g.: 

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

where vRef’s typical value is 2.37 (MCP3901 data sheet).  But as pointed out in figure 5.3 of section 5.6 (ADC Output Coding) of the data sheet ****read section 5.6 carefully! *** the equation to convert a 24 bit ADC value in either CH 0 or CH 1 is:

float volts = (float)adc_value/(G*8388608*3)*vRef

The default for the gain is 1 (see register 7.4), which is what I have designed for.

Simpson DOH

D’OH…figure out the Vpp the ADC can handle before buying the chip.  I went into this test thinking the ADC had a Vpp of 0 – 5V.  WRONG!  As stated in section 5.6:

In case of positive saturation (CHn+ – CHn- > VREF/3),the output is locked to 7FFFFF for 24 bit mode…In case of negative saturation (CHn+- CHn- <-VREF/3)

This means the maximum  voltage that can be translated to a digital representation is +/- 2.37 / 3 = +/-.79V.  And indeed, this was true in tests I ran.  Values coming in from the pH probe will range ~ +/- .415.  Within the range for this ADC.  So that’s good!

ACVRange of ph


The process of going from an analog to digital signal involves chopping up the analog signal into steps.  


VRef and resolution define the step size.  The lower the VRef / the higher the resolution means more steps which means a higher accuracy translating an analog value into a digital value.  As noted earlier, I’ll use 24-bit resolution, the VRef of 2.37.

Voltage Readings

I took 10 different voltage readings by adjusting the potentiometer such that the DMM was < .79V.  Here are the results I got:

ADC Value ADC -> Volt DMM Scope ADC-> Volt – DMM
5026041 0.47 0.458 0.462 0.012
3819007 0.36 0.347 0.349 0.013
1053439 0.1 0.082 0.082 0.018
6307071 0.59 0.58 0.584 0.01
  0.73 0.714 0.724 0.016
6669600 0.63 0.615 0.618 0.015
4377335 0.41 0.399 0.4 0.011
2458268 0.23 0.216 0.215 0.014
757361 0.07 0.055 0.054 0.015
2514621 0.24 0.221 0.221 0.019
      average: 0.0143

 I compared the voltage calculated from the ADC value with readings from my DMM and scope.  While the DMM and scope readings vary within less than 4mV, the ADC calculated voltage averaged a positive difference of 14.3mV.  Many posts ago I noted the pH reading resolution I am shooting for is .1.  Since there is a voltage change of 59.16mV per pH unit, a resolution of .1 would mean a voltage change of 5.92mV – which is slightly less than half of what I noted as the difference between the ADC calculated voltage value and the voltage value read from the DMM.  While I need to check the circuit for noise, this still could be ok since the readings are calibrated to the circuit.

When I woke up in the morning, I added averaging and taking the STDEV on n readings.  With 100 readings, I consistently got the same reading with a STDEV of 0.  I expected to see some variability.  The ADC values were not the same, but very close.

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.
RGB LED – not sure which way is cathode on the layout…the footprint doesn’t give an indication.

What’s Next

On to testing the temperature probe and pumps!  Also – just got email the Healthy EC Dev-Rev1 PCBs are being shipped.  So off I go.


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