Hacer algún tipo de sensor inalámbrico que contenga un barómetro, termómetro, higrómetro o una botella todo en uno, alimentado por 220V no es un problema. Pero alimentar un dispositivo de este tipo con baterías o acumuladores ya es más interesante. Bueno, si se trata de una batería de disco de litio (tableta), generalmente es genial, porque el dispositivo resultará muy compacto.
El único obstáculo para usar la "píldora" es su pequeña capacidad. Pero incluso entre las "tabletas" hay muestras bastante adecuadas, por ejemplo CR2450, con la capacidad reclamada de 550-610 mAh.Como en el momento de la fabricación del dispositivo ya tenía sensores de temperatura y humedad interiores y exteriores ya preparados, decidí hacer un sensor de iluminación basado en el BH1750 y colocarlo en el balcón, además de equiparlo con un sensor de temperatura DS18B20.Como tengo todas las ventanas orientadas al sur, el sensor de temperatura y humedad exterior se ve significativamente afectado por la luz solar, este efecto tiene que compensarse con los datos meteorológicos recibidos de Internet, en el futuro, planeo usar información sobre el nivel de iluminación para calcular la compensación.Para minimizar la energía consumida por el sensor, se decidió:1. Negarse a utilizar el Arduinki terminado y utilizar el microcontrolador ATmega 328P-PU con cuarzo de 8 MHz directamente. Me negué a usar el generador RC interno, porque Debido a cambios significativos en la temperatura externa, la frecuencia de funcionamiento no es estable.2. Utilice la biblioteca LowPower y active el modo de ahorro de energía LowPower.powerDown (SLEEP_8S, ADC_OFF, BOD_OFF) para el controlador3. Encienda el sensor DS18B20 desde la salida digital del microcontrolador y enciéndalo inmediatamente antes de la medición.4. Alimente el módulo de radio y el BH1750 directamente, utilizando los modos de ahorro de energía, radio.powerDown () y Light.configure (BH1750_ONE_TIME_HIGH_RES_MODE), respectivamente.Armado con el programador USBasp,
Solicité un fusible en el controlador y, por supuesto, en el gestor de arranque. Monté un prototipo, dibujé un boceto de prueba y medí las corrientes consumidas: en modo de suspensión resultó 14 μA, en el modo de tomar lecturas de sensores - 3-4 mA, en el modo de transmisión de datos a través de nRF24 a una estación meteorológica - 16-18 mA. Dado el hecho de que decidí tomar lecturas de los sensores una vez cada 3 minutos y transmitirlas cada 10 minutos, el sensor es muy económico.Para la fabricación del dispositivo final se utilizó un trozo de placa y alambre MGTF. El resultado es lo que sucedió:
para monitorear el estado de la batería, utilizamos las capacidades integradas de ATmega, bien descritas en este artículo .El proceso de flashear el gestor de arranque y los fusibles está cubierto en detalle aquí y aquí .La idea general de crear un sensor autónomo se tomó prestada en el sitio web de maniacbug .El sensor ya ha estado acostado (y funcionando) por segundo mes en el balcón del alféizar de la ventana, envía los datos correctamente. El control de potencia informa que durante este tiempo el voltaje de la fuente disminuyó de 3.05V cuando se encendió por primera vez a 2.98V. Sin embargo, durante el día, cuando el sol calienta el balcón, el voltaje puede elevarse hasta 3.00V. Estoy esperando el clima frío, veamos cómo la batería seleccionada se mostrará a bajas temperaturas.Con la duración seleccionada del modo de suspensión, resulta que el sensor está despierto solo 492-495 segundos en 24 horas.El dispositivo está completo, pero desafortunadamente hasta ahora sin un caso, no puedo encontrar un adecuado

