Beehive connected

Hello everyone,

I wanted to share my beehive connected project. I want to thank all the people who helped me in the programming. My system is currently being tested out, it allows to measure the weight of my hive, the temperature and the external humidity, the voltage of the battery and the time of wifi connection. 2 small solar panels charge the battery and Deep sleep mode allows me to send the data every 33mins. Currently the weight sensor can weigh max 50Kg but I also have another system that can go up to 200Kg

Future improvement:
Taking temperatures with DS18b20 sensors in the hive, alert when the weight between 2 measurements changes up to 500gr

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <DHT.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "*****************";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "********";
char pass[] = "******";

#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"`
#include <DHT.h>
#include <HX711.h>

// Capteur de poids setting
const int SCALE_DOUT_PIN = D5;
const int SCALE_SCK_PIN = D6;
HX711 scale(SCALE_DOUT_PIN, SCALE_SCK_PIN);

float weight;
float weightCorrection = 3.98; // The weight of the hive to be removed from the result

// Capteur tempƩrature DHT22
#define DHT2PIN D7     // what pin we're connected to
#define DHT2TYPE DHT22   // DHT 22
float t2;
float h2;

// Initialize DHT sensor for normal 16mhz Arduino
DHT dht2(DHT2PIN, DHT2TYPE);

// Voltage batterie
float volt=0;
float volt1=0.00;


void getBatterie()
{
   volt = analogRead(A0);
   volt1=volt/233.8;
   Serial.print("Voltage = ");  
   Serial.println(volt1);
}
  
void getDht2Data()
{
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  h2 = dht2.readHumidity();
  // Read temperature as Celsius
  t2 = dht2.readTemperature();
  // Check if any reads failed and exit early (to try again).
  if (isnan(h2) || isnan(t2))
  {
    Serial.println("DĆ©fault DHT22");
    return;
  }
  Serial.print("Temperature = ");    
  Serial.println(t2);
  Serial.print("Humidity = ");        
  Serial.println(h2);
} 
  
void getWeight()
{
  //String weight = String(scale.get_units(1), 2);
  weight = scale.get_units(1);
  weight = weight-weightCorrection; // The new line, which deducts the correction value from the reading
  Serial.print("Weight = ");  
  Serial.println(weight);
 
}


void setup()
{
  Serial.begin(115200);
  pinMode(A0, INPUT);
  Blynk.begin(auth, ssid, pass);//starts wifi and Blynk
  Serial.println("Connected to Blynk");
  dht2.begin(); // initialize dht22
  scale.set_scale(-6000/0.128);
  //scale.tare();
}


void loop()
{
  delay(4000);
  getBatterie();
  getDht2Data();
  getWeight();
  
  //Update Blynk with the latest readings...
  Blynk.virtualWrite(V3, volt1);
  Blynk.virtualWrite(V7, t2); //virtual pin V7 DHT22
  Blynk.virtualWrite(V8, h2); // virtual pin V8 DHT22
  Blynk.virtualWrite(V4, weight);
  float wake_time = (float)millis()/float(1000); // Find out how long since the ESP rebooted
  Blynk.virtualWrite(V2, wake_time);  // Wake time
  Serial.print("Wake Time = ");
  Serial.print(wake_time);
  Serial.println(" seconds");
  Blynk.run(); // Needed to ensure that the Wake Time value is always uploaded to Blynk before going to sleep
  delay(100);
  Serial.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Going to sleep");
  Serial.println();
  ESP.deepSleep(2000 * 1000000);  // Deep Sleep for 33mins
  delay(2000);
}
13 Likes

very nice! Well done!

1 Like

Does this code work properly with Blynk?

This may solve the problem with permanent mass on the scale in between power cycles:

Yes the code is working fine since 2 weeks I have a good result with fix weight on it. But i will read your last comment. Thanks

Interesting idea, it would alert if a swarm leave the hive. I am testing the Eventor widget but then I have to keep track of the current weight and adjust it all the time.

Yes exactly, and in fact more focus between noon and 4 pm, itā€™s where the swarms leave/move out. You also made a hive system connected? me currently I have a problem of duration feeding with my battery. Even with a deep sleep of 30mins my 5000mah battery only takes 2 days ā€¦ During the deep sleep my ESP8266 consumes 14mah not due to the esp but the rest of the board!!

