// INCLUDE
#include <Arduino_HTS221.h>
#include <HX711.h> // Balance
#include <DHT.h> // DHT
#include <Wire.h> // INA
#define MAXIMWIRE_EXTERNAL_PULLUP
#include <MaximWire.h> // DSB
#include "DFRobot_INA219.h"
#define T 64
signed short freq_amp[32][2];
signed short amplitude[10];
// --Initialisation LoraWan
static char recv_buf[512];
static bool is_exist = false;
static bool is_join = false;
int ret=0;
// ----------------------
// --Initialisation DHT
#define brocheDeBranchementDHTa 7
#define brocheDeBranchementDHTb 9
#define typeDeDHT DHT22
DHT dhta(brocheDeBranchementDHTa, typeDeDHT);
DHT dhtb(brocheDeBranchementDHTb, typeDeDHT);
// ----------------------
// --Initlisation Balance
HX711 capteurPoids;
#define DAT 13
#define CLK 12
float valeurPoids;
// ----------------------
// --Initialisation Batterie
const float TensionMax = 4.2;
const float TensionMin = 3.3;
// ----------------------
// --Initialisation INA
DFRobot_INA219_IIC ina219(&Wire, INA219_I2C_ADDRESS4);
float ina219Reading_mA = 1000;
float extMeterReading_mA = 1000;
// ----------------------
// --Initialisation DSB
#define PIN_BUS 6
MaximWire::Bus bus(PIN_BUS);
MaximWire::DS18B20 device;
int cpt=0;
signed short temp_dsb[2];
// ----------------------
// --SETUPS--
void setupLED(){
pinMode(LED_BUILTIN, OUTPUT);
pinMode(LED_PWR, OUTPUT);
digitalWrite(LED_PWR, LOW);
digitalWrite(LED_BUILTIN, HIGH);
delay(5000);
digitalWrite(LED_BUILTIN, LOW);
}
void setupDHT(){
dhta.begin();
dhtb.begin();
}
void setupBalance(){
capteurPoids.begin(DAT, CLK);
capteurPoids.set_scale(30032);
//capteurPoids.tare();
}
void setupINA(){
ina219.linearCalibrate(ina219Reading_mA, extMeterReading_mA);
unsigned long timer = millis();
while(ina219.begin() != true) {
if(millis()-timer > 10000) break;
}
}
// ----------------------
// Fonction LORA
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));
Serial1.write(p_cmd);
Serial.write(p_cmd);
delay(200);
startMillis = millis();
do{
while (Serial1.available() > 0){
ch = Serial1.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 setupLORA(){
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: DR0", 1000, "AT+DR=DR0\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,\"6D3E3B5BD04AFA9EBD6C9196EF894740\"\r\n");
at_send_check_response("+ID: DEVEUI", 1000, "AT+ID=DEVEUI,\"70B3D57ED005642E\"\r\n");
at_send_check_response("+ID: 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: 9", 1000, "AT+PORT=9\r\n");
delay(200);
is_join = true;
}
else{
is_exist = false;
Serial.print("No E5 module found.\r\n");
}
}
// ----------------------
// --Fonctions Calculs
float calculBalance(){
valeurPoids = capteurPoids.get_value(10);
float val;
val = float(valeurPoids/32500); // il faut faire un calibrage avec plein de valeurs //
return(val);
}
signed short calculBatterie(){
float a0= analogRead(A0);
float bat= 1.4*2*a0*3.3/1100; //*1.4 car voir pont div.
float minValue= 1.9;
float maxValue= 3;
signed short bat1= 100*(bat-minValue)/(maxValue-minValue);
// if(abs(bat1) > 100){
// if(abs(bat1) >150){
// bat1 = 0;
// }
// bat1 = 100;
// }
if(bat1 < 0) bat1 = 1;
if(bat1>100) bat1=100;
return(bat1);
}
float Q_FFT(int in[],int N,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=N;
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/N;
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]=20*out_r[i];
}
amplitude[0] = ( freq_amp[5][1] +freq_amp[6][1] +freq_amp[7][1] +freq_amp[8][1] );
amplitude[1] = ( freq_amp[8][1] +freq_amp[9][1] +freq_amp[10][1] );
amplitude[2] = ( freq_amp[10][1] +freq_amp[11][1] +freq_amp[12][1] +freq_amp[13][1]+freq_amp[14][1] );
amplitude[3] = ( freq_amp[13][1] +freq_amp[14][1] +freq_amp[15][1] );
amplitude[4] = ( freq_amp[16][1] +freq_amp[17][1] +freq_amp[18][1] );
amplitude[5] = ( freq_amp[18][1] +freq_amp[19][1] +freq_amp[20][1] );
amplitude[6] = ( freq_amp[21][1] +freq_amp[22][1] +freq_amp[23][1] );
amplitude[7] = ( freq_amp[23][1] +freq_amp[24][1] +freq_amp[25][1] );
amplitude[8] = ( freq_amp[26][1] +freq_amp[27][1] +freq_amp[28][1] );
amplitude[9] = ( freq_amp[28][1] +freq_amp[29][1] +freq_amp[30][1] +freq_amp[31][1] );
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/N);
}
signed short calculLumiere(){
signed short luminosite;
luminosite=(5*pow(10,(ina219.getBusVoltage_V()-0.4)));
return luminosite;
}
void calculDSB(){
cpt=0;
MaximWire::Discovery discovery = bus.Discover();
do {
MaximWire::Address address;
if (discovery.FindNextDevice(address)) {
if (address.GetModelCode() == MaximWire::DS18B20::MODEL_CODE) {
MaximWire::DS18B20 device(address);
temp_dsb[cpt] = device.GetTemperature<float>(bus);
device.Update(bus);
}
}
if (cpt == 1) cpt = 0;
else cpt++;
} while ((discovery.HaveMore())||(cpt==1));
}
// ----------------------
void setup() {
// put your setup code here, to run once:
digitalWrite(4, HIGH);
setupLED();
setupDHT();
setupBalance();
setupINA();
delay(3000);
Serial.begin(9600);
Serial1.begin(9600);
Serial.print("E5 LORAWAN TEST\r\n");
setupLORA();
}
void loop() {
digitalWrite(4, HIGH); //On r-allume les capteurs
delay(1000);
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(3000);
}
}
else{
char cmd[128];
signed short temperatureDHT_a, humidityDHT_a;
signed short temperatureDHT_b, humidityDHT_b;
signed short f1, f2, f3, f4, f5, f6, f7, f8, f9, f0;
int poids;
signed short pourcentageBatterie;
signed short courantINA;
float freqFondamentale;
signed short tempDSB_a, tempDSB_b;
int tab[T]; // pour la FFT
for (int i=0;i<T;i++){
tab[i]=analogRead(A6);
delayMicroseconds(800);
}
f0= amplitude[0];
f1= amplitude[1];
f2= amplitude[2];
f3= amplitude[3];
f4= amplitude[4];
f5= amplitude[5];
f6= amplitude[6];
f7= amplitude[7];
f8= amplitude[8];
f9= amplitude[9];
freqFondamentale= Q_FFT(tab,T,1250);
temperatureDHT_a = (dhta.readTemperature()*10 ); // +50 pour les tempratures ngatives
temperatureDHT_a +=50*10;
humidityDHT_a = ( dhta.readHumidity()*10 );
temperatureDHT_b = (dhtb.readTemperature()*10 ); // +50 pour les tempratures ngatives
temperatureDHT_b +=50*10;
humidityDHT_b = ( dhtb.readHumidity()*10 );
poids = int( calculBalance()*100 ); if(poids < 0) poids = 0;
pourcentageBatterie = ( calculBatterie() );
courantINA = ( calculLumiere() );
calculDSB();
tempDSB_a = ((temp_dsb[0]+50)*10); // +50 pour les tempratures ngatives
tempDSB_b = ((temp_dsb[1]+50)*10); // +50 pour les tempratures ngatives
Serial.println("Temperature 1 : ");
Serial.println(temperatureDHT_a);
Serial.println("Humidite 1 :");
Serial.println(humidityDHT_a);
Serial.println("Temperature 2 : ");
Serial.println(temperatureDHT_b);
Serial.println("Humidite 2 : ");
Serial.println(humidityDHT_b);
Serial.println("poids : ");
Serial.println(poids);
Serial.println("batterie : ");
Serial.println(pourcentageBatterie);
Serial.println("Lumiere en % : ");
Serial.println(courantINA);
Serial.println("Temprature DSB 1 : ");
Serial.println(tempDSB_a);
Serial.println("Temprature DSB 2 : ");
Serial.println(tempDSB_b);
Serial.println(" Amplitude 98-146Hz :");
Serial.println(amplitude[0]);
Serial.println(" Amplitude 146-195Hz :");
Serial.println(amplitude[1]);
Serial.println(" Amplitude 195-244Hz :");
Serial.println(amplitude[2]);
Serial.println(" Amplitude 244-293Hz :");
Serial.println(amplitude[3]);
Serial.println(" Amplitude 293-342Hz :");
Serial.println(amplitude[4]);
Serial.println(" Amplitude 342-391Hz :");
Serial.println(amplitude[5]);
Serial.println(" Amplitude 391-439Hz :");
Serial.println(amplitude[6]);
Serial.println(" Amplitude 439-488Hz :");
Serial.println(amplitude[7]);
Serial.println(" Amplitude 488-537Hz :");
Serial.println(amplitude[8]);
Serial.println(" Amplitude 537-586Hz :");
Serial.println(amplitude[9]);
Serial.println(" Fondamentale :");
Serial.println(freqFondamentale);
sprintf(cmd, "AT+MSGHEX=%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X\r\n",
temperatureDHT_a,
humidityDHT_a,
temperatureDHT_b,
humidityDHT_b,
poids,
pourcentageBatterie,
courantINA,
tempDSB_a,
tempDSB_b,
f0, f1, f2, f3, f4, f5, f6, f7, f8, f9
);
at_send_check_response("ACK Received", 5000, cmd);
digitalWrite(4, LOW); //On teint les capteurs
delay(30000); //600000 pour 10 minutes de temps-off
}
}
else{delay(1000);}
delay(2000);
}
Comments
Please log in or sign up to comment.