CR2450 مستشعر إضاءة لاسلكي

إن صنع نوع من أجهزة الاستشعار اللاسلكية التي تحتوي على بارومتر أو مقياس حرارة أو رطوبة أو زجاجة واحدة ، تعمل بالطاقة بجهد 220 فولت ليست مشكلة. لكن تشغيل مثل هذا الجهاز من البطاريات أو البطاريات هو بالفعل أكثر إثارة للاهتمام. حسنًا ، إذا كانت بطارية ليثيوم قرصية (جهاز لوحي) - فهي رائعة بشكل عام ، لأن الجهاز سيتحول إلى حجم صغير جدًا.
العائق الوحيد لاستخدام "حبوب منع الحمل" هو قدرتها الصغيرة. ولكن حتى بين "الأجهزة اللوحية" ، توجد عينات مناسبة تمامًا ، على سبيل المثال CR2450 ، بسعة 550-610 مللي أمبير في الساعة.
نظرًا لأنه في وقت تصنيع الجهاز ، كان لدي بالفعل أجهزة استشعار درجة الحرارة والرطوبة الجاهزة الداخلية والخارجية ، قررت إنشاء مستشعر إضاءة استنادًا إلى BH1750 ووضعه على الشرفة ، بالإضافة إلى تجهيزه بجهاز استشعار درجة الحرارة DS18B20.
نظرًا لأن لدي جميع النوافذ التي تواجه الجنوب ، يتأثر مستشعر درجة الحرارة والرطوبة في الهواء الطلق بشكل كبير بضوء الشمس ، فيجب تعويض هذا التأثير عن طريق بيانات الطقس المستلمة من الإنترنت ، وفي المستقبل ، أخطط لاستخدام معلومات حول مستوى الإضاءة لحساب التعويض.
لتقليل الطاقة التي يستهلكها المستشعر ، تقرر:
1. رفض استخدام Arduinki النهائي واستخدام متحكم ATmega 328P-PU مع كوارتز 8 MHz مباشرة. رفضت استخدام مولد RC الداخلي لأن بسبب التغيرات الكبيرة في درجة الحرارة الخارجية ، فإن تردد التشغيل غير مستقر.
2. استخدم مكتبة LowPower وقم بتمكين وضع توفير الطاقة LowPower.powerDown (SLEEP_8S ، ADC_OFF ، BOD_OFF) لوحدة التحكم
3. قم بتشغيل مستشعر DS18B20 من الإخراج الرقمي لوحدة التحكم الدقيقة وتشغيله مباشرة قبل القياس.
4. قم بتشغيل وحدة الراديو و BH1750 مباشرة ، باستخدام أوضاع توفير الطاقة ، radio.powerDown () و Light.configure (BH1750_ONE_TIME_HIGH_RES_MODE) ، على التوالي.
مسلح بمبرمج USBasp ،

طلبت الصمامات في وحدة التحكم ، وبطبيعة الحال ، محمل الإقلاع. جمعت نموذجًا أوليًا ، ورسمت رسمًا اختباريًا وقست التيارات المستهلكة: في وضع السكون اتضح 14 μA ، في طريقة أخذ القراءات من أجهزة الاستشعار - 3-4 مللي أمبير ، في وضع نقل البيانات عبر nRF24 إلى محطة الطقس - 16-18 مللي أمبير. بالنظر إلى حقيقة أنني قررت أخذ قراءات من أجهزة الاستشعار مرة كل 3 دقائق ، وإرسالها كل 10 دقائق - جهاز الاستشعار اقتصادي للغاية.
لتصنيع الجهاز النهائي يستخدم قطعة من اللوح والأسلاك MGTF. والنتيجة هي ما حدث:

لمراقبة حالة البطارية ، نستخدم الميزات المضمنة في ATmega ، والتي تم وصفها جيدًا في هذه المقالة .
يتم تغطية عملية وميض محمل الإقلاع والصمامات بالتفصيل هنا وهنا .
تم استعارة الفكرة العامة لإنشاء جهاز استشعار مستقل على موقع maniacbug .

كان المستشعر مستلقيًا بالفعل (ويعمل) للشهر الثاني على الشرفة على حافة النافذة ، ويرسل البيانات بشكل صحيح. تفيد وحدة التحكم في الطاقة أنه خلال هذا الوقت انخفض جهد المصدر من 3.05 فولت عند تشغيله لأول مرة إلى 2.98 فولت. ومع ذلك ، خلال النهار ، عندما تسخن الشمس الشرفة ، يمكن أن يرتفع الجهد إلى 3.00 فولت. أتطلع إلى الطقس البارد ، دعنا نرى كيف ستظهر البطارية المحددة نفسها في درجات حرارة منخفضة.
مع المدة المحددة لوضع السكون ، اتضح أن المستشعر مستيقظًا فقط 492-495 ثانية في 24 ساعة.

الجهاز كامل ، ولكن لسوء الحظ حتى الآن بدون حالة ، لا أستطيع العثور على جهاز مناسب



إضافة 2016/03/20.
6 , . -24, 2,5280V.
( ) 4 + .


مصدر
#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/ar385129/


All Articles