Además del 20/03/2016.6 , . -24, 2,5280V.
( ) 4 + .
Fuente#include <LowPower.h>
#include <SPI.h>
#include <RF24Network.h>
#include <RF24.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <BH1750.h>
class AVG {
#define DEPTH_AVG 10
private :
int depth;
long *mas;
int cur;
boolean first;
public :
boolean fDebug;
AVG(int d)
{
if( d == 0 || d > DEPTH_AVG)depth = DEPTH_AVG;
else depth = d;
mas = (long *)malloc(sizeof(long)*depth);
first = true;
cur = 0;
fDebug = false;
}
void Set(long x)
{
if( first )
{
for( int i=0; i<depth; i++ )mas[i] = x;
cur = 0;
}
else
{
mas[cur++] = x;
if( cur >= depth ) cur = 0;
}
first = false;
}
long Get()
{
long x=0;
for( int i=0; i<depth; i++ )
{
x+=mas[i];
}
x/=depth;
return(x);
}
};
#define pinPowerSensor 4
#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
BH1750 Light;
RF24 radio( 9, 10);
RF24Network network(radio);
uint16_t this_node = 02;
uint16_t main_node = 0;
const int Chanel = 11;
int ReadCount;
int iSend = 3;
int WaitCount = 24;
bool allowSend = false;
AVG vAVG(3);
AVG tAVG(3);
AVG lAVG(3);
struct StreetMeteoSensor
{
char ID[5];
unsigned long UpTime;
int T;
long L;
int V;
};
struct StreetMeteoSensor sensor;
RF24NetworkHeader header(main_node, 'I');
#define DEBUG_MODE 0
void setup(void)
{
if (DEBUG_MODE)
{
Serial.begin(115200);
Serial.println("-- START --");
WaitCount = 5;
}
for (int i = 1; i < 15; i++)
{
pinMode(i, OUTPUT);
digitalWrite(i,LOW);
}
digitalWrite(pinPowerSensor,HIGH);
char ID[5] = "LTS1";
memcpy(sensor.ID, ID, 5);
ReadCount = iSend;
SPI.begin();
delay(500);
radio.begin();
network.begin( Chanel, this_node );
sensors.begin();
Light.begin(BH1750_ONE_TIME_HIGH_RES_MODE);
delay(500);
radio.powerDown();
digitalWrite(pinPowerSensor,LOW);
Light.configure(BH1750_POWER_DOWN);
if (DEBUG_MODE) Serial.println("-- End SETUP --");
}
void loop(void)
{
if (DEBUG_MODE) Serial.println("data read...");
Light.configure(BH1750_POWER_ON);
Light.configure(BH1750_ONE_TIME_HIGH_RES_MODE);
digitalWrite(pinPowerSensor,HIGH);
sensors.setResolution(TEMP_9_BIT);
delay(250);
sensors.requestTemperatures();
int T = sensors.getTempCByIndex(0);
digitalWrite(pinPowerSensor,LOW);
long L = Light.readLightLevel();
int V = readVcc();
int tt = tAVG.Get();
int vv = vAVG.Get();
long ll = lAVG.Get();
if (L > 0 || ll > 0 || T < tt-2 || T > tt+2 || V < vv-100)
{
tAVG.Set(T);
lAVG.Set(L);
vAVG.Set(V);
allowSend = true;
if (ll == 0 && L > 0)
lAVG.Set(L);
}
ReadCount++;
if (DEBUG_MODE)
{
Serial.print("T= ");
Serial.print(tAVG.Get());
Serial.print(": ");
Serial.print(T);
Serial.print("; L= ");
Serial.print(lAVG.Get());
Serial.print(": ");
Serial.print(L);
Serial.print("; V= ");
Serial.print(vAVG.Get());
Serial.print(": ");
Serial.print(V);
Serial.print("; ReadCount= ");
Serial.println(ReadCount);
}
if ( ReadCount >= iSend && allowSend )
{
ReadCount = 0;
allowSend = false;
radio.powerUp();
delay(50);
sensor.T = tAVG.Get();
sensor.L = lAVG.Get();
sensor.V = vAVG.Get();
sensor.UpTime = millis()/1000;
network.write(header,&sensor,sizeof(sensor));
radio.powerDown();
}
sleep();
}
void sleep()
{
if (DEBUG_MODE) {Serial.println("----- SLEEP -----");Serial.flush();}
for (int i = 0; i < WaitCount; i++)
{
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
}
int readVcc()
{
int result;
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(75);
ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
if (DEBUG_MODE) {Serial.print("result=");Serial.println(result);}
result = 1125300L / result;
return result;
}