CubeCell stops working after 1-2 days

I have attached a BME280 sensor, a LiPo battery and a solar panel. The sketch turns on power to the sensor, gets the sensor readings, sends them out via LoRa and goes to deep sleep for 10 mins, then it repeats.

This works for about 20-30 hours but then at some point it stops sending the LoRa messages. When I bring it back inside, the battery level is fine so it looks it didn’t wake up from the deep sleep rather than got stuck running in some loop.

Anyone experienced this? Is there a trick to falling asleep in a more robust manner? Thanks.

Hello,

i have many sensors with the same configuration BME280 and deep sleep 10 min.

I can confirm this behavior with some sensors. But other sensors have been working fine for weeks! One assumption is, that in case of weak signal and e.g. rain on some days the ADR-mechanism is working and then a malfunction occurs, but it is only an assumption. Sometimes I have sensors that fail for about 2 days and suddenly start transmitting again!

It is quite time consuming to collect the sensors again and to change the hardware if you suspect it is defective.

(EU868; OTAA; ADR on ; Net Resevation off; unconformed uplink)

E_T

Thanks for your insight. My board is only broadcasting (plain LoRa, not LoraWAN) so signal strength shouldn’t play a role.

If the sensor is flaky, what do you think is actually happening with the board? In my implementation, even if it can’t read the sensor, it would still send a LoRa packet so I feel it’s the board that freezes.

I noticed the little LED light next to the USB connector was on, not sure the meaning of it but not desirable operating on battery. Perhaps that is a clue into what the board is doing. Or maybe it just indicates it’s getting power from the solar panel and it has energy to waste.

Contrary to my original post, it seems the battery level dropped more than if it was just deep sleeping the whole time so perhaps the board did get stuck on something, attempting to read the sensor for example. Will try a different sensor, see what happens. Thanks.

BTW I tried a totally different sensor (BME680) and it also stop sending within a similar time frame. I wonder if it is something silly, like letting the sensor “boot up” longer after turning the power on before trying to access it.

