Solar Powered Mini-Weather Station



  • Please can you ex-plane how i can remove 1 of the sensors in the sketch...
    I will try to build more of this sensors...
    Only 1 rain and 1 baro is good for me



  • This is my project!!!!

    0_1459952652761_schema-2_bb.jpg

    // Example sketch för a "light switch" where you can control light or something 
    // else from both vera and a local physical button (connected between digital
    // pin 3 and GND).
    // This node also works as a repeader for other nodes
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <DHT.h> 
    
    unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
    
    //pin sensori
    #define PIR_PIN 2                   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define HUMIDITY_TEMPERATURE_PIN 3  // sensore temperatura umidita
    #define RELAY_PIN  4                // relay pin
    int BATTERY_SENSE_PIN = A1;         // Pin carica batteria o pannello solare
    int FOTORESIST_SENSE_PIN = A2;      // Pin fotoresistenza
    
    //interupt per sleep arduino
    #define INTERRUPT PIR_PIN-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
    
    //id per vera
    #define CHILD_ID_RELE 1   // Id relay
    #define CHILD_ID_HUM 2    // id temperatura
    #define CHILD_ID_TEMP 3   // id umidita
    #define CHILD_ID_PIR 4    // Id pir
    #define CHILD_ID_LIGHT 5  // Id luminosita (fotoresistenza)
    
    //definizione per nodo vera
    #define NODE_ID 10
    #define SN "meteo station"
    #define SV "1.4"
    
    //variabili
    bool state_relay;                 //stato relay
    float batt_valore;                //dichiaro la variabile valore che memorizzerà il valore della batteria dal pin analogico
    float batt_volt;                  //volt batteria
    float batt_charged_percent;       //percentuale carica batteria
    float last_batt_charged_percent;  //percentuale carica batteria precedente
    float batt_min_voltage = 0.5;     //tensione minima batteria
    float batt_max_voltage = 5;       //tensione massima batteria
    float fotoresistenza_valore;      //dichiaro la variabile valore che memorizzerà il valore della fotoresistenza dal pin analogico
    float last_fotoresistenza_valore; //dichiaro la variabile valore precedente
    
    int lux_vera;                      //valore luminosita da inviare a vera
    
    MySensor gw;
    
    // sensore temperatura umidita
    DHT dht_int;
    float lastTemp_int = -1;
    float lastHum_int = -1;
    
    boolean metric = true; 
    
    MyMessage msgRelay(CHILD_ID_RELE,V_LIGHT);
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgPir(CHILD_ID_PIR, V_TRIPPED);
    MyMessage msgLux(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    
    void setup()  
    {  
      gw.begin(incomingMessage, NODE_ID, false);    
      
      gw.sendSketchInfo(SN, SV); 
    
      //Sensore umidita temperatura
      dht_int.setup(HUMIDITY_TEMPERATURE_PIN);
      
      gw.present(CHILD_ID_RELE, S_LIGHT);       //light vera
      gw.present(CHILD_ID_HUM, S_HUM);          //umidity vera
      gw.present(CHILD_ID_TEMP, S_TEMP);           // temp vera
      gw.present(CHILD_ID_PIR, S_MOTION);          // motion vera
      gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);  //light level (fotoresistenza)
      
      metric = gw.getConfig().isMetric;
      
      // Then set relay pins in output mode
      pinMode(RELAY_PIN, OUTPUT);   
      
      //PIR
      pinMode(PIR_PIN, INPUT);
      
      state_relay = 0;  
      //GestisciRelay();
      digitalWrite(RELAY_PIN, LOW);
      gw.send(msgRelay.set(state_relay)); 
         
    }
    
    void loop() 
    { 
        gw.process();
      
        //sensore temperatura umidita
        delay(dht_int.getMinimumSamplingPeriod());
    
        float temperature_int = dht_int.getTemperature();
        if (isnan(temperature_int)) 
        {
            lastTemp_int = -1;
            Serial.println("Failed reading temperature from DHT");
        } 
        else if (temperature_int != lastTemp_int) 
        {
          lastTemp_int = temperature_int;
          if (!metric) 
          {
            temperature_int = dht_int.toFahrenheit(temperature_int);
          }
          gw.send(msgTemp.set(temperature_int, 1));
          Serial.print("T int: ");
          Serial.println(temperature_int);
        }
      
        float humidity_int = dht_int.getHumidity();
        if (isnan(humidity_int)) 
        {
            lastHum_int = -1;
            Serial.println("Failed reading humidity from DHT");
        } 
        else if (humidity_int != lastHum_int) 
        {
            lastHum_int = humidity_int;
            gw.send(msgHum.set(humidity_int, 1));
            Serial.print("H int: ");
            Serial.println(humidity_int);
        }
        //sensore temperatura umidita
        
        //fotoresistenza    
        for(int i=0;i<150;i++)
        {
          fotoresistenza_valore += analogRead(FOTORESIST_SENSE_PIN);  //read the input voltage from battery or solar panel      
          delay(2);
        }
        fotoresistenza_valore = fotoresistenza_valore / 150;    
               
        Serial.print ("fotoresistenza: ");
        Serial.println(fotoresistenza_valore); 
    
        if (fotoresistenza_valore != last_fotoresistenza_valore) 
        {
          lux_vera = (int) fotoresistenza_valore;
          gw.send(msgLux.set(lux_vera));
          last_fotoresistenza_valore = fotoresistenza_valore;
        }    
        //fotoresistenza
        
        //pir relay
        // Read digital motion value
        boolean tripped = digitalRead(PIR_PIN) == HIGH; 
        Serial.println("pir:");      
        Serial.println(tripped);
        gw.send(msgPir.set(tripped?"1":"0"));  // Send tripped value to gw 
        
        //accende la luce con il buio
        if (fotoresistenza_valore < 200)  //poca luce
        {
          if (tripped == 1) 
          {
             state_relay = 1;     
          }
          else
          {
             state_relay = 0;     
          }
        }
        //accende la luce con il buio
        
        GestisciRelay();
        //pir relay
        
        //battery    
        for(int i=0;i<150;i++)
        {
          batt_valore += analogRead(BATTERY_SENSE_PIN);  //read the input voltage from battery or solar panel      
          delay(2);
        }
        batt_valore = batt_valore / 150;    
               
        Serial.print ("batt_valore: ");
        Serial.println(batt_valore);
        
        batt_volt = (batt_valore / 1024) * batt_max_voltage;
        Serial.print ("batt_volt: ");
        Serial.println(batt_volt);
        
        ////////////////////////////////////////////////
       //The map() function uses integer math so will not generate fractions
       // so I multiply battery voltage with 10 to convert float into a intiger value
       // when battery voltage is 6.0volt it is totally discharged ( 6*10 =60)
       // when battery voltage is 7.2volt it is fully charged (7.2*10=72)
       // 6.0v =0% and 7.2v =100%
       //batt_charged_percent = batt_volt*10;   
       //batt_charged_percent = map(batt_volt*10, 60 , 72, 0, 100);
        batt_charged_percent = batt_volt * 10;   
        batt_charged_percent = map(batt_volt * 10, batt_min_voltage * 10 , batt_max_voltage * 10, 0, 100);
        //batt_charged_percent = (batt_volt / batt_max_voltage) * 100;
        Serial.print ("batt_charged_percent: ");
        Serial.println(batt_charged_percent);
           
        if (last_batt_charged_percent != batt_charged_percent) 
        {
            gw.sendBatteryLevel(batt_charged_percent);
            last_batt_charged_percent = batt_charged_percent;        
        }
        //battery
        
        delay(50);
        
        // Sleep until interrupt comes in on motion sensor. Send update every two minute.   
        gw.sleep(INTERRUPT, CHANGE, SLEEP_TIME);
        
        
    } 
     
    void incomingMessage(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.isAck()) {
         Serial.println("This is an ack from gateway");
      }
    
      if (message.type == V_LIGHT) {
         // Change relay state_relay
         state_relay = message.getBool();
         GestisciRelay();
        
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
       
      
    }
    
    
    
    void GestisciRelay()
    {
        //Serial.print(" GestisciRelay state_relay:");
        //Serial.println(state_relay);
      
        if (state_relay == 0)
        {
          digitalWrite(RELAY_PIN, LOW);
          gw.send(msgRelay.set(state_relay));
          //Serial.println("SPENTO RELAY");
        }
        else 
       {
          digitalWrite(RELAY_PIN, HIGH);
          gw.send(msgRelay.set(state_relay));
          //Serial.println("ACCESO RELAY");
       } 
    
      
    }
    
    
    

    On vera
    0_1459952879015_vera-image.jpg

    On board
    0_1459952958112_IMG_20160406_162541.jpg



  • I purchased a solar kit

    Solar Panel
    battery 12v
    landstar solar charge controller

    I want to insert into Arduino in output of charge controller (I have 12 volts)

    to lower the voltage can I use a mobile charger Car 1 Ah

    do you heat so much?

    Thank

    @Salmoides Good Project!!!!!



  • what are the resistors? Or what do you u use between the wires?
    Look simple to me..



  • @Dombo71 look a fritzing schematic



  • @gigi said:

    @Dombo71 look a fritzing schematic

    Can you share the fritzing file please





  • 0_1459971075004_schema-pannello-solare-2_bb.jpg

    New fritzing

    I have two questions?

    1. voltage divider for more 5 v (battery voltage 12-13 volts)
    2. I use a auto phone charger for step down (12v --> 5 V) - warmers if I close in a box?

    Thank



  • @gigi said:

    0_1459971075004_schema-pannello-solare-2_bb.jpg

    New fritzing

    I have two questions?

    1. voltage divider for more 5 v (battery voltage 12-13 volts)
    2. I use a auto phone charger for step down (12v --> 5 V) - warmers if I close in a box?

    Thank

    Is your fritzing correct?
    On the green wire (light sensor?) you measure on ground where I guess you should measure between the resistor and the sensor.



  • @Petjepet said:

    On the green wire (light sensor?) you measure on ground where I guess you should measure between the resistor and the sensor.

    0_1460011587951_LdrUp_down.jpg

    Is the same

    0_1460011676140_vdivider.jpg

    voltage divider



  • @gigi I know but in your breadboard picture the now mentioned V output is connected directly to ground. 😏

    0_1460012243066_Knipsel.JPG



  • @Petjepet I Know, thank

    on board as I did your chart

    0_1460012626053_schema-pannello-solare-2_bb-2.jpg
    Thank



  • Back to the weather station.
    I was having problems reporting wind speed to domoticz (in hardware my sensor was listed, but there was no device creation)
    After a question on their forum, i learned tha i had to implement gust and direction to the sensor becaus Domoticz is aspectiong these to before it vreates a device.
    I had to remove the rainrate because the sketch was getting to big.
    Here is the latest sketch i am using :

    
    
    
        #include <SPI.h>
        #include <MySensor.h>  
        #include <dht.h>
        #include <BH1750.h>
        #include <Wire.h> 
        #include <Adafruit_BMP085.h>
        #include <MySigningAtsha204.h>
        
        #define CHILD_ID_HUM 0
        #define CHILD_ID_TEMP 1
        #define CHILD_ID_LIGHT 2
        #define CHILD_ID_BARO 3
        #define CHILD_ID_BTEMP 4
        #define CHILD_ID_WINDSPEED 5
        #define CHILD_ID_RAIN 6
        
        #define MESSAGEWAIT 500
        #define DIGITAL_INPUT_RAIN_SENSOR 3
        #define HUMIDITY_SENSOR_DIGITAL_PIN 5
        #define ENCODER_PIN 2
        #define INTERRUPT DIGITAL_INPUT_RAIN_SENSOR-2
    
        const int  windSpeedPin = 2; // contact on pin 2 digital
        int windSpeedPinCounter = 0; // impuls counter
        int windSpeedPinStatus = 0; // actual impuls
        int windSpeedPinStatusAlt = 0; // oude Impuls-Status
        unsigned long windmeterStart;
        unsigned long windmeterStartAlt = 0;
        int windSpeed; // Variable voor Wind Speed
        int beaufort = 0; // Variable Wind in Beaufort
        const int windmeterTime = 10000;
        //float knoten = 0.0;
        //float wind = 0.0;
        unsigned int knoten;
        unsigned int wind;
       
        boolean metric = false;
        int altitude = 16; // meters above sealevel
        float lastBmpTemp = -1;
        float lastPressure = -1;
        float lastHum = -1;
        float lastTemp = -1;
        double temp;
        double hum;
        int BATTERY_SENSE_PIN = A0;
        int lastRainValue = -1;
        int nRainVal;
        boolean bIsRaining = false;
        String strRaining = "NO";
        int lastBatteryPcnt = 0;
        int updateAll = 60;
        int updateCount = 0;
        uint16_t lastLux;
        // unsigned long SLEEP_TIME = 60000;
        unsigned long SLEEP_TIME = 600;
        int batteryBasement = 800;
        float batteryConstant = 100.0 / (1023 - batteryBasement);
    
        MyTransportNRF24 radio;  // NRFRF24L01 radio driver
        MyHwATMega328 hw; // Select AtMega328 hardware profile
        MySigningAtsha204 signer(true); // Select HW ATSHA signing backend
        
        Adafruit_BMP085 bmp = Adafruit_BMP085();
        BH1750 lightSensor;
        dht DHT;
        MySensor gw(radio, hw, signer);
    
        MyMessage msgHum(CHILD_ID_HUM, V_HUM);
        MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
        MyMessage msgLux(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
        MyMessage msgBtemp(CHILD_ID_BTEMP, V_TEMP);
        MyMessage msgPressure(CHILD_ID_BARO, V_PRESSURE);
        MyMessage msgWindSpeed(CHILD_ID_WINDSPEED, V_WIND);
        MyMessage msgWGust(CHILD_ID_WINDSPEED, V_GUST);
        MyMessage msgWDirection(CHILD_ID_WINDSPEED, V_DIRECTION);   
        MyMessage msgRain(CHILD_ID_RAIN, V_TRIPPED);
    
        void setup()  
        {
          analogReference(INTERNAL);
          gw.begin(incomingMessage, 3, true);  
          //dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
          bmp.begin();
          gw.sendSketchInfo("Weather Sensor", "1.0");
          gw.present(CHILD_ID_HUM, S_HUM, "WS Humidity");
          gw.present(CHILD_ID_TEMP, S_TEMP, "WS Temperature");
          gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL, "WS Lux");
          gw.present(CHILD_ID_BARO, S_BARO, "WS Pressure");
          gw.present(CHILD_ID_BTEMP, S_TEMP, "WS P Temperature");
          gw.present(CHILD_ID_WINDSPEED, S_WIND, "WS Windspeed");
          gw.present(CHILD_ID_RAIN, S_MOTION, "WS Rain");
    
          pinMode(DIGITAL_INPUT_RAIN_SENSOR, INPUT);
          lightSensor.begin();
          metric = gw.getConfig().isMetric;
        }
        
        // Wind Meter https://github.com/chiemseesurfer/arduinoWeatherstation/blob/master/weatherstation/weatherstation.ino
        
        float windmeter()
        {
            windmeterStart = millis(); // Actual start time measuringMessung
            windmeterStartAlt = windmeterStart; // Save start time
        
            windSpeedPinCounter = 0; // Set pulse counter to 0
            windSpeedPinStatusAlt = HIGH; // Set puls status High
        
            while ((windmeterStart - windmeterStartAlt) <= windmeterTime) // until 10000 ms (10 Seconds) ..
            {
                windSpeedPinStatus = digitalRead(windSpeedPin); // Read input pin 2
                if (windSpeedPinStatus != windSpeedPinStatusAlt) // When the pin status changed
                {
                    if (windSpeedPinStatus == HIGH) // When status - HIGH
                    {
                        windSpeedPinCounter++; // Counter + 1
                    }
                }
                windSpeedPinStatusAlt = windSpeedPinStatus; // Save status for next loop
                windmeterStart = millis(); // Actual time
            }
        
            windSpeed =  ((windSpeedPinCounter * 24) / 10) + 0.5; //  WindSpeed - one Pulse ~ 2,4 km/h, 
            windSpeed = (windSpeed / (windmeterTime / 1000)); // Devided in measure time in seconds
            Serial.print("wind Speed : ");
            Serial.println(windSpeed);    
            knoten = windSpeed / 1.852; //knot's
        
            return windSpeed;
        }
        
        void loop()      
        {
          updateCount += 1;
          if (updateCount == updateAll) {
            lastTemp = -1;
            lastHum = -1;
            lastLux = -1;
            lastBmpTemp = -1;
            lastPressure = -1;
            lastRainValue = -1;
            lastBatteryPcnt = -1;
            updateCount = 0;
          }
          delay(2000);
          int chk = DHT.read22(HUMIDITY_SENSOR_DIGITAL_PIN);
          temp = DHT.temperature;
                 //Serial.print("Temperature DHT :");
                 //Serial.println(temp);
          if (isnan(temp)) {
              lastTemp = -1;
          } else if (temp != lastTemp) {
            lastTemp = temp;
            if (!metric) {
              temp = temp * 1.8 + 32.0;
            }
            gw.send(msgTemp.set(temp, 1));
            }
          hum = DHT.humidity;
          if (isnan(hum)) {
              lastHum = -1;
          } else if (hum != lastHum) {
              lastHum = hum;
              gw.send(msgHum.set(hum, 1));
          }
          uint16_t lux = lightSensor.readLightLevel();
          if (lux != lastLux) {
              gw.send(msgLux.set(lux));
              lastLux = lux;
          }
          float pressure = bmp.readSealevelPressure(altitude) * 0.01;
          float bmptemp = bmp.readTemperature();
          if (!metric) {
            bmptemp = bmptemp * 1.8 + 32.0;
          }
          if (bmptemp != lastBmpTemp) {
            gw.send(msgBtemp.set(bmptemp,1));
            lastBmpTemp = bmptemp;
          }
          if (pressure != lastPressure) {
            gw.send(msgPressure.set(pressure, 0));
            lastPressure = pressure;
          }
          
          bIsRaining = !(digitalRead(DIGITAL_INPUT_RAIN_SENSOR));
          if(bIsRaining){
              strRaining = "YES";
          }
          else{
              strRaining = "NO";
          }
      
          //Serial.print("Raining?: ");
          //Serial.print(strRaining);  
          //Serial.print("\t Moisture Level: ");
          //Serial.println(nRainVal);
          //http://henrysbench.capnfatz.com/henrys-bench/arduino-sensors-and-input/arduino-rain-sensor-module-guide-and-tutorial/
    
          gw.send(msgRain.set(bIsRaining, 1));
    
          wind = windmeter();
          Serial.print("Wind : ");
          Serial.println(wind);
          int wdirection = 1;
          int wgust = 1;
          gw.send(msgWindSpeed.set(wind, 1));
          gw.send(msgWGust.set(wgust, 1));
          gw.send(msgWDirection.set(wdirection, 1));
          
          int sensorValue = analogRead(BATTERY_SENSE_PIN);
          int batteryPcnt = (sensorValue - batteryBasement) * batteryConstant;
          if (lastBatteryPcnt != batteryPcnt) {
            gw.sendBatteryLevel(batteryPcnt);
            lastBatteryPcnt = batteryPcnt;
          }
          gw.sleep(SLEEP_TIME);
       }
    
        void incomingMessage(const MyMessage & message) {
        // We only expect one type of message from controller. But we better check anyway.
         if (message.isAck()) {
           Serial.println("This is an ack from gateway");
         }
        }
    
    

    regards Peer



  • Hi,
    It means that there is no possibility to implement wind speed on this weather station... ok.
    I've just received the good Li-Ion charging component, I can continue with the construction!

    I'll post if I will be facing for some trouble, or when it will be finished.



  • @Salmoides - I must congratulate you on a very neat and professional build.

    I'm not sure if you are still hanging around this forum but even if you aren't, others may find the following suggestion helpful.

    @Salmoides said*:

    With it [the rain detector] I get 0.98 mA [drain] during the gw.sleep command

    There is a very easy, but often overlooked, method to disable sensors to reduce battery drain that requires no additional components. Because the sensor draws approximately 1ma, that is well within the 'drive' capacity of an Arduino output pin (which is about 20ma). So, all you need to do is wire the "+" power pin of the rain sensor to a spare output pin and "digitalWrite(pin,HIGH)" to turn it on and "digitalWrite(pin,LOW)" to turn it off.

    IMPORTANT: You should check the specs of the processor you are using to make sure the I/O pin can 'drive' or 'source' more than the required current of the sensor you wish to switch. I'd suggest allowing a 50% safety margin.

    Paul



  • @AffordableTech

    Looks like a feasible idea, as my stn does consume all the battery on bad days, and yes I needed the diode between the solar and controller to get to the right voltage

    cheers doug



  • Hello, it a nice job
    I am french so I beg your pardon for my poor English
    Can you , please show me how the lipo and the solar cell are connected and how the arduino is powered by the little shield (Charger Board ) at the right of picture over the DHT ?
    Thanks



  • @gigi: Besides the already adressed error in the Fritzing I have anaother question. In the diagram there is a charge controller for 12V. The original design in this threat uses a 5V charging module. What module are you using or planning to use?
    Thanks Ralph



  • @Renard : Bonjour! Je fais le raccordement cette semaine j'espère, je galère sur la déclaration dans Domoticz et l'étalonnage pour controler la charge de la batterie, mais je dirais:

    • OUT+ et - sur RAW et GND de l'Arduino
    • B+ B- à la batterie
    • "+ et -" au panneau solaire, c'est ce qu'il me semble sur les photos.

    @bisschopsr : Hi, There is no charge controler 5 or 12 volts. On my Fritzing to understand better the scheme (Post #70), I draw batteries and solar panel, but Fritzings following are with 12volts charger, I don't know why. If you purchased a solar lamp, it's to avoid 5 or 12volts charger and use the sun 😉



  • Merci pour la réponse
    C 'est donc l'arduino qui gère la décharge..
    Je vais donc mettre "Arduino Compatible Solar Charger shield -LiPo rider" a la place ...

    Thanks for answer
    It is the arduino wich control the discharge
    I put "Arduino Compatible Solar Charger shield -LiPo rider" without control of lipo capacity


Log in to reply
 

294
Online

6.7k
Users

7.6k
Topics

80.5k
Posts

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.