Para fazer algum tipo de sensor sem fio contendo um barômetro, termômetro, higrômetro ou tudo em uma garrafa, alimentado por 220V, não é um problema. Mas alimentar esse dispositivo a partir de baterias ou acumuladores já é mais interessante. Bem, se for uma bateria de lítio de disco (tablet) - geralmente é legal, porque o dispositivo será muito compacto.
O único obstáculo ao uso da "pílula" é sua pequena capacidade. Mas mesmo entre os "tablets" existem amostras bastante adequadas, por exemplo, CR2450, com a capacidade reivindicada de 550-610 mAh.Como no momento da fabricação do dispositivo, eu já tinha sensores de temperatura e umidade internos e externos prontos, decidi fazer um sensor de iluminação baseado no BH1750 e colocá-lo na varanda, equipando-o adicionalmente com um sensor de temperatura DS18B20.Como todas as janelas estão voltadas para o sul, o sensor externo de temperatura e umidade é significativamente afetado pela luz solar, esse efeito deve ser compensado pelos dados climáticos recebidos da Internet. No futuro, planejo usar informações sobre o nível de iluminação para calcular a compensação.Para minimizar a energia consumida pelo sensor, foi decidido:1. Recuse-se a usar o Arduinki pronto e use o microcontrolador ATmega 328P-PU diretamente com quartzo de 8 MHz. Recusei-me a usar o gerador RC interno, porque devido a mudanças significativas na temperatura externa, a frequência de operação não é estável.2. Use a biblioteca LowPower e ative o modo de economia de energia LowPower.powerDown (SLEEP_8S, ADC_OFF, BOD_OFF) para o controlador3. Ligue o sensor DS18B20 a partir da saída digital do microcontrolador e ligue-o imediatamente antes da medição.4. Ligue o módulo de rádio e o BH1750 diretamente, usando os modos de economia de energia, radio.powerDown () e Light.configure (BH1750_ONE_TIME_HIGH_RES_MODE), respectivamente.Armado com o programador USBasp,
Solicitei um fusível no controlador e, é claro, no carregador de inicialização. Montei um protótipo, desenhei um esboço de teste e medi as correntes consumidas: no modo de suspensão, foram 14 μA, no modo de fazer leituras dos sensores - 3-4 mA, no modo de transmissão de dados via nRF24 para uma estação meteorológica - 16-18 mA. Dado o fato de eu ter decidido fazer leituras dos sensores uma vez a cada 3 minutos e transmitir a cada 10 minutos - o sensor é muito econômico.Para a fabricação do dispositivo final utilizou um pedaço de tábua de pão e arame MGTF. O resultado foi o que aconteceu:
Para monitorar o status da bateria, usamos os recursos internos do ATmega, que são bem descritos neste artigo .O processo de piscar o carregador de inicialização e os fusíveis é abordado em detalhes aqui e aqui .A idéia geral de criar um sensor autônomo foi emprestada no site maniacbug .O sensor já está deitado (e funcionando) pelo segundo mês na varanda no peitoril da janela, envia os dados corretamente. O controle de energia informa que durante esse período a tensão da fonte diminuiu de 3,05V quando ligada pela primeira vez para 2,98V. No entanto, durante o dia, quando o sol aquece a varanda, a tensão pode subir até 3,00V. Estou esperando o tempo frio, vamos ver como a bateria selecionada se mostrará em baixas temperaturas.Com a duração selecionada do modo de suspensão, o sensor fica ativo apenas 492-495 segundos em 24 horas.O dispositivo está completo, mas infelizmente até agora sem um estojo, não consigo encontrar um

adição de 20/03/2016.6 , . -24, 2,5280V.
( ) 4 + .
Fonte#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;
}