Sofiane KHARROUGAAmelle ZalifZakaria ZeroualiMelissa AMIRAT
Published

Open Ruche

Equipping a hive with smart sensors to analyze and provide data on the state of health of the bees and their productivity.

IntermediateShowcase (no instructions)689
Open Ruche

Things used in this project

Hardware components

Arduino MKR Fox 1200
Arduino MKR Fox 1200
×1
DHT22 Temperature Sensor
DHT22 Temperature Sensor
×2
Seeed Studio HX711
×1
Bosch Jauge de contraintes
×1
Adafruit Waterproof DS18B20 Digital temperature sensor
Adafruit Waterproof DS18B20 Digital temperature sensor
×3
Seeed Studio Lipo Rider Pro
×1
Rechargeable Battery, 3.7 V
Rechargeable Battery, 3.7 V
×1
Cellule solaire SOL2W
×1
Photo resistor
Photo resistor
×1

Software apps and online services

KiCad
KiCad
Ubidots
Ubidots
Sigfox
Sigfox
Beep
Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Solder Wire, Lead Free
Solder Wire, Lead Free
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mmΒ² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mmΒ² Capacity Wires
Soldering iron (generic)
Soldering iron (generic)
Hot glue gun (generic)
Hot glue gun (generic)
Drill / Driver, Cordless
Drill / Driver, Cordless
Multitool, Screwdriver
Multitool, Screwdriver
Multitool, Screwdriver
Multitool, Screwdriver

Story

Read more

Schematics

PCB Schematic

This is the design for our PCB, it shows how all items are linked

System Schematic

This is the design for our system, it shows how all items are linked.

Code

Arduino Code

Arduino
This is the main code file for this project. This code reads sensor data, processes it as needed, and then sends it to Sigfox.
#include <SigFox.h>
#include "DHT.h"
#include "HX711.h"
#include <OneWire.h>

#define calibration_factor 30305.18 //This value is obtained using the SparkFun_HX711_Calibration sketch
#define LOADCELL_DOUT_PIN  4
#define LOADCELL_SCK_PIN  5

#define DHTPIN1 1 
#define DHTPIN2 2


DHT dht[] = {
  {DHTPIN1, DHT22},
  {DHTPIN2, DHT22},
};

float humidity[2];  // Temp et Hum DHT22    
float temperature[2];


const int BATTERYPIN = A1; //pin de la batterie

