Oumert AmineGloire DembiLéa Lacouture
Published © GPL3+

Open Ruche : A Connected Beehive for Smart Bee Monitoring

Connected beehive project using sensors & open tech to monitor hive health in real-time and protect bees through smart data.

IntermediateProtipOver 1 day522
Open Ruche : A Connected Beehive for Smart Bee Monitoring

Things used in this project

Hardware components

Arduino MKR WAN 1310
Arduino MKR WAN 1310
LoRaWAN-enabled microcontroller
×1
DHT22 Temperature Sensor
DHT22 Temperature Sensor
Indoor and outdoor air data
×2
Adafruit Waterproof DS18B20 Digital temperature sensor
Adafruit Waterproof DS18B20 Digital temperature sensor
Redundant internal temperature readings
×1
DFRobot SEN0562
Light Sensor
×1
Gravity: I2C 1Kg Weight Sensor Kit - HX711
DFRobot Gravity: I2C 1Kg Weight Sensor Kit - HX711
Hive weight monitoring
×1
Seeed Studio LiPo Rider Pro
Power management & backup battery
×1
LiPo Battery
Power management & backup battery
×1
Solar Panel
Recharges battery off-grid
×1
Through Hole Resistor, 82 kohm
Through Hole Resistor, 82 kohm
Voltage divider
×1
Resistor 22.1k ohm
Resistor 22.1k ohm
Voltage divider
×1
Breadboard (generic)
Breadboard (generic)
×1
Hardware, PCB Mounting Kit
Hardware, PCB Mounting Kit
Custom breakout & cabling
×1
Enclosure & mounting hardware
Weatherproof housing for sensors & board
×1

Software apps and online services

KiCad
KiCad
PCB
Ubidots
Ubidots
Dashboard and alert
Beep
Dashboard and alert
Arduino IDE
Arduino IDE
Dev code
The Things Stack
The Things Industries The Things Stack
Receive LoRa data

Hand tools and fabrication machines

Solder Wire, Lead Free
Solder Wire, Lead Free
For soldering
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire cutter
Drill / Driver, Cordless
Drill / Driver, Cordless
For hole on box
Soldering iron (generic)
Soldering iron (generic)
For soldering
Soldering Gun Kit, Instant Heat
Soldering Gun Kit, Instant Heat
For heat wires
Multitool, Screwdriver
Multitool, Screwdriver
For everything
Premium Female/Male Extension Jumper Wires, 40 x 6" (150mm)
Premium Female/Male Extension Jumper Wires, 40 x 6" (150mm)
For every connection
Box, General Purpose
Box, General Purpose
A waterproof enclosure that contains the entire system
Seeed Studio Grove - Universal 4 Pin Buckled 5cm Cable (5 PCs Pack)
For each connection on the PCB
Tape, Electrical
Tape, Electrical
For electrical isolation, the safety and the duracity

Story

Read more

Custom parts and enclosures

User Guide

How to use

Schematics

Open Hive Hardware Architecture & Sensor Integration Overview

The hardware is built around an Arduino MKR WAN 1310 powered by a solar-charged LiPo battery and a small custom PCB. This board collects temperature, humidity, weight and light readings from the attached sensors, then uses its LoRa antenna to send that data to the cloud every ten minutes.

Code

Firmware Implementation (Arduino C/C++)

C/C++
Every ten minutes, the Arduino MKR WAN 1310 wakes from deep sleep and runs a single sketch written in C/C++. First, it powers up the DHT22 and DS18B20 sensors to sample internal and external temperature/humidity, then reads the HX711 amplifier for hive weight and the BH1750 (SEN0562) for ambient light. These four measurements are packed into a compact 12-byte payload, which the on-board LoRaWAN library transmits to The Things Network. After a successful uplink (or a short retry on failure), the MCU shuts down radios and sensors, then returns to deep sleep—minimizing power draw until the next scheduled wake-up.
#include <MKRWAN.h>
#include <Wire.h>
#include "ArduinoLowPower.h"
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <BH1750.h>
#include "HX711.h"
#include <FlashStorage.h>

////////////////////////
///     SETUP      ///
////////////////////////

LoRaModem modem;
#define SECRET_APP_EUI "0000000000000001"
#define SECRET_APP_KEY "8062D07A1C984423278A7D938C73E534"
String appEui = SECRET_APP_EUI;
String appKey = SECRET_APP_KEY;

#define DHT22_PIN 2
#define DHT11_PIN 3
#define DS18B20_PIN 7
#define LOADCELL_DOUT_PIN 0
#define LOADCELL_SCK_PIN 1
#define BATTERY_SENSOR_PIN A1

const float R1 = 82.0;
const float R2 = 22.0;
const float Vref = 3.3;
const int resolution = 1023;

DHT dht22(DHT22_PIN, DHT22);
DHT dht22_outside(DHT11_PIN, DHT22);
OneWire oneWire(DS18B20_PIN);
DallasTemperature ds18b20(&oneWire);
BH1750 lightMeter;
HX711 scale;

