Bonjour,
Ci-dessous mon code qui fonctionne très bien. Avec du recul, je désire concernant uniquement la pluviométrie que cette dernière fasse une remise à zéro journalière de mes relevés.
J’utilise :
-SIM900
-UNO REV3
-DHT22
-Pluviomètre
Comment solutionner ma demande.
Merci.
Laure
#include <SoftwareSerial.h>
#include <DHT.h>
#include <EEPROM.h>
struct __attribute__ ((packed)) _paramS {
unsigned long nombreDeGodets;
} lesParametres;
const uint32_t motClef = 0xDEADBEEF;
const uint16_t adresseMotClef = 0x00;
const uint16_t adresseDesParametres = adresseMotClef + sizeof(motClef);
const byte pinResetEEPROM = 3; // pin 3 --> bouton --> GND
const byte pinDHT = 5;
const byte pinCapteurPluie = 2; // connectez la pin 2 à la pin de signal du capteur de pluie, avec résistance de pullup externe
const double hauteurPourUnGodet = 0.2794; // mm d'hauteur d'eau
const unsigned long antiRebondGodet = 20; // en ms
volatile unsigned long nombreDeGodets = 0;
const unsigned long periodeEnvoi = 30000ul; // émission toutes les 10m inutes (600s en ms)
unsigned long dernierEnvoi = -periodeEnvoi;
SoftwareSerial SIM800L(7, 8); //Serial SIM800L pin
DHT dhtSensor(pinDHT, DHT22);
#define Write_API_key "**************" //Thingspeak Write API Key
const char * apn = "orange";
const char * url = "GET https://api.thingspeak.com/update?api_key=" Write_API_key;
void etablirValeursParDefaut(bool forceReset = false)
{
uint32_t lectureMotClef;
EEPROM.get(adresseMotClef, lectureMotClef);
if (forceReset || lectureMotClef != motClef) {
// la mémoire n'avait pas encore été initialisée ou on veut forcer le reset
lesParametres.nombreDeGodets = 0;
EEPROM.put(adresseDesParametres, lesParametres);
EEPROM.put(adresseMotClef, motClef);
} else {
// la mémoire a déjà été initialisée, on peut charger les paramètres
EEPROM.get(adresseDesParametres, lesParametres);
}
}
void ShowSerialData() {
while (SIM800L.available() != 0) Serial.write(SIM800L.read());
}
void SetupModule() {
ShowSerialData();
SIM800L.println(F("AT")); delay(200);
ShowSerialData();
SIM800L.println(F("AT+CPIN?")); delay(1000);
SIM800L.println(F("AT+CREG?")); delay(1000);
SIM800L.println(F("AT+CGATT?")); delay(1000);
ShowSerialData();
SIM800L.println(F("AT+CIPSHUT")); delay(1000);
SIM800L.println(F("AT+CIPSTATUS")); delay(2000);
SIM800L.println(F("AT+CIPMUX=0")); delay(2000);
ShowSerialData();
//setting the APN,
SIM800L.print(F("AT+CSTT=\""));
SIM800L.print(apn);
SIM800L.println(F("\"")); delay(1000);
ShowSerialData();
SIM800L.println(F("AT+CIICR")); delay(2000);
ShowSerialData();
//get local IP adress
SIM800L.println(F("AT+CIFSR")); delay(2000);
ShowSerialData();
SIM800L.println(F("AT+CIPSPRT=0")); delay(2000);
ShowSerialData();
}
void godetPlein() {
static unsigned long dernierGodet = -antiRebondGodet;
unsigned long maintenant = millis();
if (maintenant - dernierGodet >= antiRebondGodet) {
nombreDeGodets++;
dernierGodet = maintenant;
}
}
void lectureCapteurs(float &h, float &t, float &p) {
h = dhtSensor.readHumidity();
t = dhtSensor.readTemperature();
noInterrupts();
lesParametres.nombreDeGodets = nombreDeGodets;
interrupts();
// on sauvegarde le nouveau bnombre de godets si nécessaire
EEPROM.put(adresseDesParametres, lesParametres);
p = lesParametres.nombreDeGodets * hauteurPourUnGodet;
Serial.println();
Serial.print(F("Température = ")); Serial.print(t); Serial.print(F(" °C"));
Serial.write('\t');
Serial.print(F("Humidité = ")); Serial.print(h); Serial.print(F(" %"));
Serial.write('\t');
Serial.print(F("Pluie = ")); Serial.print(p, 4); Serial.println(F(" mm"));
}
void setup() {
pinMode(pinResetEEPROM, INPUT_PULLUP);
pinMode(pinCapteurPluie, INPUT); // pullup externe de 10kΩ
Serial.begin(115200);
SIM800L.begin(9600);
dhtSensor.begin();
etablirValeursParDefaut(digitalRead(pinResetEEPROM) == LOW); // on fait un reset du compteur si le bouton est appuyé
nombreDeGodets = lesParametres.nombreDeGodets;
Serial.println("SIM800L GPRS Test");
delay(2000);
SetupModule();
attachInterrupt(digitalPinToInterrupt(pinCapteurPluie), godetPlein, FALLING);
}
void loop() {
unsigned long maintenant = millis();
if (maintenant - dernierEnvoi >= periodeEnvoi) { // est-ce le moment d'émettre ?
dernierEnvoi = maintenant; // on se souvient du moment
// émission
SIM800L.println(F("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\""));
delay(3000);
ShowSerialData();
Serial.println();
SIM800L.println(F("AT+CIPSEND"));
delay(2000);
ShowSerialData();
float humidite;
float temperature;
float hauteurPluie;
lectureCapteurs(humidite, temperature, hauteurPluie);
// on construit la requête GET
String requete = url;
requete += "&field1=";
requete += String(temperature);
requete += "&field2=";
requete += String(humidite);
requete += "&field3=";
requete += String(hauteurPluie, 4); // 4 chiffres après la virgule
Serial.print(F("Envoi de : ")); Serial.println(requete);
SIM800L.println(requete);
SIM800L.println((char)26); delay(4000);
Serial.println();
ShowSerialData();
SIM800L.println("AT + CIPSHUT"); delay(500); // on termine la session
ShowSerialData();
}
}
Tu veux une fois pas jour remettre ta variable "nombreDeGodets" à zéro ?
Comme tu sauvegarde tes relevés sur thinkpeak, n'est-il pas possible de gérer les auteurs cumulé sur le Dashboard avec une granularité configurable?
Dans ce cas tu pourrais remettre à zéro ta variable à chaque envois?
Sinon, il doit être possible de récupérer l'heure via ton module GPRS périodiquement, pour compenser la dérive du µC et faire ton reset à l'heure fixe.
Il faudrait regarder du coté de cette librairie pour la gestion de l'heure
Merci pour ta réponse.
"Tu veux une fois pas jour remettre ta variable "nombreDeGodets" à zéro ?" : oui
Concernant thinkpeak il faudrait que je regarde, toutefois je ne sais pas si cela se fait automatiquement.
Sinon ce bout de code ne ferait-il pas l'affaire ? Faut-il mettre obligatoirement une librairie ?
Laure
}
if(now.hour()== 0) {
dailyRain = 0.0; // pluie quotidienne claire à minuit
dailyRain_till_LastHour = 0.0; // nous ne voulons pas de pluie négative à 01h00
}
Pour avoir "now" il faut que tu fasse une inclusion d'un fichier d'en-tête d'une librairie.
Je ne crois pas que cela fasse directement partie du framework Arduino.
Mais le problème principal, c'est que l'heure va dériver petit à petit(voir pas si petit à petit ) et être remis à zéro à chaque "reset" de ton µC
Oui, lorsque tu utilises la directive "#include" cela inclus dans ton code les en-tête d'une librairie de fonction ou d'objet.
Mais en interne l'IDE ajoute aussi le code de la librairie.
Dans le cas que tu cite tu utilise une librairie RTClib.
Mais comme indiqué le problème principal n'est pas là
Ci-dessous mon code qui fonctionne très bien. Avec du recul, je désire concernant uniquement la pluviométrie que cette dernière fasse une remise à zéro journalière de mes relevés.
De passage rapide sur le forum je fais un remarque qui ne va pas très loin. faute de temps disponible
Il est possible de constuire chez/par ThingSpeak, à partir de la série temporelle horodatée brute issue du pluviomètre + un bout de code Matlab, une nouvelle série temporelle représentant les cumuls sur les intervalles de temps souhaités don par exemple une remise à zéro à minuit
je n'ai pas la solution sous le coude, l'aide en ligne ThingSpeak/Matlab est très bien faite, avec de nombreux exemples.
J'ai trouvé des codes. Toutefois, je ne sais ou les insérer pour faire des essais.
-tu ouvres la page web de ton 'Channel'
-cliques sur MATLAB VISUALIZATION ,
-fais une sélection parmi les options proposées : custom pour une page blanche, ou un des modèles de code
-cliques sur CREATE
-une fenêtre d'édition de code MATLAB s'ouvre
-une fois édité fais SAVE ou SAVE AND RUN
A chaque arrivée de donées brutes issue de ton pluviomètre le script MATLAB sera exécuté pour mettre à jour le graphe avec cumul, ça peut être présenté ou pas sous forme d'histogramme
(la syntaxe du code MATLAB n'est pas des plus limpides...)
RainMatrix = importdata('data.txt');
% Identifies the first and last year of the series
yr = RainMatrix(:,3); % years
yr1 = yr(1); yr_end = yr(end);
Raincum = NaN(yr_end-yr1+1,7); % placeholder
k=0;
for i=yr1:yr_end % scan each year
k=k+1;
idx = find(yr == i);
yri = yr(idx); r = RainMatrix(idx,4); nr = length(r);
length(yri); % check should be 365 or 366 for full years
Raincum(k,1) = max(r);
for j=2:7
rv = r(1:nr - mod(nr,j));
r2 = reshape(rv,j,length(rv)/j);
r2 = sum(r2);
Raincum(k,j) = max(r2);
end
end
%%
yrs = [yr1:yr_end]';
plot(yrs,Raincum)
legend('1','2','3','4','5','6','7')
j'ai des messages d'erreurs suivants :
Error using importdata
Unable to open file.
Error in Custom (no starter code) 14 (line 1)
RainMatrix = importdata('data.txt');
Je pense que je passe à coté de quelque chose ? Peut-être pas le bon code ?
comme indiqué dans le code et le message d'erreur cet exemple de code MATLAB travaille sur des données contenue dans un fichier (data.txt) lors qu'il faut travailler sur des données reçues par ThingSpeak dans dans un des champs (Fields) de ton canal (Channel)
Désolè je t'ai sans doute mis sur une piste sur laquelle je ne peux, actuellement, pas vraiment t'accompagner, sans avoir de doute sur la faisabilité