Bonjour à tous,
Après de longues recherches et tâtonnements, j'ai réussi a faire une station météo (anemomètre davis + DS18b20 cablés sur une Arduino pro mini et une NRF24L01+.
Les données sont envoyées toutes les deux minutes à une Wemos D1 qui les transmets à Blynk et Thingspeak.
La pro mini n'est jamais mise en sommeil car elle prend, toutes les 2.5 s, les mesures de l'anémomètre et fait une moyenne sur 2 minutes. Seule la NRF24L01 passe en mode PWR DOWN entre deux émissions.
Suivant la consommation, je pourrai à terme mettre en sommeil la nuit car les données m'interressent moins la nuit. (
Tout cela fonctionne branché au secteur.
Mais, viens le moment de poser le matériel capteur et émetteur sur le toit et à alimenter tout ça par panneau solaire et batterie !
Je dispose d'un panneau solaire qui servait a éclairer un cabanon (2 lampes Led 1W) mais il fournit 11V 4w et les accus LI-ion 7.4v 2600mAh. Je précise que j'habite dans le sud est et que l'ensoleillement est correct.
Mais, comment alimenter la pro mini avec une telle tension sans passer par un régulateur gourmand en énergie ?
Ou, faut-il s'orienter vers des panneaux solaires 5.5 v qui sont souvent petits et de faible puissance ?
PS : Je précise que je me suis inspiré du travail de Hbachetti avec son thermomètre basse consommation et que je vais faire l'assemblage Pro mini + NRF 24L01 + DS18b20 sur le PCB de son thermomètre (je câblerai l'anémomètre en filaire sur les broches).
Merci pour votre aide
Je voulais mettre le code de l'émetteur mais le message dépasse 9000 caractères...
le code entre balise </>
ou [ code ] [ / code]
Le code, en deux parties car il excède 9000 caractères :
//Capteur anémomètre-Girouette DAVIS
//Inspiré du site ci dessous
//http://cactus.io/hookups/weather/anemometer/davis/hookup-arduino-to-davis-anemometer-software
//reference :https://itechnofrance.wordpress.com/2014/04/01/sonde-de-temprature-et-transmission-rf-avec-des-modules-nrf24l01/
//Sans Watchdog
#include <SPI.h>
#include <Ethernet.h>
#include "TimerOne.h"
#include <math.h>
#include <Wire.h>
#include <OneWire.h> //Librairie du bus OneWire
#include <DallasTemperature.h> //Librairie du capteur
#include <RF24.h>
#define TX_Pin 4//led envoi
#define WindSensor_Pin (2)
#define WindVane_Pin (A2)
#define VaneOffset 0
OneWire oneWire(3); //Bus One Wire sur la pin 3 de l'arduino
DallasTemperature sensors(&oneWire); //Utilistion du bus Onewire pour les capteurs
DeviceAddress sensorDeviceAddress; //Vérifie la compatibilité des capteurs avec la librairie
volatile unsigned int timerMinCount; // used to determine 2 minutes count
volatile unsigned long contactTime;
volatile unsigned int timerCount;
volatile unsigned long rotations;
volatile unsigned long contactBounceTime;
const float DEG2RAD = 3.14156 / 180.0; // convert degrees to radian
const float RAD2DEG = 180 / 3.14156; //convert radian to degrees
const int numReadings = 48;//2mn
int winDir[numReadings];
float sinSum = 0;
float cosSum = 0;
volatile float windSpeed;
volatile float xMin;
int vaneValue;
int vaneDirection;
int calDirection;
int lastDirValue;
float minTemp = 0;
float maxTemp = 0;
int readings[numReadings];
int readIndex = 0;
int total = 0;
int windDirection = 0;
int windSpeedMax = 0;
int averageSpeed = 0;
int readingsDir[numReadings];
int readIndexDir = 0;
int avg_windDirection = 0;
int avgWinDir = 0;
String girouette = "";
float v = 0.0;
float d = 0.0;
float as = 0.0;
float ad = 0.0;
float t = 0.0;
float tension_alim = 0.0;
float valTension = 1.0;
unsigned int adc = 0;
float voltage = 0.0;
#define VREF 1.099
RF24 radio(9, 10); //création instance radio (pin ce,csn)
/** Mesure la référence interne à 1.1 volts */
unsigned int analogReadReference(void) {
/* Elimine toutes charges résiduelles */
#if defined(__AVR_ATmega328P__)
ADMUX = 0x4F;
#elif defined(__AVR_ATmega2560__)
ADCSRB &= ~(1 << MUX5);
ADMUX = 0x5F;
#elif defined(__AVR_ATmega32U4__)
ADCSRB &= ~(1 << MUX5);
ADMUX = 0x5F;
#endif
delayMicroseconds(5);
/* Sélectionne la référence interne à 1.1 volts comme point de mesure, avec comme limite haute VCC */
#if defined(__AVR_ATmega328P__)
ADMUX = 0x4E;
#elif defined(__AVR_ATmega2560__)
ADCSRB &= ~(1 << MUX5);
ADMUX = 0x5E;
#elif defined(__AVR_ATmega32U4__)
ADCSRB &= ~(1 << MUX5);
ADMUX = 0x5E;
#endif
delayMicroseconds(200);
/* Active le convertisseur analogique -> numérique */
ADCSRA |= (1 << ADEN);
/* Lance une conversion analogique -> numérique */
ADCSRA |= (1 << ADSC);
/* Attend la fin de la conversion */
while (ADCSRA & (1 << ADSC));
/* Récupère le résultat de la conversion */
return ADCL | (ADCH << 8);
}
void setup() {
Serial.begin(115200);
Serial.println("Anemomètre");
lastDirValue = 0;
rotations = 0;
timerCount = 0;
timerMinCount = 0;
sensors.begin(); //Activation des capteurs
sensors.getAddress(sensorDeviceAddress, 0); //Demande l'adresse du capteur à l'index 0 du bus
sensors.setResolution(sensorDeviceAddress, 12); //Résolutions possibles: 9,10,11,12
sensors.requestTemperatures(); //Demande la température aux capteurs
minTemp = sensors.getTempCByIndex(0);
maxTemp = sensors.getTempCByIndex(0);
for (int readIndex = 0; readIndex < numReadings; readIndex++) {
readings[readIndex] = 0;
}
for (int readIndexDir = 0; readIndexDir < numReadings; readIndexDir++) {
winDir[readIndexDir] = 0;
}
radio.begin();
radio.setPALevel(RF24_PA_LOW); //puissance minimum
radio.setChannel(0x14); //canal 20
radio.setDataRate(RF24_1MBPS);
radio.openWritingPipe(0xF1F1F1F1F1LL);
radio.enableDynamicPayloads();
radio.setAutoAck(1);
radio.setRetries(15, 15);
pinMode(TX_Pin, OUTPUT);
pinMode(WindSensor_Pin, INPUT);
attachInterrupt(digitalPinToInterrupt(WindSensor_Pin), isr_rotation, FALLING);
// Setup the timer interupt for 0.5 second (500 000 microSecondes)
Timer1.initialize(500000);
Timer1.attachInterrupt(isr_timer);
sei();//enable interrupts
}
La suite :
void loop() {
sensors.requestTemperatures();
sensors.getTempCByIndex(0);
// update min and max temp values
if (sensors.getTempCByIndex(0) < minTemp) {
minTemp = sensors.getTempCByIndex(0);
}
if (sensors.getTempCByIndex(0) > maxTemp) {
maxTemp = sensors.getTempCByIndex(0);
}
getWindDirection();
float v = windSpeed;
float d = calDirection;
float as = averageSpeed;
float ad = avg_windDirection;
float t = sensors.getTempCByIndex(0);
// if two minutes timer is up then send data(48 x 2.5s = 120s)
if (timerMinCount > 48) {
float tension_alim = (1023 * 1.1) / analogReadReference();
Serial.print(F("WindSpeed : "));
Serial.print((v), 2);
Serial.print(" Km/h");
Serial.print(F("\tDirection : "));
Serial.print((d), 2);
Serial.print(" Deg");
Serial.print (F("\tAverageSpeed : "));
Serial.print((as), 2);
Serial.print(" Km/h");
Serial.print (F("\tAverageDirection : "));
Serial.print((ad), 2);
Serial.print(" Deg");
Serial.print (F("\ttemperature : "));
Serial.print((t), 2);
Serial.println(" Deg");
Serial.print (F("\ttension : "));
Serial.print((tension_alim), 2);
Serial.println(" Volts");
delay(1000);
float txbuffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
txbuffer[0] = v;
txbuffer[1] = d;
txbuffer[2] = as;
txbuffer[3] = ad;
txbuffer[4] = t;
txbuffer[5] = tension_alim;
txbuffer[6] = minTemp;
txbuffer[7] = maxTemp;
Serial.print (F("\tTemperature mini : "));
Serial.println(minTemp);
Serial.print (F("\tTemperature maxi : "));
Serial.println(maxTemp);
// reset the timer
cli(); // disable interrupts
timerMinCount = 0;
sei(); // enable interrupts
Serial.println ("Radio Power Up ");
radio.powerUp(); //alimente le module nrf24l01+
radio.write(&txbuffer, sizeof(txbuffer));
delay(500);
radio.powerDown(); //arrêt de l’alimentation du module nrf24l01+
Serial.println ("Radio Power Down ");
}
}
// isr routine for timer interrupt
void isr_timer() {
timerCount++;
if (timerCount == 5)//5 x .5 = 2.5 s
{
// convert to mp/h using the formula V=P(2.25/T)- Davis Anemometer
// V = P(2.25/2.5) = P * 0.9
//en Km/h = P * 0.9 * 1.60934
windSpeed = rotations * 0.9 * 1.60934;
// ************Calcul moyenne sur 2 mn************
total = total - readings[readIndex];
readings[readIndex] = windSpeed;
total = total + readings[readIndex];
readIndex = readIndex + 1;
if (readIndex >= numReadings) {
readIndex = 0;
}
averageSpeed = total / numReadings;
if (windSpeed >= windSpeedMax ) {
windSpeedMax = windSpeed;
}
rotations = 0;
timerCount = 0;
timerMinCount++;
}
}
// interrupt handler to increment the rotation count for wind speed
void isr_rotation () {
if ((millis() - contactBounceTime) > 15 ) {
rotations++;
contactBounceTime = millis();
}
}
// **********Get Wind Direction*************
void getWindDirection() {
vaneValue = analogRead(WindVane_Pin);
vaneDirection = map(vaneValue, 0, 1023, 0, 360);
calDirection = vaneDirection + VaneOffset;
if (calDirection > 360)
calDirection = calDirection - 360;
if (calDirection < 0)
calDirection = calDirection + 360;
//*********Calcul Moyenne Direction sur 2 mn**************
winDir[readIndexDir] = calDirection;
readIndexDir = readIndexDir + 1;
Serial.println(readIndexDir);
// if (readIndexDir == numReadings ) {
if (readIndexDir >= numReadings ) {
for (readIndexDir = 0; readIndexDir < numReadings; readIndexDir++)
{
sinSum += sin((winDir[readIndexDir]) * DEG2RAD);
cosSum += cos((winDir[readIndexDir]) * DEG2RAD);
}
float avgWinDir = atan2(sinSum, cosSum);
avgWinDir = avgWinDir / DEG2RAD;
if ( avgWinDir < 0 )
{
avgWinDir += 360;
}
int windDirection = (int)avgWinDir % 360;
avg_windDirection = windDirection;
Serial.print("moyenne : ");
Serial.println(avg_windDirection);
sinSum = 0;
cosSum = 0;
readIndexDir = 0;
}
}
// Converts compass direction to heading
void getHeading(int direction) {
if (direction < 22)
girouette = (" N");
else if (direction < 67)
girouette = (" NE");
else if (direction < 112)
girouette = (" E");
else if (direction < 157)
girouette = (" SE");
else if (direction < 202)
girouette = (" S");
else if (direction < 247)
girouette = (" SO");
else if (direction < 292)
girouette = (" O");
else if (direction < 337)
girouette = (" NO");
else
girouette = (" N");
}
float getTensionData() {
analogReference(INTERNAL);
analogRead(0);
delay(2);
unsigned int adc = analogRead(0);
float voltage = adc * VREF / 1023 / 0.248;
return voltage;
}
Salut
Pourquoi deux batteries en série et 7.4V ?
Bonjour Hbachetti,
C'est de la récup. Un chargeur solaire avec un panneau 11 v 4 w et un boitier distributeur avec 1 prise USB et 4 sorties pour des lampes Led. Il y a deux accus 18650 en série donc 7.4 V nominal. J'ai mesuré 8 v en sortie.
Je pensais récupérer l'électronique de charge et surtout le panneau qui fait 180 x 205 mm de surface.
En ce moment, sous secteur, j'utilise ce module :
https://fr.aliexpress.com/item/Special-promotions-Bread-board-dedicated-power-module-compatible-5V-3-3V-Breadboard-power-module-Power/739800218.html?spm=a2g0s.9042311.0.0.27426c372x0Eh0
j'utilise une sortie 5 v pour alimenter le capteur DAVIS et le DS18B20, une sortie 3.3 v pour alimenter la Pro mini et une autre 3.3 v pour alimenter la NRF24L01.
Si j'utilise ce module, même en enlevant la Led, il va certainement consommer un peu trop ?
et celui ci : https://fr.aliexpress.com/store/product/DC-DC-9V-12V-19V-To-5V-USB-Step-Down-Buck-Power-Supply-Charger-Module-Voltage/612195_32850075412.html?spm=a2g0w.12010615.8148356.3.681c4c89w1STL7
conviendrait-il mieux ?
Au départ, j'étais parti pour l'alimenter avec une LI-ion 18650 (voire 2 ou 3 en //) et un panneau solaire. Mais, les panneaux solaires 5 v sont toujours très petits et j'ai peur qu'ils ne suffisent pas. j'en ai un qui fait 105 x 60, je pourrais toujours essayer de voir la durée de fonctionnement...
Le problème c'est que je ne sais pas trop combien va consommer mon montage !
Merci pour l'aide et les conseils avisés...