const float TensionMin = 1.75; //tension min
const float TensionMax = 2.1; //tension max
int dataTemp = 0;             // BufferTemporaire                    
uint16_t poids = 0;
const byte BROCHE_ONEWIRE = 3;
byte data1[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


typedef struct __attribute__ ((packed)) sigfox_message {
  uint8_t humidite_DHT22:7; // Humidite sur 10bits
  int16_t temp_DHT22:10;      // Temprature sur 11bits
  int16_t temp_OW_NUM1:10;    // Temprature sur 11bits
  int16_t temp_OW_NUM2:10;    // Temprature sur 11bits
  int16_t temp_OW_NUM3:10;    // Temprature sur 11bits
  int32_t poids:18;           // Poids sur 11bits
  uint8_t Lumos:6;
  //uint8_t batterie:7;         // Tension Batterie sur 7bits
  //uint8_t panneau:7;          // Tension Panneau sur 7bits
} SigfoxMessage;

enum DS18B20_RCODES {
  READ_OK,
  NO_SENSOR_FOUND,
  INVALID_ADDRESS,
  INVALID_SENSOR
};

HX711 capteur;
OneWire ds(BROCHE_ONEWIRE);
HX711 scale;

// stub for message which will be sent
SigfoxMessage msg;

// =================== UTILITIES ===================
void reboot() {
 NVIC_SystemReset();
 while (1);
}
// =================================================

void setup() {
  Serial.begin(9600);
  for (auto& sensor : dht) {
    sensor.begin();
  }
  if (!SigFox.begin()) {
    Serial.println("SigFox error, rebooting");
    reboot();
  }
  delay(100); // Wait at least 30ms after first configuration
  // Enable debug prints and LED indication
  SigFox.debug();
  Serial.println("HX711 scale demo");
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0
  Serial.println("Readings:");
  pinMode(1, INPUT);
  pinMode(7,OUTPUT); //règle la borne numérique numéro 1 de la carte Arduino en mode sortie
  digitalWrite(7,HIGH); //le courant est envoyΓ© sur la borne 1, la LEDΒ  s'allume
  delay(1000);
  digitalWrite(7,LOW); //le courant est envoyΓ© sur la borne 1, la LEDΒ  s'allume

}


void loop() {
  allumerCapteur();
  mesureDHT22(); 
  mesureHX711(); 
  mesureDS18B20();
  Lumos();
  getBattery();
  eteindreCapteur();
  sendData();
  delay(600000);
  resetData();
}


void sendData(){
  SigFox.begin(); 
  // Clears all pending interrupts
  SigFox.status();
  delay(1);// Send the data
  SigFox.beginPacket();
  SigFox.write((uint8_t*)&data1, sizeof(data1));
  Serial.println("ENVOIE DU MESSAGE ...");
  Serial.print("Status: ");
  if(SigFox.endPacket()==0){
    Serial.println("Message EnvoyΓ©\n\n");
  }
}

void mesureHX711(){
  uint32_t poids = (uint32_t) (scale.get_units() * 1000.0); // tempΓ©rature 1/100th of degrees
  Serial.print("Poids: ");
  Serial.print(scale.get_units(), 1); //scale.get_units() returns a float
  Serial.println(" KG"); //You can change this to kg but you'll need to refactor the calibration_factor
  dataTemp = (data1[2]|poids>>11) ;
  data1[2] = lowByte(dataTemp) ;
  dataTemp = (data1[3]|poids>>3) ;
  data1[3] = lowByte(dataTemp) ;
  dataTemp = (data1[4]|poids<<5) ;
  data1[4] =lowByte(dataTemp) ;
  //Serial.println(msg.Poids);
}

void mesureDHT22(){

  for (int i = 0; i < 2; i++) {
    temperature[i] = dht[i].readTemperature();
    humidity[i] = dht[i].readHumidity();
  }

  for (int i = 0; i < 2; i++) {
  Serial.print("Humidity ");
  Serial.print(i);
  Serial.print(" : ");
  Serial.print(humidity[i]);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(i);
  Serial.print(" : ");
  Serial.print(temperature[i]);
  Serial.println(" Β°C\t");
  }

  if (isnan(temperature[0]) || isnan(temperature[1]) || isnan(humidity[0]) || isnan(humidity[1])) {
    Serial.println(F("Failed to read from DHT sensors!"));
    return;
  }
  uint8_t hTemp0 =(uint8_t)humidity[0];
  dataTemp = (data1[0]|hTemp0<<1) ;
  data1[0] = lowByte(dataTemp) ;

  int16_t tTemp0 =(int16_t)(temperature[0]*10);
  dataTemp = (data1[0]|tTemp0>>9) ;
  data1[0] = lowByte(dataTemp) ;
  dataTemp = (data1[1]|tTemp0>>1) ;
  data1[1] = lowByte(dataTemp) ;
  dataTemp = (data1[2]|tTemp0<<7) ;
  data1[2] = lowByte(dataTemp) ;

  uint8_t hTemp1 =(uint8_t)humidity[1];
  dataTemp = (data1[9]|hTemp1>>5) ;
  data1[9] = lowByte(dataTemp) ;
  dataTemp = (data1[10]|hTemp1<<3) ;
  data1[10] = lowByte(dataTemp) ;

  int16_t tTemp1 =(int16_t)(temperature[1]*10);
  dataTemp = (data1[10]|tTemp1>>7) ;
  data1[10] = lowByte(dataTemp) ;
  dataTemp = (data1[11]|tTemp1<<1) ;
  data1[11] = lowByte(dataTemp) ;
  return;
}

void mesureDS18B20(){
  float temperature[3];
   
  /* Lit les tempΓ©ratures des trois capteurs */
  if (getTemperature(&temperature[0], true) != READ_OK) {
    Serial.println(F("Erreur de lecture du capteur 1"));
    return;
  }
  if (getTemperature(&temperature[1], false) != READ_OK) {
    Serial.println(F("Erreur de lecture du capteur 2"));
    return;
  }
  if (getTemperature(&temperature[2], false) != READ_OK) {
    Serial.println(F("Erreur de lecture du capteur 3"));
    return;
  }
   
  /* Affiche les tempΓ©ratures */
  Serial.print(F("Temperatures : "));
  Serial.print(temperature[0], 2);
  uint16_t temp0=(uint16_t) temperature[0];
  dataTemp  = (data1[4] | temp0 >>5) ;
  data1[4] = lowByte(dataTemp) ;
  dataTemp = (data1[5] | temp0<<3) ;
  data1[5] = lowByte(dataTemp) ;

  Serial.write("°"); // Caractère degré
  Serial.print(F("C, "));
  Serial.print(temperature[1], 2);
  uint16_t temp1=(uint16_t) temperature[1];
  dataTemp = (data1[5]|temp1>>7) ;
  data1[5] = lowByte(dataTemp) ;
  dataTemp = (data1[6] |temp1<<1) ;
  data1[6]= lowByte(dataTemp) ;
  Serial.write("°"); // Caractère degré
  Serial.print(F("C, "));
  Serial.print(temperature[2], 2);
  uint16_t temp2=(uint16_t) temperature[2];
  dataTemp = (data1[6] | temp2>>9);
  data1[6] = lowByte(dataTemp) ;
  dataTemp = (data1[7] | temp2 >>1) ;
  data1[7] = lowByte(dataTemp) ;
  dataTemp =(data1[8] | temp2<<7) ;
  data1[8] = lowByte(dataTemp) ;
   
  Serial.write("°"); // Caractère degré
  Serial.println('C');  
}

byte getTemperature(float *temperature, byte reset_search) {
  byte data[9], addr[8];
  // data[] : DonnΓ©es lues depuis le scratchpad
  // addr[] : Adresse du module 1-Wire dΓ©tectΓ©
  
  /* Reset le bus 1-Wire ci nΓ©cessaire (requis pour la lecture du premier capteur) */
  if (reset_search) {
    ds.reset_search();
  }
 
  /* Recherche le prochain capteur 1-Wire disponible */
  if (!ds.search(addr)) {
    // Pas de capteur
    return NO_SENSOR_FOUND;
  }
  
  /* VΓ©rifie que l'adresse a Γ©tΓ© correctement reΓ§ue */
  if (OneWire::crc8(addr, 7) != addr[7]) {
    // Adresse invalide
    return INVALID_ADDRESS;
  }
 
  /* VΓ©rifie qu'il s'agit bien d'un DS18B20 */
  if (addr[0] != 0x28) {
    // Mauvais type de capteur
    return INVALID_SENSOR;
  }
 
  /* Reset le bus 1-Wire et sΓ©lectionne le capteur */
  ds.reset();
  ds.select(addr);
  
  /* Lance une prise de mesure de tempΓ©rature et attend la fin de la mesure */
  ds.write(0x44, 1);
  delay(800);
  
  /* Reset le bus 1-Wire, sΓ©lectionne le capteur et envoie une demande de lecture du scratchpad */
  ds.reset();
  ds.select(addr);
  ds.write(0xBE);
 
 /* Lecture du scratchpad */
  for (byte i = 0; i < 9; i++) {
    data[i] = ds.read();
  }
   
  /* Calcul de la tempΓ©rature en degrΓ© Celsius */
  *temperature = (int16_t) ((data[1] << 8) | data[0]) * 0.0625 * 10; 
  
  // Pas d'erreur
  return READ_OK;
}

void Lumos(){
  int valeur = analogRead(A2);
  float tension = valeur * (3.3 / 1024.0);
  uint8_t Lumos = (uint8_t) (tension*10);
  dataTemp =(data1[8]| Lumos<<1) ;
  data1[8] = lowByte(dataTemp) ;
  Serial.print("LuminiositΓ© : ");
  Serial.println(tension);
  //Serial.println(Lumos);
}

void resetData(){
  for(uint8_t i=0; i<11; i++){
    data1[i]= 0x00;
  }
}

void getBattery ()
{
  float b = analogRead(BATTERYPIN); //valeur analogique
  int minValue = (1023 * TensionMin) / 3.3; //Arduino
  int maxValue = (1023 * TensionMax) / 4.2; //Arduino
  b = ((b - minValue) / (maxValue - minValue)) * 100; //mettre en pourcentage

  if (b > 100) //max is 100%
    b = 100;

  else if (b < 0) //min is 0%
    b = 0;
  int valeur = b;
  uint8_t batterie=(uint8_t) b;
    Serial.print("Batterie :");
  Serial.println(batterie);
  dataTemp = (data1[8] | batterie >> 6) ;
  data1[8] = lowByte(dataTemp) ;
  dataTemp=(data1[9] | batterie << 2) ;
  data1[9] = lowByte(dataTemp) ;
}

void til()
{
  Serial.print(analogRead(A2));
    if (digitalRead(1)==HIGH)
    {
      Serial.println("La ruche bouge !");
        delay(100);
    } 
}

void allumerCapteur(){
  digitalWrite(10, HIGH);
  digitalWrite(11, HIGH);
  digitalWrite(12, HIGH);
  capteur.power_up();
}

void eteindreCapteur(){
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  capteur.power_down();
}

Credits

Sofiane KHARROUGA
1 project β€’ 2 followers
Amelle Zalif
1 project β€’ 2 followers
Zakaria Zerouali
1 project β€’ 3 followers
Melissa AMIRAT
1 project β€’ 2 followers

Comments