Hardware components | ||||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
Hand tools and fabrication machines | ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
|
During our 4th year at Polytech Sorbonne🏫, we took part in the conception and set-up of a monitoring embedded system💻📲 applied on hives in order to help beekeepers watch the activity of bees🐝 and face CCD : Colony Collapse Disorder.
With this system, we can collect the following data :
- The weight( to prevent the decrease of the number of the bees🐝 or robbery)
- The temperatures and humidity( inside and outside )the hive to prevent CCD which is especially threatening during winter.
- The lux ( here in percentage depending on the voltage we can see on the solar panel)
- The level of our battery(since we are using to supply the system; the solar panel to recharge allows the system autonomy)
- Some bands of frequencies: First because we can 😜 and then because it can useful to determine the state of the bees(rest, stress or work)
All the components will be put in a waterproof box. The microphone, the weight sensor, the box and the temperature & humidity (DHT22) sensor will be under the beehive. Temperature sensors (DS18B20) will be put inside the beehive. The solar panel will be placed on the roof.
How does it work :According to the requirements of intelligent beehive data detection, we designed the following system for BEEP BEEP:
From theses circuit schematics come the following PCB, paramount to simplify the system.
After that, we connect all sensors, power supplies, switches, etc. to the PCB board, put them into the box and seal them after the test is correct, and assemble them in the beehive:
À rajouter à la fin du setup
// Basse consommation
digitalWrite(LED_PWR, LOW); // "ON" LED turned off:
digitalWrite(PIN_ENABLE_SENSORS_3V3, LOW); //PIN_ENABLE_SENSORS_3V3 set to LOW:
digitalWrite(PIN_ENABLE_I2C_PULLUP, LOW); // PIN_ENABLE_I2C_PULLUP set to LOW:
#define MAXIMWIRE_EXTERNAL_PULLUP
#include <MaximWire.h>
#define PIN_BUS 10
MaximWire::Bus bus(PIN_BUS);
MaximWire::DS18B20 device;
int temp_tab[2];
void automatic_run_MaximWire(){
MaximWire::Discovery discovery = bus.Discover();
int cmpt=0;
do {
MaximWire::Address address;
if (discovery.FindNextDevice(address)) {
if (address.GetModelCode() == MaximWire::DS18B20::MODEL_CODE) {
MaximWire::DS18B20 device(address);
temp_tab[cmpt] = device.GetTemperature<float>(bus) *100;
Serial.print(F("Temperature : "));
Serial.print(temp_tab[cmpt]);
Serial.print(F("°C "));
Serial.println();
device.Update(bus);
if(cmpt==1) cmpt--;
else cmpt++;
} else {
Serial.println();
}
} else {
Serial.println("NOTHING FOUND");
}
} while (discovery.HaveMore());
}
ina_maison (1).h
#include "DFRobot_INA219.h"
DFRobot_INA219_IIC ina219(&Wire, INA219_I2C_ADDRESS4);
float ina219Reading_mA = 1000;
float extMeterReading_mA = 1000;
float lux = 0;
float courant=0;
void calcul_lux(){
courant = ina219.getCurrent_mA();
if (courant>=140){
lux=100;
}
else if(courant<=0){
lux=0;
}
else{
lux = courant*100/140;
}
}
void automatic_run_INA(){
calcul_lux();
Serial.print("Current: ");
Serial.print(courant);
Serial.println("mA");
Serial.print("Lux: ");
Serial.print(lux);
Serial.println("%");
}
#include <DFRobot_HX711.h>
DFRobot_HX711 MyScale(A2, A3);//weigh
int w ;
void automatic_run_HX711(){
w = (MyScale.readWeight()*0.6789)*10;
w=(w<0)?0:w;
Serial.print(MyScale.getValue());
//Serial.println(MyScale.getValue());
Serial.print(F(" Weight: "));
Serial.print(w);
Serial.println(F(" Kg\n"));
}
FFT_maison (1).h
float Q_FFT(int in[],int Np,float Frequency);
#define Np2 64
float freq_amp[32][2];
unsigned int s_bin098_146Hz=0;
unsigned int s_bin146_195Hz=0;
unsigned int s_bin195_244Hz=0;
unsigned int s_bin244_293Hz=0;
unsigned int s_bin293_342Hz=0;
unsigned int s_bin342_391Hz=0;
unsigned int s_bin391_439Hz=0;
unsigned int s_bin439_488Hz=0;
unsigned int s_bin488_537Hz=0;
unsigned int s_bin537_586Hz=0;
int data[64]={14, 30, 35, 34, 34, 40, 46, 45, 30, 4, -26, -48, -55, -49, -37,
-28, -24, -22, -13, 6, 32, 55, 65, 57, 38, 17, 1, -6, -11, -19, -34,
-51, -61, -56, -35, -7, 18, 32, 35, 34, 35, 41, 46, 43, 26, -2, -31, -50,
-55, -47, -35, -27, -24, -21, -10, 11, 37, 58, 64, 55, 34, 13, -1, -7};
void automatic_run_FFT() {
int i = 0;
int tab[Np2];
unsigned long StartTime= micros();
for (int i=0;i<Np2;i++){
tab[i]=analogRead(A6);
delayMicroseconds(800);
}
float f=Q_FFT(tab,Np2,1200);
unsigned long CurrentTime= micros();
unsigned long ElapsedTime= CurrentTime - StartTime;
Serial.println(f);
//Serial.print("Le temps écoulé est:");
//Serial.println(ElapsedTime);
delay(1000);
}
//-----------------------------FFT Function----------------------------------------------//
/*
Code to perform High speed (5-7 times faster) and low accuracy FFT on arduino,
This code compromises accuracy for speed,
setup:
1. in[] : Data array,
2. N : Number of sample (recommended sample size 2,4,8,16,32,64,128...)
3. Frequency: sampling frequency required as input (Hz)
It will by default return frequency with max aplitude,
If sample size is not in power of 2 it will be clipped to lower side of number.
i.e, for 150 number of samples, code will consider first 128 sample, remaining sample will be omitted.
For Arduino nano, FFT of more than 256 sample not possible due to mamory limitation
Code by ABHILASH
Contact: abhilashpatel121@gmail.com
Documentation & deatails: https://www.instructables.com/member/abhilash_patel/instructables/
*/
float Q_FFT(int in[],int Np,float Frequency)
{
unsigned int Pow2[13]={1,2,4,8,16,32,64,128,256,512,1024,2048}; // declaring this as global array will save 1-2 ms of time
int a,c1,f,o,x;
byte check=0;
a=Np;
for(int i=0;i<12;i++) //calculating the levels
{ if(Pow2[i]<=a){o=i;} }
int out_r[Pow2[o]]={}; //real part of transform
int out_im[Pow2[o]]={}; //imaginory part of transform
x=0;
for(int b=0;b<o;b++) // bit reversal
{
c1=Pow2[b];
f=Pow2[o]/(c1+c1);
for(int j=0;j<c1;j++)
{
x=x+1;
out_im[x]=out_im[j]+f;
}
}
for(int i=0;i<Pow2[o];i++) // update input array as per bit reverse order
{
out_r[i]=in[out_im[i]];
out_im[i]=0;
}
int i10,i11,n1,tr,ti;
float e;
int c,s;
for(int i=0;i<o;i++) //fft
{
i10=Pow2[i]; // overall values of sine/cosine
i11=Pow2[o]/Pow2[i+1]; // loop with similar sine cosine
e=360/Pow2[i+1];
e=0-e;
n1=0;
for(int j=0;j<i10;j++)
{
c=e*j;
while(c<0){c=c+360;}
while(c>360){c=c-360;}
n1=j;
for(int k=0;k<i11;k++)
{
if(c==0) { tr=out_r[i10+n1];
ti=out_im[i10+n1];}
else if(c==90){ tr= -out_im[i10+n1];
ti=out_r[i10+n1];}
else if(c==180){tr=-out_r[i10+n1];
ti=-out_im[i10+n1];}
else if(c==270){tr=out_im[i10+n1];
ti=-out_r[i10+n1];}
else if(c==360){tr=out_r[i10+n1];
ti=out_im[i10+n1];}
else if(c>0 && c<90) {tr=out_r[i10+n1]-out_im[i10+n1];
ti=out_im[i10+n1]+out_r[i10+n1];}
else if(c>90 && c<180) {tr=-out_r[i10+n1]-out_im[i10+n1];
ti=-out_im[i10+n1]+out_r[i10+n1];}
else if(c>180 && c<270) {tr=-out_r[i10+n1]+out_im[i10+n1];
ti=-out_im[i10+n1]-out_r[i10+n1];}
else if(c>270 && c<360) {tr=out_r[i10+n1]+out_im[i10+n1];
ti=out_im[i10+n1]-out_r[i10+n1];}
out_r[n1+i10]=out_r[n1]-tr;
out_r[n1]=out_r[n1]+tr;
if(out_r[n1]>15000 || out_r[n1]<-15000){check=1;}
out_im[n1+i10]=out_im[n1]-ti;
out_im[n1]=out_im[n1]+ti;
if(out_im[n1]>15000 || out_im[n1]<-15000){check=1;}
n1=n1+i10+i10;
}
}
if(check==1){ // scale the matrics if value higher than 15000 to prevent varible from overloading
for(int i=0;i<Pow2[o];i++)
{
out_r[i]=out_r[i]/100;
out_im[i]=out_im[i]/100;
}
check=0;
}
}
/*
for(int i=0;i<Pow2[o];i++)
{
Serial.print(out_r[i]);
Serial.print("\t"); // un comment to print RAW o/p
Serial.print(out_im[i]); Serial.println("i");
}
*/
//---> here onward out_r contains amplitude and our_in conntains frequency (Hz)
int fout,fm,fstp;
float fstep;
fstep=Frequency/Np;
fstp=fstep;
fout=0;fm=0;
for(int i=1;i<Pow2[o-1];i++) // getting amplitude from compex number
{
if((out_r[i]>=0) && (out_im[i]>=0)){out_r[i]=out_r[i]+out_im[i];}
else if((out_r[i]<=0) && (out_im[i]<=0)){out_r[i]=-out_r[i]-out_im[i];}
else if((out_r[i]>=0) && (out_im[i]<=0)){out_r[i]=out_r[i]-out_im[i];}
else if((out_r[i]<=0) && (out_im[i]>=0)){out_r[i]=-out_r[i]+out_im[i];}
// to find peak sum of mod of real and imaginery part are considered to increase speed
out_im[i]=out_im[i-1]+fstp;
if (fout<out_r[i]){fm=i; fout=out_r[i];}
/*
Serial.print(out_im[i]);Serial.print("Hz");
Serial.print("\t"); // un comment to print freuency bin
Serial.println(out_r[i]);
*/
freq_amp[i][0]=out_im[i];
freq_amp[i][1]=5*out_r[i];
}
s_bin098_146Hz = unsigned((freq_amp[5][1]+freq_amp[6][1]+freq_amp[7][1]+freq_amp[8][1]));
s_bin146_195Hz = unsigned((freq_amp[8][1]+freq_amp[9][1]+freq_amp[10][1]));
s_bin195_244Hz = unsigned((freq_amp[10][1]+freq_amp[11][1]+freq_amp[12][1]+freq_amp[13][1]));
s_bin244_293Hz = unsigned((freq_amp[13][1]+freq_amp[14][1]+freq_amp[15][1]));
s_bin293_342Hz = unsigned((freq_amp[16][1]+freq_amp[17][1]+freq_amp[18][1]));
s_bin342_391Hz = unsigned((freq_amp[18][1]+freq_amp[19][1]+freq_amp[20][1]));
s_bin391_439Hz = unsigned((freq_amp[21][1]+freq_amp[22][1]+freq_amp[23][1]));
s_bin439_488Hz = unsigned((freq_amp[23][1]+freq_amp[24][1]+freq_amp[25][1]));
s_bin488_537Hz = unsigned((freq_amp[26][1]+freq_amp[27][1]+freq_amp[28][1]));
s_bin537_586Hz = unsigned((freq_amp[28][1]+freq_amp[29][1]+freq_amp[30][1]+freq_amp[31][1]));
// Serial.print(freq_amp[5][1]);
/*Serial.print("Amplitude bande de fréquences 93.75 Hz à 150 Hz");
Serial.println();
Serial.println(s_bin098_146Hz);
Serial.print("Amplitude bande de fréquences 150 Hz à 187,5 Hz");
Serial.println();
Serial.println(s_bin146_195Hz);
Serial.print("Amplitude bande de fréquences 187,5 Hz à 243,75 Hz");
Serial.println();
Serial.println(s_bin195_244Hz);
Serial.print("Amplitude bande de fréquences 243,75 Hz à 281,25 Hz");
Serial.println();
Serial.println(s_bin244_293Hz);
Serial.print("Amplitude bande de fréquences 281,25 Hz à 337,5 Hz");
Serial.println();
Serial.println(s_bin293_342Hz);
Serial.print("Amplitude bande de fréquences 337,5 Hz à 393,75 Hz");
Serial.println();
Serial.println(s_bin342_391Hz);
Serial.print("Amplitude bande de fréquences 393,75 Hz à 431,25 Hz");
Serial.println();
Serial.println(s_bin391_439Hz);
Serial.print("Amplitude bande de fréquences 431,25 Hz à 487,5 Hz");
Serial.println();
Serial.println(s_bin439_488Hz);
Serial.print("Amplitude bande de fréquences 487,5Hz à 525 Hz");
Serial.println();
Serial.println(s_bin488_537Hz);
Serial.print("Amplitude bande de fréquences 525Hz à 581,25 Hz");
Serial.println();
Serial.println(s_bin537_586Hz);*/
float fa,fb,fc;
fa=out_r[fm-1];
fb=out_r[fm];
fc=out_r[fm+1];
fstep=(fa*(fm-1)+fb*fm+fc*(fm+1))/(fa+fb+fc);
return(fstep*Frequency/Np);
}
//------------------------------------------------------------------------------------//
dht_maison (1).h
#include "DHT.h"
#define DHTPIN A0 // Digital pin connected to the DHT sensor
#define DHTPIN2 A1 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);
DHT dht2(DHTPIN2, DHTTYPE);
int h,t,h2,t2;
void automatic_run_DHT22(){
h = (dht.readHumidity())*100;
t = (dht.readTemperature())*100;
h2 = (dht2.readHumidity())*100;
t2 = (dht2.readTemperature()-1)*100;
if (isnan(h) || isnan(t) ||isnan(h2) || isnan(t2) ) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
Serial.print(F("Humidity Outdoor: "));
Serial.print(h);
Serial.print(F("% Temperature Outdoor(hum&temp): "));
Serial.print(t);
Serial.print(F("°C \n"));
Serial.print(F("Humidity Indoor: "));
Serial.print(h2);
Serial.print(F("% Temperature Indoor(hum&temp): "));
Serial.print(t2);
Serial.print(F("°C \n"));
}
bat_maison (1).h
/*BATTERIE*/
int niveau;
float ubatterie;
float pctbatterie;
/**********/
void automatic_run_bat(){
niveau = analogRead(A7);
ubatterie = (niveau* 3.3/1023);
pctbatterie = (ubatterie-1.65)/(4.5*0.001);
if (ubatterie <= 1.65){
ubatterie = 0;
pctbatterie = 0;
}
else if (ubatterie >= 2.1){
pctbatterie = 100;
}
Serial.print(ubatterie*2,3);
Serial.print(" V");
Serial.print("\n");
Serial.print(pctbatterie);
Serial.print("%");
Serial.print("\n");
}
Code for Arduino
Arduino#include "dht_maison.h"
#include "FFT_maison.h"
#include "HX711_maison.h"
#include "MaximWire_maison.h"
#include "bat_maison.h"
#include "ina_maison.h"
UART e5(digitalPinToPinName(0),digitalPinToPinName(1),NC,NC);
static char recv_buf[512];
static bool is_exist = false;
static bool is_join = false;
static int led = 0;
int ret=0;
static int at_send_check_response(char *p_ack, int timeout_ms, char *p_cmd, ...) {
int ch;
int num = 0;
int index = 0;
int startMillis = 0;
memset(recv_buf, 0, sizeof(recv_buf));
e5.write(p_cmd);
Serial.write(p_cmd);
delay(200);
startMillis = millis();
do {
while (e5.available() > 0) {
ch = e5.read();
recv_buf[index++] = ch;
Serial.write(ch);
delay(2);
}
}while (millis() - startMillis < timeout_ms);
if (strstr(recv_buf, p_ack) != NULL){
return 1;
}
else return 0;
}
void setup() {
pinMode(4, OUTPUT);
pinMode(LED_PWR, OUTPUT);
//Dmarrage
for(int compteur=0;compteur<4;compteur++){
digitalWrite(LED_PWR, HIGH);
delay(250);
digitalWrite(LED_PWR, LOW);
delay(250);
}
Serial.begin(9600);
MyScale.setCalibration(1992);
MyScale.setOffset(8526400);
dht.begin();
dht2.begin();
ina219.begin();
/*while(ina219.begin() != true) {
Serial.println("INA219 begin faild");
delay(2000);
}*/
ina219.linearCalibrate(ina219Reading_mA,extMeterReading_mA);
e5.begin(9600);
Serial.print("E5 LORAWAN TEST\r\n");
if(at_send_check_response("+AT: OK", 100, "AT\r\n"))
{
is_exist = true;
at_send_check_response("+ID: AppEui", 1000, "AT+ID\r\n");
at_send_check_response("+MODE: LWOTAA", 1000, "AT+MODE=LWOTAA\r\n");
at_send_check_response("+DR: EU868", 1000, "AT+DR=EU868\r\n");
at_send_check_response("+CH: NUM", 1000, "AT+CH=NUM,0-2\r\n");
at_send_check_response("+KEY: APPKEY", 1000,
"AT+KEY=APPKEY,\"6914025E7B58DB62707D6610522D22AE\"\r\n");
at_send_check_response("+KEY: DEVEUI", 1000, "AT+ID=DEVEUI,\"88AE55DFC59B20FF\"\r\n");
at_send_check_response("+KEY: APPEUI", 1000, "AT+ID=APPEUI,\"0000000000000000\"\r\n");
at_send_check_response("+CLASS: C", 1000, "AT+CLASS=A\r\n");
ret=at_send_check_response("+PORT: 8", 1000, "AT+PORT=8\r\n");
delay(200);
is_join = true;
}
else
{
is_exist = false;
Serial.print("No E5 module found.\r\n");
}
digitalWrite(PIN_ENABLE_SENSORS_3V3, LOW); //PIN_ENABLE_SENSORS_3V3 set to LOW:
digitalWrite(PIN_ENABLE_I2C_PULLUP, LOW); // PIN_ENABLE_I2C_PULLUP set to LOW:
}
void loop() {
digitalWrite(4, HIGH);
//delay(10000);
digitalWrite(LED_PWR, HIGH);
delay(250);
digitalWrite(LED_PWR, LOW);
automatic_run_INA();
automatic_run_bat();
automatic_run_FFT();
automatic_run_MaximWire();
delay(1000);
automatic_run_DHT22();
automatic_run_HX711();
if (is_exist)
{
int ret = 0;
if (is_join)
{
ret = at_send_check_response("+JOIN: Network joined", 12000, "AT+JOIN\r\n");
if (ret)
{
is_join = false;
Serial.println();
Serial.print("Network JOIN !\r\n\r\n");
}
else{
at_send_check_response("+ID: AppEui", 1000, "AT+ID\r\n");
Serial.println();
Serial.print("JOIN failed!\r\n\r\n");
delay(2500);
}
}
else{
char cmd[128];
sprintf(cmd, "AT+MSGHEX=%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X\r\n", t, h, w,temp_tab[0],temp_tab[1], t2, h2,int(ubatterie*200),int(lux*100),
s_bin098_146Hz,s_bin146_195Hz,s_bin195_244Hz,s_bin244_293Hz,s_bin293_342Hz,s_bin342_391Hz,s_bin391_439Hz,s_bin439_488Hz,s_bin488_537Hz,s_bin537_586Hz,int(pctbatterie*100),flg*1000,fg2*1000,fgt[0]*1000,fgt[1]*1000);
at_send_check_response("ACK Received", 5000, cmd);
delay(10000);
}
}
else {
delay(1000);
}
digitalWrite(4, LOW);
delay(576000);
}
Comments