ESP32 and MQTT Setup/Questions - PH Data

Home Assistant automation projects, questions, etc. go here.
jaysal
LED Enthusiast
LED Enthusiast
Reactions:
Posts: 75
Joined: Sat May 30, 2020 7:49 am

Hello, I was wondering if someone can help me out publishing data to my MQTT broker running in HA. I have other Tasmota devices communicating with the broker so I know that side is setup correctly. I now have an ESP32 that is running code (Using Arduino IDE) to read data from a DFRobot PH Sensor. I just need help adding the code for the MQTT connecting and publishing the PH Values every 5 seconds or so. Here is what I have so far. I attempted to send "Hello" at the bottom of the code as a test but nothing seems to come over to HA. Any help would be greatly appreciated.

I can see the ph data come across in the serial monitor.

Code: Select all

#include <Arduino.h>
#include "DFRobot_ESP_PH_WITH_ADC.h"
#include "OneWire.h"
#include "DallasTemperature.h"
#include "Adafruit_ADS1015.h"
#include "EEPROM.h"
#include "WiFi.h"
#include <PubSubClient.h>




const char* ssid = "SSID"; //Enter SSID
const char* password = "PASSWORD"; //Enter Password
const char* mqtt_server = "192.168.1.70";
const int mqtt_port = 1883;
const char* mqttUser = "USER";
const char* mqttPassword = "PASS";

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE  (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;


#define ONE_WIRE_BUS 15
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);



DFRobot_ESP_PH_WITH_ADC ph;
Adafruit_ADS1115 ads;

float voltage, phValue, temperature = 25;

float readTemperature()
{
  //add your code here to get the temperature from your temperature sensor
  sensors.requestTemperatures();
  return sensors.getTempCByIndex(0);
}

