Story

Introduction

In France there is about 1 million beehives.

The objective is to monitor the gain/loss in beehive weight for:


Mindmap

Acquisition system

Remarks: Bee weight is between 60 to 80 mg, so 1g = 14 bees approximately. The average honey consumption during winter (in center of France) is from 12 to 15 kg.

Prerequisites

Possible additional measurements

Global costs,

http://stephane.gouttebroze.free.fr/gruche/gruche.html

Recording examples:

Internal and external temperature can be monitored,

Example herefater show bee brood temperature (around 35°C) as constant even if external temperature is varying.


Additional measurement is beehive internal humidity using DHT22 sensor.

All the datas have to be sent to network using Sigfox facility for example.

Schematics

Code example. (see files for additional versions)

//*******************************************
//
//  Systme eruche installe au Joug
//
// S.GOUTTEBROZE (c) 01.2017
//*******************************************


#include "HX711.h"
#include <OneWire.h>
#include <DHT.h>;

//Constants
#define DHTPIN 4     // what pin we're connected to = D2
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino

// DS18S20 Temperature chip i/o
OneWire ds(2);  // on pin 4


//Variables
int chk,cpt;
float hum;  //Stores humidity value
float temp; //Stores temperature value


 // the setup function runs once when you press reset or power the board
unsigned long Weight = 0;
unsigned long AverageWeight = 0;
unsigned long AverageWeightot = 0;
unsigned long AverageWeightold = 0;
int ini(0);
int Clock = 7; //3 on board
int Dout = 6; //2 on board
  

float poidsD(0);

float Tc_100_A,Tc_100_B;
byte i;
byte type_s;
byte present = 0;
byte data[12];
byte addr[8];
char *msg ;

void lire_scaleD() {
  //Serial.println("Lire D...");
  // wait for the chip to become ready
 while (digitalRead(Dout) == HIGH);

 AverageWeight = 0;
  for (char j = 0; j<100; j++)
  {
     Weight =0;
    // pulse the clock pin 24 times to read the data
    for (char i = 0; i<24; i++)
    {
      digitalWrite(Clock, HIGH);
      delayMicroseconds(2);
      Weight = Weight <<1;
      if (digitalRead(Dout)==HIGH) Weight++;
      digitalWrite(Clock, LOW);
    }
    // set the channel and the gain factor (A 128) for the next reading using the clock pin (one pulse)
    digitalWrite(Clock, HIGH);
    Weight = Weight ^ 0x800000;
    digitalWrite(Clock, LOW);
    AverageWeight += Weight;
    delayMicroseconds(60);
  }
  AverageWeight = AverageWeight/100;
  //Serial.print("PoidsDnew=");
  //Serial.println(AverageWeight);

}


void setup() {
     
  Serial.begin(9600);

  //intialize HX711    "Module 4"  SCALE D
  pinMode(Clock, OUTPUT); // initialize digital pin 4 as an output.(clock)

  digitalWrite(Clock, HIGH); 
  delayMicroseconds(100);   //be sure to go into sleep mode if > 60s
  digitalWrite(Clock, LOW);     //exit sleep mode*/

  pinMode(Dout, INPUT);  // initialize digital pin 5 as an input.(data Out)
       
  dht.begin();
  
  Serial.println("ready");

  ini=1;
  
  // Initialisation...
  
  lire_scaleD();
  //poidsD=AverageWeight*0.8774529-7360044.76;
  //Serial.println(poidsD);
  
}


void loop() {


// Pour les tests sans Bluetooth,
lecture_data();
envoi_msg();

// Pause entre 2mesures...
delay(3000);
delay(1000);
// pour 10secondes de dlai
delay(20000);
// on ajoute 20sec

delay(90054);
// on ajoute 90sec --> lecture toutes les 2min
delay(3000); // ajustement pour atteindre 2min

delay(500);
 
}


void lecture_data() {
  //Serial.println("Loop Readings:...");

//  Temperature #A capteur interne boitier
  ds.reset();
  addr[0]=16;
  addr[1]=71;
  addr[2]=193;
  addr[3]=37;
  addr[4]=1;
  addr[5]=8;
  addr[6]=0;
  addr[7]=200;
  
 // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      //Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      //Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      //Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }


  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  Tc_100_A = (float)raw / 16.0;


  
//  Temperature #B  capteur volant
  ds.reset();
  addr[0]=16;
  addr[1]=228;
  addr[2]=224;
  addr[3]=37;
  addr[4]=1;
  addr[5]=8;
  addr[6]=0;
  addr[7]=248;
 // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      //Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      //Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      //Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }


  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  Tc_100_B = (float)raw / 16.0;


// Lecture du quatrime module connect sur Digital PIN
//Serial.print("PoidsD_old=");
//Serial.println(AverageWeightold);
lire_scaleD();
//Serial.print("PoidsDnew=");
//Serial.println(AverageWeight);

while (AverageWeightold-AverageWeight>5) {

  lire_scaleD();
  if (ini==1) {
    AverageWeightold=AverageWeight;
    ini=0;
  }
  AverageWeightold=AverageWeight;
  //Serial.print(".");
  
}

  AverageWeightold=AverageWeight;
  poidsD=AverageWeight*4.6645331632-4605.0-39148787.5+16000.0;   // capteur de 200kg


  
      //Read data and store it to variables hum and temp from DHT22 on pin #D2
    hum = dht.readHumidity();
    temp= dht.readTemperature();
    
}

void envoi_msg() {
  
 //Serial.println("envoi ok        ");
 char str_tempa[10];
 dtostrf(Tc_100_A, 4, 2, str_tempa);
 char str_tempb[10];
 dtostrf(Tc_100_B, 4, 2, str_tempb);
 char str_poids[20];
 dtostrf(poidsD, 4, 2, str_poids);
 char str_tempc[10];
 dtostrf(temp, 4, 2, str_tempc);
 char str_hum[10];
 dtostrf(hum, 4, 2, str_hum);

 char message[100]; 

 sprintf(message, ";GRJ;%s;%s;%s;%s;%s;0.0", str_tempa,str_tempb,str_tempc,str_hum,str_poids);
  Serial.println(message);
}