It also happens to me that after a few days the CubeCell node stops transmitting.
I connected sensors via Vext.
The code I use is the following:`
#include “LoRaWan_APP.h”
#include “Arduino.h”

/*

  • set LoraWan_RGB to Active,the RGB active in loraWan
  • RGB red means sending;
  • RGB purple means joined done;
  • RGB blue means RxWindow1;
  • RGB yellow means RxWindow2;
  • RGB green means received done;
    */

/* ABP para Cavit_01*/
uint8_t devEui[] = { };;
uint8_t appEui[] = { };;
uint32_t devAddr = ( uint32_t )0x???;
uint8_t appKey[] = { };
uint8_t appSKey[] = { };
uint8_t nwkSKey[] = { };

/LoraWan channelsmask, default channels 0-7/
uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 };

/LoraWan region, select in arduino IDE tools/
LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;

/LoraWan Class, Class A and Class C are supported/
DeviceClass_t loraWanClass = LORAWAN_CLASS;

/the application data transmission duty cycle. value in [ms]./
uint32_t appTxDutyCycle = 15000;

/OTAA or ABP/
bool overTheAirActivation = LORAWAN_NETMODE;

/ADR enable/
bool loraWanAdr = LORAWAN_ADR;

/* set LORAWAN_Net_Reserve ON, the node could save the network info to flash, when node reset not need to join again */
bool keepNet = LORAWAN_NET_RESERVE;

/* Indicates if the node is sending confirmed or unconfirmed messages */
bool isTxConfirmed = LORAWAN_UPLINKMODE;

/* Application port */
uint8_t appPort = 58;

uint16_t sensor_1 = 0;
uint16_t sensor_2 = 0;
/*!

  • Number of trials to transmit the frame, if the LoRaMAC layer did not
  • receive an acknowledgment. The MAC performs a datarate adaptation,
  • according to the LoRaWAN Specification V1.0.2, chapter 18.4, according
  • to the following table:
  • Transmission nb | Data Rate
  • ----------------|-----------
  • 1 (first) | DR
  • 2 | DR
  • 3 | max(DR-1,0)
  • 4 | max(DR-1,0)
  • 5 | max(DR-2,0)
  • 6 | max(DR-2,0)
  • 7 | max(DR-3,0)
  • 8 | max(DR-3,0)
  • Note, that if NbTrials is set to 1 or 2, the MAC will not decrease
  • the datarate, in case the LoRaMAC layer did not receive an acknowledgment
    */
    uint8_t confirmedNbTrials = 4;

/* Prepares the payload of the frame */
static void prepareTxFrame( uint8_t port )
{
/*appData size is LORAWAN_APP_DATA_MAX_SIZE which is defined in “commissioning.h”.
*appDataSize max value is LORAWAN_APP_DATA_MAX_SIZE.
*if enabled AT, don’t modify LORAWAN_APP_DATA_MAX_SIZE, it may cause system hanging or failure.
*if disabled AT, LORAWAN_APP_DATA_MAX_SIZE can be modified, the max value is reference to lorawan region and SF.
*for example, if use REGION_CN470,
*the max value for different DR can be found in MaxPayloadOfDatarateCN470 refer to DataratesCN470 and BandwidthsCN470 in “RegionCN470.h”.
*/
appDataSize = 9;

    // abilito l'alimentazione esterna
    Serial.println("Misuro la il valore del sensore analogico");
    digitalWrite(Vext,LOW);
    delay(40);
    ///leggo il valore del sensore analogico
    sensor_1 = analogRead(ADC2); //return the voltage in mV, max value can be read is 2400mV
    //Aspetto un attimo per leggerte il secondo sensore
    delay(50);
    ///leggo il valore del secondo sensore analogico
    sensor_2 = analogRead(ADC3); //return the voltage in mV, max value can be read is 2400mV
    delay(40);
    digitalWrite(Vext,HIGH);

    //Serial.print(millis());
    Serial.print("Valore della batteria");
    uint16_t BatteryVoltage = getBatteryVoltage();
    Serial.println(BatteryVoltage);
appData[0] = 0x01;
appData[1] = (uint8_t)(BatteryVoltage >> 8);
appData[2] = (uint8_t)BatteryVoltage;
appData[3] = 0x02;
appData[4] = (uint8_t)(sensor_1 >> 8);
appData[5] = (uint8_t)sensor_1;
 appData[6] = 0x03;
appData[7] = (uint8_t)(sensor_2 >> 8);
appData[8] = (uint8_t)sensor_2;

}

void app(uint8_t port, const uint8_t const data)
{
// lora_printf(“data:%d\r\n”,data);
switch (port)
{
case 6:
{
if (data != 0 )
{
Serial.println(" ---------- Imposto il nuovo tempo di trasmissione in secondi ---------------- “);
Serial.print(” tempo di trasmissione: “);
int intervallo = (data[0] & 0b11111111) << 8;
intervallo |= (data[1] & 0b11111111);
Serial.print (intervallo);
Serial.println(” secondi");
int tempo = intervallo
1000;
delay(200);
Serial.println(tempo);
appTxDutyCycle = tempo;
}

    delay(1000);
    break;
  }
case 20:
  {
    Serial.println(" reset board ");
    delay(200);
    HW_Reset(0);
    Serial.println(" resetted board ");
    break;
  }
case 51:
  {
    Serial.println(" ---------------- 51 ---------------- ");

    break;
  }

default:
  {
    Serial.print("data: ");
    Serial.println(data[0]);
    Serial.println(" ---------------- NN ---------------- ");
    break;
  }

}
}

//downlink data handle function example
void downLinkDataHandle(McpsIndication_t *mcpsIndication)
{
Serial.printf("+REV DATA:%s,RXSIZE %d,PORT %d\r\n",mcpsIndication->RxSlot?“RXWIN2”:“RXWIN1”,mcpsIndication->BufferSize,mcpsIndication->Port);
Serial.print("+REV DATA:");
app(mcpsIndication->Port, mcpsIndication->Buffer);

for(uint8_t i=0;iBufferSize;i++)
{
Serial.printf("%02X",mcpsIndication->Buffer[i]);
}
Serial.println();
uint32_t color=mcpsIndication->Buffer[0]<<16|mcpsIndication->Buffer[1]<<8|mcpsIndication->Buffer[2];
#if(LoraWan_RGB==1)
turnOnRGB(color,5000);
turnOffRGB();
#endif
}

void setup() {

boardInitMcu();
Serial.begin(115200);

#if(AT_SUPPORT)
enableAt();
#endif
deviceState = DEVICE_STATE_INIT;
LoRaWAN.ifskipjoin();
//digitalWrite(Vext,LOW);
}

void loop()
{
switch( deviceState )
{
case DEVICE_STATE_INIT:
{
#if(AT_SUPPORT)
getDevParam();
#endif
printDevParam();
LoRaWAN.init(loraWanClass,loraWanRegion);
deviceState = DEVICE_STATE_JOIN;
break;
}
case DEVICE_STATE_JOIN:
{
LoRaWAN.join();
break;
}
case DEVICE_STATE_SEND:
{
prepareTxFrame( appPort );
LoRaWAN.send();
deviceState = DEVICE_STATE_CYCLE;
break;
}
case DEVICE_STATE_CYCLE:
{
// Schedule next packet transmission
txDutyCycleTime = appTxDutyCycle + randr( 0, APP_TX_DUTYCYCLE_RND );
LoRaWAN.cycle(txDutyCycleTime);
deviceState = DEVICE_STATE_SLEEP;
break;
}
case DEVICE_STATE_SLEEP:
{
//Serial.print(“I’m going to sleep…”);
LoRaWAN.sleep();
break;
}

    default:
    {
        deviceState = DEVICE_STATE_INIT;                        
        break;
    }
}

}`

