王屹飞Yasmine AMANGARSteve KibouaJeremy Batchi
Published

Beep Beep

In order to prevent colony collapse syndrome, we have created an autonomous embedded system to help beekeepers

AdvancedWork in progress287
Beep Beep

Things used in this project

Hardware components

DHT22 Temperature Sensor
DHT22 Temperature Sensor
×2
SparkFun Load Cell Amplifier - HX711
SparkFun Load Cell Amplifier - HX711
×1
Rechargeable Battery, 3.7 V
Rechargeable Battery, 3.7 V
×1
Adafruit Waterproof DS18B20 Digital temperature sensor
Adafruit Waterproof DS18B20 Digital temperature sensor
×2
Cellule solaire SOL2W
×1
Nano 33 BLE Sense
Arduino Nano 33 BLE Sense
×1
LiPo Rider Pro
×1
LoRa-E5
×1
Antenne Sigfox
×1

Software apps and online services

Arduino IDE
Arduino IDE
KiCad
KiCad
Ubidots
Ubidots
BEEP
The Things Stack
The Things Industries The Things Stack

Hand tools and fabrication machines

Bantam Tools Desktop PCB Milling Machine
Bantam Tools Desktop PCB Milling Machine
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Solder Wire, Lead Free
Solder Wire, Lead Free
Soldering iron (generic)
Soldering iron (generic)
Hot glue gun (generic)
Hot glue gun (generic)
Drill / Driver, Cordless
Drill / Driver, Cordless
Breadboard, 400 Pin
Breadboard, 400 Pin
Mastech MS8217 Autorange Digital Multimeter
Digilent Mastech MS8217 Autorange Digital Multimeter
PCB Holder, Soldering Iron
PCB Holder, Soldering Iron

Story

Read more

Schematics

PCB audio

.

Schematic system

PCB system

Code

Mode basse consommation

C/C++
À 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:

MaximWire_maison

C/C++
#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

C/C++
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("%");

}       

HX711_maison

C/C++
#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

C/C++
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

C/C++
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

C/C++
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
This is a code which contains the setup and the loop for running all the files together
#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);
}

Credits

王屹飞

王屹飞

1 project • 0 followers
Yasmine AMANGAR

Yasmine AMANGAR

2 projects • 0 followers
Steve Kiboua

Steve Kiboua

1 project • 1 follower
Jeremy Batchi

Jeremy Batchi

1 project • 1 follower

Comments