Yes, right now Iā€™m testing a new off grid solution with a solar panel, 20W and 12V or 5V ( aliexpress.com 20W 12V/5V Waterproof Solar Panel Kit ). I use a Wemos D1 mini Pro with external antenna and battery shield. A 18650 Li-ion 3400 mAh battery back up. Everything seems to work pretty well in my indoor test environment so far but we donā€™t have enough sunlight here this time of the year.

I have a similar system connected since almost a year on another platform. There I can check how the food is consumed and the temperature in, and outside the hive during the winter. Right now the temperature is inside + 23Ā° C and outside of -15Ā° C. The weight of the hive is now 51.8 Kg. Itā€™s 1.6 kg less than a month ago.

Blockchain now saving the worldā€™s bees - https://www.buzzcoin.info/buzzcoin-whitepaper.pdf

3 Likes

Sounds like a lot of buzzwords to me :smile:

3 Likes

My new update

Now Iā€™m using an ESP32!

3 Likes

Hi, very great project, can you share the code for ESP32 instead ESP8266 ?

Thanks Mirek

i think you need to re-write your code and optimize the loop function is overloaded , i know that you are using deep sleep but you shouldnā€™t keep the loop reading and sending data to server in every
MCU cycle when it is awake.

i suggest you need to use a bare ESP-12 with removed LED also the nodemcu has voltage regulator which use the battery even when it is almost idle

If you look at the void loop youā€™ll see that it only executes once, as the last line of the void loop puts the device to sleep. That code could be in void setup and have an empty void loop and it would work exactly the same way.

The ESP8266 code has actually moved-on quite a bit since the version that @christophebl has posted here, as he realised that Blynk.begin was causing problems if the device wasnā€™t able to connect to Wi-Fi, or Blynk, for any reason. The ESP was constantly trying to connect and draining his battery because it was never going to sleep.
We made some changes to use Blynk.connect instead, and limit the number of Wi-Fi connection attempts and added some logic that allowed a different sleep duration after a failed connection attempt.

Pete.

1 Like

thanks for this info. nice to know

Thanks Pete for your repply.

All now itā€™s working perfectly. My new project is to get data access when my beehives are in a forestā€¦ GSM can be one solution but if a have many beehive to connect it will cost a lot!!! so one solution is to use Lora. So I will try to make a Gateway with The Things Network and after try to connect my ESP32 with a Lora module. Some of you have experience with Lora?

Here my new code:

Again without the help of Pete, this code will be not working propely. Many thanks again Pete! :slight_smile:

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include "max6675.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include "HX711.h"


#define uS_TO_S_FACTOR 1000000  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 7200      /* Time ESP32 will go to sleep (in seconds) */
#define BLYNK_PRINT Serial

//capteur de poids
#define DOUT  17
#define CLK  16
//void getWeight(void);
float weight = 0;
//HX711 scale(DOUT, CLK);
float calibration_factor = - 19800;  //You must change this factor depends on your scale,sensors and etc.


// Data wire is plugged into port 4 on the Arduino or ESP32
#define ONE_WIRE_BUS 15
#define TEMPERATURE_PRECISION 100

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature DS18B20(&oneWire); 
float tempruche;

//BME sensor
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C
unsigned long delayTime;



RTC_DATA_ATTR int bootCount = 0;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
const char auth[] =            "################";
//const char blynk_server [] =   "blynk-cloud.com"; // new variable to hold the name of the Blynk server
//const int blynk_port =         8080;              // new variable to hold the port used by the Blynk server

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "#######";
char pass[] = "#######";

int wifi_connect_count = 0;          // New variable to keep track of how manty times we've tried to connect to the Wi-Fi
int wifi_connect_max_retries = 50;   // New variable to specify how many attempts we will have at connecting to the Wi-Fi

float sleep_time_minutes =     1;   // New variable - how long (in minutes) we sleep for. As this is a float variable then it can be 0.5 for a 30 second test

//thermocouple
int thermoDO = 18;
int thermoCS = 19;
int thermoCLK = 5;
MAX6675 thermo(thermoCLK, thermoCS, thermoDO);

// supply control
const int transistorPin = 14;

