I’m using a Boron to connect to an Atlas Scientific pH sensor using the Tentacle 3 HAT board. All the connections are as per the specifications I found online but the Boron is unable to listen to the sensor. This is the code I’m running and I keep getting a -1 value for Wire.read(). Please help!
Whenever experiencing difficulties communicating with an I2C device it’s advisable to check the most basic communication with an I2C scanner application.
If this doesn’t find the device chances are that your are missing the pull-up resistors on the communication lines.
To exactly understand your HW setup it’s also,good practice to provide a schematic or at least a pin connection table and the exact types of the sensor and connection board (preferable with link).
@njbsoft202
Were you able to resolve this issue?
My understanding is that the Tentacle 3 HAT is for connecting the sensors to a Raspberry Pi.
Please let us know what was the solution.
@no1089 Thanks for chiming in. I wish people who take the opportunity to tap into the vast knowledge of the experts here would also take the effort to provide feedback when their problem is solved.
I’m glad that this case was fairly straightforward.
My pleasure - I’m part of the support team, so feel free to reach out if you need help.
Tentacle actually sells a breakout that is just for the PH sensor, so you can still use a reliable probe connector, and have the supporting circuits.
I’m currently using an Argon OS1.5 with a NCD ControlEverything breakout board, Gravity Atlas Scientific V2.1board, and a ph probe. Using the 5v and attaching via the A1 Pin. I have imported the DFRobot library for pH. I’m currently getting readings in the -51 to -54 on pH with storage solution:
Voltage:11772.46
temperature:25.0^C pH:-51.26
I have setup and tested an arduino uno and everything is working. I checked and have replaced the wires. I tried changing the voltage equation to voltage = analogRead(PH_PIN)/4096.0*5000; Which obviously increases but is still in the -1 area. Once I figure this out I’m also not understanding how to send messages like arduino and calibrate the probe.
My current code
#include "DFRobot_PH.h"
//#include "EEPROM.h"
#define PH_PIN A1
float voltage,phValue,temperature = 25;
DFRobot_PH ph;
void setup()
{
Serial.begin(115200);
ph.begin();
}
void loop()
{
static unsigned long timepoint = millis();
if(millis()-timepoint>1000U){ //time interval: 1s
timepoint = millis();
//temperature = readTemperature(); // read your temperature sensor to execute temperature compensation
voltage = analogRead(PH_PIN)/1024.0*5000; // read the voltage
phValue = ph.readPH(voltage,temperature); // convert voltage to pH with temperature compensation
Serial.print("temperature:");
Serial.print(temperature,1);
Serial.print("^C pH:");
Serial.println(phValue,2);
Serial.print("Voltage:");
Serial.println(voltage,2);
//Particle.publish("phValue", String(phValue, 2));
//Particle.publish("Temperature", String(temperature, 2));
}
ph.calibration(voltage,temperature); // calibration process by Serail CMD
}
float readTemperature()
{
//add your code here to get the temperature from your temperature sensor
}
Which version are you now running - the code block you posted still uses the wrong calculation (although you got a better one in your text).
It should be
voltage = analogRead(PH_PIN) * 3300 / 4095.0;
BTW, you can simplify your print statemen this way
Serial.printlnf("Temp: %.1f °C pH: %.2f %% Voltage: %.2f mV"
, temperature
, phValue
, voltage);
However, have you tried looking into the library how the voltage and temperature readings are converted into the pH reading? That might provide some clue about the origin of the issue.
So your formula works. I'm still not sure why the test code supplied by the library is wrong though? It's the same formula as the arduino code from what I can tell.
Also I'm having problems with it locating the EEPROM.h using VSCode
In file included from src/pHSensor1.ino:3:0:
lib/DFRobot_PH/src/DFRobot_PH.h:16:5: warning: "ARDUINO" is not defined [-Wundef]
#if ARDUINO >= 100
^
src/pHSensor1.ino:4:21: fatal error: EEPROM.h: No such file or directory
Probably because the examples were not ported to reflect the differences between target platforms. While it would be nice if they were, knowing the basic characterisitics of any given target platform should enable anybody to adapt the samples accordingly.
EEPROM.h is not required for Particle as it is baked into the device OS API.
This suggests that the library wasn't ported properly.
For Particle ports you'd usually see something like this
Thanks again @ScruffR! One more thing that I’m trying to understand is how to send messages to the device over serial to calibrate the pH Sensor. Is there a way to do this?
Can you specify that a bit more?
What do you want to send to the Boron and what should it do with the data?
Have you considered using the core features that makes Particle devices stand for - e.g. sending the data to the Boron not over USB but the cloud?
You can send commands in the serial monitor to execute the calibration.
Serial Commands:
enterph -> enter the calibration mode
calph -> calibrate with the standard buffer solution, two buffer solutions(4.0 and 7.0) will be automaticlly recognized
exitph -> save the calibrated parameters and exit from calibration mode
With Arduino you can send the commands via the serial monitor. I’ve tried calling the functions via the Particle CLI.
particle call <device> function calibration()
It gives me:
function>
When I enter ‘enterph’ or the other commands nothing seems to happen. So I thought I’d check if I’m missing something before I try to create specific Particle cloud functions.
I haven't had a look at the Arduino code for this device, but in order to forward any thing to the sensor you first need to catch it from somewhere (anywhere).
An Arduino does - out the box - not offer any means to receive data other than via serial.
However Particle devices do.
I'd start with something like this
const char cmdList[][16] = // list of all possible commands
{ "n/a" // for ease of use when parsing
, "enterph"
, "calph"
, "exitph"
, ...
};
const int maxCmd = sizeof(cmdList) / sizeof(cmdList[0]); // number of defined commands
int newCmd = 0;
void setup() {
Particle.function("sendCommand", sendCmd); // hook-up function handler
...
}
void loop() {
switch(newCmd) { // select command branches
case 0:
// do nothing
break;
case 1: // enterph
// do what's needed
break;
case 2: // calph
// do what's needed
break;
case 3: // exitph
// do what's needed
break;
...
default:
Log.warn("command '%d' not in list", newCmd);
break;
}
newCmd = 0; // command has been treated - clear
}
int sendCmd(const char* cmd) {
// find sent command in list
for (newCmd = 0; strcmp(cmd, cmdList[newCmd]) && newCmd < maxCmd; newCmd++);
if (newCmd >= maxCmd) {
newCmd = 0;
Log.warn("command '%s' not in list", cmd);
}
return newCmd;
}