//--------------------------------------------------------------
//------------- BEES MAYHELP ---------------------------------
//--------------------------------------------------------------
//Project by: Davide Cogliati for the Build2together challenge
// edition for Nov-2023
//
//
//revision: 1.0 November 2023
//--------------------------------------------------------------
//
//Abstract:
//-------------
//This software was think to model the sound from bees in a hive
//in order to get information on strenght, health, problems in the hive
//and activity level (depending on the season of the year).
//Many observations were made on the field before coding this model in order
//to match the most real behaviour of honey bees.
//This modeling can permit to disable people to assist and follow a bee farming
//acitvity avoiding heavy work on the field on the hives, actually necessary due
//to the lack in a tool as the one I tought in this project.
//I hope can be used and make possible to averybody to approach fully free from
//restrictions a farming activity.
//Of course someone helping for fatigue job is necessary but the most is done
//just sitting down by a computer or laptop or similar.
//
//This work will be sharpened using Blues card technology as a second step
//and I hope in a real interest in my research so I can evolve in a greater
//work soon.
//
//----------------------------------------
//HARDWARE PINS: assigned to ARDUINO UNO
//----------------------------------------
#define SOUND_PIN A0
#define LED_alarm_high 9
#define DIGITAL_SOUND 6 //input for digital out from sensor to measure frequency of sound (not used!)
#define BUZZER_alarm 7
#define LED_alarm 8
//-----------------------------------------
//WORKING PARAMETERS FOR AI IMPLEMENTATION
//-----------------------------------------
#define THRESHOLD 300 //not used yet parameter!
#define SOUND_SAMPLING 200 //time between sampling SOUND LEVEL, works on delay() instruction.
#define ALARM_EVENT_1 50 //20 //TRESHOLD FOR ALARM EVENT ON BEES BEHAVIOUR
#define ALARM_EVENT_HIGH 100 //TRESHOLD FOR HIGHER GRADE ALARM - can be modified based on experience on the field
#define ALARM_PEAK_time 50 //number of ALARM PEAKS collected in a CONSTANT elapse of time...30= 30 seconds
#define AVERAGE_SAMPLES_GET 10 // processed samples to get a running average on sound samples
#define STORE_TIME 24 //stores in internal memory every x_Hours, if 24= 24 hours (1 time a day)
//data stored are:
//
//1-average level of sound
//2-max.peak of sound recorded in x_Hours
//3-Alarm events
//4-max. average activity
//
//
#define GRAPH 1 //0= MONITOR MODE-TEXT 1= GRAPHICAL X-Y MODE
//-----------------------------------------
unsigned long timestamp = 0;
void setup(){
pinMode(SOUND_PIN, INPUT);
pinMode(LED_alarm_high, OUTPUT);
pinMode(LED_alarm, OUTPUT);
pinMode(BUZZER_alarm, OUTPUT);
pinMode(DIGITAL_SOUND,INPUT);
Serial.begin(9600); // setup serial
}
void loop()
{
//--------------------------------
//program variables initialize
//--------------------------------
int sound_LEVEL = 0;
int freq=0;
int Average=0;
int samples=0;
int Average_AV=0;
int sub_AV=0;
int sound_Level_2 =0;
int sound_Level_1 =0;
int Grad=0;
int toggle=0;
int Average_1=0;
int Average_2=0;
int Grad_AV=0;
int Points=0; //points measure collected
int Global_average=0; //the global average of many points collected
int Ref_zero =0; //the zero sound value reference
int Acty_mean=0; //the mean value activity going on
int Acty_sum=0; //summing value for activity
int val=0; //general use!
int Points_acty=0; //points to evaluate activuty figure
int Peak_activity=0; //peak value in activity evaluation, single point evalued
int val_before=0; //value before latest to clamp the max. value acitvity
int val_max=0; //peak value for activity
int Activity_ratio=0; //the ratio between peak level and average activity level
int Alarm_flag=0; //flag for ALARM_1 threshold
int Alarm_time=0; //time to plot the Alarm-Alert trace
int Peak_timer=0; //time to collect the number of ALARMS peaks (warning on bees!)
int Peaks_alarm=0; //number of peaks collected in one window of Peak_timer = ALARM_PEAK_time .
int Plot_n_alarms=0; //the number to plot or readable data out of the collected alarms
int Graph_val_max=0; //max value interpolation on graph
unsigned long Sec_milli=0; //used by internal timer for save data
unsigned long Milli_1=0; //used for time
unsigned long Milli_2=0; //used fo time
int Period_alrs_HIGHER=0; //higher grade alarms during period
//-------------------------------------------
//time function FOR SAVING PERIODICALLY DATA
//-------------------------------------------
int seconds = 0;
int minutes = 0;
int hours = 0;
int days=0;
//------------------------------------------
//SAVED DATA VARIABLES
//------------------------------------------
//1-average level of sound
//2-max.peak of sound recorded in x_Hours
//3-Alarm events
//4-max. average activity
//------------------------------------------
int Period_ave_sound_min=10000;
int Period_ave_sound_max=0;
int Period_peak_sound=0;
int Period_alrs=0;
int Period_max_acty=0;
//--------------------------------------
//GRAPH LAYOUT SCREEN
//--------------------------------------
if(GRAPH)
{
Serial.print("sound");
Serial.print(" ");
Serial.print("Aver");
Serial.print(" ");
Serial.print("Acti_ratio");
Serial.print(" ");
Serial.print("Max_acti");
Serial.print(" ");
Serial.print("Ref");
Serial.print(" ");
Serial.print("Acty_mean");
Serial.print(" ");
Serial.print("Alert");
Serial.print(" ");
Serial.print("nAlarms");
Serial.print(" ");
Serial.print("Valmax");
//Serial.print(" ");
//
//Serial.print("Sec"); //could also print seconds elapsed, not used now
Serial.println();
}
//--------------------------------------------------------
//SET POINT FOR HARDWARE SOUND ELECTRONIC AMPLIFIER STAGE
//--------------------------------------------------------
for(Points=1; Points <11; Points++)
{
sound_LEVEL = analogRead(SOUND_PIN); //READ SOUND SENSOR INPUT - ANALOG MEASURE
Average = (Average + sound_LEVEL ); //adding for average
delay(10); //waiting before next measure
}
Average = Average/10; //divide 10 because 10 measures are taken
Ref_zero = Average; //assign ref. point
Average =0;
Points =0;
//----------------------------------------
//ENDLESS LOOP WITH PROGRAM RUNNING
//----------------------------------------
while(1)
{
Points = Points +1; //increment count of points
Points_acty= Points_acty +1;
sound_LEVEL = analogRead(SOUND_PIN); //READ SOUND SENSOR INPUT - ANALOG MEASURE
sound_Level_1 = sound_LEVEL; //first value for gradient calculus
//--------------------------------------
if(1) //always true, main loop
{
//--------------------------------------
//TIME - DATE counter
//--------------------------------------
Milli_2 = millis() / 1000;
Sec_milli = Milli_2 - Milli_1;
Milli_1 = Milli_2;
if (Sec_milli ==1)
{
seconds = seconds +1;
if(seconds ==60)
{
minutes = minutes +1;
seconds=0;
}
if (minutes == 60)
{
hours = hours +1;
minutes =0;
}
if (hours == 24)
{
days = days +1;
hours =0;
}
Sec_milli=0;
}
//---------------------------------------
//SAVE DATA AT ESTABLISHED TIME ELAPSED
//--------------------------------------
if(hours == STORE_TIME)
{
//--------------------------------------------------------
//get storage address memory adr.0 of I2C
//or apply a SD shield to Arduino to store Giga of data
//-------------------------------------------------------
//----------------------------------------------------------------------------
//STORE data:
//-------------
//these data can be modified to save more variables for a more complete view
//of the hive
//----------------------------------------------------------------------------
//1-average level of sound
//2-max.peak of sound recorded in x_Hours
//3-Alarm events
//4-max. average activity
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//--------------------------------
//store NEW updated next address
//--------------------------------
//--------------------------------------
//print data on serial
//--------------------------------------
Serial.println("========================================");
Serial.println("DATA RECORDED IN ONE PERIOD OF TIME");
Serial.println("========================================");
Serial.println("Peak value of record time");
Serial.println(Period_peak_sound);
Serial.println("Average sound max value");
Serial.println(Period_ave_sound_max);
Serial.println("Average sound min value");
Serial.println(Period_ave_sound_min);
Serial.println("Number of alarms each period");
Serial.println(Period_alrs);
Serial.println("Peak value of activity");
Serial.println(Period_max_acty);
Serial.println("Number of HIGHER GRADE alarms each period");
Serial.println(Period_alrs_HIGHER);
Serial.println("****************************************");
Serial.println("******** END DATA **********************");
Serial.println("****************************************");
//--------------------------------------
//-------------
//reset DATA
//-------------
seconds = 0;
minutes = 0;
hours = 0;
Period_peak_sound=0;
Period_ave_sound_max=0;
Period_ave_sound_min =10000; //arbitrary high value to get the minimum
Period_alrs=0;
Period_alrs_HIGHER=0;
Period_max_acty=0;
}
//--------------------------------------
samples= samples +1; //SAMPLES are incrementing +1
Average = (Average + sound_LEVEL ); //adding for average
if(sound_LEVEL > Ref_zero) //COLLECT ONLY Sounds greater than REFERENCE-zero level of audio equipment
{
val = sound_LEVEL - Ref_zero; //the useful SOUND signal
//}
//---------------------------------------
//SEARCH FOR MAX VALUE: clamping process
//---------------------------------------
if (val > val_before)
{
val_max = val; //clamp the peak!
//--------------------------------------
//GRAPH interpolation for MAX value
//--------------------------------------
if (val_max > 0) //accept only values greater than zero, val_max is put =0 at every data collection sampled!
{
Graph_val_max = val_max;
if (val_max >Period_peak_sound) //clamp max. value for the period data sampling
Period_peak_sound=val_max; //DATA STORED <==================================>
}
}
//--------------------------------------
Acty_sum= Acty_sum + val; //adding up "val" for the AVERAGE PEAK MAX. VALUE
val_before = val; //saved as formerly value
}
//---------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
if(samples == AVERAGE_SAMPLES_GET) //number of samples to count for the local mean
{
Average_AV = (Average )/ samples; //calculate average value
//----------------------------------------------------
//AVERAGE VALUE FOR STORE PERIOD
//-----------------------------------------------------
if(Period_ave_sound_min > Average_AV)
Period_ave_sound_min= Average_AV; //clamp the minimum
if(Average_AV > Period_ave_sound_max )
Period_ave_sound_max= Average_AV; //clamp the maximum
// Period_ave_soundmin/max // DATA STORED <==============================>
//
//------------------------------------------------------
samples=0; //reset samples count
Average =0; //reset mean value to zero
toggle = toggle +1;
if (toggle ==2)
toggle =0;
if (toggle==0)
Average_1= Average_AV;
if (toggle==1)
Average_2= Average_AV;
}
sound_LEVEL = analogRead(SOUND_PIN); //READ SOUND SENSOR INPUT - ANALOG MEASURE
//-----------------------------------------------------------------------------
sound_Level_2 = sound_LEVEL; //second value for gradient calculus
Grad = ((sound_Level_2) - (sound_Level_1))/0.1;
Grad_AV = (( Average_2) - ( Average_1))/0.1;
if(Points_acty == 10) //Average for activity level
{
Acty_mean = (Acty_sum/ Points_acty);//*10; // x 10 amplified
//-------------------------------
//useful signal
//-------------------------------
if(Acty_mean >2)
{
//TRESHOLD VALUE TO AVOID NOISE ON ELECTRONICS AMPLIFIER!
Activity_ratio = ((val_max )/(Acty_mean))*10; //Amplify value x 10
if (Acty_mean > Period_max_acty)
Period_max_acty= Acty_mean; //clamp for the peak activity value in the period
} //DATA STORED <================================>
//--------------------------------
//NOT useful signal, cut off noise
//---------------------------------
if(Acty_mean <= 2) //TRESHOLD VALUE TO AVOID NOISE ON ELECTRONICS AMPLIFIER!
Activity_ratio = 0;
Points_acty=0; //reset data collection
Acty_sum= 0;
val_before=0;
val_max=0;
Alarm_time=0;
}
//-------------------------------------------------------------
//LOOKS FOR ALARM_EVENT, high localized activity from sound
//-------------------------------------------------------------
if (Alarm_flag < 100)
{
digitalWrite(BUZZER_alarm,LOW);
digitalWrite(LED_alarm,LOW);
digitalWrite(LED_alarm_high,LOW);
}
if ((Activity_ratio > ALARM_EVENT_1)& (Alarm_time < 2)) // <2 determines the amplitude of the visible peak on graph (a rectangular shape!)
{
Alarm_flag = 300 ; //show a peak on the graph, ALARM_1 signal height=300
Peaks_alarm= Peaks_alarm +1; //increment +1 alarm peaks
digitalWrite(BUZZER_alarm,HIGH);
digitalWrite(LED_alarm,HIGH);
Period_alrs = Period_alrs+1; //clamp the adding of the alarms in the storing time interval
//DATA STORED <=====================================>
}
if ((Activity_ratio > ALARM_EVENT_HIGH)& (Alarm_time < 2)) // <2 determine the amplitude of the visible peak on graph (a rectangular shape!)
{
Alarm_flag = 600 ; //show a peak on the graph, ALARM_1 signal height=600
digitalWrite(BUZZER_alarm,HIGH);
digitalWrite(LED_alarm,HIGH);
digitalWrite(LED_alarm_high,HIGH);
Peaks_alarm= Peaks_alarm +1; //increment +1 alarm peaks
Period_alrs_HIGHER= Period_alrs_HIGHER+1; //clamp the adding of the alarms in the storing time interval
//DATA STORED <=====================================>
}
Alarm_time = Alarm_time +1; //time show window for the ALARM peak
if (Alarm_time > 2) //sets to zero the signal peak, just squared out.
Alarm_flag = 0 ;
Peak_timer = Peak_timer + 1; //increment the time for collecting number of alarms in the "ALARM_PEAK_time" window
if (Peak_timer > ALARM_PEAK_time)
{
Plot_n_alarms= Peaks_alarm*10; //amplify x 10
Peaks_alarm=0;
Peak_timer =0;
}
}
freq= digitalRead(DIGITAL_SOUND);
// Serial.print(sound_LEVEL);//,DEC); // debug value
// Serial.print(" ");
// Serial.print(freq)*700;
// Serial.print(" ");
// Serial.print(Average_AV);
// Serial.print(" ");
//---------------------------------------------------
//GRADIENT evaluation of signal intensity variation
//not used in this model but maybe in the next time
//---------------------------------------------------
if (Points > 10) //starting average gradients after 3 points to load sufficient data
{
// Serial.print(Grad);
// Serial.print(" ");
// Serial.print(Grad_AV);
// Serial.print(" ");
}
//---------------------------------------------
//OUTPUT ON SCREEN
//---------------------------------------------
//--------------------------------------
//print data on serial
//--------------------------------------
if(!GRAPH)
{
Serial.println("=========================================");
Serial.println("DAYS -- HOURS -- MINUTES -- SECONDS ");
Serial.print(days); Serial.print(" -- "); Serial.print(hours); Serial.print(" -- "); Serial.print(minutes); Serial.print(" -- "); Serial.print(seconds);
Serial.println("-----------------------------------------");
Serial.println("Reference level of sound");
Serial.println(Ref_zero);
Serial.println("Level of sound");
Serial.println(sound_LEVEL - Ref_zero);
Serial.println("Peak value of record time");
Serial.println(Period_peak_sound);
Serial.println("Average sound max value");
Serial.println(Period_ave_sound_max);
Serial.println("Average sound min value");
Serial.println(Period_ave_sound_min);
Serial.println("Number of alarms each period");
Serial.println(Period_alrs);
Serial.println("Peak value of activity");
Serial.println(Period_max_acty);
Serial.println("Number of HIGHER GRADE alarms each period");
Serial.println(Period_alrs_HIGHER);
Serial.println("========================================");
}
//--------------------------------------
if(GRAPH)
{
Serial.print(sound_LEVEL);
Serial.print(" ");
Serial.print(Average_AV);
Serial.print(" ");
Serial.print(Activity_ratio);
Serial.print(" ");
Serial.print(val_max);
Serial.print(" ");
Serial.print(Ref_zero);
Serial.print(" ");
Serial.print(Acty_mean);
Serial.print(" ");
Serial.print(Alarm_flag);
Serial.print(" ");
Serial.print(Plot_n_alarms);
Serial.print(" ");
Serial.print(Graph_val_max);
//Serial.print(" ");
//Serial.print(seconds); //can also print/plot seconds elapsed...
Serial.println();
}
delay(SOUND_SAMPLING);
}
}
Comments