Drahtloser Beleuchtungssensor CR2450

Es ist kein Problem, einen drahtlosen Sensor herzustellen, der ein Barometer, ein Thermometer, ein Hygrometer oder alles in einer Flasche enthält und mit 220 V betrieben wird. Interessanter ist es jedoch schon, ein solches Gerät mit Batterien oder Akkus zu versorgen. Wenn es sich um einen Disc-Lithium-Akku (Tablet) handelt, ist er im Allgemeinen cool, da sich das Gerät als sehr kompakt herausstellt.
Das einzige Hindernis für die Verwendung der „Pille“ ist ihre geringe Kapazität. Aber auch unter den "Tabletten" gibt es durchaus geeignete Proben, zum Beispiel CR2450, mit der beanspruchten Kapazität von 550-610 mAh.
Da ich zum Zeitpunkt der Herstellung des Geräts bereits vorgefertigte Temperatur- und Feuchtigkeitssensoren für den Innen- und Außenbereich hatte, entschied ich mich, einen Beleuchtungssensor auf Basis des BH1750 herzustellen und auf dem Balkon zu platzieren und zusätzlich mit einem Temperatursensor DS18B20 auszustatten.
Da alle Fenster nach Süden ausgerichtet sind und der Temperatur- und Feuchtigkeitssensor im Freien erheblich vom Sonnenlicht beeinflusst wird, muss dieser Effekt durch Wetterdaten aus dem Internet kompensiert werden. In Zukunft plane ich, Informationen über das Beleuchtungsniveau zur Berechnung der Kompensation zu verwenden.
Um den Energieverbrauch des Sensors zu minimieren, wurde entschieden:
1. Verweigern Sie die Verwendung des fertigen Arduinki und verwenden Sie den ATmega 328P-PU-Mikrocontroller direkt mit 8-MHz-Quarz. Ich habe mich geweigert, den internen RC-Generator zu verwenden, weil Aufgrund signifikanter Änderungen der Außentemperatur ist die Betriebsfrequenz nicht stabil.
2. Verwenden Sie die LowPower-Bibliothek und aktivieren Sie den Energiesparmodus LowPower.powerDown (SLEEP_8S, ADC_OFF, BOD_OFF) für den Controller.
3. Schalten Sie den DS18B20-Sensor über den Digitalausgang des Mikrocontrollers ein und schalten Sie ihn unmittelbar vor der Messung ein.
4. Schalten Sie das Funkmodul und BH1750 direkt mit den Energiesparmodi radio.powerDown () und Light.configure (BH1750_ONE_TIME_HIGH_RES_MODE) ein.
Mit dem USBasp-Programmierer bewaffnet,

Ich habe eine Sicherung im Controller und natürlich im Bootloader angefordert. Ich baute einen Prototyp zusammen, skizzierte eine Testskizze und maß die verbrauchten Ströme: Im Schlafmodus wurden 14 μA gemessen, im Messmodus von Sensoren - 3-4 mA, im Modus der Datenübertragung über nRF24 zu einer Wetterstation - 16-18 mA. Angesichts der Tatsache, dass ich mich entschlossen habe, alle 3 Minuten Messwerte von den Sensoren zu erfassen und alle 10 Minuten zu senden, ist der Sensor sehr sparsam.
Für die Herstellung des Endgeräts wurde ein Stück Steckbrett und Draht MGTF verwendet. Das Ergebnis ist, was passiert ist:

Um den Batteriestatus zu überwachen, verwenden wir die in diesem Artikel beschriebenen Funktionen von ATmega .
Der Vorgang des Flashens des Bootloaders und der Sicherungen wird hier und hier ausführlich behandelt .
Die allgemeine Idee, einen autonomen Sensor zu erstellen, wurde auf der Maniacbug-Website ausgeliehen .

Der Sensor hat bereits den zweiten Monat auf dem Balkon auf der Fensterbank gelegen (und funktioniert) und sendet die Daten korrekt. Die Leistungsregelung meldet, dass während dieser Zeit die Spannung der Quelle von 3,05 V beim ersten Einschalten auf 2,98 V abnahm. Tagsüber, wenn die Sonne den Balkon erwärmt, kann die Spannung jedoch auf 3,00 V ansteigen. Ich freue mich auf kaltes Wetter, mal sehen, wie sich der ausgewählte Akku bei niedrigen Temperaturen zeigt.
Bei der gewählten Dauer des Schlafmodus stellt sich heraus, dass der Sensor in 24 Stunden nur 492-495 Sekunden wach ist.

Das Gerät ist komplett, aber leider bisher ohne Koffer kann ich kein passendes finden



Hinzufügung vom 20.03.2016.
6 , . -24, 2,5280V.
( ) 4 + .


Quelle
#include <LowPower.h>
#include <SPI.h>
#include <RF24Network.h>   
#include <RF24.h>          
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <BH1750.h>
/////// lass AVG //////////////////////////////////////////////////////////
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    //    Pin 4
#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
BH1750 Light;
RF24 radio(/*ce*/ 9, /*cs*/ 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;   //     8 .
bool allowSend = false; //   
AVG vAVG(3);
AVG tAVG(3);
AVG lAVG(3);
struct StreetMeteoSensor
{
  char    ID[5];     // 
  unsigned long UpTime;
  int   T;           //
  long  L;           //  (Lx) 
  int   V;           //   (mV)
};
struct StreetMeteoSensor sensor;
RF24NetworkHeader header(main_node, 'I');
////////////////////////////////////////////
#define DEBUG_MODE     0
////////////////////////////////////////////
void setup(void)
{
    if (DEBUG_MODE) 
  {
    Serial.begin(115200);
    //tAVG.fDebug = true;  
    //lAVG.fDebug = true;      
    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...");
  //  BH1750    , 
  Light.configure(BH1750_POWER_ON);                    //  
  Light.configure(BH1750_ONE_TIME_HIGH_RES_MODE);     //   
  digitalWrite(pinPowerSensor,HIGH);                  //    DS18B20
  sensors.setResolution(TEMP_9_BIT);   
  delay(250); 
  sensors.requestTemperatures();
  int T = sensors.getTempCByIndex(0);
  digitalWrite(pinPowerSensor,LOW);  //   DS18B20
  long L = Light.readLightLevel();  // ONE_TIME   
  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/*0.1V*/) 
  { //  -    
    tAVG.Set(T);
    lAVG.Set(L);
    vAVG.Set(V); 
    allowSend = true;     //   -  
    //     0 ()
    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;
  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(75); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA,ADSC)); // measuring
  result = ADCL;
  result |= ADCH<<8;
  if (DEBUG_MODE) {Serial.print("result=");Serial.println(result);}
  result =  1125300L / result; // (Kvcc * 1023.0 * 1000) (in mV);
  return result; 
}

Source: https://habr.com/ru/post/de385129/


All Articles