void setup()
{
  Serial.begin(115200);
  EEPROM.begin(32);//needed EEPROM.begin to store calibration k in eeprom
  ph.begin();
  sensors.begin();
  ads.setGain(GAIN_ONE);
  ads.begin();
  WiFi.begin(ssid, password);
  Serial.println("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();


}

void loop()
{
  static unsigned long timepoint = millis();
  if (millis() - timepoint > 1000U) //time interval: 1s
  {
    timepoint = millis();
    /**
     * index 0 for adc's pin A0
     * index 1 for adc's pin A1
     * index 2 for adc's pin A2
     * index 3 for adc's pin A3
    */
    voltage = ads.readADC_SingleEnded(1) / 10; // read the voltage
    Serial.print("voltage:");
    Serial.println(voltage, 4);

    temperature = readTemperature(); // read your temperature sensor to execute temperature compensation
    Serial.print("temperature:");
    Serial.print(temperature, 1);
    Serial.println("^C");

    phValue = ph.readPH(voltage, temperature); // convert voltage to pH with temperature compensation
    Serial.print("pH:");
    Serial.println(phValue, 4);
  }
  ph.calibration(voltage, temperature); // calibration process by Serail CMD
  
  client.publish("ESP32", "Hello");
  client.subscribe("ESP32");
  delay(5000);
  
}

Shimbob
LED Wizard
LED Wizard
Reactions:
Posts: 642
Joined: Mon Nov 27, 2017 11:29 pm

Looks like you're not setting up mqtt before using it.
There's some stuff that goes into setup(), pick apart my sketch for the mqtt bits.
jaysal
LED Enthusiast
LED Enthusiast
Reactions:
Posts: 75
Joined: Sat May 30, 2020 7:49 am

Shimbob wrote:
Sun Jan 10, 2021 7:23 am
Looks like you're not setting up mqtt before using it.
There's some stuff that goes into setup(), pick apart my sketch for the mqtt bits.
Hey Shimbob,yes you are correct. I think I am getting closer now, I can publish a static text to Node-Red every 5 seconds but now when I try to send over a float value I get an error while trying to complie.
Here is the updated code.

Code: Select all

#include <Arduino.h>
#include "DFRobot_ESP_PH_WITH_ADC.h"
#include "OneWire.h"
#include "DallasTemperature.h"
#include "Adafruit_ADS1015.h"
#include "EEPROM.h"
#include "WiFi.h"
#include <PubSubClient.h>

const char* ssid = "SSID";
const char* password = "PASS";
const char* mqttServer = "192.168.1.70";
const int mqttPort = 1883;
const char* mqttUser = "user";
const char* mqttPassword = "pass";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

//GPIO where the DS18B20 is connected to
#define ONE_WIRE_BUS 15
//Setup a onWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
//Password onewire to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);



DFRobot_ESP_PH_WITH_ADC ph;
Adafruit_ADS1115 ads;

float voltage, phValue, temperature = 25;

float readTemperature()
{
  //add your code here to get the temperature from your temperature sensor
  sensors.requestTemperatures();
  return sensors.getTempCByIndex(0);
}

void setup()
{
  Serial.begin(115200);
  EEPROM.begin(32);//needed EEPROM.begin to store calibration k in eeprom
  ph.begin();
  sensors.begin();
  ads.setGain(GAIN_ONE);
  ads.begin();
  
//Connect to WiFi
WiFi.begin(ssid, password);
Serial.println("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
 
Serial.println("Connected to the WiFi network");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
 
client.setServer(mqttServer, mqttPort);
 
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
 
if (client.connect("ESP32Client", mqttUser, mqttPassword )) {
 
Serial.println("connected");
 
} else {
 
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);


}

void loop() {
  
  static unsigned long timepoint = millis();
  if (millis() - timepoint > 1000U) //time interval: 1s
  {
    timepoint = millis();
    /**
     * index 0 for adc's pin A0
     * index 1 for adc's pin A1
     * index 2 for adc's pin A2
     * index 3 for adc's pin A3
    */
    voltage = ads.readADC_SingleEnded(1) / 10; // read the voltage
    Serial.print("voltage:");
    Serial.println(voltage, 4);

    temperature = readTemperature(); // read your temperature sensor to execute temperature compensation
    Serial.print("temperature:");
    Serial.print(temperature, 1);
    Serial.println("^C");

    phValue = ph.readPH(voltage, temperature); // convert voltage to pH with temperature compensation
    Serial.print("pH:");
    Serial.println(phValue, 4);
  }
  ph.calibration(voltage, temperature); // calibration process by Serail CMD
//Send data to Node-Red every 5 seconds  
client.publish("esp32/esp32ph", phValue);
delay(5000);
  
}
IDE Error.png
Shimbob
LED Wizard
LED Wizard
Reactions:
Posts: 642
Joined: Mon Nov 27, 2017 11:29 pm

You're missing two closing curly brackets in your setup(), try this:

Code: Select all

void setup()
{
  Serial.begin(115200);
  EEPROM.begin(32);//needed EEPROM.begin to store calibration k in eeprom
  ph.begin();
  sensors.begin();
  ads.setGain(GAIN_ONE);
  ads.begin();
  
  //Connect to WiFi
  WiFi.begin(ssid, password);
  Serial.println("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi..");
  }
 
  Serial.println("Connected to the WiFi network");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
 
  client.setServer(mqttServer, mqttPort);
 
  while (!client.connected()) {
    Serial.println("Connecting to MQTT...");
    if (client.connect("ESP32Client", mqttUser, mqttPassword )) {
      Serial.println("connected");
    } else {
      Serial.print("failed with state ");
      Serial.print(client.state());
      delay(2000);
    }
  }
}

I'm assuming you set up your mtqq broker to have a login&password correctly?
jaysal
LED Enthusiast
LED Enthusiast
Reactions:
Posts: 75
Joined: Sat May 30, 2020 7:49 am

Shimbob wrote:
Sun Jan 10, 2021 8:49 pm
You're missing two closing curly brackets in your setup(), try this:

Code: Select all

void setup()
{
  Serial.begin(115200);
  EEPROM.begin(32);//needed EEPROM.begin to store calibration k in eeprom
  ph.begin();
  sensors.begin();
  ads.setGain(GAIN_ONE);
  ads.begin();
  
  //Connect to WiFi
  WiFi.begin(ssid, password);
  Serial.println("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi..");
  }
 
  Serial.println("Connected to the WiFi network");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
 
  client.setServer(mqttServer, mqttPort);
 
  while (!client.connected()) {
    Serial.println("Connecting to MQTT...");
    if (client.connect("ESP32Client", mqttUser, mqttPassword )) {
      Serial.println("connected");
    } else {
      Serial.print("failed with state ");
      Serial.print(client.state());
      delay(2000);
    }
  }
}

