Electron not waking up

Hi,

I’m using a Sparkfun wind station and I would like to installt it in my roof. The problem is the energy. The device is solar power and will be operative twice per hour.

I wrote an script, but did not wake up, anyone could help to me?

Thank’s

STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));
SYSTEM_MODE(SEMI_AUTOMATIC)
SYSTEM_THREAD(ENABLED)

#include <Adafruit_BME280.h>
#include <SparkFun_Photon_Weather_Shield_Library.h>
#include <math.h>

#define BME_SCK D4
Adafruit_BME280 bme; // I2C

// Each time we loop through the main loop, we check to see if it's time to capture the sensor readings
unsigned int sensorCapturePeriod = 100;
unsigned int timeNextSensorReading;

// Each time we loop through the main loop, we check to see if it's time to publish the data we've collected
unsigned int publishPeriod = 90000;
unsigned int timeNextPublish; 
const    int   sleepPeriode = 30 * 60; // 2 minutes sleep time

void setup() {

    initializeTekphumidityAndPressure();
    initializeRainGauge();
    initializeAnemometer();
    initializeWindVane();
    bme.begin();
    // Schedule the next sensor reading and publish events
    timeNextSensorReading = millis() + sensorCapturePeriod;
    timeNextPublish = millis() + publishPeriod; 
}

void loop() {

    // Capture any sensors that need to be polled (temp, humidity, pressure, wind vane)
    // The rain and wind speed sensors use interrupts, and so data is collected "in the background"
    if(timeNextSensorReading <= millis()) {
        captureTekphumidityPressure();
        captureWindVane();
        // Schedule the next sensor reading
        timeNextSensorReading = millis() + sensorCapturePeriod;
    }
    
    // Publish the data collected to Particle
    if(timeNextPublish <= millis()) {
        
        // Variables from values read
        float wstempC = getAndResetTempF();
        float wshumidityRH = getAndResetHumidityRH();
        float wspressureHPa = getAndResetPressurePascals() / 100.0;
        float rainmm = getAndResetRainInches()*25.4;
        float gustKPH;
        float windKPH = (getAndResetAnemometerkph(&gustKPH))*1.609;
        float knots = windKPH*0.5399;
        float windDegrees = getAndResetWindVaneDegrees();
        
        
        
        float bmetempC = bme.readTemperature();
        float bmehum = (bme.readPressure() / 100.0F);
        float bmepress =bme.readHumidity();
        
        
        /////////////////////////Battery level Reading/////////////////////////
        FuelGauge fuel;
        float batt;
        batt = fuel.getVCell();
        float battp = fuel.getSoC();
                          
        // Preparing the values to String
        String Stemp = String(bmetempC);
        String Spress = String(bmehum); //String(press);
        String Shum = String(bmepress); //String(hum);
        //SI1145
        String Svis = String("");//String(UVvis);
        String SUV = String("");//String(UVindex);
        //SHT10
        String Stempsoil1 =String("");//String(tempsoil);
        String Shumsoil1 =String("");//String(humsoil);
        String Stempsoil2 =String("");//String("");
        String Shumsoil2 =String("");//String("");
        //Battery
        String Sbatt = String(batt);
        String Sbattp = String(battp);
        //Water Mark
        String Ssoil1 = String("");//String(WMValue1);
        String Ssoilp1 = String("");//String(WMValueP1);
        String Ssoil2 = String("");//String(WMValue2);
        String Ssoilp2 = String("");//String(WMValueP2);
        //Decagon leaf
        String Sleaf1 = String("");//String(leaf1);
        String Sleafp1 = String("");//String(leafP1);
        String Sleaf2 = String("");//String(leaf2);
        String Sleafp2 = String("");//String(leafP2);
        //Capacitive
        String Scapacv1 = String("");//String(capacitive1);
        String Scapacp1 = String("");//String(capacitive1P);
        String Scapacv2 = String("");//String(capacitive2);
        String Scapacp2 = String("");//String(capacitive2P);
        //Sparkfun Weather station
        String SPKtemp = String(wstempC);
        String SPKhum = String(wshumidityRH);
        String SPKpress = String(wspressureHPa);
        String SPKwind =String(windKPH);
        String SPKdegrees =String(windDegrees);
        String SPKrain =String(rainmm);
        String SPKgust =String(gustKPH);
        String SPKknots =String(knots);
        //Ulatracker
        String UBXamb = String("");//String(tempeatureFresh);
        String UBXfrozen = String("");//String(temperatureFrozen);

        Particle.connect();
        if (waitFor(Particle.connected, 300000 ))
            { // proceede only if a connection could be established within 60 seconds 
            //Building JSON
            String dest = "{";
            if(Spress.length()>0){ dest = dest + "\"5\":\""+ Stemp +"\",";}
            if(Spress.length()>0){ dest = dest + "\"6\":\""+ Spress +"\",";}
            if(Shum.length()>0){ dest = dest + "\"7\":\""+ Shum +"\",";}
            if(SPKtemp.length()>0){ dest = dest + "\"28\":\""+ SPKtemp +"\",";}
            if(SPKhum.length()>0){ dest = dest + "\"29\":\""+ SPKhum +"\",";}
            if(SPKpress.length()>0){ dest = dest + "\"30\":\""+ SPKpress +"\",";}
            if(SPKrain.length()>0){ dest = dest + "\"31\":\""+ SPKrain +"\",";}
            if(SPKgust.length()>0){ dest = dest + "\"32\":\""+ SPKgust +"\",";}
            if(SPKwind.length()>0){ dest = dest + "\"33\":\""+ SPKwind +"\",";}
            if(SPKknots.length()>0){ dest = dest + "\"34\":\""+ SPKknots +"\",";}
            if(SPKdegrees.length()>0){ dest = dest + "\"35\":\""+ SPKdegrees +"\",";}
            + "}";
            
            Particle.publish("test",dest ,60,PRIVATE);

            }

        
    }
    //delay(30000);
    System.sleep(SLEEP_MODE_DEEP, sleepPeriode, SLEEP_NETWORK_STANDBY); //Sleep a while to save battery
}