#include “LoRaWan_APP.h”
#include “Arduino.h”

/*

  • set LoraWan_RGB to Active,the RGB active in loraWan
  • RGB red means sending;
  • RGB purple means joined done;
  • RGB blue means RxWindow1;
  • RGB yellow means RxWindow2;
  • RGB green means received done;
    */

/* ABP para Cavit_01*/
uint8_t devEui[] ={ xxxxxxxxxxxx };;;
uint8_t appEui[] ={ xxxxxxxxxxxx };;;
uint32_t devAddr = ( uint32_t )0x???;
uint8_t appKey[] = { xxxxxxxxxxxx };;
uint8_t appSKey[] = { xxxxxxxxxxxx };;
uint8_t nwkSKey[] = { xxxxxxxxxxxx };;

/LoraWan channelsmask, default channels 0-7/
uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 };

/LoraWan region, select in arduino IDE tools/
LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;

/LoraWan Class, Class A and Class C are supported/
DeviceClass_t loraWanClass = LORAWAN_CLASS;

/the application data transmission duty cycle. value in [ms]./
uint32_t appTxDutyCycle = 15000;

/OTAA or ABP/
bool overTheAirActivation = LORAWAN_NETMODE;

/ADR enable/
bool loraWanAdr = LORAWAN_ADR;

/* set LORAWAN_Net_Reserve ON, the node could save the network info to flash, when node reset not need to join again */
bool keepNet = LORAWAN_NET_RESERVE;

/* Indicates if the node is sending confirmed or unconfirmed messages */
bool isTxConfirmed = LORAWAN_UPLINKMODE;

/* Application port */
uint8_t appPort = 58;