float tempDHT22, humDHT22;
float tempDHT11, humDHT11;
float tempDS18B20;
float luminosite;
float poids;
float batteryVoltage;
int batteryPercentage;
float calibration_factor = 30226.0;
byte buffer[16];

// Stockage du tare HX711 en flash
FlashStorage(tareStorage, long);

void connection() {
  if (!modem.begin(EU868)) {
    Serial.println("chec de l'initialisation LoRa !");
    while (1);
  }
  Serial.print("Version module : ");
  Serial.println(modem.version());
  Serial.print("Device EUI : ");
  Serial.println(modem.deviceEUI());

  if (!modem.joinOTAA(appEui, appKey)) {
    Serial.println("chec de connexion  TTN !");
    while (1);
  }
  Serial.println("Connect  TTN !");
}

void setup() {
  Serial.begin(115200);
  Serial.println("=== Dmarrage du systme ===");

  connection();

  dht22.begin();
  dht22_outside.begin();
  ds18b20.begin();

  Wire.begin();
  if (!lightMeter.begin()) {
    Serial.println("Erreur : BH1750 non dtect !");
    while (1);
  }

  Serial.println("Initialisation du HX711...");
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  delay(5000);

  long tareOffset = tareStorage.read();
  if (tareOffset == 0 || tareOffset == -1L) {
    Serial.println("Premire utilisation : calibration en cours...");
    scale.tare(); // Mettre la balance  vide pour cette tape !
    tareOffset = scale.get_offset();
    tareStorage.write(tareOffset);
    Serial.println("Tare calibr et sauvegard !");
  } else {
    Serial.println("Tare trouv en mmoire, utilisation directe.");
    scale.set_offset(tareOffset);
  }

  scale.set_scale(calibration_factor);
}

void measureBattery() {
  int rawValue = analogRead(BATTERY_SENSOR_PIN);
  float Vmesure = (rawValue * Vref) / resolution;
  batteryVoltage = Vmesure * 1.28;
  batteryPercentage = getBatteryPercentage(batteryVoltage);
  buildMessage(batteryPercentage, 14);
}

int getBatteryPercentage(float voltage) {
  if (voltage >= 4.2) return 100;
  else if (voltage >= 4.1) return 95;
  else if (voltage >= 4.05) return 90;
  else if (voltage >= 4.0) return 85;
  else if (voltage >= 3.95) return 80;
  else if (voltage >= 3.9) return 75;
  else if (voltage >= 3.85) return 70;
  else if (voltage >= 3.8) return 65;
  else if (voltage >= 3.75) return 60;
  else if (voltage >= 3.7) return 55;
  else if (voltage >= 3.65) return 50;
  else if (voltage >= 3.6) return 45;
  else if (voltage >= 3.55) return 40;
  else if (voltage >= 3.5) return 35;
  else if (voltage >= 3.45) return 30;
  else if (voltage >= 3.4) return 20;
  else if (voltage >= 3.35) return 10;
  else if (voltage >= 3.3) return 5;
  else return 0;
}

void measureDHTSensors() {
  humDHT22 = dht22.readHumidity();
  tempDHT22 = dht22.readTemperature();
  humDHT11 = dht22_outside.readHumidity();
  tempDHT11 = dht22_outside.readTemperature();
  buildMessage(tempDHT22, 0);
  buildMessage(humDHT22, 2);
  buildMessage(tempDHT11, 4);
  buildMessage(humDHT11, 6);
}

void measureDS18B20() {
  ds18b20.requestTemperatures();
  tempDS18B20 = ds18b20.getTempCByIndex(0);
  buildMessage(tempDS18B20, 8);
}

void measureLuminosity() {
  luminosite = lightMeter.readLightLevel();
  buildMessage(luminosite, 10);
}

void measureWeight() {
  poids = scale.get_units(10);
  buildMessage(poids, 12);
}

void buildMessage(float donnee_float, int index) {
  short donnee_short = (short)(donnee_float * 100);
  buffer[index] = donnee_short & 0xFF;
  buffer[index + 1] = (donnee_short >> 8) & 0xFF;
}

bool sendMessageSafe() {
  modem.beginPacket();
  modem.write(buffer, 16);
  int err = modem.endPacket(true);
  return err > 0;
}

void loop() {
  if (modem.getDataRate() == -1) {
    Serial.println("Connexion LoRa perdue, reconnexion...");
    connection();
  }

  measureDHTSensors();
  measureDS18B20();
  measureLuminosity();
  measureWeight();
  measureBattery();

  if (!sendMessageSafe()) {
    Serial.println("Envoi LoRa chou !");
    connection(); 
    connection();
  } else {
    Serial.println("Donnes envoyes !");
  }

  Wire.end();
  scale.power_down();
  modem.sleep();

  Serial.println("Deep Sleep 10 minutes...");
  LowPower.deepSleep(600000); 

  Serial.println("Rveil !");
  Wire.begin();
  scale.power_up();
}

Credits

Oumert Amine
1 project • 2 followers
Gloire Dembi
0 projects • 1 follower
Léa Lacouture
0 projects • 0 followers

Comments