//Partie temp et hum
//Serial1(6, 7); // (RX, TX)le port fait partie de la carte il est directement relié par les branchements
#define SHDN 2 //D21.
#define LED 11 //déclaration de la LED
#include <DHT.h>
#define brocheDeBranchementDHT_1 7 // La ligne de communication du DHT22 sera donc branchée sur la pin D7 de l'Arduino
#define typeDeDHT DHT22 // Ici, le type de DHT utilisé est un DHT22 (que vous pouvez changer en DHT11, DHT21, ou autre, le cas échéant)
// Instanciation de la librairie DHT
DHT dht1(brocheDeBranchementDHT_1, typeDeDHT);
#define brochedeBranchementDHT_2 6
DHT dht2(brochedeBranchementDHT_2, typeDeDHT);
//Partie poids
#include "HX711.h"
#define LOADCELL_DOUT_PIN 8
#define LOADCELL_SCK_PIN 9
HX711 scale;
short pds=0;
//Partie Lora
static char recv_buf[512];
static bool is_exist = false;
static bool is_join = false;
static int led = 0;
int ret=0;
//Variable temp et hum
short tmp1;
short hum1;
float tauxHumidite1; // Lecture du taux d'humidité (en %)
float temperatureEnCelsius1; // Lecture de la température, exprimée en degrés Celsius
short tmp2;
short hum2;
float tauxHumidite2;
float temperatureEnCelsius2;
//Partie temp seule
#define MAXIMWIRE_EXTERNAL_PULLUP
#include <MaximWire.h>
#define PIN_BUS 10 //D10
MaximWire::Bus bus(PIN_BUS);
MaximWire::DS18B20 device;
//partie mesure du courant et de la tension pour calculer la luminosité et l'état de la batterie
#include <Wire.h>
#include "DFRobot_INA219.h"
DFRobot_INA219_IIC ina219(&Wire, INA219_I2C_ADDRESS4);
float ina219Reading_mA = 1000;
float extMeterReading_mA = 1000;
//bool etat = false, etat_avant = false;
short tauxluminosite; // Lecture du taux de liminosite (en %)
short batterie; // état de la batterie (en %)
//partie FFT
#include "arduinoFFT.h"
//Variables gloabeles nécessaires
#define SAMP_FREQ 2048
#define NUM_SAMP 256
unsigned int samp_period;
unsigned long timing;
// Vectors to hold samples
double real[NUM_SAMP];
double imag[NUM_SAMP];
double freq_imp;
double freq[(NUM_SAMP>>1)+1];
short fft;
arduinoFFT FFT = arduinoFFT();
//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 setup() {
//paramétrage de la led pour qu'elle s'allume 3 secondes si on allume l'interrupteur
// 2 lignes suivantes en +
pinMode(SHDN, OUTPUT);
digitalWrite(SHDN,HIGH);
pinMode(LED_PWR, OUTPUT);
delay(1000);
digitalWrite(LED_PWR, LOW);
pinMode(LED, OUTPUT);
delay(1000);
digitalWrite(LED, HIGH);
delay(3000);
digitalWrite(LED, LOW);
delay(3000);
// put your setup code here, to run once:
Serial.begin(9600);
Serial1.begin(9600);
Serial.print("Serial1 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("+DR: DR0", 1000, "AT+DR=DR0\r\n"); //ligne ajoutéé!
at_send_check_response("+CH: NUM", 1000, "AT+CH=NUM,0-2\r\n");
at_send_check_response("+KEY: APPKEY", 1000,"AT+KEY=APPKEY,\"D65874A71B9E99229F2D43C9D3C6E000\"\r\n");
at_send_check_response("+KEY: DEVEUI", 1000, "AT+ID=DEVEUI,\"2CF7F1203230C97C\"\r\n");
at_send_check_response("+KEY: APPEUI", 1000, "AT+ID=APPEUI,\"8000000000000006\"\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 Serial1 module found.\r\n");
}
// Initialisation de la liaison série (pour retourner les infos au moniteur série de l'ordi)
//Serial.begin(9600);
//Serial.println("Programme de test du DHT22");
//Serial.println("==========================");
//Serial.println();
// Initialisation du DHT22;
dht1.begin();
dht2.begin();
//Partie balance
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
//partie mesure courant et tension
Serial.println();
while(ina219.begin() != true)
{
Serial.println("INA219 begin failed");
delay(2000);
}
ina219.linearCalibrate(ina219Reading_mA, extMeterReading_mA);
Serial.println();
//Partie FFT
samp_period = round(1000000 * (1.0 / SAMP_FREQ));
}
void loop() {
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");
// Lecture des données
tauxHumidite1 = dht1.readHumidity();
Serial.println(tauxHumidite1);
temperatureEnCelsius1 = dht1.readTemperature();
Serial.println(temperatureEnCelsius1);
tauxHumidite2 = dht2.readHumidity();
Serial.println(tauxHumidite2);
temperatureEnCelsius2 = dht2.readTemperature();
Serial.println(temperatureEnCelsius2);
//lecture des données de courant et de tension
Serial.print("Batterie chargée à ");
Serial.print(analogRead(A7)*0.1538); // *100 / 650
Serial.println("%");
//batterie = analogRead(A7)*0.1538*100;
Serial.print("Current: ");
Serial.print(abs(ina219.getCurrent_mA()), 1);
Serial.print("mA -> ");
Serial.print(abs(ina219.getCurrent_mA()/4), 1);
Serial.println(" pourcent de luminosité");
//tauxluminosite = abs(ina219.getCurrent_mA()/4)*100;
// Vérification si données bien reçues
if (isnan(tauxHumidite1) || isnan(temperatureEnCelsius1) || isnan(tauxHumidite2) || isnan(temperatureEnCelsius2)) {
Serial.println("Aucune valeur retournée par le DHT22. Est-il bien branché ?");
delay(2000);
return; // Si aucune valeur n'a été reçue par l'Arduino, on attend 2 secondes, puis on redémarre la fonction loop()
}
// Calcul de la température ressentie
//float temperatureRessentieEnCelsius = dht.computeHeatIndex(temperatureEnCelsius, tauxHumidite, false); // Le "false" est là pour dire qu'on travaille en °C, et non en °F
// Affichage des valeurs
//Serial.print("Humidité = "); Serial.print(tauxHumidite); Serial.println(" %");
//Serial.print("Température = "); Serial.print(temperatureEnCelsius); Serial.println(" °C");
//Serial.print("Température ressentie = "); Serial.print(temperatureRessentieEnCelsius); Serial.println(" °C");
//Serial.println();
// Temporisation de 2 secondes (pour rappel : il ne faut pas essayer de faire plus d'1 lecture toutes les 2 secondes, avec le DHT22, selon le fabricant)
delay(2000);
}
else{
at_send_check_response("+ID: AppEui", 1000, "AT+ID\r\n");
Serial.println();
Serial.print("JOIN failed!\r\n\r\n");
delay(5000);
}
}
else{
char cmd[128];
//poids + sleep mode
scale.power_up();
pds = ((scale.get_units()-333857)/29661)*100;
scale.power_down();
//partie batterie
//important : a 100% de batterie, analogRead vaut 642, a 0%, il vaut 512
//(analogRead(A7)-512)doit donner une valeur entre 130 et 0 -> /130 * 100 = pourcentage
batterie = analogRead(A7); //510 pour avoir une marge -> pas de valeurs négatives
tauxluminosite = abs(ina219.getCurrent_mA()/4)*100;
digitalWrite(SHDN,HIGH);
dht1.begin();
dht2.begin();
delay(10000);//histoire de laisser le temps de s'init bien
//Partie FFT
// Sampling
for (int i=0; i<NUM_SAMP; i++) {
// Time since Arduino began script
timing = micros();
// Take in ADC measurement from pin A0
real[i] = analogRead(A3);
//Set imaginary term of sample to 0
imag[i] = 0;
// Pause to set frequency
while((samp_period + timing) > micros()){
}
}
// FFT
FFT.Windowing(real, NUM_SAMP, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(real, imag, NUM_SAMP, FFT_FORWARD);
FFT.ComplexToMagnitude(real, imag, NUM_SAMP);
// Calculate most prominant frequency
freq_imp = FFT.MajorPeak(real, NUM_SAMP, SAMP_FREQ)-15;
Serial.print("frequence :");
Serial.println(freq_imp);
fft=freq_imp*100;
freq[0]=0;
for(int i=1; i<((NUM_SAMP>>1)+1); i++){
double delta = 0.5 * ((real[i-1] - real[i+1]) / (real[i-1] - (2.0 * real[i]) + real[i+1]));
double interpolatedX = ((i + delta) * SAMP_FREQ) / (NUM_SAMP-1);
if(i==(NUM_SAMP>> 1)) //To improve calculation on edge values
interpolatedX = ((i + delta) * SAMP_FREQ) / (NUM_SAMP);
freq[i]=interpolatedX-15;
}
double val[10]={0,0,0,0,0,0,0,0,0,0};
int cpt[10]={0,0,0,0,0,0,0,0,0,0};
for(int i=0; i<((NUM_SAMP>>1)+1); i++){
if(freq[i]>98 && freq[i]<=146){
val[0]+=real[i]*(3.3/1024)*1000;
cpt[0]++;
}
else if(freq[i]>146 && freq[i]<=195){
val[1]+=real[i]*(3.3/1024)*1000;
cpt[1]++;
}
else if(freq[i]>195 && freq[i]<=244){
val[2]+=real[i]*(3.3/1024)*1000;
cpt[2]++;
}
else if(freq[i]>244 && freq[i]<=293){
val[3]+=real[i]*(3.3/1024)*1000;
cpt[3]++;
}
else if(freq[i]>293 && freq[i]<=342){
val[4]+=real[i]*(3.3/1024)*1000;
cpt[4]++;
}
else if(freq[i]>342 && freq[i]<=391){
val[5]+=real[i]*(3.3/1024)*1000;
cpt[5]++;
}
else if(freq[i]>391 && freq[i]<=439){
val[6]+=real[i]*(3.3/1024)*1000;
cpt[6]++;
}
else if(freq[i]>439 && freq[i]<=488){
val[7]+=real[i]*(3.3/1024)*1000;
cpt[7]++;
}
else if(freq[i]>488 && freq[i]<=537){
val[8]+=real[i]*(3.3/1024)*1000;
cpt[8]++;
}
else if(freq[i]>537 && freq[i]<=586){
val[9]+=real[i]*(3.3/1024)*1000;
cpt[9]++;
}
}
short f[10];
Serial.println("Valeur :");
for(int i=0; i<10; i++){
if(cpt[i]!=0){
f[i]=val[i]/cpt[i];
}else{
f[i]=0;
}
//f[i]=val[i]*10;
Serial.println(val[i]/cpt[i]);
Serial.println(f[i]);
}
tauxHumidite1 = dht1.readHumidity();
Serial.println(tauxHumidite1);
temperatureEnCelsius1 = dht1.readTemperature();
Serial.println(temperatureEnCelsius1);
tauxHumidite2 = dht2.readHumidity();
Serial.println(tauxHumidite2);
temperatureEnCelsius2 = dht2.readTemperature();
Serial.println(temperatureEnCelsius2);
//hum et temp
tmp1 = (temperatureEnCelsius1*1.02)*100;
hum1 = tauxHumidite1*100;
tmp2 = (temperatureEnCelsius2)*100;
hum2 = tauxHumidite2*100;
//code temp solo
MaximWire::Discovery discovery = bus.Discover();
short temp1_solo=(temperatureEnCelsius1+0.07)*100;
short temp2_solo=(temperatureEnCelsius1-0.09)*100;
int i=0;
do {
MaximWire::Address address;
if (discovery.FindNextDevice(address)) {
if (address.GetModelCode() == MaximWire::DS18B20::MODEL_CODE) {
MaximWire::DS18B20 device(address);
float tp = device.GetTemperature<float>(bus);
device.Update(bus);
if(i==0){
temp1_solo=(tp*1.02)*100;
i++;
}else{
temp2_solo=(tp)*100;
i--;
}
}
}
}while (discovery.HaveMore());
//partie mode sleep
digitalWrite(SHDN,LOW);
//envoie de mess
//ligne en + non vérifiée pour assurer l'émission en SF12
at_send_check_response("+DR: DR0", 1000, "AT+DR=DR0\r\n"); //ligne ajoutéé!
//sprintf(cmd, "AT+MSGHEX=%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X\r\n", tmp1, hum1, temp1_solo,temp2_solo, pds, tmp2, hum2, tauxluminosite, batterie, fft);
sprintf(cmd, "AT+MSGHEX=%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X\r\n", tmp1, hum1, temp1_solo,temp2_solo, pds, tmp2, hum2, tauxluminosite, batterie, fft, f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7], f[8], f[9]);
//sprintf(cmd, "AT+MSGHEX=%04X%04X%04X%04X%04X%04X%04X%04X%04X%04X\r\n", f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7], f[8], f[9]);
//les valeurs sont multipliées par 100 pour être entière -> pouvoir envoyer en hexadécimale
at_send_check_response("ACK Received", 5000, cmd);
delay(20000);
}
}
else{
delay(1000);
}
//delay(3600000); //pour un délai d'1h car delay 1000=1sec
//delay(580000);
//delay(5000);
}
Comments