uint16_t sensor_1 = 0;
uint16_t sensor_2 = 0;
/*!

  • Number of trials to transmit the frame, if the LoRaMAC layer did not
  • receive an acknowledgment. The MAC performs a datarate adaptation,
  • according to the LoRaWAN Specification V1.0.2, chapter 18.4, according
  • to the following table:
  • Transmission nb | Data Rate
  • ----------------|-----------
  • 1 (first) | DR
  • 2 | DR
  • 3 | max(DR-1,0)
  • 4 | max(DR-1,0)
  • 5 | max(DR-2,0)
  • 6 | max(DR-2,0)
  • 7 | max(DR-3,0)
  • 8 | max(DR-3,0)
  • Note, that if NbTrials is set to 1 or 2, the MAC will not decrease
  • the datarate, in case the LoRaMAC layer did not receive an acknowledgment
    */
    uint8_t confirmedNbTrials = 4;

/* Prepares the payload of the frame */
static void prepareTxFrame( uint8_t port )
{
/*appData size is LORAWAN_APP_DATA_MAX_SIZE which is defined in “commissioning.h”.
*appDataSize max value is LORAWAN_APP_DATA_MAX_SIZE.
*if enabled AT, don’t modify LORAWAN_APP_DATA_MAX_SIZE, it may cause system hanging or failure.
*if disabled AT, LORAWAN_APP_DATA_MAX_SIZE can be modified, the max value is reference to lorawan region and SF.
*for example, if use REGION_CN470,
*the max value for different DR can be found in MaxPayloadOfDatarateCN470 refer to DataratesCN470 and BandwidthsCN470 in “RegionCN470.h”.
*/
appDataSize = 9;

    // abilito l'alimentazione esterna
    Serial.println("Misuro la il valore del sensore analogico");
    digitalWrite(Vext,LOW);
    delay(40);
    ///leggo il valore del sensore analogico
    sensor_1 = analogRead(ADC2); //return the voltage in mV, max value can be read is 2400mV
    //Aspetto un attimo per leggerte il secondo sensore
    delay(50);
    ///leggo il valore del secondo sensore analogico
    sensor_2 = analogRead(ADC3); //return the voltage in mV, max value can be read is 2400mV
    delay(40);
    digitalWrite(Vext,HIGH);

    //Serial.print(millis());
    Serial.print("Valore della batteria");
    uint16_t BatteryVoltage = getBatteryVoltage();
    Serial.println(BatteryVoltage);
appData[0] = 0x01;
appData[1] = (uint8_t)(BatteryVoltage >> 8);
appData[2] = (uint8_t)BatteryVoltage;
appData[3] = 0x02;
appData[4] = (uint8_t)(sensor_1 >> 8);
appData[5] = (uint8_t)sensor_1;
 appData[6] = 0x03;
appData[7] = (uint8_t)(sensor_2 >> 8);
appData[8] = (uint8_t)sensor_2;

}