// Voltage batterie
#define ANALOG_PIN_0 32
int analog_value = 0;
float volt=0.00;
float volt1=0.00;


void getBatterie()
{
   analog_value = analogRead(ANALOG_PIN_0);
   Serial.println(analog_value);
   volt = analog_value;
   volt1=volt/794;
   Serial.print("Voltage = ");  
   Serial.println(volt1);
}
void getBme()
 {

  Wire.begin(); //just added
  float t = bme.readTemperature();
  float p  = (bme.readPressure() / 100.0F);
  float h =  bme.readHumidity();
  float a =  bme.readAltitude(SEALEVELPRESSURE_HPA);
  if (isnan(t) || isnan(p) || isnan(h) || isnan(a)) {
    Serial.println("Failed to read from BME sensor!");
    return;
  }
    Serial.print("Temperature = ");
    Serial.print(t);
    //Serial.print(bme.readTemperature());
    Serial.println(" *C");

    Serial.print("Pressure = ");

    //Serial.print(bme.readPressure() / 100.0F);
    Serial.print(p);
    Serial.println(" hPa");

    Serial.print("Approx. Altitude = ");
    //Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.print(a);
    Serial.println(" m");

    Serial.print("Humidity = ");
    //Serial.print(bme.readHumidity());
    Serial.print(h);
    Serial.println(" %");

    Serial.println();
}


void getWeight()
{
  HX711 scale(DOUT, CLK);
  scale.set_scale(calibration_factor); //Adjust to this calibration factor
  Serial.print("Reading: ");
  weight = scale.get_units();
  Serial.print(weight, 1);
  Serial.print(" kg"); // You can change this to other type of weighing value and re-adjust the calibration factor.
  Serial.print(" calibration_factor: ");
  Serial.print(calibration_factor);
  Serial.println();
 
}

void getSendData() 
{ 
 DS18B20.requestTemperatures();  
 tempruche = DS18B20.getTempCByIndex(0); // Sensor 0 will capture Temp in Celcius 
 Serial.print("tempruche: "); 
 Serial.println(tempruche); 
 
} 


void thermoTemp()
{
float tempThermo = thermo.readCelsius();         // reading sensor from analog pin
  Serial.print("tempThermo = ");
  Serial.println(tempThermo);
}

void WiFi_Connect() // New functon to handle the connectuon to the Wi-Fi network
{
  Serial.println(F("Connecting to Wi-Fi"));
  //WiFi.config(device_ip, dns, gateway, subnet); // Not needed if you just want to have a DHCP assigned IP address. If you diont use this then delete the device_ip, dns, gateway & subnet declarations
    
  if (WiFi.status() != WL_CONNECTED)
  {
      WiFi.begin(ssid, pass); // connect to the network
  }
  while (WiFi.status() != WL_CONNECTED  && wifi_connect_count < wifi_connect_max_retries) // Loop until we've connected, or reached the maximum number of attemps allowed
  {
    delay(500);
    wifi_connect_count++;   
    Serial.print(F("Wi-Fi connection - attempt number "));
    Serial.println(wifi_connect_count);
  }
  
  if (WiFi.status() == WL_CONNECTED)
  {
    WiFi.mode(WIFI_STA);
    Serial.println(F("Wi-Fi CONNECTED"));
    Serial.println();
  }
} // End of void WiFi_Connect

