The BNC sensor shield allows you to hook up pH and ORP probes to your arduino. Measure acids and bases with ease and using the 2 calibration trimpots (slope and gain) it's a snap to setup.
This documentation is for the BNC Sensor Shield (Assembed) and the BNC Sensor Shield PCB
You can also find additional posts about this shield here: posts tagged with BNC Sensor Shield
Parts Needed:
| Part | Digikey # | Sparkfun # | # Required |
| 0.1uf cap | 478-3192-ND | 8 | |
| 1M ohm pot | 3006P-105LF-ND | 1 | |
| 1000uf x 6.3v | P5115-ND | 2 | |
| TL072 | 497-2201-5-ND | 1 | |
| TC1121 | TC1121CPA-ND | 1 | |
| BNC Connector | A32253-ND | 1 | |
| 10K Pot | SP043-10K-ND | 1 | |
| 41.2K resistor | 41.2KXBK-ND | 1 | |
| 1K Resistor | RNF14FTD1K00 | 3 | |
| 10K Resistor | RNF14FTD10K0CT-ND | 6 | |
| 100K Resistor | RNF14FTD100KCT-ND | 1 | |
| Board | 1 | ||
| 8 Pin Header | PRT-09279 | 2 | |
| 6 Pin Header | PRT-09280 | 2 | |
| Reset Button | COM-09190 | 1 | |
| Jumper | S900-ND | 1 | |
| Headers | WM6436-ND | 1 | |
| 5.1V Zener Diode | Any will do | 1 | |
| MCP3202** | s |
**Take note that the MCP3202 doesn't come standard with the shield. In order to use it you'll need an MCP3202 + 2 X 6 pin headers (in order to let you choose CS)
Sample Code
This sample code takes 50 samples from the analog pin and averages them out. It then converts that analog value into a millivolt reading. Lastly, we figure out the pH by dividing by the gain, dividing by 59.2 (millivolts per pH step) and adding 7 to that total. For acids you may need to subtract 7 (need to check on that). Watch the configuration video for how to configure the shield as it's been updated to provide more detail.
// change this to whatever pin you've moved the jumper to
int ph_pin = 5;
//int for the averaged reading
int reading;
//int for conversion to millivolts
int millivolts;
//float for the ph value
float ph_value;
int i;
// highly recommended that you hook everything up and check the arduino's voltage with a multimeter.
// It doesn't make that much of a difference, but
// if you want it to be highly accurate than do this step
#define ARDUINO_VOLTAGE 5.0
// PH_GAIN is (4000mv / (59.2 * 7)) // 4000mv is max output and 59.2 * 7 is the maximum range (in millivolts) for the ph probe.
#define PH_GAIN 9.6525
void setup() {
Serial.begin(9600);
}
void loop() {
//take a sample of 50 readings
reading = 0;
for(i = 0; i < 50; i++) {
reading += analogRead(ph_pin);
delay(10);
}
//average it out
reading /= i;
//convert to millivolts. remember for higher accuracy measure your arduino's
//voltage with a multimeter and change ARDUINO_VOLTAGE
millivolts = ((reading * ARDUINO_VOLTAGE) / 1024) * 1000;
ph_value = ((millivolts / PH_GAIN) / 59.2) + 7;
Serial.print("pH= ");
Serial.println(ph_value);
delay(500);
}Sample Code w/ Temperature Compensation
Coming Soon
Configuration Video
Usage Video
Eagle Files:
Can be downloaded here
License
Released under the TAPR Open Hardware License
Comments
Hi, Very nice work you have
Hi Tim, I'll hopefully get
Hi Tim,
I'll hopefully get kits up shortly. Just need to find time lol.
Hi i friend of my ordered a
Hi, Very nice work, but it's
You could use the i2c bus to
Great shield! I just got mine
Great shield! I just got mine pre-assembled and am working on a controller for a freshwater aquarium. I'd like to measure a pH range from 6-7.5, but it looks like Arduino's inability to read negative voltages makes this a huge problem with only one probe. Am I correct that, out of the box, this shield can measure from pH 0-7 OR 7-14?
Do you have any suggestions how I might be able to modify the code (or augment the electronics) to read across the 7 pH boundary without adding a second probe? It feels like there's room to be clever here but my understanding of the circuit and probe operation is too crude to puzzle it out.
Any thoughts greatly appreciated!
P.S. the image scroller at the top of the page is a bit distracting when you've scrolled past it. Since many images have different heights, it keeps resizing, making the videos and comment box constantly bounce up and down. I'm dizzy! :)
Hello Andrew,
Hello Andrew,
I was wondering if you got the time to program the temperature compensation in to the sketch?
I'm currently building my own Hydroponics controller with Arduino and am a bit stuck on the conversion for temperature.
pH(0.0178 * sensorValue - 1.889)Your Eagle files are a BIG help though... Thank you for making everything open source!!
With kind reagards,
Billie
"For acids you may need to
"For acids you may need to subtract 7 (need to check on that)."
Did you check on that yet? What should the pH_Value math be to get acid readings to work (0-7 pH).
Hello all right?
Hello all right?
PH electrode which I could use for this experiment.
If you can help me?
Thank you.
Great Product, but I would
Great Product, but I would like to point out a couple of things in the code.
for(i = 1; i < 50; i++) {
should read
for(i = 0; i < 50; i++) {
This will take 50 readings, i 0 to 49, and still leave i at 50 for your averaging line.
The current code takes 49 samples but divides by 50.
Also the variable reading should be an unsigned int to avoid overflowing into a negative number since the maximum reading of 1024 * 50 is above the 32767 maximum for int.
Here is the code I am using,
Here is the code I am using, created an Analog_Sample function to average the readings since I am going to be using multiple sensors in my project.
#define PH_PIN 5
#define ARDUINO_VOLTAGE 4.99
float ph_value;
void setup() {
Serial.begin(9600);
}
void loop() {
read_ph();
Serial.print("pH= ");
Serial.println(ph_value);
delay(500);
}
///////////////////////////////////////////////////////////////
// Calculates ph_value from average sensor reading
// Sensor reads linearly from ph 7-14 from 0-4v which results
// in a value of 571.428mv per ph point.
///////////////////////////////////////////////////////////////
void read_ph() {
int ph_reading;
int ph_millivolts;
ph_reading = Analog_Sample(PH_PIN);
ph_millivolts = ((ph_reading * ARDUINO_VOLTAGE) / 1024) * 1000;
ph_value = (ph_millivolts / 571.428) + 7;
}
int Analog_Sample(int PIN) {
int i;
unsigned int reading = 0;
for(i = 0; i < 50; i++) {
reading += analogRead(PIN);
delay(10);
}
reading /= i;
return reading;
}
@Justin thanks a bunch! I
Add new comment