Possible Bug version 2.2.0



  • Good morning, for one of my Weather Station (very early stage) I used the code below. Which works perfectly with MySensors 2.1.1
    Yesterday I updated my Arduino IDE to Version 2.2.0 and when I try to compile the code it goes, but once loaded the scketch on my arduino Pro, it does not work, while reloading the code compiled with MySensors 2.1.1 It works !!

    I think there is something wrong with the latest version of Mysensors

    // ---- - Stazione Meteo Francy Ver 1 - ----
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached 
    #define MY_RADIO_NRF24
    
    #define MY_PARENT_NODE_ID 0
    #define MY_PARENT_NODE_IS_STATIC
    
    
    #define   MY_RF24_CHANNEL 84
    
    
    #define MY_SIGNING_SOFT
    #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
    #define MY_SIGNING_REQUEST_SIGNATURES
    
    
    
    // Definisco il Nodo
    #define MY_NODE_ID 66
    
    // Nomino i figli del Nodo
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_aaaa 2
    #define CHILD_ID_HUMI 3
    #define CHILD_ID_bbbb 4
    #define CHILD_ID_BARO 5
    #define CHILD_ID_LIGHT 6
    
    
    #define LIGHT_SENSOR_ANALOG_PIN 0
    
    const float ALTITUDE = 335;
    //----------------------------- Pressione
    //float pressione = 1017;
    //int forecast = 4;
    const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
    enum FORECAST
    {
        STABLE = 0,            // "Stable Weather Pattern"
        SUNNY = 1,            // "Slowly rising Good Weather", "Clear/Sunny "
        CLOUDY = 2,            // "Slowly falling L-Pressure ", "Cloudy/Rain "
        UNSTABLE = 3,        // "Quickly rising H-Press",     "Not Stable"
        THUNDERSTORM = 4,    // "Quickly falling L-Press",    "Thunderstorm"
        UNKNOWN = 5            // "Unknown (More Time needed)
    };
    //-----------------------------------------
    
    
    
    
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DHT.h>
    #include <Wire.h>
    #include <Adafruit_BMP085.h>
    DHT dht;
    
    //-----------------------------
    Adafruit_BMP085 bmp = Adafruit_BMP085();      // Digital Pressure Sensor 
    
    float lastPressure = -1;
    float lastTemp = -1;
    int lastForecast = -1;
    
    const int LAST_SAMPLES_COUNT = 5;
    float lastPressureSamples[LAST_SAMPLES_COUNT];
    
    // this CONVERSION_FACTOR is used to convert from Pa to kPa in forecast algorithm
    // get kPa/h be dividing hPa by 10 
    #define CONVERSION_FACTOR (1.0/10.0)
    
    int minuteCount = 0;
    bool firstRound = true;
    // average value is used in forecast algorithm.
    float pressureAvg;
    // average after 2 hours is used as reference value for the next iteration.
    float pressureAvg2;
    
    float dP_dt;
    bool metric;
    //-----------------------------
    
    //Dichiarazioni per pause dei diversi blocchi
    unsigned long int time;
    unsigned long int lettura_Press;
    unsigned long int lettura_Temp;
    
    unsigned long int letturaluce_time;
    //------------------------------
    
    int lastLightLevel; //Dichiarazione Luminosita
    
    float temperatureDTH2;
    
    
    void presentation()  
     { 
      sendSketchInfo("Temp e Umidita", "3");
      present(CHILD_ID_TEMP, S_TEMP);
      present(CHILD_ID_aaaa, S_LIGHT);
      present(CHILD_ID_HUMI, S_HUM);
      present(CHILD_ID_bbbb, S_LIGHT);
      present(CHILD_ID_BARO, S_BARO);
      present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
      }
      
    
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgaaaa(CHILD_ID_HUMI, V_LIGHT);
    MyMessage msgHumi(CHILD_ID_HUMI, V_HUM);
    MyMessage msgbbbb(CHILD_ID_HUMI, V_LIGHT);
    MyMessage msgPres(CHILD_ID_BARO, V_PRESSURE);
    MyMessage msgForecast(CHILD_ID_BARO, V_FORECAST);
    MyMessage msg4(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    
    
    
    void setup()
    {
      // Setto il Pin dove e collegato il sensore di Temperatura DHT22
      dht.setup(3);
    
      //Settaggi del BMP180
          if (!bmp.begin()) 
        {
            Serial.println("Could not find a valid BMP085 sensor, check wiring!");
            while (1) {}
        }
        metric = getControllerConfig().isMetric;
      //Fine settaggi BMP180 
    
    //-- Setup Variabili MILLIS per sensore di Pressione
    time=millis();
    lettura_Press = millis();
    lettura_Temp = millis();
    letturaluce_time = millis();
      }
    
    
    void loop()
    {
    //Attivo Time MILLIS       
    time=millis();
      
    //----------- Inizio DHT22 ------------------------
    if(time>lettura_Temp+12000){
    delay(dht.getMinimumSamplingPeriod());
    
    Serial.println("--- Temperatura ---  ");
    
    float temperatureDTH;
    
    float humidity = dht.getHumidity();
    float temperatureDHT = dht.getTemperature();
    
    temperatureDTH2 = temperatureDTH;
    
     //Invio la lettura della Temperatura
      send(msgTemp.set(temperatureDHT, 1));
      //delay(6000); // Faccio una pausa ed invio altra lettura
     //Invio lettura Umidita
      send(msgHumi.set(humidity, 1));
      //delay(4000);
      
    lettura_Temp=millis();
    }
    
    //---------- Inizio Pressione ---------------------------
    if(time>lettura_Press+11000){
    Serial.println("--- Tempo passato lego la Pressione---  ");
    
    float temperatureDHT2;
    
    float pressure = bmp.readSealevelPressure(ALTITUDE) / 100.0;
    float temperature = temperatureDHT2;
    
    if (!metric) 
        {
            // Convert to fahrenheit
            temperature = temperature * 9.0 / 5.0 + 32.0;
        }
        
    int forecast = sample(pressure);
        Serial.print("Pressione = ");
        Serial.print(pressure);
        Serial.println(" hPa");
        Serial.print("Forecast = ");
        Serial.println(weather[forecast]);
    
     if (pressure != lastPressure) 
        {
            send(msgPres.set(pressure, 0));
            lastPressure = pressure;
        }
    if (forecast != lastForecast)
        {
            send(msgForecast.set(weather[forecast]));
            lastForecast = forecast;
        }
      
    lettura_Press=millis();
    }
    
    //-------------- Inizio Luminosita --------------------------
    if(time>letturaluce_time+10000){
    Serial.print("Tempo passato lego la Luce: ");
      
            int16_t lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
        Serial.println(lightLevel);
        //delay(1000); 
        
        if (lightLevel != lastLightLevel) {
           if(lightLevel > lastLightLevel + 7 || lightLevel < lastLightLevel - 7){
            send(msg4.set(lightLevel));
            Serial.print("Invio nuova lettura LUX: ");
            Serial.println(lightLevel);
            lastLightLevel = lightLevel;
           }
        }
    letturaluce_time=millis();    
    }    
        //Fine Luminosita
    
      
    //--------- Eventuale 4 Modulo -------------------------
    
    // Chiusura Loop
    }
    
    
    
    
    
    
    //------------ Aggiuntivo Previsione del Barometro ---------------------
    
    float getLastPressureSamplesAverage()
    {
        float lastPressureSamplesAverage = 0;
        for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
        {
            lastPressureSamplesAverage += lastPressureSamples[i];
        }
        lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
    
        return lastPressureSamplesAverage;
    }
    
    
    // Algorithm found here
    // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf
    // Pressure in hPa -->  forecast done by calculating kPa/h
    int sample(float pressure)
    {
      
        // Calculate the average of the last n minutes.
        int index = minuteCount % LAST_SAMPLES_COUNT;
        lastPressureSamples[index] = pressure;
    
        minuteCount++;
        if (minuteCount > 185)
        {
            minuteCount = 6;
        }
    
        if (minuteCount == 5)
        {
            pressureAvg = getLastPressureSamplesAverage();
        }
        else if (minuteCount == 35)
        {
            float lastPressureAvg = getLastPressureSamplesAverage();
            float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
            if (firstRound) // first time initial 3 hour
            {
                dP_dt = change * 2; // note this is for t = 0.5hour
            }
            else
            {
                dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value.
            }
        }
        else if (minuteCount == 65)
        {
            float lastPressureAvg = getLastPressureSamplesAverage();
            float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
            if (firstRound) //first time initial 3 hour
            {
                dP_dt = change; //note this is for t = 1 hour
            }
            else
            {
                dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value
            }
        }
        else if (minuteCount == 95)
        {
            float lastPressureAvg = getLastPressureSamplesAverage();
            float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
            if (firstRound) // first time initial 3 hour
            {
                dP_dt = change / 1.5; // note this is for t = 1.5 hour
            }
            else
            {
                dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value
            }
        }
        else if (minuteCount == 125)
        {
            float lastPressureAvg = getLastPressureSamplesAverage();
            pressureAvg2 = lastPressureAvg; // store for later use.
            float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
            if (firstRound) // first time initial 3 hour
            {
                dP_dt = change / 2; // note this is for t = 2 hour
            }
            else
            {
                dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value
            }
        }
        else if (minuteCount == 155)
        {
            float lastPressureAvg = getLastPressureSamplesAverage();
            float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
            if (firstRound) // first time initial 3 hour
            {
                dP_dt = change / 2.5; // note this is for t = 2.5 hour
            }
            else
            {
                dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value
            }
        }
        else if (minuteCount == 185)
        {
            float lastPressureAvg = getLastPressureSamplesAverage();
            float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
            if (firstRound) // first time initial 3 hour
            {
                dP_dt = change / 3; // note this is for t = 3 hour
            }
            else
            {
                dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value
            }
            pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past.
            firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop.
        }
    
        int forecast = UNKNOWN;
        if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval.
        {
            forecast = UNKNOWN;
        }
        else if (dP_dt < (-0.25))
        {
            forecast = THUNDERSTORM;
        }
        else if (dP_dt > 0.25)
        {
            forecast = UNSTABLE;
        }
        else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
        {
            forecast = CLOUDY;
        }
        else if ((dP_dt > 0.05) && (dP_dt < 0.25))
        {
            forecast = SUNNY;
        }
        else if ((dP_dt >(-0.05)) && (dP_dt < 0.05))
        {
            forecast = STABLE;
        }
        else
        {
            forecast = UNKNOWN;
        }
    
        // uncomment when debugging
        Serial.print(F("Forecast at minute "));
        Serial.print(minuteCount);
        Serial.print(F(" dP/dt = "));
        Serial.print(dP_dt);
        Serial.print(F("kPa/h --> "));
        Serial.println(weather[forecast]);
    
        return forecast;
    }```


  • @sindrome73 it does not work is a large statement. Did you try different Arduino? Logs?


  • Contest Winner

    @sindrome73 you use signing? Have you followed the signing migration guide for 2.1 to 2.2?
    https://forum.mysensors.org/topic/7843/security-migrating-from-library-version-2-1-to-2-2



  • @anticimex Just out of curiosity - what happens if re-personalisation is not done after moving to 2.2.0? Signing fails?


  • Contest Winner

    @alexsh1 checksum verification for the signing backend will fail and signing will not operate



  • @anticimex OK, but if the GW is still on 2.1.1 and nodes are 2.2.0 it should be fine, right?


  • Contest Winner

    @alexsh1 if the 2.2 node has correct checksum yes. And this is shown in the debug log.



  • @anticimex

    532/5000
    I made the customization from the beginning, with MySensors 2.2.0

    I followed these steps:

    • The EEPROM has been deleted
    • Open SecurityPersonalize.ino inserted the new Key
    • loaded the scketch and it does not go

    I redid the same procedure above, then EEprom deleted, SecurityPersonalize file, and loaded the scketch, but this time using Mysensors 2.1.1
    And here it worked ..... The same thing I did on Several Pro Mini at 5V 16Mhz and the result is the same ..... That's why I assume there may be something wrong with 2.2.0


  • Contest Winner

    @sindrome73 2.2 works. At least signing. Log please.



  • I apologize, but I did not understand what you tell me ....

    I would like to add that the script without the signature with the 2.2 version works, while the signature works only with MySensors 2.1


  • Contest Winner

    @sindrome73 log please.



  • In the evening ..... Now I'm at work and I can not


  • Contest Winner

    @sindrome73 no problem



  • Here I am at home .... I proceeded to redo the procedure and this sot is the log ....

    I had to put an image because the last signs that mida I can not copy them as text ....

    0_1522266474450_Log_arduino.jpg


  • Contest Winner

    @sindrome73 log looks pretty corrupt, but I can't find any signing related messages so it would seem signing is not enabled on the node. Do you have a log from the GW? Is it also running 2.2.0?


  • Contest Winner

    @sindrome73 sorry, the capabilities string indicate software signing. But I don't see the backend initialization message. Could you please enable verbose signing debug?



  • tell me how to abbilitate the detailed signature debug .....


  • Contest Winner



  • Here is the log with the Debug signed abbreviation.
    I specify that I had to disable // # define MY_DEBUG because the scketch is too big

    0_1522270397919_Log_arduino2.jpg


  • Contest Winner

    @sindrome73 signing messages look sane. But the logs look very corrupt. It also looks like the sketch crashed and restarted so I suspect you are running out of stack space. The arduino IDE reports and warns about memory usage and I suspect you get a warning on that.



  • Yes indeed I have already said this !! So true that to have the DEBUG of the signature I had to disable the DEBUG.

    But with this same script, and going to Mysensors 2.1 it works !!


  • Contest Winner

    @sindrome73 you could try to completely disable debug on your node and observe the behavior of your gw or controller.



  • Ok .... Tomorrow I'll do it ..... But it will be difficult to have the Gateway Log because with the signature enabled, the sketch is very large, and does not allow me to activate the Debug ....


  • Contest Winner

    @sindrome73 well, 2.2.0 could be requiring more memory than 2.1. You can compare since the IDE reports exactly how much memory is used.



  • But it is the same with both 2.2 and 2.1.
    With Arduino Pro Mini, enabling the signature debugging must be disabled because it exceeds counque the maximum available memory .......


  • Contest Winner

    @sindrome73 you could see in your controller if communication gets though. I could see in the node log that signing handshaking takes place. So I am sure your problem is memory use. You need to reduce the size of your sketch. Or get more powerful hardware to support the features you want to use.



  • Ok tomorrow calmly I will make these changes and update you .... A Tomorrow, and thanks for now .....


  • Contest Winner

    @sindrome73 I'm off to bed as well. Good night and we will figure something out later on.



  • @sindrome73 You can try to load a default sketch from examples with signing to make sure everything is working fine.
    If you are out of memory, strange things may happen.


  • Contest Winner



  • @anticimex I must admit that in the world of ESP32 or SAMD I find atmega328p memory restriction more and more an issue. Its ok for 1 sensor and signing, but on some nodes I have 3-4 sensors and debugging and signing have to be disabled due to memory constrains.

    BTW, some nodes do behave strangely even when you approach memory limit.

    Having said that, I think we need to establish if @sindrome73 node is working fine - a default sketch plus signing would reveal it.


  • Contest Winner

    @alexsh1 sensors behave strange because stack space is consumed.
    Regarding signing and 2.2.0, I know for a fact it works, and I have tested it on atmega328p. But sure, trying with the secure actuator sketch should help reveal if the problem lies with the GW.



  • Hello!! Sorry if I'm late.....
    So I tried to do the checks as suggested .....

    If I load the schetck with Mysensors Ver 2.1 the Arduino IDE gives me 28620 Bytes used 93% of the space

    If I load the schetck with Mysensors Ver 2.2 the IDE of Arduino gives me 29310 Bytes used 95% of the space

    So it could be a problem of space and therefore makes my Arduino Pro unstable .....
    Tomorrow I'll try to load the same Scketch on An Arduino Uno that should have a little more space ..... I keep you updated on the developments


  • Contest Winner

    @sindrome73 anything above 90% puts you well into the danger zone. Stack space is what is left after linker has placed the symbols. And the atmega328p has little ram so less than 10% of that ram is not much for the stack. I don't have the numbers of the library worst case stack usage but it depend heavily on what features you use and in the order they are used, and so on.



  • @sindrome73 Try to load any sketch from MySensors examples just to see if everything is working fine with v2.2.0. If you are running out of memory its a good practice to try the sketch on Mega or SAMD (more cpu+memory)



  • Other sketches work, already tried !! And this from problems with 2.2



  • @sindrome73 said in Possible Bug version 2.2.0:

    Other sketches work, already tried !! And this from problems with 2.2

    If other sketches work with v2.2.0, the problem is 100% in low memory.
    I had similar issue with my dust sensor - 98% memory was used. The node was unstable and froze on many occasions. I had to reduce the sketch.



  • Test if this reduces your memory consumption.
    This is what I have added
    Disable the splash screen with:
    #define MY_SPLASH_SCREEN_DISABLED // This saves a couple of bytes
    Then for every serial.print I have embedded those with #ifdef MY_DEBUG/#endif
    There is no need to serial print when running in silent mode.
    I have also embedded the missing serial.print with the F("string") function.
    This saves memory by storing strings in flash instead of memory.
    I could not get the code to compile as I don't have the proper DHT library.

    // ---- - Stazione Meteo Francy Ver 1 - ----
    
    // Enable debug prints
    // #define MY_DEBUG
    #define MY_SPLASH_SCREEN_DISABLED  // This saves a couple of bytes
    // Enable and select radio type attached 
    #define MY_RADIO_NRF24
    
    #define MY_PARENT_NODE_ID 0
    #define MY_PARENT_NODE_IS_STATIC
    
    #define   MY_RF24_CHANNEL 84
    
    #define MY_SIGNING_SOFT
    #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
    #define MY_SIGNING_REQUEST_SIGNATURES
    
    // Definisco il Nodo
    #define MY_NODE_ID 66
    
    // Nomino i figli del Nodo
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_aaaa 2
    #define CHILD_ID_HUMI 3
    #define CHILD_ID_bbbb 4
    #define CHILD_ID_BARO 5
    #define CHILD_ID_LIGHT 6
    
    #define LIGHT_SENSOR_ANALOG_PIN 0
    
    const float ALTITUDE = 335;
    //----------------------------- Pressione
    //float pressione = 1017;
    //int forecast = 4;
    const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
    enum FORECAST
    {
        STABLE = 0,            // "Stable Weather Pattern"
        SUNNY = 1,            // "Slowly rising Good Weather", "Clear/Sunny "
        CLOUDY = 2,            // "Slowly falling L-Pressure ", "Cloudy/Rain "
        UNSTABLE = 3,        // "Quickly rising H-Press",     "Not Stable"
        THUNDERSTORM = 4,    // "Quickly falling L-Press",    "Thunderstorm"
        UNKNOWN = 5            // "Unknown (More Time needed)
    };
    //-----------------------------------------
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DHT.h>
    #include <Wire.h>
    #include <Adafruit_BMP085.h>
    DHT dht;
    
    //-----------------------------
    Adafruit_BMP085 bmp = Adafruit_BMP085();      // Digital Pressure Sensor 
    
    float lastPressure = -1;
    float lastTemp = -1;
    int lastForecast = -1;
    
    const int LAST_SAMPLES_COUNT = 5;
    float lastPressureSamples[LAST_SAMPLES_COUNT];
    
    // this CONVERSION_FACTOR is used to convert from Pa to kPa in forecast algorithm
    // get kPa/h be dividing hPa by 10 
    #define CONVERSION_FACTOR (1.0/10.0)
    
    int minuteCount = 0;
    bool firstRound = true;
    // average value is used in forecast algorithm.
    float pressureAvg;
    // average after 2 hours is used as reference value for the next iteration.
    float pressureAvg2;
    
    float dP_dt;
    bool metric;
    //-----------------------------
    
    //Dichiarazioni per pause dei diversi blocchi
    unsigned long int time;
    unsigned long int lettura_Press;
    unsigned long int lettura_Temp;
    
    unsigned long int letturaluce_time;
    //------------------------------
    
    int lastLightLevel; //Dichiarazione Luminosita
    
    float temperatureDTH2;
    
    
    void presentation()  
     { 
      sendSketchInfo("Temp e Umidita", "3");
      present(CHILD_ID_TEMP, S_TEMP);
      present(CHILD_ID_aaaa, S_LIGHT);
      present(CHILD_ID_HUMI, S_HUM);
      present(CHILD_ID_bbbb, S_LIGHT);
      present(CHILD_ID_BARO, S_BARO);
      present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
      }
      
    
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgaaaa(CHILD_ID_HUMI, V_LIGHT);
    MyMessage msgHumi(CHILD_ID_HUMI, V_HUM);
    MyMessage msgbbbb(CHILD_ID_HUMI, V_LIGHT);
    MyMessage msgPres(CHILD_ID_BARO, V_PRESSURE);
    MyMessage msgForecast(CHILD_ID_BARO, V_FORECAST);
    MyMessage msg4(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    
    
    void setup()
    {
      // Setto il Pin dove e collegato il sensore di Temperatura DHT22
      dht.setup(3);
    
    
    #ifdef MY_DEBUG
      //Settaggi del BMP180
          if (!bmp.begin()) 
        {
            Serial.println(F("Could not find a valid BMP085 sensor, check wiring!"));
            while (1) {}
        }
    #endif
    metric = getControllerConfig().isMetric;
      //Fine settaggi BMP180 
    
    //-- Setup Variabili MILLIS per sensore di Pressione
    time=millis();
    lettura_Press = millis();
    lettura_Temp = millis();
    letturaluce_time = millis();
      }
    
    
    void loop()
    {
    //Attivo Time MILLIS       
    time=millis();
      
    //----------- Inizio DHT22 ------------------------
    if(time>lettura_Temp+12000){
    delay(dht.getMinimumSamplingPeriod());
    
    #ifdef MY_DEBUG
    Serial.println(F("--- Temperatura ---  "));
    #endif
    float temperatureDTH;
    
    float humidity = dht.getHumidity();
    float temperatureDHT = dht.getTemperature();
    
    temperatureDTH2 = temperatureDTH;
    
     //Invio la lettura della Temperatura
      send(msgTemp.set(temperatureDHT, 1));
      //delay(6000); // Faccio una pausa ed invio altra lettura
     //Invio lettura Umidita
      send(msgHumi.set(humidity, 1));
      //delay(4000);
      
    lettura_Temp=millis();
    }
    
    //---------- Inizio Pressione ---------------------------
    if(time>lettura_Press+11000){
    #ifdef MY_DEBUG
    Serial.println(F("--- Tempo passato lego la Pressione---  "));
    #endif
    float temperatureDHT2;
    
    float pressure = bmp.readSealevelPressure(ALTITUDE) / 100.0;
    float temperature = temperatureDHT2;
    
    if (!metric) 
        {
            // Convert to fahrenheit
            temperature = temperature * 9.0 / 5.0 + 32.0;
        }
        
    int forecast = sample(pressure);
    #ifdef MY_DEBUG
        Serial.print(F("Pressione = "));
        Serial.print(pressure);
        Serial.println(F(" hPa"));
        Serial.print(F("Forecast = "));
        Serial.println(weather[forecast]);
    #endif
     if (pressure != lastPressure) 
        {
            send(msgPres.set(pressure, 0));
            lastPressure = pressure;
        }
    if (forecast != lastForecast)
        {
            send(msgForecast.set(weather[forecast]));
            lastForecast = forecast;
        }
      
    lettura_Press=millis();
    }
    
    //-------------- Inizio Luminosita --------------------------
    if(time>letturaluce_time+10000){
    #ifdef MY_DEBUG
    Serial.print(F("Tempo passato lego la Luce: "));
    #endif  
        int16_t lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
    #ifdef MY_DEBUG
        Serial.println(lightLevel);
    #endif
        //delay(1000); 
        
        if (lightLevel != lastLightLevel) {
           if(lightLevel > lastLightLevel + 7 || lightLevel < lastLightLevel - 7){
            send(msg4.set(lightLevel));
    #ifdef MY_DEBUG
            Serial.print(F("Invio nuova lettura LUX: "));
            Serial.println(lightLevel);
    #endif
            lastLightLevel = lightLevel;
           }
        }
    letturaluce_time=millis();    
    }    
        //Fine Luminosita
    
      
    //--------- Eventuale 4 Modulo -------------------------
    
    // Chiusura Loop
    }
    
    //------------ Aggiuntivo Previsione del Barometro ---------------------
    
    float getLastPressureSamplesAverage()
    {
        float lastPressureSamplesAverage = 0;
        for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
        {
            lastPressureSamplesAverage += lastPressureSamples[i];
        }
        lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
    
        return lastPressureSamplesAverage;
    }
    
    
    // Algorithm found here
    // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf
    // Pressure in hPa -->  forecast done by calculating kPa/h
    int sample(float pressure)
    {
      
        // Calculate the average of the last n minutes.
        int index = minuteCount % LAST_SAMPLES_COUNT;
        lastPressureSamples[index] = pressure;
    
        minuteCount++;
        if (minuteCount > 185)
        {
            minuteCount = 6;
        }
    
        if (minuteCount == 5)
        {
            pressureAvg = getLastPressureSamplesAverage();
        }
        else if (minuteCount == 35)
        {
            float lastPressureAvg = getLastPressureSamplesAverage();
            float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
            if (firstRound) // first time initial 3 hour
            {
                dP_dt = change * 2; // note this is for t = 0.5hour
            }
            else
            {
                dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value.
            }
        }
        else if (minuteCount == 65)
        {
            float lastPressureAvg = getLastPressureSamplesAverage();
            float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
            if (firstRound) //first time initial 3 hour
            {
                dP_dt = change; //note this is for t = 1 hour
            }
            else
            {
                dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value
            }
        }
        else if (minuteCount == 95)
        {
            float lastPressureAvg = getLastPressureSamplesAverage();
            float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
            if (firstRound) // first time initial 3 hour
            {
                dP_dt = change / 1.5; // note this is for t = 1.5 hour
            }
            else
            {
                dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value
            }
        }
        else if (minuteCount == 125)
        {
            float lastPressureAvg = getLastPressureSamplesAverage();
            pressureAvg2 = lastPressureAvg; // store for later use.
            float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
            if (firstRound) // first time initial 3 hour
            {
                dP_dt = change / 2; // note this is for t = 2 hour
            }
            else
            {
                dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value
            }
        }
        else if (minuteCount == 155)
        {
            float lastPressureAvg = getLastPressureSamplesAverage();
            float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
            if (firstRound) // first time initial 3 hour
            {
                dP_dt = change / 2.5; // note this is for t = 2.5 hour
            }
            else
            {
                dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value
            }
        }
        else if (minuteCount == 185)
        {
            float lastPressureAvg = getLastPressureSamplesAverage();
            float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
            if (firstRound) // first time initial 3 hour
            {
                dP_dt = change / 3; // note this is for t = 3 hour
            }
            else
            {
                dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value
            }
            pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past.
            firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop.
        }
    
        int forecast = UNKNOWN;
        if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval.
        {
            forecast = UNKNOWN;
        }
        else if (dP_dt < (-0.25))
        {
            forecast = THUNDERSTORM;
        }
        else if (dP_dt > 0.25)
        {
            forecast = UNSTABLE;
        }
        else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
        {
            forecast = CLOUDY;
        }
        else if ((dP_dt > 0.05) && (dP_dt < 0.25))
        {
            forecast = SUNNY;
        }
        else if ((dP_dt >(-0.05)) && (dP_dt < 0.05))
        {
            forecast = STABLE;
        }
        else
        {
            forecast = UNKNOWN;
        }
    
        // uncomment when debugging
    #ifdef MY_DEBUG
        Serial.print(F("Forecast at minute "));
        Serial.print(minuteCount);
        Serial.print(F(" dP/dt = "));
        Serial.print(dP_dt);
        Serial.print(F("kPa/h --> "));
        Serial.println(weather[forecast]);
    #endif
        return forecast;
    }```

Log in to reply
 

Suggested Topics

  • 33
  • 6
  • 2
  • 11
  • 8
  • 9

20
Online

11.2k
Users

11.1k
Topics

112.5k
Posts