void setup()
{
  Serial.begin(115200);
  pinMode (transistorPin, OUTPUT);

  // New section of code - stop using Blynk.begin, which is a blocking function, and instead do the following:
  //
  // 1) Attempt to connect to Wi-Fi a few times (how many times we try is specified by the 'wifi_connect_max_retries' variable)
  // 2) If we successfully connected to Wi-Fi then attempt to connect to Blynk in a non-blocking way. If we aren't connected to Wi-Fi then go to sleep
  // 3) If we connected to Blynk then run the rest of the code as normal. If we aren't connected to Blynk then go to sleep
  
  //  Blynk.begin(auth, ssid, pass);//starts wifi and Blynk - Not used in the new code as it's a blocking function
  WiFi_Connect(); // Attempt to connect to Wi-Fi

  if (WiFi.status() == WL_CONNECTED)               // If we managed to connect to Wi-Fi then try to connect to Blynk, else go to sleep
  {
    Blynk.config(auth, blynk_server, blynk_port);  // Initialise the Blynk connection settings
    Blynk.connect();                               // Attempt to connect to Blynk
  }
  else
  {
    Serial.println ("Wi-Fi connection failed - going to sleep");
    //sleep_time_minutes = sleep_time_minutes * 2; // If you enable this line of code the it will make the device go to sleep for twice as long before trying again. Changing to 0.5 would make it try again sooner than normal
    Deep_Sleep_Now();
  }
  
  if (Blynk.connected())                          // If we manages to connect to Blynk then carry-on as normal, else go to sleep
  {  
    Serial.println ("Connected to Blynk");
  }
  else
  {  
    //sleep_time_minutes = sleep_time_minutes * 2; // If you enable this line of code the it will make the device go to sleep for twice as long before trying again. Changing to 0.5 would make it try again sooner than normal
    Serial.println("Blynk connection failed - going to sleep");
    Deep_Sleep_Now();
  }
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));
  digitalWrite (transistorPin, HIGH);  // turn on the supply
  delay(2000);
   bme.begin(0x76);
  // scale.set_scale();
   DS18B20.begin(); 
 // scale.tare(); //Reset the scale to 0
  //long zero_factor = scale.read_average();
  

}

void loop()
{
  delay(2000);
  float tempThermo = thermo.readCelsius(); 
  float t = bme.readTemperature();
  float p  = (bme.readPressure() / 100.0F);
  float h =  bme.readHumidity();
  float a =  bme.readAltitude(SEALEVELPRESSURE_HPA);
  thermoTemp();
  getBme();
  getWeight();
  getSendData(); 
  getBatterie();
  delay(2000);
  Blynk.virtualWrite(V0, bootCount);
  Blynk.virtualWrite(V1, volt1);
  Blynk.virtualWrite(V4, tempThermo);
  Blynk.virtualWrite(V5,t);
  Blynk.virtualWrite(V6, p); 
  Blynk.virtualWrite(V7, h);
  Blynk.virtualWrite(V8, a);
  Blynk.virtualWrite(V9, weight);
  Blynk.virtualWrite(V10, tempruche);
  Blynk.virtualWrite(V11, TIME_TO_SLEEP);
  float wake_time = (float)millis()/float(1000); // Find out how long since the ESP rebooted
  Blynk.virtualWrite(V2, wake_time);  // Wake time
  Serial.print("Wake Time = ");
  Serial.print(wake_time);
  Serial.println(" seconds");
  Blynk.run(); // Needed to ensure that the Wake Time value is always uploaded to Blynk before going to sleep
  delay(100);
  digitalWrite (transistorPin, LOW);  // turn off the supply
  Deep_Sleep_Now();
}

void Deep_Sleep_Now() // New function - moded code out of void loop so that the sleep function can be called if we fail to connect to Wi-Fi or Blynk
{
  esp_sleep_enable_timer_wakeup((uint64_t)(TIME_TO_SLEEP) * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
  " Seconds");
  Serial.println("Going to sleep now");
  Serial.flush(); 
  esp_deep_sleep_start();
  
  delay(2000);
}
5 Likes

On the subject of LORA, have you watched any of Andreas Spiessā€™s videos?


He doesnā€™t use Blynk, but he has done quite a few experiments with long range LORA communications. His recent videos seem to have become a bit boring because he hints at various projects without sharing any detail, but some of the older ones are more in-depth.

Pete.

Yes i watched many time all the video that Andreas made. :slight_smile: the guy with theā€¦ lol

1 Like

Hello everyone,
Iā€™m coming back to my evolution of my connected hive project. The main problem I had, was having a wifi connection available around my house, and I moved to a LORA connection. I first made a gateway with a Raspberry PI with a dragon module connected to the TTN server. Then with a nano ESP32 TTGO and a Lora modulre RFM 95 I made a transmitter module called LoraNode. This module sends the weight, temperature, pressure, humidity, connection number and Lora parameters every X minutes (With a deep sleep function). This data is then sent to TTN, retrieved by Node-red (installed in the raspberry) and sent back to the Blynk server.

My LoraNode :grinning:

Next for me is to creat a outdoor lora gateway, test the maximun distance range I can have and install my new Loranode under a hive! and if all work creat a PCB!

7 Likes