I'm assuming you set up your mtqq broker to have a login&password correctly?
Thank you! That did it, I added another curly bracket at the end of setup and it verified straight away. This is my first time working with Arduino IDE code so I have so much to learn. Yes, my MQTT broker has a login and password requirement which I did place in my code.

I am almost there, I just need to publish the phValue every 5 seconds. Here is my next error message, I think I am missing a const char ? or maybe need to convert the value into a string?
float error.PNG
Shimbob
LED Wizard
LED Wizard
Reactions:
Posts: 642
Joined: Mon Nov 27, 2017 11:29 pm

Instead of

Code: Select all

//Send data to Node-Red every 5 seconds  
client.publish("esp32/esp32ph", phValue);
something like:

Code: Select all

//Send data to Node-Red every 5 seconds  
char tempString[8];
dtostrf(phValue, 5, 3, tempString);
client.publish("esp32/esp32ph", tempString);
jaysal
LED Enthusiast
LED Enthusiast
Reactions:
Posts: 75
Joined: Sat May 30, 2020 7:49 am

Shimbob wrote:
Sun Jan 10, 2021 10:00 pm
Instead of

Code: Select all

//Send data to Node-Red every 5 seconds  
client.publish("esp32/esp32ph", phValue);
something like:

Code: Select all

//Send data to Node-Red every 5 seconds  
char tempString[8];
dtostrf(phValue, 5, 3, tempString);
client.publish("esp32/esp32ph", tempString);
Wow thank you my friend! Works like a charm. Thank you very much shimbob, I was up for hours yesterday trying to figure this out.
MQTT_PH.PNG
MQTT_PH.PNG (3.42 KiB) Viewed 1904 times
Here is my a pic of the hardware setup. The connections are soldered on the back of the board. I would like to implement an EC probe in the future however DFRobot currently does not offer an industrial version.
ph_box.jpg
Baylos
LED-Curious
LED-Curious
Reactions:
Posts: 22
Joined: Sat Nov 07, 2020 11:49 am

Looks great!

They have a guide on the webpage. If you have a look at it, look at the EC probe ;) It is from ATLAS.

https://www.dfrobot.com/blog-733.html


Greetings
jaysal
LED Enthusiast
LED Enthusiast
Reactions:
Posts: 75
Joined: Sat May 30, 2020 7:49 am

Baylos wrote:
Mon Jan 11, 2021 6:19 pm
Looks great!

They have a guide on the webpage. If you have a look at it, look at the EC probe ;) It is from ATLAS.

https://www.dfrobot.com/blog-733.html


Greetings
Thanks! haha, it is from Atlas, I just cant bring myself to pay $250 for a single EC probe. Someone else here mentioned ufire ec and ph probes, I can get an EC interface and probe from them for $100. I wonder if anyone has gone through the setup on one of those.
Baylos
LED-Curious
LED-Curious
Reactions:
Posts: 22
Joined: Sat Nov 07, 2020 11:49 am

My DFRobot EC Probe will come soon. Let's see how long the durability is.

By the way, I found a cheaper solution to make an EC probe :)

https://hackaday.io/project/7008-fly-wa ... er-arduino
Post Reply