Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. OpenHardware.io
  3. 💬 Various bootloader files based on Optiboot 6.2

💬 Various bootloader files based on Optiboot 6.2

Scheduled Pinned Locked Moved OpenHardware.io
optiboot
164 Posts 18 Posters 63.7k Views 18 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • GertSandersG GertSanders

    @Samuel235
    If you are using a nano, what crystal is mounted on it ? Fast flashing indicates the processor is running faster then the expected 8MHz (expected by the timing routines of the bootloader). Could it be a 16MHz model ?
    In that case you could try to upload a sketch at a higher speed: 76K8 baud.
    Or you can try to load the bootloader for 16MHz/D13 (which in effect is the standard bootloader of an Arduino).

    S Offline
    S Offline
    Samuel235
    Hardware Contributor
    wrote on last edited by Samuel235
    #132

    @GertSanders Soon as i say the fast flashing I instantly thought that its running quicker than needed, but i had no idea about the resetting that you have pointed out, so thanks for pointing that one out. The reason i didn't even bother trying the 16MHz settings in fuses would be that because when i read the fuses of the arduino before i did anything, it indicated that it was running with fuses of 8MHz and the blink sketch was perfectly timed on those settings.... Could it be a miss read on the fuse settings maybe? Should i read at a slower speed when using avrdude?

    The crystal is so small on the nano and i can't even see the engraving with a microscope properly either.

    I can confirm that the 16MHz bootloader is working perfectly on this nano. Thanks.

    MySensors 2.1.1
    Controller - OpenHAB (Virtual Machine)
    Gateway - Arduino Mega MQTT Gateway W5100

    1 Reply Last reply
    0
    • D Offline
      D Offline
      DavidZH
      wrote on last edited by
      #133

      @GertSanders

      I have been running your bootloader for all my nodes now and that works very well.
      But there is something that surprised me. When I compile the next sketch and compare that with the Moteino bootloader it's substantially larger.

      /***************************************************************************************
      **
      ** Outdoor sensor v1.0 Measuring temperature, humdity, pressure and light level
      **  Calculating a weather forecast with the height comensated air pressure.
      **      powered by a solar panel and a 1000mAh Li-Ion battery.
      **
      ** Scraped together by D Hille. MySensors library by Henrik Ekblad et al.
      **
      **      Heat index calculation from DHT library by Adafruit
      **      MAX44009 bij Rob Tillaart
      **      Weather forecast based on AN3914 by Freescale
      **
      ****************************************************************************************/
      //                    MySensors definitions
      
      //#define MY_DEBUG                      // Enable debug prints (6 kb flash space)
      //#define MY_DEBUG_VERBOSE_SIGNING      // Comment out when no signing is used or when everything is OK (3 kb flash space)
      
      #define MY_BAUD_RATE 57600            // Set serial baudrate
      
      #define MY_RADIO_RFM69                // Enable and select radio type attached
      //#define MY_IS_RFM69HW                 // Comment out when using standard RFM69W
      
      #define MY_NODE_ID 110                 // Delete to use automatic ID assignment
      
      //#define MY_CORE_ONLY
      
      /**************************************************************************/
      //                        Transport
      /**************************************************************************/
      
      //#define MY_TRANSPORT_WAIT_READY_MS 1000 //Start the node even if no connection to the GW could be made (disable for sensor nodes).
      #define MY_TRANSPORT_STATE_RETRIES 1
      #define MY_TRANSPORT_MAX_TSM_FAILURES    (2u)
      #define MY_TRANSPORT_TIMEOUT_EXT_FAILURE_STATE (60*1000ul)
      
      
      /**************************************************************************/
      //                        Security
      /**************************************************************************/
      
      //#define MY_SIGNING_ATSHA204
      //#define MY_SIGNING_SOFT
      //#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
      //#define MY_SIGNING_REQUEST_SIGNATURES
      //#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = 0,.serial = {0xD0,0xB1,0x90,0x99,0xC3,0x03,0x08,0xD1,0x34}}}
      
      //#define MY_RFM69_ENABLE_ENCRYPTION
      
      
      /**************************************************************************/
      //                    Sensor definitions
      /**************************************************************************/
      
      #define BATTERY_POWERED
      #define battUpdater 300           //Number of TX actions to count before a new battery status update is sent.
      
      #define MY_DEFAULT_TX_LED_PIN 5   // Comment out when no LED is attached.
      #define MY_WITH_LEDS_BLINKING_INVERSE
      
      #define SENSOR_TYPE 3
      // Sensor types:
      // 0.: no climate sensor attached
      // 1.: RFM69 on-die               Temperature sensor on the RFM69 module (whole integers only)
      // 2.: DS18B20                    Dallas one-wire sensor(data pin D14)
      // 3.: HTU21D                     Temp/humidity (I2C)
      // 4.: BME280                     Temp/humidity/pressure (I2C) (node will wake every minute to keep up with trend measureing)
      #define SENSOR_UPDATE 2           // Time in minutes the sensor sends an update
      
      //#define LIGHT_SENSOR_PRESENT      // Comment out when not present. (I2C) (Light sensor will update every 60 seconds.)
      
      //#define INTERRUPT_SENSOR_PRESENT  // Comment out when not present (e. g. motion sensor connect to D3)
      
      #define alti 57                  //altitude offset to compensate the barometric pressure
      
      
      /**************************************************************************/
      //                  Debug definitions
      /**************************************************************************/
      
      //#define LOCAL_DEBUG                              //Comment out to switch all debug messages off (saves 2 kb flash)
      
      #ifdef MY_DEBUG                                  //Differentiate between global debug including radio and local debug 
        #define LOCAL_DEBUG                            //for the sketch alone.
      #endif 
      
      #ifdef LOCAL_DEBUG 
        #define Sprint(a) (Serial.print(a))            // Macro as substitute for serial debug. Will be an empty macro when
        #define Sprintln(a) (Serial.println(a))        // debug is switched off
      #else
        #define Sprint(a)                                       
        #define Sprintln(a)
      #endif
      
      
      /**************************************************************************/
      
      #include <Button.h>
      #include <SPI.h>
      #include <Wire.h>
      #include <MySensors.h>
      //#include <SparkFunBME280.h>
      //#include <MAX44009.h>                           // Uncomment library used in sketch
      #include <Adafruit_HTU21DF.h>
      //#include <OneWire.h>
      //#include <DallasTemperature.h>
      #include <Vcc.h>
      
      
      #define BMEaddr 0x76
      #define Max44099Addr 0x4A
      #define sketchName "sensorNode(living)"
      #define sketchVer "1.0" 
      
      #define sensorPowerPin 20
      
      #define digitalSensorPin 14
      #define analogSensorPin A0
      #define oneWireBusPin 14
      #define interruptPin 3
      #define altSensorPin 18
      #define altAnalogPin A4
      #define sensorPowerPin 6
      
      #define chanTemp 0
      #define chanHum 1
      #define chanHeat 2 
      #define chanBaro 3
      #define chanDelta 4
      #define chanLight 5
      #define chanRate 6
      #define chanInterrupt 8
      
      #define PULLUP false
      #define INVERT false
      #define bounceTime 20
      #define sleepWait 500           //Time to wait in ms before node sleeps (to be able to receive notification messages).
      
      bool battPower = true;
      
      unsigned long currTime = 0;
      unsigned long sleepTime = (60000 * SENSOR_UPDATE);
      unsigned long lastSensorUpdate;
      unsigned long nextSensor;
      unsigned long measureTime;
      int wakeReason = -1;
      int sendLoop = 0;
      bool updated = false;
      bool ACKed = false;
      
      int sensorFunc = 0;
      float sensorData = 0.0;
      float heatTemp = 0.0;
      float heatHum = 0.0;
      bool interruptState = false;
      bool lastInterrupt = false;
      bool sensorPresent = false;
      bool lightPresent = false;
      bool interruptPresent = false;
      
      int minuteCount = 0;
      bool firstRound = true;         
      float pressureAvg;               // average value is used in forecast algorithm. 
      float pressureAvg2;              // average after 2 hours is used as reference value for the next iteration.
      float dP_dt;
      const int LAST_SAMPLES_COUNT = 5;
      float lastPressureSamples[LAST_SAMPLES_COUNT];
      
      bool startUp = true;
      bool metric = true; 
      
      int battStatCounter = 0;
      const float VccMin = 1.8;                   // Minimum expected Vcc level, in Volts.
      const float VccMax = 3.0;                   // Maximum expected Vcc level, in Volts.
      const float VccCorrection = 1.0/1.0;      // Measured Vcc by multimeter divided by reported Vcc
      
      
      /**************************************************************************/
      //                  Library declarations
      /**************************************************************************/
      
      //  Uncomment necessary declarations.
      
      //RFM69 wireless;
      
      //OneWire OWB(oneWireBusPin);
      //DallasTemperature DS18(&OWB);
      //DeviceAddress DS18address;
      
      Adafruit_HTU21DF HTU = Adafruit_HTU21DF();
      
      //BME280 BME;
      
      //Max44009 lightMax(Max44099Addr);
      
      //Button reedContact(interruptPin, PULLUP, INVERT, bounceTime);
      
      MyMessage msgHum(chanHum, V_HUM);
      MyMessage msgTemp(chanTemp, V_TEMP);
      //MyMessage msgBaro(chanBaro, V_PRESSURE);
      //MyMessage msgTrend(chanUniversal, V_VAR5);
      //MyMessage msgLight(chanLight, V_LEVEL);
      //MyMessage msgIntr(chanInterrupt, V_TRIPPED);
      
      Vcc vcc(VccCorrection);
      
      /**************************************************************************/
      //                  Error messages
      /**************************************************************************/
      
        #if (defined INTERRUPT_SENSOR_PRESENT && defined LIGHT_SENSOR_PRESENT && SENSOR_TYPE >= 4)
          #error Motion sensor can anly be combined with either I2C OR one-wire sensors, not both.
        #endif
      
        #if (defined INTERRUPT_SENSOR_PRESENT && (defined LIGHT_SENSOR_PRESENT || SENSOR_TYPE == 4) && defined BATTERY_POWERED)
          #error Interrupt sensor is not compatible with trend sensors like 'baro' and 'light' because the timer will misalign.
        #endif
      
        #if (SENSOR_TYPE > 4)
          #error Not a valid sensor type!
        #endif
      
      
      /**************************************************************************/
      
      void before(void)
      {  
        Serial.println("\nReading config...");
      
        #ifndef BATTERY_POWERED
          battPower = false;
        #endif
      
        sensorFunc = SENSOR_TYPE;
      
        #ifdef LIGHT_SENSOR_PRESENT
          lightPresent = true;
        #endif
      
        #ifdef INTERRUPT_SENSOR_PRESENT
          interruptPresent = true;
          lastInterrupt = reedContact.read();
        #endif
      
        #if (defined MY_SIGNING_SOFT || defined MY_SIGNING_ATSHA204)
          #define sendPause 100
        #else
          #define sendPause 50
        #endif
      }
       
      /**************************************************************************/
      
      void setup(void)
      {  
        pinMode(sensorPowerPin, OUTPUT);       //switch on the sensor power
        digitalWrite(sensorPowerPin, HIGH);    
        wait(50);                              //wait 50 ms for the sensors to settle.
        
        switch (sensorFunc) {
          case 0:
          break;
          case 1:
            sensorPresent = true;
          break;
          case 2: 
            //DS18.begin();
            //DS18.getAddress(DS18address, 0);
            //DS18.setResolution(DS18address, 10);
            sensorPresent = true;
          break;
          case 3:
            HTU.begin();
            sensorPresent = true;
          break;
          case 4:
            //startBME();
            sleepTime = 60000;
            sensorPresent = true;
          break;    
        }
      
        #if (lightPresent)
          sleepTime = 60000;
          sensorPresent = true;
        #endif
      
        #ifdef MY_DEBUG                //Differentiate between global debug including radio and local debug          
          sleepTime = 30000;              //for the sketch alone.
        #endif
      
        batteryStats();
      
        Serial.println("\nDone. \n\nStarting program.\n");
        
        currTime = millis();
      }
      
      /**************************************************************************/
      
      void presentation()  
      {
        Serial.println("Start radio and sensors");  
        
        sendSketchInfo(sketchName, sketchVer);
      
        Sprint("\nPresent ");  
        
        if (sensorFunc >= 1) {
          wait(sendPause);
          present(chanTemp, S_TEMP, "Climate", true);
          Sprint("temperature");
        }
        if (sensorFunc >= 3) {
          wait(sendPause);
          present(chanHum, S_HUM);
          Sprint(", humidity");
          //wait(sendPause);
          //present(chanHeat ,S_TEMP);
          //Sprint(", heatindex");
        }
        if (sensorFunc == 4) {
          wait(sendPause);
          present(chanBaro, S_BARO);
          Sprint(", barometric");
          wait(sendPause);
          present(chanDelta, S_CUSTOM);
          Sprint(" and rate");
        }
        Sprintln(" sensor.");
        
        if (lightPresent) {
          wait(sendPause);   
          present(chanLight, S_LIGHT_LEVEL, "Light", true);
          Sprintln("\nLightsensor "); 
          if (sensorFunc < 4) {
            wait(sendPause);   
            present(chanRate, S_CUSTOM);
            Sprintln("with rate ");
          }
          Sprintln("presented.");     
        }
      
        if (interruptPresent) {
          wait(sendPause);
          present(chanInterrupt, S_MOTION, "Motion", true);
          Sprintln("Interrupt sensor presented.");
        }
      
        wait(sendPause);
      }
      
      
      /**************************************************************************/
      
      void loop(void)
      {
        if (wakeReason < 0) { 
          Serial.println("Reading sensors...");
          switch (sensorFunc) {
            case 0:
            break;
            case 1:
              updateRFM();
            break;
            case 2:
              updateDS18();
            break;
            case 3:
              updateHTU();
            break;  
            case 4:
              if (sendLoop <= 0) {
                updateBME();
                updated = true;
              }  
              else {
                Sprint("\nTrend: ");
                updateTrend();
                sendLoop--;
              }
            break;
          }
          if (lightPresent) {
            updateMAX();
            if (sensorFunc <= 3) {
              Sprint("\nTrend: ");
              updateTrend();
            }
          }
          wakeReason = 0;
          Sprintln("\nSensors updated...");
        }
        else if (wakeReason == 1) {
          updateInterrupt();
          wakeReason = 0;
        }
        
        if (battStatCounter >= battUpdater) {  
          batteryStats();
        }
        
        if (updated) {
          sendLoop = SENSOR_UPDATE;
          updated = false;
        }
        
        if (millis() >= currTime + sleepWait) {
          startUp = false;
          sleepSensor();
        }
      }
      
      
      /**************************************************************************/
      
      void updateInterrupt()
      {/*
        Sprintln("\nInterrupt: ");
        interruptState = reedContact.read();
        wait(50);
        if (interruptState == !lastInterrupt) {
          send(msgIntr.setSensor(chanInterrupt).set(interruptState),true);
          lastInterrupt = interruptState;
        }
        
        Sprint("Door/window is ");
        if (interruptState) {
          Sprintln("opened.");
        }
        else {
          Sprintln("closed");
        }*/
      }
      
      
      /**************************************************************************/
      
      void updateRFM()
      {/*
        Sprintln("\nRFM: ");
        sensorData = wireless.readTemperature();
        wait(20);
        send(msgTemp.set(sensorData, 0));
        Sprint("Temperature: \t"); Sprint(sensorData); Sprintln(" sent.");
        battStatCounter++;*/
      }
      
      /**************************************************************************/
      
      void updateDS18()
      {/*
        Sprintln("\nOne-wire: ");
        DS18.requestTemperatures();
        sensorData = DS18.getTempCByIndex(0);
        wait(20);
        send(msgTemp.set(sensorData, 2));
        battStatCounter++;
        Sprint("Temperature: "); Sprint(sensorData); Sprintln(" sent.");*/
      }
      
      
      /**************************************************************************/
      
      void updateHTU()
      {
        Sprintln("\nHTU: ");
        sensorData = HTU.readTemperature();
        heatTemp = sensorData;
        wait(20);
        send(msgTemp.set(sensorData, 1));
        Sprint("Temperature: \t"); Sprint(sensorData); Sprintln(" sent.");
        sensorData = HTU.readHumidity();
        heatHum = sensorData;
        wait(sendPause);
        send(msgHum.set(sensorData, 1));
        Sprint("Humidity: \t"); Sprint(sensorData); Sprintln(" sent.");
        //wait(sendPause);
        //send(msgHeat.set(computeHeatIndex(heatTemp, heatHum), 1));
        //Sprint("Heatindex sent.");  
        battStatCounter++;
      }
      
      
      /**************************************************************************/
      
      void updateBME()
      {
        /*Sprintln("\nBME: ");
        BME.begin();
        wait(100);
        sensorData = (BME.readFloatPressure()/pow(1-(alti/44330.0),5.255)/100);
        if (!startUp) {
          trend(sensorData);
          send(msgBaro.set(sensorData,1));
          Sprint("Pressure: \t"); Sprint(sensorData); Sprintln(" sent.");
        }
        if (!(minuteCount < 35 && firstRound)) {
          wait(sendPause);
          send(msgTrend.set(dP_dt,2));
          Sprint("Trend: \t\t"); Sprint(dP_dt); Sprintln(" sent.");
        }
        wait(sendPause);  
        sensorData = BME.readTempC();
        heatTemp = sensorData;
        send(msgTemp.set(sensorData,1));
        Sprint("Temperature: \t"); Sprint(sensorData); Sprintln(" sent.");
        wait(sendPause);
        sensorData = BME.readFloatHumidity();
        heatHum = sensorData;
        send(msgHum.set(sensorData,1));
        Sprint("Humidity: \t"); Sprint(sensorData); Sprintln(" sent.");
        wait(sendPause);
        send(msgHeat.set(computeHeatIndex(heatTemp, heatHum), 1));
        Sprint("Heatindex sent.");
        battStatCounter++;*/
      }
      
      
      /**************************************************************************/
      
      float computeHeatIndex(float tempInput, float humInput)       //Function derived from Adafruit DHT library
      {
        /*// Using both Rothfusz and Steadman's equations
        // http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
        float hiFar;
      
        float tempFar = tempInput * 1.8 + 32;
      
        hiFar = 0.5 * (tempFar + 61.0 + ((tempFar - 68.0) * 1.2) + (humInput * 0.094));
      
        if (hiFar > 79) {
          hiFar = -42.379 +
                   2.04901523 * tempFar +
                  10.14333127 * humInput +
                  -0.22475541 * tempFar*humInput +
                  -0.00683783 * pow(tempFar, 2) +
                  -0.05481717 * pow(humInput, 2) +
                   0.00122874 * pow(tempFar, 2) * humInput +
                   0.00085282 * tempFar*pow(humInput, 2) +
                  -0.00000199 * pow(tempFar, 2) * pow(humInput, 2);
      
          if((humInput < 13) && (tempFar >= 80.0) && (tempFar <= 112.0))
            hiFar -= ((13.0 - humInput) * 0.25) * sqrt((17.0 - abs(tempFar - 95.0)) * 0.05882);
      
          else if((humInput > 85.0) && (tempFar >= 80.0) && (tempFar <= 87.0))
            hiFar += ((humInput - 85.0) * 0.1) * ((87.0 - tempFar) * 0.2);
        }
      
        return (hiFar - 32) * 0.55555;*/
      }
      
      
      /**************************************************************************/
      void updateTrend()
      {
        /*if (sensorFunc == 4) {
         * Sprint("BME -> ");
          BME.begin();
          wait(100);
          sensorData = (BME.readFloatPressure()/pow(1-(alti/44330.0),5.255)/100);
        }
        else if (lightPresent) {
          Sprint("MAX -> ");
          sensorData = lightMax.getLux();
        }
        trend(sensorData);*/
      }
      
      
      /**************************************************************************/
      
      void updateMAX()
      {
        /*Sprintln("\nLight: ");
        sensorData = lightMax.getLux();
        if (sensorFunc <= 3) {
          trend(sensorData);
        }
        send(msgLight.set(sensorData,1));
        Sprint("Light: \t"); Sprint(sensorData); Sprintln(" sent.");
        if (sensorFunc <= 3) {
          if (!(minuteCount < 35 && firstRound)) {
            wait(sendPause);
            send(msgTrend.set(dP_dt,2));
            Sprint("Trend: \t"); Sprint(dP_dt); Sprintln(" sent.");
          }
        }
        battStatCounter++;*/
      }
      
      
      /**************************************************************************/
      
      void sleepSensor()
      {
        if (battPower) {
          Serial.println("\nSleep the sensor.");
          wait(50); 
          unsigned long lightsOut = (sleepTime - (millis() - currTime));
          if (interruptPresent) {
            if (sensorPresent) {
              wakeReason = sleep(1, CHANGE, lightsOut);
            }
            else {
              wakeReason = sleep(1, CHANGE, 0);
            }
          }
          else {
            //digitalWrite(sensorPowerPin, LOW);      //Disabled because of the I2C pull ups on the HTU board
            sleep(lightsOut);                         //causing a 140uA load in sleep. Without, sleep drain is 5uA.
            wakeReason = -1;
            //digitalWrite(sensorPowerPin, HIGH);
            wait(50);
          }
          currTime = millis();
          Sprint("Wake reason: ");Sprintln(wakeReason);
        }
        else if (millis() >= currTime + sleepTime) {
          wakeReason = -1;
          currTime = millis();
        }
      }
      
      
      /**************************************************************************/
      
      /*void startBME()
      {
        BME.settings.commInterface = I2C_MODE;
        BME.settings.I2CAddress = BMEaddr;
        BME.settings.runMode = 1;            //  1, Single mode
        BME.settings.tStandby = 0;           //  0, 0.5ms
        BME.settings.filter = 0;             //  0, filter off
        BME.settings.tempOverSample = 1;
        BME.settings.pressOverSample = 1;
        BME.settings.humidOverSample = 1;  
        
        BME.begin();
      }
      
      
      /**************************************************************************/
      
      float getLastPressureSamplesAverage()
      {
        float lastPressureSamplesAverage = 0;
        for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
        {
          lastPressureSamplesAverage += lastPressureSamples[i];
        }
        lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
      
        return lastPressureSamplesAverage;
      }
      
      
      /**************************************************************************/
      
      void trend(float pressure)
      {/*
        int index = minuteCount % LAST_SAMPLES_COUNT;                 // Calculate the average of the last 5 minutes.
        lastPressureSamples[index] = pressure;
      
        minuteCount++;
        if (minuteCount > 185)
        {
          minuteCount = 6;
        }
      
        if (minuteCount == 5)
        {
          pressureAvg = getLastPressureSamplesAverage();
          Sprint("First average: "); Sprint(pressureAvg);
        }
        else if (minuteCount == 35)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg);
          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);
          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);
          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);
          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);
          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);
          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.
        }
      
        Sprint(F("\tForecast at minute "));
        Sprint(minuteCount);
        Sprint(F(" dP/dt = "));
        Sprint(dP_dt);
        Sprint(F("hPa/h --> "));*/
      }
      
      
      /**************************************************************************/
      
      void batteryStats()
      {
        if (battPower) {
          float battPct = vcc.Read_Perc();
          float battVolt = vcc.Read_Volts();
          wait(50);
          sendBatteryLevel(battPct);
          Sprint("Battery level: "); Sprint(battVolt); Sprintln("V.\n");
          battStatCounter = 0;
          wait(50);
        }  
      }
      
      
      /**************************************************************************/
      
      void sendBattLevel()
      {
        /*Serial.println("\nBattery: ");
        int ADread = analogRead(batteryPin);
        int battPcnt = map(ADread, 570, 704, 0, 100);  //Usable voltage range from 3.4 to 4.2V
        battPcnt = constrain(battPcnt, 0, 100);        //Charging keeps it at 100%
        sendBatteryLevel(battPcnt);
        Sprint("\nADread\t"); Sprint(ADread); Sprint("\t"); Sprintln(battPcnt);
        battStatCounter = 0;*/
      }  
      

      GertSanders ATMega328p 32p TFQP, 8MHz, 38400baud

      Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB
      
      Sketch uses 16,680 bytes (51%) of program storage space. Maximum is 32,256 bytes.
      Global variables use 942 bytes (45%) of dynamic memory, leaving 1,106 bytes for local variables. Maximum is 2,048 bytes.
      

      LowPowerLab Moteino 16MHz

      Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB
      
      Sketch uses 14,264 bytes (44%) of program storage space. Maximum is 31,744 bytes.
      Global variables use 890 bytes of dynamic memory.
      

      In this sketch the size difference doesn't matter that much. But when I introduce signing it will get tight.
      Any thoughts?

      (This is a standard sketch which I adapt for every node by commenting out the parts I do not need. So it might seem large for a simple temperature node. It is...).

      GertSandersG 1 Reply Last reply
      0
      • D DavidZH

        @GertSanders

        I have been running your bootloader for all my nodes now and that works very well.
        But there is something that surprised me. When I compile the next sketch and compare that with the Moteino bootloader it's substantially larger.

        /***************************************************************************************
        **
        ** Outdoor sensor v1.0 Measuring temperature, humdity, pressure and light level
        **  Calculating a weather forecast with the height comensated air pressure.
        **      powered by a solar panel and a 1000mAh Li-Ion battery.
        **
        ** Scraped together by D Hille. MySensors library by Henrik Ekblad et al.
        **
        **      Heat index calculation from DHT library by Adafruit
        **      MAX44009 bij Rob Tillaart
        **      Weather forecast based on AN3914 by Freescale
        **
        ****************************************************************************************/
        //                    MySensors definitions
        
        //#define MY_DEBUG                      // Enable debug prints (6 kb flash space)
        //#define MY_DEBUG_VERBOSE_SIGNING      // Comment out when no signing is used or when everything is OK (3 kb flash space)
        
        #define MY_BAUD_RATE 57600            // Set serial baudrate
        
        #define MY_RADIO_RFM69                // Enable and select radio type attached
        //#define MY_IS_RFM69HW                 // Comment out when using standard RFM69W
        
        #define MY_NODE_ID 110                 // Delete to use automatic ID assignment
        
        //#define MY_CORE_ONLY
        
        /**************************************************************************/
        //                        Transport
        /**************************************************************************/
        
        //#define MY_TRANSPORT_WAIT_READY_MS 1000 //Start the node even if no connection to the GW could be made (disable for sensor nodes).
        #define MY_TRANSPORT_STATE_RETRIES 1
        #define MY_TRANSPORT_MAX_TSM_FAILURES    (2u)
        #define MY_TRANSPORT_TIMEOUT_EXT_FAILURE_STATE (60*1000ul)
        
        
        /**************************************************************************/
        //                        Security
        /**************************************************************************/
        
        //#define MY_SIGNING_ATSHA204
        //#define MY_SIGNING_SOFT
        //#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
        //#define MY_SIGNING_REQUEST_SIGNATURES
        //#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = 0,.serial = {0xD0,0xB1,0x90,0x99,0xC3,0x03,0x08,0xD1,0x34}}}
        
        //#define MY_RFM69_ENABLE_ENCRYPTION
        
        
        /**************************************************************************/
        //                    Sensor definitions
        /**************************************************************************/
        
        #define BATTERY_POWERED
        #define battUpdater 300           //Number of TX actions to count before a new battery status update is sent.
        
        #define MY_DEFAULT_TX_LED_PIN 5   // Comment out when no LED is attached.
        #define MY_WITH_LEDS_BLINKING_INVERSE
        
        #define SENSOR_TYPE 3
        // Sensor types:
        // 0.: no climate sensor attached
        // 1.: RFM69 on-die               Temperature sensor on the RFM69 module (whole integers only)
        // 2.: DS18B20                    Dallas one-wire sensor(data pin D14)
        // 3.: HTU21D                     Temp/humidity (I2C)
        // 4.: BME280                     Temp/humidity/pressure (I2C) (node will wake every minute to keep up with trend measureing)
        #define SENSOR_UPDATE 2           // Time in minutes the sensor sends an update
        
        //#define LIGHT_SENSOR_PRESENT      // Comment out when not present. (I2C) (Light sensor will update every 60 seconds.)
        
        //#define INTERRUPT_SENSOR_PRESENT  // Comment out when not present (e. g. motion sensor connect to D3)
        
        #define alti 57                  //altitude offset to compensate the barometric pressure
        
        
        /**************************************************************************/
        //                  Debug definitions
        /**************************************************************************/
        
        //#define LOCAL_DEBUG                              //Comment out to switch all debug messages off (saves 2 kb flash)
        
        #ifdef MY_DEBUG                                  //Differentiate between global debug including radio and local debug 
          #define LOCAL_DEBUG                            //for the sketch alone.
        #endif 
        
        #ifdef LOCAL_DEBUG 
          #define Sprint(a) (Serial.print(a))            // Macro as substitute for serial debug. Will be an empty macro when
          #define Sprintln(a) (Serial.println(a))        // debug is switched off
        #else
          #define Sprint(a)                                       
          #define Sprintln(a)
        #endif
        
        
        /**************************************************************************/
        
        #include <Button.h>
        #include <SPI.h>
        #include <Wire.h>
        #include <MySensors.h>
        //#include <SparkFunBME280.h>
        //#include <MAX44009.h>                           // Uncomment library used in sketch
        #include <Adafruit_HTU21DF.h>
        //#include <OneWire.h>
        //#include <DallasTemperature.h>
        #include <Vcc.h>
        
        
        #define BMEaddr 0x76
        #define Max44099Addr 0x4A
        #define sketchName "sensorNode(living)"
        #define sketchVer "1.0" 
        
        #define sensorPowerPin 20
        
        #define digitalSensorPin 14
        #define analogSensorPin A0
        #define oneWireBusPin 14
        #define interruptPin 3
        #define altSensorPin 18
        #define altAnalogPin A4
        #define sensorPowerPin 6
        
        #define chanTemp 0
        #define chanHum 1
        #define chanHeat 2 
        #define chanBaro 3
        #define chanDelta 4
        #define chanLight 5
        #define chanRate 6
        #define chanInterrupt 8
        
        #define PULLUP false
        #define INVERT false
        #define bounceTime 20
        #define sleepWait 500           //Time to wait in ms before node sleeps (to be able to receive notification messages).
        
        bool battPower = true;
        
        unsigned long currTime = 0;
        unsigned long sleepTime = (60000 * SENSOR_UPDATE);
        unsigned long lastSensorUpdate;
        unsigned long nextSensor;
        unsigned long measureTime;
        int wakeReason = -1;
        int sendLoop = 0;
        bool updated = false;
        bool ACKed = false;
        
        int sensorFunc = 0;
        float sensorData = 0.0;
        float heatTemp = 0.0;
        float heatHum = 0.0;
        bool interruptState = false;
        bool lastInterrupt = false;
        bool sensorPresent = false;
        bool lightPresent = false;
        bool interruptPresent = false;
        
        int minuteCount = 0;
        bool firstRound = true;         
        float pressureAvg;               // average value is used in forecast algorithm. 
        float pressureAvg2;              // average after 2 hours is used as reference value for the next iteration.
        float dP_dt;
        const int LAST_SAMPLES_COUNT = 5;
        float lastPressureSamples[LAST_SAMPLES_COUNT];
        
        bool startUp = true;
        bool metric = true; 
        
        int battStatCounter = 0;
        const float VccMin = 1.8;                   // Minimum expected Vcc level, in Volts.
        const float VccMax = 3.0;                   // Maximum expected Vcc level, in Volts.
        const float VccCorrection = 1.0/1.0;      // Measured Vcc by multimeter divided by reported Vcc
        
        
        /**************************************************************************/
        //                  Library declarations
        /**************************************************************************/
        
        //  Uncomment necessary declarations.
        
        //RFM69 wireless;
        
        //OneWire OWB(oneWireBusPin);
        //DallasTemperature DS18(&OWB);
        //DeviceAddress DS18address;
        
        Adafruit_HTU21DF HTU = Adafruit_HTU21DF();
        
        //BME280 BME;
        
        //Max44009 lightMax(Max44099Addr);
        
        //Button reedContact(interruptPin, PULLUP, INVERT, bounceTime);
        
        MyMessage msgHum(chanHum, V_HUM);
        MyMessage msgTemp(chanTemp, V_TEMP);
        //MyMessage msgBaro(chanBaro, V_PRESSURE);
        //MyMessage msgTrend(chanUniversal, V_VAR5);
        //MyMessage msgLight(chanLight, V_LEVEL);
        //MyMessage msgIntr(chanInterrupt, V_TRIPPED);
        
        Vcc vcc(VccCorrection);
        
        /**************************************************************************/
        //                  Error messages
        /**************************************************************************/
        
          #if (defined INTERRUPT_SENSOR_PRESENT && defined LIGHT_SENSOR_PRESENT && SENSOR_TYPE >= 4)
            #error Motion sensor can anly be combined with either I2C OR one-wire sensors, not both.
          #endif
        
          #if (defined INTERRUPT_SENSOR_PRESENT && (defined LIGHT_SENSOR_PRESENT || SENSOR_TYPE == 4) && defined BATTERY_POWERED)
            #error Interrupt sensor is not compatible with trend sensors like 'baro' and 'light' because the timer will misalign.
          #endif
        
          #if (SENSOR_TYPE > 4)
            #error Not a valid sensor type!
          #endif
        
        
        /**************************************************************************/
        
        void before(void)
        {  
          Serial.println("\nReading config...");
        
          #ifndef BATTERY_POWERED
            battPower = false;
          #endif
        
          sensorFunc = SENSOR_TYPE;
        
          #ifdef LIGHT_SENSOR_PRESENT
            lightPresent = true;
          #endif
        
          #ifdef INTERRUPT_SENSOR_PRESENT
            interruptPresent = true;
            lastInterrupt = reedContact.read();
          #endif
        
          #if (defined MY_SIGNING_SOFT || defined MY_SIGNING_ATSHA204)
            #define sendPause 100
          #else
            #define sendPause 50
          #endif
        }
         
        /**************************************************************************/
        
        void setup(void)
        {  
          pinMode(sensorPowerPin, OUTPUT);       //switch on the sensor power
          digitalWrite(sensorPowerPin, HIGH);    
          wait(50);                              //wait 50 ms for the sensors to settle.
          
          switch (sensorFunc) {
            case 0:
            break;
            case 1:
              sensorPresent = true;
            break;
            case 2: 
              //DS18.begin();
              //DS18.getAddress(DS18address, 0);
              //DS18.setResolution(DS18address, 10);
              sensorPresent = true;
            break;
            case 3:
              HTU.begin();
              sensorPresent = true;
            break;
            case 4:
              //startBME();
              sleepTime = 60000;
              sensorPresent = true;
            break;    
          }
        
          #if (lightPresent)
            sleepTime = 60000;
            sensorPresent = true;
          #endif
        
          #ifdef MY_DEBUG                //Differentiate between global debug including radio and local debug          
            sleepTime = 30000;              //for the sketch alone.
          #endif
        
          batteryStats();
        
          Serial.println("\nDone. \n\nStarting program.\n");
          
          currTime = millis();
        }
        
        /**************************************************************************/
        
        void presentation()  
        {
          Serial.println("Start radio and sensors");  
          
          sendSketchInfo(sketchName, sketchVer);
        
          Sprint("\nPresent ");  
          
          if (sensorFunc >= 1) {
            wait(sendPause);
            present(chanTemp, S_TEMP, "Climate", true);
            Sprint("temperature");
          }
          if (sensorFunc >= 3) {
            wait(sendPause);
            present(chanHum, S_HUM);
            Sprint(", humidity");
            //wait(sendPause);
            //present(chanHeat ,S_TEMP);
            //Sprint(", heatindex");
          }
          if (sensorFunc == 4) {
            wait(sendPause);
            present(chanBaro, S_BARO);
            Sprint(", barometric");
            wait(sendPause);
            present(chanDelta, S_CUSTOM);
            Sprint(" and rate");
          }
          Sprintln(" sensor.");
          
          if (lightPresent) {
            wait(sendPause);   
            present(chanLight, S_LIGHT_LEVEL, "Light", true);
            Sprintln("\nLightsensor "); 
            if (sensorFunc < 4) {
              wait(sendPause);   
              present(chanRate, S_CUSTOM);
              Sprintln("with rate ");
            }
            Sprintln("presented.");     
          }
        
          if (interruptPresent) {
            wait(sendPause);
            present(chanInterrupt, S_MOTION, "Motion", true);
            Sprintln("Interrupt sensor presented.");
          }
        
          wait(sendPause);
        }
        
        
        /**************************************************************************/
        
        void loop(void)
        {
          if (wakeReason < 0) { 
            Serial.println("Reading sensors...");
            switch (sensorFunc) {
              case 0:
              break;
              case 1:
                updateRFM();
              break;
              case 2:
                updateDS18();
              break;
              case 3:
                updateHTU();
              break;  
              case 4:
                if (sendLoop <= 0) {
                  updateBME();
                  updated = true;
                }  
                else {
                  Sprint("\nTrend: ");
                  updateTrend();
                  sendLoop--;
                }
              break;
            }
            if (lightPresent) {
              updateMAX();
              if (sensorFunc <= 3) {
                Sprint("\nTrend: ");
                updateTrend();
              }
            }
            wakeReason = 0;
            Sprintln("\nSensors updated...");
          }
          else if (wakeReason == 1) {
            updateInterrupt();
            wakeReason = 0;
          }
          
          if (battStatCounter >= battUpdater) {  
            batteryStats();
          }
          
          if (updated) {
            sendLoop = SENSOR_UPDATE;
            updated = false;
          }
          
          if (millis() >= currTime + sleepWait) {
            startUp = false;
            sleepSensor();
          }
        }
        
        
        /**************************************************************************/
        
        void updateInterrupt()
        {/*
          Sprintln("\nInterrupt: ");
          interruptState = reedContact.read();
          wait(50);
          if (interruptState == !lastInterrupt) {
            send(msgIntr.setSensor(chanInterrupt).set(interruptState),true);
            lastInterrupt = interruptState;
          }
          
          Sprint("Door/window is ");
          if (interruptState) {
            Sprintln("opened.");
          }
          else {
            Sprintln("closed");
          }*/
        }
        
        
        /**************************************************************************/
        
        void updateRFM()
        {/*
          Sprintln("\nRFM: ");
          sensorData = wireless.readTemperature();
          wait(20);
          send(msgTemp.set(sensorData, 0));
          Sprint("Temperature: \t"); Sprint(sensorData); Sprintln(" sent.");
          battStatCounter++;*/
        }
        
        /**************************************************************************/
        
        void updateDS18()
        {/*
          Sprintln("\nOne-wire: ");
          DS18.requestTemperatures();
          sensorData = DS18.getTempCByIndex(0);
          wait(20);
          send(msgTemp.set(sensorData, 2));
          battStatCounter++;
          Sprint("Temperature: "); Sprint(sensorData); Sprintln(" sent.");*/
        }
        
        
        /**************************************************************************/
        
        void updateHTU()
        {
          Sprintln("\nHTU: ");
          sensorData = HTU.readTemperature();
          heatTemp = sensorData;
          wait(20);
          send(msgTemp.set(sensorData, 1));
          Sprint("Temperature: \t"); Sprint(sensorData); Sprintln(" sent.");
          sensorData = HTU.readHumidity();
          heatHum = sensorData;
          wait(sendPause);
          send(msgHum.set(sensorData, 1));
          Sprint("Humidity: \t"); Sprint(sensorData); Sprintln(" sent.");
          //wait(sendPause);
          //send(msgHeat.set(computeHeatIndex(heatTemp, heatHum), 1));
          //Sprint("Heatindex sent.");  
          battStatCounter++;
        }
        
        
        /**************************************************************************/
        
        void updateBME()
        {
          /*Sprintln("\nBME: ");
          BME.begin();
          wait(100);
          sensorData = (BME.readFloatPressure()/pow(1-(alti/44330.0),5.255)/100);
          if (!startUp) {
            trend(sensorData);
            send(msgBaro.set(sensorData,1));
            Sprint("Pressure: \t"); Sprint(sensorData); Sprintln(" sent.");
          }
          if (!(minuteCount < 35 && firstRound)) {
            wait(sendPause);
            send(msgTrend.set(dP_dt,2));
            Sprint("Trend: \t\t"); Sprint(dP_dt); Sprintln(" sent.");
          }
          wait(sendPause);  
          sensorData = BME.readTempC();
          heatTemp = sensorData;
          send(msgTemp.set(sensorData,1));
          Sprint("Temperature: \t"); Sprint(sensorData); Sprintln(" sent.");
          wait(sendPause);
          sensorData = BME.readFloatHumidity();
          heatHum = sensorData;
          send(msgHum.set(sensorData,1));
          Sprint("Humidity: \t"); Sprint(sensorData); Sprintln(" sent.");
          wait(sendPause);
          send(msgHeat.set(computeHeatIndex(heatTemp, heatHum), 1));
          Sprint("Heatindex sent.");
          battStatCounter++;*/
        }
        
        
        /**************************************************************************/
        
        float computeHeatIndex(float tempInput, float humInput)       //Function derived from Adafruit DHT library
        {
          /*// Using both Rothfusz and Steadman's equations
          // http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
          float hiFar;
        
          float tempFar = tempInput * 1.8 + 32;
        
          hiFar = 0.5 * (tempFar + 61.0 + ((tempFar - 68.0) * 1.2) + (humInput * 0.094));
        
          if (hiFar > 79) {
            hiFar = -42.379 +
                     2.04901523 * tempFar +
                    10.14333127 * humInput +
                    -0.22475541 * tempFar*humInput +
                    -0.00683783 * pow(tempFar, 2) +
                    -0.05481717 * pow(humInput, 2) +
                     0.00122874 * pow(tempFar, 2) * humInput +
                     0.00085282 * tempFar*pow(humInput, 2) +
                    -0.00000199 * pow(tempFar, 2) * pow(humInput, 2);
        
            if((humInput < 13) && (tempFar >= 80.0) && (tempFar <= 112.0))
              hiFar -= ((13.0 - humInput) * 0.25) * sqrt((17.0 - abs(tempFar - 95.0)) * 0.05882);
        
            else if((humInput > 85.0) && (tempFar >= 80.0) && (tempFar <= 87.0))
              hiFar += ((humInput - 85.0) * 0.1) * ((87.0 - tempFar) * 0.2);
          }
        
          return (hiFar - 32) * 0.55555;*/
        }
        
        
        /**************************************************************************/
        void updateTrend()
        {
          /*if (sensorFunc == 4) {
           * Sprint("BME -> ");
            BME.begin();
            wait(100);
            sensorData = (BME.readFloatPressure()/pow(1-(alti/44330.0),5.255)/100);
          }
          else if (lightPresent) {
            Sprint("MAX -> ");
            sensorData = lightMax.getLux();
          }
          trend(sensorData);*/
        }
        
        
        /**************************************************************************/
        
        void updateMAX()
        {
          /*Sprintln("\nLight: ");
          sensorData = lightMax.getLux();
          if (sensorFunc <= 3) {
            trend(sensorData);
          }
          send(msgLight.set(sensorData,1));
          Sprint("Light: \t"); Sprint(sensorData); Sprintln(" sent.");
          if (sensorFunc <= 3) {
            if (!(minuteCount < 35 && firstRound)) {
              wait(sendPause);
              send(msgTrend.set(dP_dt,2));
              Sprint("Trend: \t"); Sprint(dP_dt); Sprintln(" sent.");
            }
          }
          battStatCounter++;*/
        }
        
        
        /**************************************************************************/
        
        void sleepSensor()
        {
          if (battPower) {
            Serial.println("\nSleep the sensor.");
            wait(50); 
            unsigned long lightsOut = (sleepTime - (millis() - currTime));
            if (interruptPresent) {
              if (sensorPresent) {
                wakeReason = sleep(1, CHANGE, lightsOut);
              }
              else {
                wakeReason = sleep(1, CHANGE, 0);
              }
            }
            else {
              //digitalWrite(sensorPowerPin, LOW);      //Disabled because of the I2C pull ups on the HTU board
              sleep(lightsOut);                         //causing a 140uA load in sleep. Without, sleep drain is 5uA.
              wakeReason = -1;
              //digitalWrite(sensorPowerPin, HIGH);
              wait(50);
            }
            currTime = millis();
            Sprint("Wake reason: ");Sprintln(wakeReason);
          }
          else if (millis() >= currTime + sleepTime) {
            wakeReason = -1;
            currTime = millis();
          }
        }
        
        
        /**************************************************************************/
        
        /*void startBME()
        {
          BME.settings.commInterface = I2C_MODE;
          BME.settings.I2CAddress = BMEaddr;
          BME.settings.runMode = 1;            //  1, Single mode
          BME.settings.tStandby = 0;           //  0, 0.5ms
          BME.settings.filter = 0;             //  0, filter off
          BME.settings.tempOverSample = 1;
          BME.settings.pressOverSample = 1;
          BME.settings.humidOverSample = 1;  
          
          BME.begin();
        }
        
        
        /**************************************************************************/
        
        float getLastPressureSamplesAverage()
        {
          float lastPressureSamplesAverage = 0;
          for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
          {
            lastPressureSamplesAverage += lastPressureSamples[i];
          }
          lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
        
          return lastPressureSamplesAverage;
        }
        
        
        /**************************************************************************/
        
        void trend(float pressure)
        {/*
          int index = minuteCount % LAST_SAMPLES_COUNT;                 // Calculate the average of the last 5 minutes.
          lastPressureSamples[index] = pressure;
        
          minuteCount++;
          if (minuteCount > 185)
          {
            minuteCount = 6;
          }
        
          if (minuteCount == 5)
          {
            pressureAvg = getLastPressureSamplesAverage();
            Sprint("First average: "); Sprint(pressureAvg);
          }
          else if (minuteCount == 35)
          {
            float lastPressureAvg = getLastPressureSamplesAverage();
            float change = (lastPressureAvg - pressureAvg);
            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);
            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);
            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);
            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);
            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);
            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.
          }
        
          Sprint(F("\tForecast at minute "));
          Sprint(minuteCount);
          Sprint(F(" dP/dt = "));
          Sprint(dP_dt);
          Sprint(F("hPa/h --> "));*/
        }
        
        
        /**************************************************************************/
        
        void batteryStats()
        {
          if (battPower) {
            float battPct = vcc.Read_Perc();
            float battVolt = vcc.Read_Volts();
            wait(50);
            sendBatteryLevel(battPct);
            Sprint("Battery level: "); Sprint(battVolt); Sprintln("V.\n");
            battStatCounter = 0;
            wait(50);
          }  
        }
        
        
        /**************************************************************************/
        
        void sendBattLevel()
        {
          /*Serial.println("\nBattery: ");
          int ADread = analogRead(batteryPin);
          int battPcnt = map(ADread, 570, 704, 0, 100);  //Usable voltage range from 3.4 to 4.2V
          battPcnt = constrain(battPcnt, 0, 100);        //Charging keeps it at 100%
          sendBatteryLevel(battPcnt);
          Sprint("\nADread\t"); Sprint(ADread); Sprint("\t"); Sprintln(battPcnt);
          battStatCounter = 0;*/
        }  
        

        GertSanders ATMega328p 32p TFQP, 8MHz, 38400baud

        Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB
        
        Sketch uses 16,680 bytes (51%) of program storage space. Maximum is 32,256 bytes.
        Global variables use 942 bytes (45%) of dynamic memory, leaving 1,106 bytes for local variables. Maximum is 2,048 bytes.
        

        LowPowerLab Moteino 16MHz

        Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB
        
        Sketch uses 14,264 bytes (44%) of program storage space. Maximum is 31,744 bytes.
        Global variables use 890 bytes of dynamic memory.
        

        In this sketch the size difference doesn't matter that much. But when I introduce signing it will get tight.
        Any thoughts?

        (This is a standard sketch which I adapt for every node by commenting out the parts I do not need. So it might seem large for a simple temperature node. It is...).

        GertSandersG Offline
        GertSandersG Offline
        GertSanders
        Hardware Contributor
        wrote on last edited by
        #134

        @DavidZH
        Do you also get these differences when compiling for both 16Mhz ? In this case one node is 16MHz (Moteino) and the second is 8MHz.
        Apart from that I have no clue why this would result in different sizes.

        1 Reply Last reply
        0
        • D Offline
          D Offline
          DavidZH
          wrote on last edited by
          #135

          I have tried with your bootloader on 16MHz and 8 MHz with crystal.

          8MHz, crystal, 1V8

          Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB
          Build options changed, rebuilding all
          
          Sketch uses 16,680 bytes (51%) of program storage space. Maximum is 32,256 bytes.
          Global variables use 942 bytes (45%) of dynamic memory, leaving 1,106 bytes for local variables. Maximum is 2,048 bytes.
          

          16MHz, crystal, 1V8

          Warning: Board breadboard:avr:atmega328bb doesn't define a 'build.board' preference. Auto-set to: AVR_ATMEGA328BB
          Build options changed, rebuilding all
          
          Sketch uses 16,694 bytes (51%) of program storage space. Maximum is 32,256 bytes.
          Global variables use 942 bytes (45%) of dynamic memory, leaving 1,106 bytes for local variables. Maximum is 2,048 bytes. 
          

          So the 16Mhz file is actally even a bit bigger. I also tried if changing the BOD voltage would change anything, but nope on that.

          Might be something to look into in a spare hour.

          1 Reply Last reply
          0
          • mar.conteM Offline
            mar.conteM Offline
            mar.conte
            wrote on last edited by
            #136

            hy,
            can anyone tell me what is the word near cpu 8mhz-38k4-d13 etc..??
            tanks

            S 1 Reply Last reply
            0
            • mar.conteM mar.conte

              hy,
              can anyone tell me what is the word near cpu 8mhz-38k4-d13 etc..??
              tanks

              S Offline
              S Offline
              Samuel235
              Hardware Contributor
              wrote on last edited by
              #137

              @mar.conte - Your question isn't very clear. If you're asking what the name means its broken down as:

              8mhz - Crystal speed/frequency
              38k4 - 38400 upload speed
              D13 - Pin 13 to flash the LED (if needed) just for visual indication that the bootloader has been burnt/installed.

              Not sure if that is what you meant but I could only assume. If not then please attempt to explain a little clearly for us :)

              Hope that sorts your problem!

              MySensors 2.1.1
              Controller - OpenHAB (Virtual Machine)
              Gateway - Arduino Mega MQTT Gateway W5100

              mar.conteM 1 Reply Last reply
              0
              • S Samuel235

                @mar.conte - Your question isn't very clear. If you're asking what the name means its broken down as:

                8mhz - Crystal speed/frequency
                38k4 - 38400 upload speed
                D13 - Pin 13 to flash the LED (if needed) just for visual indication that the bootloader has been burnt/installed.

                Not sure if that is what you meant but I could only assume. If not then please attempt to explain a little clearly for us :)

                Hope that sorts your problem!

                mar.conteM Offline
                mar.conteM Offline
                mar.conte
                wrote on last edited by
                #138

                @Samuel235
                Sorry for my english, your answer is ok Tanks you

                S 1 Reply Last reply
                0
                • mar.conteM mar.conte

                  @Samuel235
                  Sorry for my english, your answer is ok Tanks you

                  S Offline
                  S Offline
                  Samuel235
                  Hardware Contributor
                  wrote on last edited by
                  #139

                  @mar.conte - Its okay, i understood you, just about ;)

                  Now just apply that description to all of the other bootloader varients that the great @Gertsanders has provided us with :)

                  MySensors 2.1.1
                  Controller - OpenHAB (Virtual Machine)
                  Gateway - Arduino Mega MQTT Gateway W5100

                  1 Reply Last reply
                  0
                  • mar.conteM Offline
                    mar.conteM Offline
                    mar.conte
                    wrote on last edited by
                    #140

                    Help!!!
                    I have upload bootloader 8mhz 38k bod 2,7 and internal clock with sketch j gammon!!!
                    Consumption 2 mh!!!
                    Why?
                    Tanks

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      Samuel235
                      Hardware Contributor
                      wrote on last edited by
                      #141

                      I'm sorry, i don't understand the issue at hand.... Could you attempt to explain any clearer?

                      MySensors 2.1.1
                      Controller - OpenHAB (Virtual Machine)
                      Gateway - Arduino Mega MQTT Gateway W5100

                      mar.conteM 1 Reply Last reply
                      0
                      • mar.conteM Offline
                        mar.conteM Offline
                        mar.conte
                        wrote on last edited by
                        #142
                        This post is deleted!
                        1 Reply Last reply
                        0
                        • S Samuel235

                          I'm sorry, i don't understand the issue at hand.... Could you attempt to explain any clearer?

                          mar.conteM Offline
                          mar.conteM Offline
                          mar.conte
                          wrote on last edited by
                          #143

                          @Samuel235
                          Hy
                          My project is simple atmega328 with internal clock 8 mhz in powerdown mode end rfm69 hw which send to gateway when pir motion is high powered all with 2 aa battery.
                          The First test what i do is in breadboard atmega328 with optiboot 6.2 ( i have upload bootloader 8mhz internal , 38vk, bod 2v7) and simple sketch j gammon: result no microampere but around 2/5 mah in sleep mode;

                          alexsh1A 1 Reply Last reply
                          0
                          • mar.conteM mar.conte

                            @Samuel235
                            Hy
                            My project is simple atmega328 with internal clock 8 mhz in powerdown mode end rfm69 hw which send to gateway when pir motion is high powered all with 2 aa battery.
                            The First test what i do is in breadboard atmega328 with optiboot 6.2 ( i have upload bootloader 8mhz internal , 38vk, bod 2v7) and simple sketch j gammon: result no microampere but around 2/5 mah in sleep mode;

                            alexsh1A Offline
                            alexsh1A Offline
                            alexsh1
                            wrote on last edited by
                            #144

                            @mar.conte I'm not familiar with the sketch you mentioned. The best is to use the voltmeter and oscillograph to determine consumption.

                            Why do you have BOD 2.7v? I do not have any BOD - this would let a node to run on two batteries until voltage drops to below 1.9V

                            mar.conteM 1 Reply Last reply
                            0
                            • alexsh1A alexsh1

                              @mar.conte I'm not familiar with the sketch you mentioned. The best is to use the voltmeter and oscillograph to determine consumption.

                              Why do you have BOD 2.7v? I do not have any BOD - this would let a node to run on two batteries until voltage drops to below 1.9V

                              mar.conteM Offline
                              mar.conteM Offline
                              mar.conte
                              wrote on last edited by
                              #145

                              @alexsh1
                              I have only voltmeter extec, can i mesure ua?
                              Can you send simple sketch for deep sleep ?

                              S alexsh1A 2 Replies Last reply
                              0
                              • mar.conteM mar.conte

                                @alexsh1
                                I have only voltmeter extec, can i mesure ua?
                                Can you send simple sketch for deep sleep ?

                                S Offline
                                S Offline
                                Samuel235
                                Hardware Contributor
                                wrote on last edited by
                                #146

                                @mar.conte - Are you basically saying that your hardware is using too much power to enable you to run on battery for any substantial time?

                                MySensors 2.1.1
                                Controller - OpenHAB (Virtual Machine)
                                Gateway - Arduino Mega MQTT Gateway W5100

                                mar.conteM 1 Reply Last reply
                                0
                                • S Samuel235

                                  @mar.conte - Are you basically saying that your hardware is using too much power to enable you to run on battery for any substantial time?

                                  mar.conteM Offline
                                  mar.conteM Offline
                                  mar.conte
                                  wrote on last edited by
                                  #147

                                  @Samuel235
                                  Yes, i want obtain few micro amp but its two month wich i try without result.....

                                  tonnerre33T 1 Reply Last reply
                                  0
                                  • mar.conteM mar.conte

                                    @Samuel235
                                    Yes, i want obtain few micro amp but its two month wich i try without result.....

                                    tonnerre33T Offline
                                    tonnerre33T Offline
                                    tonnerre33
                                    Hardware Contributor
                                    wrote on last edited by tonnerre33
                                    #148

                                    @mar.conte Which skecth did you use ?
                                    Did you have radio errors in your log ?

                                    1 Reply Last reply
                                    0
                                    • S Offline
                                      S Offline
                                      Samuel235
                                      Hardware Contributor
                                      wrote on last edited by
                                      #149

                                      Could you please either include your sketch here or give us a link to the example sketch that you used please.

                                      MySensors 2.1.1
                                      Controller - OpenHAB (Virtual Machine)
                                      Gateway - Arduino Mega MQTT Gateway W5100

                                      mar.conteM 1 Reply Last reply
                                      0
                                      • S Samuel235

                                        Could you please either include your sketch here or give us a link to the example sketch that you used please.

                                        mar.conteM Offline
                                        mar.conteM Offline
                                        mar.conte
                                        wrote on last edited by mar.conte
                                        #150

                                        @Samuel235
                                        Resolved
                                        I have try with sketc j gammon https://www.gammon.com.au/forum/?id=11497
                                        And the problem are pir input (model hrc-501)
                                        Are ever high and the cpu dont go in sleep.
                                        I have remove pir and all ok the atmega run 20 uah very good.
                                        Can you advise a good pir wich run to 3,3 V for my project?
                                        Tanks

                                        mar.conteM 1 Reply Last reply
                                        0
                                        • mar.conteM mar.conte

                                          @Samuel235
                                          Resolved
                                          I have try with sketc j gammon https://www.gammon.com.au/forum/?id=11497
                                          And the problem are pir input (model hrc-501)
                                          Are ever high and the cpu dont go in sleep.
                                          I have remove pir and all ok the atmega run 20 uah very good.
                                          Can you advise a good pir wich run to 3,3 V for my project?
                                          Tanks

                                          mar.conteM Offline
                                          mar.conteM Offline
                                          mar.conte
                                          wrote on last edited by mar.conte
                                          #151

                                          @mar.conte
                                          im not sure why pir with simple test like this http://playground.arduino.cc/Code/PIRsense is ok
                                          but with my sketch the cpu reset forever

                                          
                                          #include <Arduino.h>            // assumes Arduino IDE v1.0 or greater
                                          #include <avr/sleep.h>
                                          #include <avr/wdt.h>
                                          #include <avr/power.h>
                                          #include <avr/io.h>
                                                      
                                          
                                          
                                          ISR (PCINT2_vect)
                                          {
                                            // handle pin change interrupt for D0 to D7 here
                                          }  // end of PCINT2_vect
                                          
                                          
                                          
                                          const unsigned long WAIT_TIME = 4000;
                                          
                                          
                                           const byte  LED =8 ;
                                           
                                           const byte  LED2 =9 ;
                                          int  wakepin =3 ;
                                            unsigned long lastSleep;
                                          
                                          
                                          
                                          volatile boolean motionDetected=false;
                                          float batteryVolts = 5;
                                          char BATstr[10]; //longest battery voltage reading message = 9chars
                                          char sendBuf[32];
                                          byte sendLen;
                                          void checkBattery(void);
                                          
                                          #include <RFM69.h>    //get it here: https://www.github.com/lowpowerlab/rfm69
                                          #include <SPI.h>
                                          
                                          //*********************************************************************************************
                                          // *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
                                          //*********************************************************************************************
                                          #define NETWORKID     100  // The same on all nodes that talk to each other
                                          #define NODEID        2    // The unique identifier of this node
                                          #define RECEIVER      1    // The recipient of packets
                                          
                                          //Match frequency to the hardware version of the radio on your Feather
                                          //#define FREQUENCY     RF69_433MHZ
                                          //#define FREQUENCY     RF69_868MHZ
                                          #define FREQUENCY     RF69_868MHZ
                                          #define ENCRYPTKEY    "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
                                          #define IS_RFM69HW   true // set to 'true' if you are using an RFM69HCW module
                                          
                                          //*********************************************************************************************
                                          #define SERIAL_BAUD   115200
                                          
                                          #define RFM69_CS      10
                                          #define RFM69_IRQ     2
                                          #define RFM69_IRQN    0  // Pin 2 is IRQ 0!
                                          #define RFM69_RST     9
                                          
                                          
                                          
                                          
                                          int16_t packetnum = 0;  // packet counter, we increment per xmission
                                          
                                          RFM69 radio = RFM69(RFM69_CS, RFM69_IRQ, IS_RFM69HW, RFM69_IRQN);  
                                          
                                          void setup () {
                                          
                                          
                                          
                                           
                                            pinMode (wakepin,INPUT);
                                              pinMode(LED, OUTPUT);
                                               pinMode(LED2, OUTPUT);
                                                 digitalWrite(wakepin,HIGH);
                                             
                                            
                                            char buff[50];
                                           
                                            Serial.begin(SERIAL_BAUD);
                                          
                                            Serial.println("Arduino RFM69HCW Transmitter");
                                            
                                            // Hard Reset the RFM module
                                            pinMode(RFM69_RST, OUTPUT);
                                            digitalWrite(RFM69_RST, HIGH);
                                            delay(100);
                                            digitalWrite(RFM69_RST, LOW);
                                            delay(100);
                                          
                                            // Initialize radio
                                            radio.initialize(FREQUENCY,NODEID,NETWORKID);
                                            if (IS_RFM69HW) {
                                              radio.setHighPower();    // Only for RFM69HCW & HW!
                                            }
                                            radio.setPowerLevel(31); // power output ranges from 0 (5dBm) to 31 (20dBm)
                                            
                                            radio.encrypt(ENCRYPTKEY);
                                            
                                            pinMode(LED, OUTPUT);
                                            Serial.print("\nTransmitting at ");
                                            Serial.print(FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
                                            Serial.println(" MHz");
                                          
                                           }
                                          
                                          
                                          
                                          
                                          uint16_t batteryReportCycles=0;
                                          
                                          
                                          
                                          void loop () 
                                          { 
                                              
                                             //rf();
                                          
                                          
                                            sleepNow();
                                             rf();
                                              
                                           //radio.sleep();
                                             
                                                          // sleep function called here 
                                          
                                          
                                           radio.sleep();
                                          }
                                          
                                          
                                          
                                          void wake ()
                                          {
                                          
                                           // cancel sleep as a precaution
                                            //sleep_disable();
                                            // precautionary while we do other stuff
                                           detachInterrupt (1);
                                          }  // end of wake
                                          
                                          void sleepNow()
                                          
                                          {
                                          
                                             if (millis () - lastSleep >= WAIT_TIME)
                                            {
                                              lastSleep = millis ();
                                          
                                          
                                              byte old_ADCSRA = ADCSRA;
                                              // disable ADC
                                              ADCSRA = 0;  
                                              // pin change interrupt (example for D0)
                                              PCMSK2 |= bit (PCINT16); // want pin 0
                                              PCIFR  |= bit (PCIF2);   // clear any outstanding interrupts
                                              PCICR  |= bit (PCIE2);   // enable pin change interrupts for D0 to D7
                                          
                                              set_sleep_mode (SLEEP_MODE_PWR_DOWN);
                                            
                                              power_adc_disable();
                                              power_spi_disable();
                                              power_timer0_disable();
                                              power_timer1_disable();
                                              power_timer2_disable();
                                              power_twi_disable();
                                            //PORTB = 0x00;
                                              UCSR0B &= ~bit (RXEN0);  // disable receiver
                                              UCSR0B &= ~bit (TXEN0);  // disable transmitter
                                          
                                              sleep_enable();
                                              
                                              noInterrupts ();
                                            attachInterrupt (1, wake,HIGH);
                                              digitalWrite (LED, LOW);
                                           
                                            interrupts ();
                                              sleep_cpu ();      
                                             digitalWrite (LED, HIGH);
                                          
                                              sleep_disable();
                                              power_all_enable();
                                           
                                              ADCSRA = old_ADCSRA;
                                              PCICR  &= ~bit (PCIE2);   // disable pin change interrupts for D0 to D7
                                              UCSR0B |= bit (RXEN0);  // enable receiver
                                              UCSR0B |= bit (TXEN0);  // enable transmitter
                                          
                                            }  // end of time to sleep
                                             
                                           
                                          }
                                          
                                          void rf()
                                          {
                                           char radiopacket[20] = "Hello World #";
                                            itoa(packetnum++, radiopacket+13, 10);
                                            Serial.print("Sending "); Serial.println(radiopacket);
                                              
                                            if (!radio.sendWithRetry(RECEIVER, radiopacket, strlen(radiopacket))) { //target node Id, message as string or byte array, message length
                                              Serial.println("OK");
                                          
                                            }
                                          
                                            radio.receiveDone(); //put radio in RX mode
                                            Serial.flush(); //make sure all serial data is clocked out before sleeping the MCU
                                            
                                            
                                          
                                          
                                           }
                                          
                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          12

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.0k

                                          Posts


                                          Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular