Arduino Code for ESP8266 used on Plant Sensor

Arduino Code for ESP8266 used on Plant Sensor

Please read Liability Disclaimer and License Agreement CAREFULLY

Revolutionize your plant care with this Arduino code for ESP8266 used on a plant sensor.

This code is measuring vital plant health indicators like soil moisture, temperature, UV and light and humidity in air.

With user-friendly instructions and customizable settings, the code is the perfect tool for hobbyists and professionals alike.

Read further to learn more and take your plant care to the next level.

This is the code that runs on the ESP8266 connected to 

#include <ESP8266WiFi.h>
#include "PubSubClient.h" // Connect and publish to the MQTT broker

enum data_type {

//Sensors on board
//#define has_BMP280		//Bosch Absolute barometric pressure and temperature - comment if not used
//#define has_SI7006		//Silicon Labs Humidity and temperature sensor - comment if not used
//#define has_TCS3471_a	//AMS Color sensor - comment if not used
//#define has_TCS3471_b	//AMS Color sensor - comment if not used
//#define has_VEML6070	//Vishay UV sensor - comment if not used

//Sensor location
#define sen_location  "outdoor"
#define sen_ID        "S1"
#define clientID      (sen_ID sen_location) // MQTT client ID
#define dataLen       0
//MQTT topics - comment the defines not used on specific board configuration
//Battery level
#define BL_topic sen_location "/" sen_ID "/bl"

#ifdef BL_topic
	const uint8_t BL_len = 4;
	const uint8_t BL_len = 0;

#ifdef has_BMP280
	#define AP_topic sen_location "/" sen_ID "/ap"
	const uint8_t BMP280_len = 4;
	const uint8_t BMP280_len = 0;

#ifdef has_SI7006
	#define AH_topic sen_location "/" sen_ID "/ah"
	const uint8_t SI7006_len = 4;
	const uint8_t SI7006_len = 0;

#ifdef has_SI7006 || has_BMP280
	//If we use only BMP280 or SI7006 publish only one temperature
	//If we use both the we publish the average
	#define AT_topic sen_location "/" sen_ID "/at"
	const uint8_t AT_len = 4;
	const uint8_t AT_len = 0;

#ifdef has_TCS3471_a
  #define R_topic0 sen_location "/" sen_ID "/r0"
  #define G_topic0 sen_location "/" sen_ID "/g0"
  #define B_topic0 sen_location "/" sen_ID "/b0"
  #define C_topic0 sen_location "/" sen_ID "/c0"
  const uint8_t TCS3471_a_len = 8;
	const uint8_t TCS3471_a_len = 0;

#ifdef has_TCS3471_b
  #define R_topic1 sen_location "/" sen_ID "/r1"
  #define G_topic1 sen_location "/" sen_ID "/g1"
  #define B_topic1 sen_location "/" sen_ID "/b1"
  #define C_topic1 sen_location "/" sen_ID "/c1"
  const uint8_t TCS3471_b_len = 8;
	const uint8_t TCS3471_b_len = 0;

#ifdef has_VEML6070
  #define UV_topic sen_location "/" sen_ID "/uv"
  const uint8_t VEML6070_len = 8;
	const uint8_t VEML6070_len = 0;

//Up to 6 soil humidity sensors
#define SH0_topic sen_location "/" sen_ID "/sh0"
//#define SH1_topic sen_location "/" sen_ID "/sh1"
//#define SH2_topic sen_location "/" sen_ID "/sh2"
//#define SH3_topic sen_location "/" sen_ID "/sh3"
//#define SH4_topic sen_location "/" sen_ID "/sh4"
//#define SH5_topic sen_location "/" sen_ID "/sh5"
#ifdef SH0_topic
  const uint8_t SH0_len = 4;
	const uint8_t SH0_len = 0;
#ifdef SH1_topic
  const uint8_t SH1_len = 4;
	const uint8_t SH1_len = 0;
#ifdef SH2_topic
  const uint8_t SH2_len = 4;
  const uint8_t SH2_len = 0;
#ifdef SH3_topic
  const uint8_t SH3_len = 4;
  const uint8_t SH3_len = 0;
#ifdef SH4_topic
  const uint8_t SH4_len = 4;
	const uint8_t SH4_len = 0;
#ifdef SH5_topic
  const uint8_t SH5_len = 4;
	const uint8_t SH5_len = 0;

const uint8_t  dLen = (BL_len + BMP280_len + SI7006_len + AT_len + TCS3471_a_len + TCS3471_b_len + VEML6070_len + SH0_len + SH1_len + SH2_len + SH3_len + SH4_len + SH5_len);
// WiFi 80:7d:3a:3e:50:f7
const char *ssid     		= "xxxx"; //Your 2.4GHz network name
const char *password	= "yyyy"; //Your 2.4GHz network password
// Mosquitto MQTT server credentials
const char* mqtt_server		= "zz.zz.zz.zz";// IP of the MQTT broker
const char* mqtt_username	= "JohnDoe"; // MQTT username
const char* mqtt_password	= "JohnDoe!"; // MQTT password

const uint8_t msTime = 50;
//The end marker is not added to buffer
//Blue pill will transmit 34 bytes including markers

BL_topic		0
AP_topic		4
AT_topic		8
AH_topic		12
SH0_topic		16
SH1_topic		20
SH2_topic		24
SH3_topic		28
SH4_topic		32
SH5_topic		36
UV_topic		40
has_TCS3471_a	42
	R_topic0	42
	G_topic0	44
	B_topic0	46
	C_topic0	48
has_TCS3471_b	50
	R_topic1	50
	G_topic1	52
	B_topic1	54
	C_topic1	56

const uint8_t BL_pos = 0;//Battery level
const uint8_t AP_pos = 0;//Air pressure
const uint8_t AT_pos = 0;//Air Temperature
const uint8_t AH_pos = 0;//Air humidity
const uint8_t SH0_pos = 0;//Soil humidity
const uint8_t SH1_pos = 0;//Soil humidity
const uint8_t SH2_pos = 0;//Soil humidity
const uint8_t SH3_pos = 0;//Soil humidity
const uint8_t SH4_pos = 0;//Soil humidity
const uint8_t SH5_pos = 0;//Soil humidity
const uint8_t UV_pos = 0;//UV
const uint8_t R0_pos = 0;//Red sensor 1
const uint8_t G0_pos = 0;//Green sensor 1
const uint8_t B0_pos = 0;//Blue sensor 1
const uint8_t C0_pos = 0;//Clear sensor 1
const uint8_t R1_pos = 0;//Red sensor 2
const uint8_t G1_pos = 0;//Green sensor 2
const uint8_t B1_pos = 0;//Blue sensor 2
const uint8_t C1_pos = 0;//Clear sensor 2

const uint8_t sMarker = 60;//<
const uint8_t eMarker = 62;//>
//Messages we get from BP
const uint8_t BP_SYNK_1     = 125;//To get from BP when is ready for first synk
const uint8_t BP_SYNK_2     = 126;//To get from BP when is ready for second synk
//Messages we send to BP
const uint8_t ESP_READY     = 100;//To send to BP when ESP is ready, first synk
const uint8_t ESP_WAIT      = 101;//To send to BP when ESP is ready, second synk
const uint8_t ESP_DATA_I    = 102;//To confirm the 32 bytes received
const uint8_t ESP_HTTP_IR   = 103;//To send to BP when HTTP request is invalid
const uint8_t ESP_HTTP_RF   = 104;//To send to BP when HTTP request failed
const uint8_t ESP_DATA_O    = 105;//To send to BP when data is received
const uint8_t ESP_HTTP_OK   = 106;//To send to BP when HTTP request is OK

const uint8_t ESP_SHORT		= 0;//We are expecting a short message
const uint8_t ESP_LONG		= 1;//We are expecting a Long message
uint8_t ESP_EXPECT			  = 0;//Variable to hold the size of expected message

//array to holde the data received from ESP
uint8_t BP_DATA[dLen];
//variables that will hold the sensors values receive from ESP

boolean ESP_Reading = false;
uint8_t ESP_Msg = 0;
uint8_t MsgLen = 0;
uint32_t MsgTime = 0;

WiFiClient wifi_Client;
PubSubClient mqtt_Client(mqtt_server, 1883, wifi_Client); 
float battery = 1.0f; //for testing
void setup(){
  pinMode(0, OUTPUT);
  //Serial.setRxBufferSize(256); //require ESP8266 >= 2.4.0
  //Static IP address configuration
  IPAddress staticIP(10, 0, 1, 125); //ESP static ip
  IPAddress gateway(10, 0, 1, 1);   //IP Address of your WiFi Router (Gateway)
  IPAddress subnet(255, 255, 255, 0);  //Subnet mask
  IPAddress dns(10, 0, 1, 1);  //DNS
  //Static IP address configuration
  WiFi.config(staticIP, subnet, gateway, dns);
  WiFi.begin(ssid, password);
  MsgTime = millis();
  while (WiFi.status() != WL_CONNECTED) {
  // Connect to MQTT Broker
  if (mqtt_Client.connect(clientID, mqtt_username, mqtt_password)) {
    Serial.println("Connected to MQTT Broker!");
  else {
    Serial.println("Connection to MQTT Broker failed...");
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.print("WiFi connected in ");
  Serial.print((millis() - MsgTime)/1000);
  Serial.println(" seconds");
  Serial.print("IP address: ");
  //we are expecting short messages
  sendDataToBluePill(ESP_READY);//let Blue pill know that ESP is ready to first synk
  //wait for BluePill to respond
//  while(ESP_Msg != BP_SYNK_1){
//    CheckBluePillData();
//  }
  MsgTime = millis();

void loop() {
//get in synk with BP
//  while(ESP_Msg != BP_SYNK_2){
//    CheckBluePillData();
//	  //sendDataToBluePill(ESP_WAIT);//let Blue pill know that ESP is ready to get 32 bytes
//  }
//  //wait to get the 32bytes from BP
//  while(ESP_Msg != ESP_DATA_I){
//    //Check data fron serialport
//    CheckBluePillData();
//  }
//  //turn ON the LED for transmission
//  digitalWrite(LED_BUILTIN, LOW); 
  //for(uint8_t i = 0; i < 100; i++){
  //  sendDataToBluePill(ESP_DATA_O);
  //prepare the data to be sent to server
  //R, G, B, C bytes for each value, so 8 bytes per sensor
  //UV 2 bytes 
  //Pressure, temperature, humidity, temperture, soil humidity will have 4 bypes per value
  if(millis() > MsgTime){
    battery += 0.1f;
    if(battery > 100.0f) battery = 1.0f;
    String val = String(battery);
    if (!mqtt_Client.publish(BL_topic, String(val).c_str())) {
      mqtt_Client.connect(clientID, mqtt_username, mqtt_password);
      delay(10); // This delay ensures that client.publish doesn't clash with the client.connect call
      mqtt_Client.publish(BL_topic, String(val).c_str());
    Serial.print("Sent : ");Serial.println(val);
    MsgTime = millis() + 10000;
  //Turn OFF the LED to signal end transmission
  //digitalWrite(LED_BUILTIN, HIGH);
  //Serial.print("T2=");Serial.println(millis() - MsgTime);
//  while(1) {
//    sendDataToBluePill(ESP_Msg);
//  }

void sendInterrupt(void){
  digitalWrite(0, HIGH);
  digitalWrite(0, LOW);
void sendDataToBluePill(uint8_t data){
  uint8_t arrBP[3] = {sMarker, data, eMarker};
  Serial.write(arrBP, 3);

void CheckBluePillData() {
  // receive data from BluePill and save it into BP_DATA
  if(Serial.available() > 0) {
    uint8_t DataIn =;
    // the order of these IF clauses is significant 
    //Do we have the end marker?
    if (DataIn == eMarker) {
      //we have the end marker,do we expect more data?
      //if we expect 3 bytes then
      if(!ESP_EXPECT) {
        //if we have 1 byte in the message
        if(MsgLen == 1) {
          ESP_Reading = false;
          ESP_Msg = BP_DATA[0];
          //Serial.print("3Bytes in:");
          //Serial.println(millis() - MsgTime);
      } else {
        //if we have 32 bytes in buffer
        if(MsgLen == dLen) {
          ESP_Reading = false;
          ESP_Msg = ESP_DATA_I;
          //Serial.print("32Bytes in:");
          //Serial.println(millis() - MsgTime);
    //if we are reading
    if(ESP_Reading) {
      BP_DATA[MsgLen] = DataIn;
      MsgLen ++;
    //if we read the start marker and we are not reading
    if ((DataIn == sMarker) && !ESP_Reading) { 
      MsgLen = 0; 
      ESP_Reading = true;
      //MsgTime = millis();

void SendData() {
	//Publishto the MQTT Broker
	//Battery level
	#ifdef BL_topic
		publishMQTT(BL_topic, BL_pos, float_data);
	//Air Pressure
	#ifdef AP_topic
		publishMQTT(AP_topic, AP_pos, float_data);
	//Air Temperature
	#ifdef AT_topic
		publishMQTT(AT_topic, AT_pos, float_data);
	//Air Humidity
	#ifdef AH_topic
		publishMQTT(AH_topic, AH_pos, float_data);
	//Soil humidity 0
	#ifdef SH0_topic
		publishMQTT(SH0_topic, SH0_pos, float_data);
	//Soil humidity 1
	#ifdef SH1_topic
		publishMQTT(SH1_topic, SH1_pos, float_data);
	//Soil humidity 2
	#ifdef SH2_topic
		publishMQTT(SH2_topic, SH2_pos, float_data);
	//Soil humidity 3
	#ifdef SH3_topic
		publishMQTT(SH3_topic, SH3_pos, float_data);
	//Soil humidity 4
	#ifdef SH4_topic
		publishMQTT(SH4_topic, SH4_pos, float_data);
	//Soil humidity 5
	#ifdef SH5_topic
		publishMQTT(SH5_topic, SH5_pos, float_data);
	//UV level
	#ifdef UV_topic
		publishMQTT(UV_topic, UV_pos, int_data);
	//R0 level
	#ifdef R_topic0
		publishMQTT(R_topic0, R0_pos, int_data);
	//G0 level
	#ifdef G_topic0
		publishMQTT(G_topic0, G0_pos, int_data);
	//B0 level
	#ifdef B_topic0
		publishMQTT(B_topic0, B0_pos, int_data);
	//C0 level
	#ifdef C_topic0
		publishMQTT(C_topic0, C0_pos, int_data);
	//R1 level
	#ifdef R_topic1
		publishMQTT(R_topic1, R1_pos, int_data);
	//G1 level
	#ifdef G_topic1
		publishMQTT(G_topic1, G1_pos, int_data);
	//B1 level
	#ifdef B_topic1
		publishMQTT(B_topic1, B1_pos, int_data);
	//C1 level
	#ifdef C_topic1
		publishMQTT(C_topic1, C1_pos, int_data);

void publishMQTT(char* topic, uint8_t position, data_type myType){
  String val;
  if(!myType) {
    val = String(getInt(position));
  }else {
    val = String(getFloat(position));
  if (!mqtt_Client.publish(topic, String(val).c_str())) {
    mqtt_Client.connect(clientID, mqtt_username, mqtt_password);
    delay(10); // This delay ensures that client.publish doesn't clash with the client.connect call
    mqtt_Client.publish(topic, String(val).c_str());
//Serial.flush() function does not empty the input buffer. It is only relevant when the Arduino
//is sending data and its purpose is to block the Arduino until all outgoing the data has been sent.
void ClearBuffer(){
  while (Serial.available() > 0) {;

void Blink_Led(void) {
  digitalWrite(LED_BUILTIN, LOW);
  delay (msTime);
  digitalWrite(LED_BUILTIN, HIGH);
  delay (msTime);

uint16_t getInt(uint8_t pos){
  uint16_t retVal = ((uint16_t)BP_DATA[pos] << 8); 
  retVal |= BP_DATA[pos + 1];
  return retVal;

float getFloat(uint8_t pos){
  int32_t newVal = ((uint32_t)BP_DATA[pos] << 24);
  newVal |= ((uint32_t)BP_DATA[pos + 1] << 16); 
  newVal |= ((uint32_t)BP_DATA[pos + 2] << 8); 
  newVal |= BP_DATA[pos + 3]; 
  return (float)newVal/100.0f;

Comments powered by CComment

Who’s online

We have 146 guests and no members online