Weather sensor;

void initializeTekphumidityAndPressure() {
    //Initialize the I2C sensors and ping them
    sensor.begin();
    //Set to Barometer Mode
    sensor.setModeBarometer();
    // Set Oversample rate
    sensor.setOversampleRate(7); 
    //Necessary register calls to enble temp, baro and alt
    sensor.enableEventFlags(); 
    
    return;
}

float wshumidityRHTotal = 0.0;
unsigned int wshumidityRHReadingCount = 0;
float wstempCTotal = 0.0;
unsigned int wstempCReadingCount = 0;
float pressurePascalsTotal = 0.0;
unsigned int pressurePascalsReadingCount = 0;

void captureTekphumidityPressure() {
  // Read the humidity and pressure sensors, and update the running average
  // The running (mean) average is maintained by keeping a running sum of the observations,
  // and a count of the number of observations
  
  // Measure Relative Humidity from the HTU21D or Si7021
  float wshumidityRH = sensor.getRH();
  
  //If the result is reasonable, add it to the running mean
  if(wshumidityRH > 0 && wshumidityRH < 105) // It's theoretically possible to get supersaturation humidity levels over 100%
  {
      // Add the observation to the running sum, and increment the number of observations
      wshumidityRHTotal += wshumidityRH;
      wshumidityRHReadingCount++;
  }

  // Measure Temperature from the HTU21D or Si7021
  // Temperature is measured every time RH is requested.
  // It is faster, therefore, to read it from previous RH
  // measurement with getTemp() instead with readTemp()
  float wstempC = getAndResetTempF();
  
  //If the result is reasonable, add it to the running mean
  if(wstempC > -50 && wstempC < 150)
  {
      // Add the observation to the running sum, and increment the number of observations
      wstempCTotal += wstempC;
      wstempCReadingCount++;
  }

  //Measure Pressure from the MPL3115A2
  float pressurePascals = sensor.readPressure();
  
  //If the result is reasonable, add it to the running mean
  // What's reasonable? http://findanswers.noaa.gov/noaa.answers/consumer/kbdetail.asp?kbid=544
  if(pressurePascals > 80000 && pressurePascals < 110000)
  {
      // Add the observation to the running sum, and increment the number of observations
      pressurePascalsTotal += pressurePascals;
      pressurePascalsReadingCount++;
  }
  
  return;
}

float getAndResetTempF()
{
    if(wstempCReadingCount == 0) {
        return 0;
    }
    float result = (wstempCTotal/float(wstempCReadingCount))-32/1.8;
    wstempCTotal = 0.0;
    wstempCReadingCount = 0;
    return result;
}