void app(uint8_t port, const uint8_t const data)
{
// lora_printf(“data:%d\r\n”,data);
switch (port)
{
case 6:
{
if (data != 0 )
{
Serial.println(" ---------- Imposto il nuovo tempo di trasmissione in secondi ---------------- “);
Serial.print(” tempo di trasmissione: “);
int intervallo = (data[0] & 0b11111111) << 8;
intervallo |= (data[1] & 0b11111111);
Serial.print (intervallo);
Serial.println(” secondi");
int tempo = intervallo
1000;
delay(200);
Serial.println(tempo);
appTxDutyCycle = tempo;
}

    delay(1000);
    break;
  }
case 20:
  {
    Serial.println(" reset board ");
    delay(200);
    HW_Reset(0);
    Serial.println(" resetted board ");
    break;
  }
case 51:
  {
    Serial.println(" ---------------- 51 ---------------- ");

    break;
  }

default:
  {
    Serial.print("data: ");
    Serial.println(data[0]);
    Serial.println(" ---------------- NN ---------------- ");
    break;
  }

}
}

//downlink data handle function example
void downLinkDataHandle(McpsIndication_t *mcpsIndication)
{
Serial.printf("+REV DATA:%s,RXSIZE %d,PORT %d\r\n",mcpsIndication->RxSlot?“RXWIN2”:“RXWIN1”,mcpsIndication->BufferSize,mcpsIndication->Port);
Serial.print("+REV DATA:");
app(mcpsIndication->Port, mcpsIndication->Buffer);

for(uint8_t i=0;iBufferSize;i++)
{
Serial.printf("%02X",mcpsIndication->Buffer[i]);
}
Serial.println();
uint32_t color=mcpsIndication->Buffer[0]<<16|mcpsIndication->Buffer[1]<<8|mcpsIndication->Buffer[2];
#if(LoraWan_RGB==1)
turnOnRGB(color,5000);
turnOffRGB();
#endif
}

void setup() {

boardInitMcu();
Serial.begin(115200);

#if(AT_SUPPORT)
enableAt();
#endif
deviceState = DEVICE_STATE_INIT;
LoRaWAN.ifskipjoin();
//digitalWrite(Vext,LOW);
}

void loop()
{
switch( deviceState )
{
case DEVICE_STATE_INIT:
{
#if(AT_SUPPORT)
getDevParam();
#endif
printDevParam();
LoRaWAN.init(loraWanClass,loraWanRegion);
deviceState = DEVICE_STATE_JOIN;
break;
}
case DEVICE_STATE_JOIN:
{
LoRaWAN.join();
break;
}
case DEVICE_STATE_SEND:
{
prepareTxFrame( appPort );
LoRaWAN.send();
deviceState = DEVICE_STATE_CYCLE;
break;
}
case DEVICE_STATE_CYCLE:
{
// Schedule next packet transmission
txDutyCycleTime = appTxDutyCycle + randr( 0, APP_TX_DUTYCYCLE_RND );
LoRaWAN.cycle(txDutyCycleTime);
deviceState = DEVICE_STATE_SLEEP;
break;
}
case DEVICE_STATE_SLEEP:
{
//Serial.print(“I’m going to sleep…”);
LoRaWAN.sleep();
break;
}

    default:
    {
        deviceState = DEVICE_STATE_INIT;                        
        break;
    }
}

}

Mine was/is hanging when trying to read from an I2C sensor (BME280 or BME680 using Adafruit or Seeed libraries - the bme.begin or init function). It seems you’re reading analog ports so your problem is elsewhere, not that I have a solution for mine. Thanks for sharing.

Have you tried isolating the I2C issue from the rest of the lorawan/sleep code, strip all extra code out and simple run a read from BME280 every 5 mins over 3+ days ?

Didn’t go that route yet. However, I added some sensor-detecting code into the setup method (tries to communicate over the whole range of i2c addresses and notes which address gives a valid response - similar to the Heltec’s MultiSensorAutoRecognize example). It is not recognizing VEML6075 (address 0x10) but it is recognizing BME280 and BME680 and if I try to use the sensor after this auto-recognition step, it looks better, running both 280 and 680 for 2-3 days (every 10 mins and sending a LoRa message) and so far it still works on both accounts (knock knock). Don’t know if the initial probe wakes something more or if the additional step gives the sensor more time to wake up fully or what.

Once I am comfortable with the BME stability, I will go back to the VEML6075 and get that working too.

It seems the probing of all the possible addresses (or at least one of them) throws the i2c bus off and subsequent valid read fails. If I only probe addresses that make sense in my scenario (0x10, 0x76 and 0x77), then the sensor gets detected correctly and the reading also happens correctly. I should probably mention that at this point I am running off of the CubeCell github master (main) code. Will see how it behaves longer term.

Any long-term experiences?

With a LoRaWAN-enviroment i will calculate with 30% of failure!

It will probably have many different causes!

High power consumption
Poor reception and impractical ADR
Faulty sensors
Failure for no apparent reason

It is an expensive problem as these faults often occur in the field!

E_T

I have 2 solar cubcells and both just stop transmitting after an hour or so. I monitor the voltage and it’s not low voltage. I wonder if it’s onwake the stack pointer is not getting reset or memory leak?