float getAndResetHumidityRH()
{
    if(wshumidityRHReadingCount == 0) {
        return 0;
    }
    float result = wshumidityRHTotal/float(wshumidityRHReadingCount);
    wshumidityRHTotal = 0.0;
    wshumidityRHReadingCount = 0;
    return result;
}


float getAndResetPressurePascals()
{
    if(pressurePascalsReadingCount == 0) {
        return 0;
    }
    float result = pressurePascalsTotal/float(pressurePascalsReadingCount);
    pressurePascalsTotal = 0.0;
    pressurePascalsReadingCount = 0;
    return result;
}

//===========================================================================
// Rain Guage
//===========================================================================
int RainPin = D2;
volatile unsigned int rainEventCount;
unsigned int lastRainEvent;
float RainScaleInches = 0.011; // Each pulse is .011 inches of rain

void initializeRainGauge() {
  pinMode(RainPin, INPUT_PULLUP);
  rainEventCount = 0;
  lastRainEvent = 0;
  attachInterrupt(RainPin, handleRainEvent, FALLING);
  return;
  }
  
void handleRainEvent() {
    // Count rain gauge bucket tips as they occur
    // Activated by the magnet and reed switch in the rain gauge, attached to input D2
    unsigned int timeRainEvent = millis(); // grab current time
    
    // ignore switch-bounce glitches less than 10mS after initial edge
    if(timeRainEvent - lastRainEvent < 10) {
      return;
    }
    
    rainEventCount++; //Increase this minute's amount of rain
    lastRainEvent = timeRainEvent; // set up for next event
}

float getAndResetRainInches()
{
    float result = RainScaleInches * float(rainEventCount);
    rainEventCount = 0;
    return result;
}

//===========================================================================
// Wind Speed (Anemometer)
//===========================================================================

// The Anemometer generates a frequency relative to the windspeed.  1Hz: 1.492kph, 2Hz: 2.984kph, etc.
// We measure the average period (elaspsed time between pulses), and calculate the average windspeed since the last recording.

int AnemometerPin = D3;
float AnemometerScalekph = 1.492; // Windspeed if we got a pulse every second (i.e. 1Hz)
volatile unsigned int AnemoneterPeriodTotal = 0;
volatile unsigned int AnemoneterPeriodReadingCount = 0;
volatile unsigned int GustPeriod = UINT_MAX;
unsigned int lastAnemoneterEvent = 0;

void initializeAnemometer() {
  pinMode(AnemometerPin, INPUT_PULLUP);
  AnemoneterPeriodTotal = 0;
  AnemoneterPeriodReadingCount = 0;
  GustPeriod = UINT_MAX;  //  The shortest period (and therefore fastest gust) observed
  lastAnemoneterEvent = 0;
  attachInterrupt(AnemometerPin, handleAnemometerEvent, FALLING);
  return;
  }
  
void handleAnemometerEvent() {
    // Activated by the magnet in the anemometer (2 ticks per rotation), attached to input D3
     unsigned int timeAnemometerEvent = millis(); // grab current time
     
    //If there's never been an event before (first time through), then just capture it
    if(lastAnemoneterEvent != 0) {
        // Calculate time since last event
        unsigned int period = timeAnemometerEvent - lastAnemoneterEvent;
        // ignore switch-bounce glitches less than 10mS after initial edge (which implies a max windspeed of 149kph)
        if(period < 10) {
          return;
        }
        if(period < GustPeriod) {
            // If the period is the shortest (and therefore fastest windspeed) seen, capture it
            GustPeriod = period;
        }
        AnemoneterPeriodTotal += period;
        AnemoneterPeriodReadingCount++;
    }
    
    lastAnemoneterEvent = timeAnemometerEvent; // set up for next event
}

float getAndResetAnemometerkph(float * gustKPH)
{
    if(AnemoneterPeriodReadingCount == 0)
    {
        *gustKPH = 0.0;
        return 0;
    }
    // Nonintuitive math:  We've collected the sum of the observed periods between pulses, and the number of observations.
    // Now, we calculate the average period (sum / number of readings), take the inverse and muliple by 1000 to give frequency, and then mulitply by our scale to get kph.
    // The math below is transformed to maximize accuracy by doing all muliplications BEFORE dividing.
    float result = AnemometerScalekph * 1000.0 * float(AnemoneterPeriodReadingCount) / float(AnemoneterPeriodTotal);
    AnemoneterPeriodTotal = 0;
    AnemoneterPeriodReadingCount = 0;
    *gustKPH = AnemometerScalekph  * 1000.0 / float(GustPeriod);
    GustPeriod = UINT_MAX;
    return result;
}


//===========================================================
// Wind Vane
//===========================================================
void initializeWindVane() {
    return;
}

// For the wind vane, we need to average the unit vector components (the sine and cosine of the angle)
int WindVanePin = A0;
float windVaneCosTotal = 0.0;
float windVaneSinTotal = 0.0;
unsigned int windVaneReadingCount = 0;

void captureWindVane() {
    // Read the wind vane, and update the running average of the two components of the vector
    unsigned int windVaneRaw = analogRead(WindVanePin);
    
    float windVaneRadians = lookupRadiansFromRaw(windVaneRaw);
    if(windVaneRadians > 0 && windVaneRadians < 6.14159)
    {
        windVaneCosTotal += cos(windVaneRadians);
        windVaneSinTotal += sin(windVaneRadians);
        windVaneReadingCount++;
    }
    return;
}

float getAndResetWindVaneDegrees()
{
    if(windVaneReadingCount == 0) {
        return 0;
    }
    float avgCos = windVaneCosTotal/float(windVaneReadingCount);
    float avgSin = windVaneSinTotal/float(windVaneReadingCount);
    float result = atan(avgSin/avgCos) * 180.0 / 3.14159;
    windVaneCosTotal = 0.0;
    windVaneSinTotal = 0.0;
    windVaneReadingCount = 0;
    // atan can only tell where the angle is within 180 degrees.  Need to look at cos to tell which half of circle we're in
    if(avgCos < 0) result += 180.0;
    // atan will return negative angles in the NW quadrant -- push those into positive space.
    if(result < 0) result += 360.0;
    
   return result;
}


float lookupRadiansFromRaw(unsigned int analogRaw)
{
    // The mechanism for reading the weathervane isn't arbitrary, but effectively, we just need to look up which of the 16 positions we're in.
    if(analogRaw >= 2200 && analogRaw < 2400) return (3.14);//South
    if(analogRaw >= 2100 && analogRaw < 2200) return (3.53);//SSW
    if(analogRaw >= 3200 && analogRaw < 3299) return (3.93);//SW
    if(analogRaw >= 3100 && analogRaw < 3200) return (4.32);//WSW
    if(analogRaw >= 3890 && analogRaw < 3999) return (4.71);//West
    if(analogRaw >= 3700 && analogRaw < 3780) return (5.11);//WNW
    if(analogRaw >= 3780 && analogRaw < 3890) return (5.50);//NW
    if(analogRaw >= 3400 && analogRaw < 3500) return (5.89);//NNW
    if(analogRaw >= 3570 && analogRaw < 3700) return (0.00);//North
    if(analogRaw >= 2600 && analogRaw < 2700) return (0.39);//NNE
    if(analogRaw >= 2750 && analogRaw < 2850) return (0.79);//NE
    if(analogRaw >= 1510 && analogRaw < 1580) return (1.18);//ENE
    if(analogRaw >= 1580 && analogRaw < 1650) return (1.57);//East
    if(analogRaw >= 1470 && analogRaw < 1510) return (1.96);//ESE
    if(analogRaw >= 1900 && analogRaw < 2000) return (2.36);//SE
    if(analogRaw >= 1700 && analogRaw < 1750) return (2.74);//SSE
    if(analogRaw > 4000) return(-1); // Open circuit?  Probably means the sensor is not connected
    Particle.publish("error", String::format("Got %d from Windvane.",analogRaw), 60 , PRIVATE);
    return -1;
}

Is it really not waking up, or is it waking up and immediately going back to sleep? It looks like the problem is that your two if conditions at the top of loop() will never be true. When the device goes into deep sleep, it resets when it wakes up (setup runs again), so you are resetting timeNextSensorReading and timeNextPublish to values grater than millis() each time the device awakens. Therefore, the device will go right back to sleep.

2 Likes

Hi Ric,

Definitely I erase all the if, because are not compatible with the script, now the device wakes up and sleep correctly

Thank’s for your help

Eduard