Solar cubcell stops after about 3 hours?

Cubecell stops after a random amount of wakes and sleeps. looked and edited my code as suggested in other posts. But they still stop working after a couple of hours. Could it be a memory leak or Stack pointer not being reset on wake? Is there a way to test this theory?
2022-12-09T00:00:00Z

#include “LoRaWan_APP.h”

#include “Arduino.h”

#include “time.h”

#include <Wire.h>

#include <string.h>

#include “SHT3x.h”

#ifdef asr650x

#include “innerWdt.h”

#endif

/*

  • For asr650x, the max feed time is 2.8 seconds.

  • For asr6601, the max feed time is 24 seconds.

*/

#ifdef asr650x

#define MAX_FEEDTIME 2800// ms // was 2800

#else

#define MAX_FEEDTIME 24000// ms

#endif

SHT3x Sensor;

#ifndef LoraWan_RGB

#define LoraWan_RGB = 0 //set both to 1 for led to work

#endif

#define RF_FREQUENCY 868000000 // Hz

#define TX_OUTPUT_POWER 5 // dBm // WAS 5

#define LORA_BANDWIDTH 0 // [0: 125 kHz,

                                                          //  1: 250 kHz,

                                                          //  2: 500 kHz,

                                                          //  3: Reserved]

#define LORA_SPREADING_FACTOR 7 // [SF7…SF12]

#define LORA_CODINGRATE 1 // [1: 4/5,

                                                          //  2: 4/6,

                                                          //  3: 4/7,

                                                          //  4: 4/8]

#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx

#define LORA_SYMBOL_TIMEOUT 0 // Symbols

#define LORA_FIX_LENGTH_PAYLOAD_ON false

#define LORA_IQ_INVERSION_ON false

#define RX_TIMEOUT_VALUE 900

#define BUFFER_SIZE 255 // Define the payload size here

uint64_t TxLastTimne ; // timestamp last TX

uint64_t TXinterval; // time until next TX

uint64_t ThisAwake; // time spent awake

byte txpacket[BUFFER_SIZE];

byte rxpacket[BUFFER_SIZE];

bool AllTXdone =false;

byte packetList[255]; // store packets

byte pointer;

float Temp=0;

float Humid=0;

byte TXsize=0;

uint64_t TXchipID=getID();

byte groupID =0; // set group ID to your mesh group. Only matching ID nodes will repeat

byte action =1; // Action 0 is following bytes are Voltage, Temperature,Humidity values

uint16_t volts;

int SleepTime ; //minutes to sleep

int awakeTime =70; //second

byte RecieveSync=0; //

static TimerEvent_t sleep;

static TimerEvent_t wakeUp;

bool BatteryLow;

bool debug=false; ///**** debug with print statements

RadioEvents_t RadioEvents;

void OnTxDone( void );

void OnTxTimeout( void );

void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );

typedef enum

{

WAIT_TX_DONE,

LOWPOWER,

RX,

TX

}States_t;

int16_t txNumber;

States_t state;

bool sleepMode = false;

int16_t Rssi,rxSize;

void setup() {

boardInitMcu( );

CommonBoot();

RadioEvents.TxDone = OnTxDone;

RadioEvents.TxTimeout = OnTxTimeout;

RadioEvents.RxDone = OnRxDone;

Radio.Init( &RadioEvents );



Radio.SetChannel( RF_FREQUENCY );

Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,

                               LORA_SPREADING_FACTOR, LORA_CODINGRATE,

                               LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,

                               true, 0, 0, LORA_IQ_INVERSION_ON, 3000 );

Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,

                               LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,

                               LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,

                               0, true, 0, 0, LORA_IQ_INVERSION_ON, true );

 Radio.SetSyncWord(0xF2);  

if (debug==true){

  Serial.println(MAX_FEEDTIME);

  Serial.println("Booting from SetUp");

}                      

}

void loop()

{

feedInnerWdt(); // feed watchdog timer

if ((millis() - TxLastTimne> TXinterval)&&(state==RX)){

TxLastTimne = millis();            // timestamp the message

state=TX;

}

switch(state)

{

case TX:

  TXPacket();

   

   break;

case RX:

   

  break;



case LOWPOWER:

  if (debug==true){

    Serial.println("LOW POWER MODE");

  }

  CySysWdtDisable();

  Serial.println();

  Serial.flush();

  lowPowerHandler();

    break;

default:

 

    break;

Radio.IrqProcess( );

}

}

void TXPacket(){

if (AllTXdone==true){

  awakeTime=5;    // All done, go into lowpower and sleep in 5 seconds

  SetAwakeTime();

  state=LOWPOWER;

}

else

{

  if (debug==true){

    Serial.println("Get a TX packet.");

  }

   TXpacketGet();

   if (AllTXdone==false){

    //turnOnRGB(COLOR_SEND,0);

    //turnOnRGB(0x000050,0);// blue help shine through case  

    Radio.Send( (uint8_t *)txpacket,TXsize); // *** remember to change the packet length to send

    TXPacketPrint();

    state=WAIT_TX_DONE;  

   }

}

}

void OnTxDone( void )

{

if (debug==true){

Serial.print("TX done......\r\n");

}

turnOnRGB(0,0);

awakeTime=60; // just stay awake for another 10 seconds to see if any other node joins or transmits

SetAwakeTime();

delay(1000);

Radio.Rx( 0 );

state=RX;

}

void OnTxTimeout( void )

{

delay(1000);

Radio.Sleep();

if (debug==true){

  Serial.print("TX Timeout......");

}

delay(1000);

Radio.Rx( 0 );

state=RX;

}

void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )

{

Rssi=rssi;

rxSize=size;

//turnOnRGB(COLOR_RECEIVED,0);

delay(1000);

Radio.Sleep();

if (rxSize==18){  // found a potential node packet

  memcpy(rxpacket, payload, size );

  if (rxpacket[6]==groupID){ // group ID matches to add the packet to the repeat que

    RXpacketApend();

    RecieveSync=3;  // reset sycn to keep trying for 2 attempts so could lose contact for 3 hours

    SleepTime=20;   // sycned so sleep and wake together every 20 minutes

    awakeTime=10;    // just stay awake for another 10 seconds to see if any other node joins or transmits

    SetAwakeTime();

  }

}

delay(1000);

Radio.Rx( 0 );

state=RX;

}

void TXpacketInsert(){

pointer=1;     // start at position 1 to insert packet length at 0

volts = getBatteryVoltage();

if (debug==true){

  Serial.printf("ChipID:%04X%08X\r\n",(uint32_t)(TXchipID>>32),(uint32_t)TXchipID);

  Serial.printf("Battery:");

  Serial.println((float)volts/1000);

}

SHT30();



byte *aStr = new byte[8];

byte *bStr =  new byte[8];

byte *cStr =  new byte[8];

packetList[pointer]=0; // transmit recieve counter

pointer++;

int64ToChar(aStr, TXchipID);

for (int i=0;i<6;++i) {

  packetList[pointer]=aStr[i];

  pointer++;

}

packetList[pointer]=groupID; // Group ID location 6

pointer++;

packetList[pointer]=action;  // action location 7

pointer++;

int16ToChar(bStr, volts);

for (int i=0;i<2;++i) {

  packetList[pointer]=bStr[i];

  pointer++;

}



floatToChar(cStr,Temp);  // pack in temperature in packet

for (int i=0;i<4;++i) {

  packetList[pointer]=cStr[i];

  pointer++;

}

floatToChar(cStr,Humid);

for (int i=0;i<4;++i) {

  packetList[pointer]=cStr[i];

  pointer++;

}

packetList[pointer]=0; // End terminated ready for appending

packetList[0]=pointer; // put the packet length at the start.

}

void TXpacketGet(){

byte BasePoint=0;

pointer=0;

TXsize=0;

while (packetList[BasePoint+pointer]!=0) {

TXsize=packetList[BasePoint+pointer]-2;

  pointer++;

  if (packetList[BasePoint+pointer]<2){

    packetList[BasePoint+pointer]++;  // increment it as going to transmit this one

   

    pointer++; // incement to point at packet data

    for (int i=0;i<TXsize;++i) {

      txpacket[i]=packetList[BasePoint+pointer];

      pointer++;

    }



    awakeTime=60;    // seconds

    SetAwakeTime();

    return;

  }



BasePoint+=20;

pointer=0;

}

TXsize=0;

if (debug==true){

Serial.println(“Nothing to send”);

}

AllTXdone=true;

delay(1000);

Radio.Rx( 0 );

state=RX;

}

void RXpacketApend(){

byte BasePoint=0;

pointer=0;

while (packetList[BasePoint+pointer]!=0){ // look for end zero

bool match=true;

pointer++; // Now pointing at TX RX count

pointer++; // Now pointing at Data

for (int i=0;i<rxSize;++i) {

if ((packetList[BasePoint+pointer]!=rxpacket[i])&&(i<8)){  // Compare ID's only

  match=false;

}

pointer++;

}

if (match==true) { // packet already in list don’t append just add recieved count and return

if (debug==true){

  Serial.println("RX-packet matched already");

}

packetList[BasePoint+1]++;

return;

}

//BasePoint+=packetList[BasePoint]; // point to start of next packet and test match again

BasePoint+=20;

pointer=0;

}

if (BasePoint+rxSize>254){

Serial.print("Append packet full");

return;        // if buffer full do not append

}

packetList[BasePoint+pointer]= rxSize+2;

pointer++;

packetList[BasePoint+pointer]=0; // transmit recieve counter

pointer++;

for (int i=0;i<rxSize;++i) {// check for matching ID and payload

packetList[BasePoint+pointer]=rxpacket[i];

pointer++;

}

packetList[BasePoint+pointer]=0; // End terminated ready for appending

if (debug==true){

Serial.println("New Packet appended at");

Serial.println( BasePoint);

}

packetList[1]=1; // Send this Device again to confirm new recieved device has it.

}

void TXPacketPrint(){

byte *aStr = new byte[8];

byte *bStr = new byte[8];

byte *cStr = new byte[8];

int pointer =0;

for (int i=0;i<8;++i) { // get Chip ID

aStr[i]=txpacket[pointer];

pointer++;

}

int64_t RXchipID = charTo64bitNum(aStr);

if (debug==true){

Serial.printf("TX-ChipID:%04X%08X\r\n",(uint32_t)(RXchipID>>32),(uint32_t)RXchipID);

}

for (int i=0;i<2;++i) { // get battery voltage from packet

bStr[i]=txpacket[pointer];

pointer++;

}

volts=charTo16bitNum(bStr);

if (debug==true){

Serial.printf(“TX-Battery:”);

Serial.println((float)volts/1000);

}

for (int i=0;i<4;++i) { // get temperature from packet

cStr[i]=txpacket[pointer];

pointer++;

}

Temp= charTofloatNum(cStr);

if (debug==true){

Serial.print("TX-Temperature: ");

Serial.print(Temp);

Serial.write("\xC2\xB0"); //The Degree symbol

Serial.println("C");

}

for (int i=0;i<4;++i) { // get Humidity from packet

cStr[i]=txpacket[pointer];

pointer++;

}

Humid= charTofloatNum(cStr);

if (debug==true){

Serial.print("TX-Humidity   : ");

Serial.print(Humid);

Serial.println("%");

Serial.println("------------------------");

}

}

void onSleep(){

delay(1000);

Radio.Sleep( );

turnOnRGB(0,0);

if (debug==true){

Serial.printf("Going to sleep for %d Minutes....\r\n",SleepTime);

}

Serial.println();

Serial.flush();

state=LOWPOWER;

//TimerStop(&wakeUp);

TimerInit( &wakeUp, onWakeUp );

TimerSetValue( &wakeUp, (SleepTime *60000));

TimerStart( &wakeUp );

}

void SetAwakeTime(){

if (debug==true){

Serial.printf(“Awake for %d Seconds…\r\n”,awakeTime);

}

//TimerStop(&sleep);

TimerSetValue( &sleep, awakeTime*1000);

TimerStart( &sleep );

}

void onWakeUp(){

CommonBoot();

if (debug==true){

Serial.println(“Just Woke Up”);

}

}

void CommonBoot(){

CySysWdtEnable();

//innerWdtEnable(true);

Sensor.Begin();

Serial.begin(115200);

volts = getBatteryVoltage();

if (RecieveSync==0){ // lost sync or no nodes so go into long listen short sleep mode.

SleepTime=constrain(map(volts,3500,3000,2,90),2,90); // sleep for longer to charge from solar

//SleepTime=2;

}

else

{

SleepTime=30; // sycnd , so wake every 30 minutes to exchange data

}

awakeTime=60;

if(RecieveSync>0){

RecieveSync--;

}

TXpacketInsert();

TxLastTimne = millis(); // timestamp the message

TXinterval =20000; //between 2.5 and 7.5 seconds next T

TimerSetValue( &wakeUp, (SleepTime *60000));

TimerInit( &sleep, onSleep );

SetAwakeTime();

delay(1000);

Radio.Rx( 0 );

state=RX;

AllTXdone=false;

if (debug==true){

Serial.println("");

}

TxLastTimne = millis(); // timestamp the message

TXinterval =20000; //between 2.5 and 7.5 seconds next TX

if ((volts)<3000){

BatteryLow=true;

}

if ((volts)>3100){

BatteryLow=false;

}

if (BatteryLow==true){

SleepTime=240; // battery is flat and risks a brownout WDT trigger so sleep for 4 hours to charge

awakeTime=5; // seconds

RecieveSync=0; // no chance we will wake from recharge with sync so wake as lost sync

state=LOWPOWER; // Just go lowpower mode and sleep ASAP

}

}

void SHT30() {

// Vext ON

digitalWrite(Vext, LOW);

delay(500);

Sensor.UpdateData();

if (Humid==0){ // error reading so try again

Sensor.UpdateData();

}

Temp=Sensor.GetTemperature();

if (debug==true){

Serial.print("Temperature: ");

Serial.print(Temp);

Serial.write("\xC2\xB0"); //The Degree symbol

Serial.println("C");

}

Humid=Sensor.GetRelHumidity();

if (debug==true){

Serial.print("Humidity   : ");

Serial.print(Humid);

Serial.println("%");

}

 Wire.end();

 delay(50);

// Vext OFF

digitalWrite(Vext, HIGH);

}

// Service routines…

void int64ToChar(byte a[], int64_t n) {

memcpy(a, &n, 8);

}

void int16ToChar(byte a[], int16_t n) {

memcpy(a, &n, 2);

}

void floatToChar(byte a[], float f) {

memcpy(a, &f, sizeof(float));

}

int64_t charTo64bitNum(byte a[]) {

int64_t n = 0;

memcpy(&n, a, 8);

return n;

}

int16_t charTo16bitNum(byte a[]) {

int16_t n = 0;

memcpy(&n, a, 2);

return n;

}

float charTofloatNum(byte a[]) {

float n = 0;

memcpy(&n, a, sizeof(float));

return n;

}

You can try to check the serial port log. If there is an error, it will print out.

I think it might be lowPowerHandler() not looped through enough or complete, before OnSleep() happens. I have added a longer wake time from 5 seconds to 10 . To see if it solves it. it would be nice to have a way of knowing the lowPowerHandler is complete . like WHILE (lowPowerHandler()==false). I have read that LowPowerHandler has been updated and only needs to called once. But my code needs to call it a few times in the loop. How can i tell what version i am running? I am using Visual Studio code. As i can’t get the github jason for heltec to work with Arduino.

Yes with serial port logging. The problem is lowPowerHandler() stopping the board from going to sleep. and hanging there. So what is the solution?

Just one suggestion. I’ve not had this exact problem, but I did manage to get things working consistently by:

  1. Having everything inside the main loop within one of the cases of the switch statement (this may not be critical, but it may help you structure things the right way);
  2. Having the call to the lowPowerHandler() as the only code in the LOWPOWER case (other than the break statement).

The lowPowerHandler() (used to?) cycles around several times waiting for tasks to finish, but I found that if you do anything else within the LOWPOWER case, other than call the lowPowerHandler(), things can end up not working as you might expect. Any sort of Serial output there can be problematic because even trivial stuff is time consuming (in a relative sense).

So, maybe see if you can restructure your code to do those other things you currently have in the LOWPOWER case before you actually set the state to LOWPOWER and pass through the loop to call the lowPowerHandler().

(Another tip: You should be able to include all of your code, when posting on a forum, in a single scrollable box by selecting it and marking it as ‘Preformated Text’ (the little </> icon up on the menu bar).)

1 Like

Program still locked up after tidying up the code so everything is done before low power mode. I have now moved Radio.IrqProcess( ); out of the loop so they are procced all other states apart form LOWPOWER state. And on test now. Really running out of ideas now. Can some one post a simple working version of pingpong that sleeps and wakes? So i can build my code from that.

#include “LoRaWan_APP.h”

#include "Arduino.h"

#include "time.h"

#include <Wire.h>

#include <string.h>

#include "SHT3x.h"

#ifdef __asr650x__

#include "innerWdt.h"

#endif

/*

 * For asr650x, the max feed time is 2.8 seconds.

 * For asr6601, the max feed time is 24 seconds.

 */

#ifdef __asr650x__

#define MAX_FEEDTIME 2800// ms // was 2800

#else

#define MAX_FEEDTIME 24000// ms

#endif

SHT3x Sensor;

#ifndef LoraWan_RGB

#define LoraWan_RGB = 0    //set both to 1 for led to work

#endif

#define RF_FREQUENCY                                868000000 // Hz

#define TX_OUTPUT_POWER                             5        // dBm // WAS 5

#define LORA_BANDWIDTH                              0         // [0: 125 kHz,

                                                              //  1: 250 kHz,

                                                              //  2: 500 kHz,

                                                              //  3: Reserved]

#define LORA_SPREADING_FACTOR                       7        // [SF7..SF12]

#define LORA_CODINGRATE                             1         // [1: 4/5,

                                                              //  2: 4/6,

                                                              //  3: 4/7,

                                                              //  4: 4/8]

#define LORA_PREAMBLE_LENGTH                        8         // Same for Tx and Rx

#define LORA_SYMBOL_TIMEOUT                         0         // Symbols

#define LORA_FIX_LENGTH_PAYLOAD_ON                  false

#define LORA_IQ_INVERSION_ON                        false

#define RX_TIMEOUT_VALUE                            900

#define BUFFER_SIZE                                 255 // Define the payload size here

uint64_t TxLastTime ;         // timestamp last TX

uint64_t TXinterval= 15000;   // time until next TX

uint64_t ThisAwake;           // time spent awake

byte txpacket[BUFFER_SIZE];

byte rxpacket[BUFFER_SIZE];

bool AllTXdone =false;

byte packetList[255];                            // store packets

byte pointer;

float Temp=0;

float Humid=0;

byte TXsize=0;

uint64_t TXchipID=getID();

byte groupID =0;    // set group ID to your mesh group. Only matching ID nodes will repeat

byte action =1;   // Action 0 is following bytes are Voltage, Temperature,Humidity values

uint16_t volts;

int SleepTime ;  //minutes to sleep

int awakeTime ;   //second

byte RecieveSync=0; //

static TimerEvent_t sleep;

static TimerEvent_t wakeUp;

bool BatteryLow;

bool debug=false;      ///**** debug with print statements

RadioEvents_t RadioEvents;

void OnTxDone( void );

void OnTxTimeout( void );

void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );

typedef enum

{

    WAIT_TX_DONE,

    LOWPOWER,

    RX,

    SLEEP_NOW,

    TX

}States_t;

int16_t txNumber;

States_t state;

bool sleepMode = false;

int16_t Rssi,rxSize;

void setup() {

    boardInitMcu( );

    CommonBoot();

    RadioEvents.TxDone = OnTxDone;

    RadioEvents.TxTimeout = OnTxTimeout;

    RadioEvents.RxDone = OnRxDone;

    Radio.Init( &RadioEvents );

   

    Radio.SetChannel( RF_FREQUENCY );

    Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,

                                   LORA_SPREADING_FACTOR, LORA_CODINGRATE,

                                   LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,

                                   true, 0, 0, LORA_IQ_INVERSION_ON, 3000 );

    Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,

                                   LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,

                                   LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,

                                   0, true, 0, 0, LORA_IQ_INVERSION_ON, true );

     Radio.SetSyncWord(0xF2);  

    if (debug==true){

      Serial.println(MAX_FEEDTIME);

      Serial.println("Booting from SetUp");

    }                      

  delay(1000);

  Radio.Rx( 0 );

  state=RX;

  TimerInit( &sleep, onSleep );

  TimerInit( &wakeUp, onWakeUp );

   

}

void loop()

{

  //feedInnerWdt();   // feed watchdog timer

  if ((millis() - TxLastTime> TXinterval)&&(AllTXdone==false)){

    TxLastTime = millis();            // timestamp the message

    state=TX;

  }

  switch(state)

  {

   

    case TX:

      TXPacket();

      Radio.IrqProcess( );  

       break;

    case RX:

     Radio.IrqProcess( );      

      break;

    case WAIT_TX_DONE:

      Radio.IrqProcess( );  

      break;

    case LOWPOWER:

   

      lowPowerHandler();

        break;

    default:

      Radio.IrqProcess( );    

        break;

   

  }

   

}

void TXPacket(){

    if (AllTXdone==true){

      awakeTime=10;    // All done, go into lowpower and sleep in 10 seconds

      SetAwakeTime();

      if (debug==true){

      Serial.printf("And then Sleep for %d Minutes..\r\n",SleepTime);

    }

      delay(1000);

      Radio.Rx(0);

      turnOnRGB(0,0);

      Serial.println();

      Serial.flush();

      state=LOWPOWER;

    }

    else

    {

      if (debug==true){

        Serial.println("Get a TX packet.");

      }

       TXpacketGet();

       if (AllTXdone==false){

        //turnOnRGB(COLOR_SEND,0);

        //turnOnRGB(0x000050,0);// blue help shine through case  

        Radio.Send( (uint8_t *)txpacket,TXsize); // *** remember to change the packet length to send

        if (debug==true){

        TXPacketPrint();

       }

        state=WAIT_TX_DONE;  

       }

    }

}

void OnTxDone( void )

{

 

  if (debug==true){

    Serial.print("TX done......\r\n");

  }

  turnOnRGB(0,0);

  awakeTime=20;    // just stay awake for another 20  seconds to see if any other node joins or transmits

  SetAwakeTime();

  delay(1000);

  Radio.Rx( 0 );

  state=RX;

   

}

void OnTxTimeout( void )

{

    delay(1000);

    Radio.Sleep();

    if (debug==true){

      Serial.print("TX Timeout......");

    }

    delay(1000);

    Radio.Rx( 0 );

    state=RX;

}

void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )

{

    Rssi=rssi;

    rxSize=size;

    //turnOnRGB(COLOR_RECEIVED,0);

   

    if (rxSize==18){  // found a potential node packet

      memcpy(rxpacket, payload, size );

      if (rxpacket[6]==groupID){ // group ID matches to add the packet to the repeat que

        RXpacketApend();

        RecieveSync=3;  // reset sycn to keep trying for 2 attempts so could lose contact for 3 hours

        SleepTime=20;   // sycned so sleep and wake together every 20 minutes

        awakeTime=20;    // just stay awake for another 30 seconds to see if any other node joins or transmits

        SetAwakeTime();

      }

    }

  delay(1000);

  Radio.Rx( 0 );

  state=RX;  

}

void TXpacketInsert(){

    pointer=1;     // start at position 1 to insert packet length at 0

    volts = getBatteryVoltage();

    if (debug==true){

      Serial.printf("ChipID:%04X%08X\r\n",(uint32_t)(TXchipID>>32),(uint32_t)TXchipID);

      Serial.printf("Battery:");

      Serial.println((float)volts/1000);

    }

     SHT30();

   

    byte *aStr = new byte[8];

    byte *bStr =  new byte[8];

    byte *cStr =  new byte[8];

    packetList[pointer]=0; // transmit recieve counter

    pointer++;

    int64ToChar(aStr, TXchipID);

    for (int i=0;i<6;++i) {

      packetList[pointer]=aStr[i];

      pointer++;

    }

    packetList[pointer]=groupID; // Group ID location 6

    pointer++;

    packetList[pointer]=action;  // action location 7

    pointer++;

    int16ToChar(bStr, volts);

    for (int i=0;i<2;++i) {

      packetList[pointer]=bStr[i];

      pointer++;

    }

   

    floatToChar(cStr,Temp);  // pack in temperature in packet

    for (int i=0;i<4;++i) {

      packetList[pointer]=cStr[i];

      pointer++;

    }

    floatToChar(cStr,Humid);

    for (int i=0;i<4;++i) {

      packetList[pointer]=cStr[i];

      pointer++;

    }

  packetList[pointer]=0;   // End terminated ready for appending

  packetList[0]=pointer;  // put the packet length at the start.

}

void TXpacketGet(){

  byte BasePoint=0;

  pointer=0;

  TXsize=0;

  while (packetList[BasePoint+pointer]!=0)  {

   

    TXsize=packetList[BasePoint+pointer]-2;

      pointer++;

      if (packetList[BasePoint+pointer]<2){

        packetList[BasePoint+pointer]++;  // increment it as going to transmit this one

       

        pointer++; // incement to point at packet data

        for (int i=0;i<TXsize;++i) {

          txpacket[i]=packetList[BasePoint+pointer];

          pointer++;

        }

   

        awakeTime=60;    // seconds

        SetAwakeTime();

        return;

      }

   

    BasePoint+=20;

    pointer=0;

  }

TXsize=0;

 if (debug==true){

  Serial.println("Nothing to send");

 }

 AllTXdone=true;

}

void RXpacketApend(){

  byte BasePoint=0;

  pointer=0;

  while (packetList[BasePoint+pointer]!=0){  // look for end zero

 

  bool match=true;

  pointer++; // Now pointing at TX RX count

  pointer++; // Now pointing at Data

  for (int i=0;i<rxSize;++i) {

    if ((packetList[BasePoint+pointer]!=rxpacket[i])&&(i<8)){  // Compare ID's only

      match=false;

    }

    pointer++;

  }

   if (match==true) {                    // packet already in list don't append just add recieved count and return

    if (debug==true){

      Serial.println("RX-packet matched already");

    }

    packetList[BasePoint+1]++;

    return;

   }

 

  //BasePoint+=packetList[BasePoint]; // point to start of next packet and test match again

  BasePoint+=20;

  pointer=0;

  }

  if (BasePoint+rxSize>254){

    Serial.print("Append packet full");

    return;        // if buffer full do not append

  }

  packetList[BasePoint+pointer]= rxSize+2;

  pointer++;

  packetList[BasePoint+pointer]=0; // transmit recieve counter

  pointer++;

  for (int i=0;i<rxSize;++i) {// check for matching ID and payload

    packetList[BasePoint+pointer]=rxpacket[i];

    pointer++;

  }

  packetList[BasePoint+pointer]=0;   // End terminated ready for appending

  if (debug==true){

    Serial.println("New Packet appended at");

    Serial.println( BasePoint);

  }

  packetList[1]=1; // Send this Device packet again to forward it and to confirm it from sender

}

void TXPacketPrint(){

  byte *aStr =  new byte[8];

  byte *bStr =  new byte[8];

  byte *cStr =  new byte[8];

  int pointer =0;

   

  for (int i=0;i<8;++i) {   // get Chip ID

    aStr[i]=txpacket[pointer];

    pointer++;

  }

  int64_t RXchipID = charTo64bitNum(aStr);

  Serial.printf("TX-ChipID:%04X%08X\r\n",(uint32_t)(RXchipID>>32),(uint32_t)RXchipID);

 

  for (int i=0;i<2;++i) {   // get battery voltage from packet

    bStr[i]=txpacket[pointer];

    pointer++;

  }

  volts=charTo16bitNum(bStr);

  Serial.printf("TX-Battery:");

  Serial.println((float)volts/1000);

   for (int i=0;i<4;++i) {      // get temperature from packet

    cStr[i]=txpacket[pointer];

    pointer++;

  }

    Temp= charTofloatNum(cStr);

    Serial.print("TX-Temperature: ");

    Serial.print(Temp);

    Serial.write("\xC2\xB0"); //The Degree symbol

    Serial.println("C");

  for (int i=0;i<4;++i) {    // get Humidity from packet

    cStr[i]=txpacket[pointer];

    pointer++;

  }

 

    Humid= charTofloatNum(cStr);

    Serial.print("TX-Humidity   : ");

    Serial.print(Humid);

    Serial.println("%");

    Serial.println("------------------------");

}

void onSleep(){

 

TimerSetValue( &wakeUp, (SleepTime *60000));

TimerStart( &wakeUp );  

        

}

void SetSleepTime(){

if (debug==true){

  Serial.printf("Sleep for %d Minutes..\r\n",SleepTime);

}

 

  TimerSetValue( &wakeUp, (SleepTime *60000));

  TimerStart( &wakeUp );  

}

 

void SetAwakeTime(){

if (debug==true){

  Serial.printf("Awake for %d Seconds..\r\n",awakeTime);

}

 

//TimerStop(&sleep);

TimerSetValue( &sleep, awakeTime*1000);

TimerStart( &sleep );

}

void onWakeUp(){

  if (debug==true){

  Serial.println("Wake from sleep");

  }

 

  CommonBoot();

   

  delay(1000);

  Radio.Rx( 0 );

  state=RX;

 

}

 

void  CommonBoot(){

//CySysWdtEnable();

//innerWdtEnable(true);

Sensor.Begin();

Serial.begin(115200);

volts = getBatteryVoltage();

if (RecieveSync==0){  // lost sync or no nodes so go into long listen short sleep mode.

    SleepTime=constrain(map(volts,3700,3000,2,30),2,30); // sleep for longer to charge from solar

  }

  else

  {

   SleepTime=30;    // sycnd , so wake every 30 minutes to exchange  data

  }

 

  if(RecieveSync>0){

    RecieveSync--;

  }

 

  TXpacketInsert();

  TxLastTime = millis();            // timestamp the message

 

  awakeTime=60;

  AllTXdone=false;

 

  if (debug==true){

    Serial.println("");

  }

 

  if ((volts)<3000){

    BatteryLow=true;

  }

if ((volts)>3100){

    BatteryLow=false;

  }

  if (BatteryLow==true){

   SleepTime=240;    // battery is flat and risks a brownout WDT trigger so sleep for 4 hours to charge

   awakeTime=10;    // seconds

   RecieveSync=0; // no chance we will wake from recharge with sync so wake as lost sync

   state=LOWPOWER; // Just go lowpower mode and sleep ASAP

  AllTXdone=true;  // Don't even bother looking to TX anything.

  }

  SetAwakeTime();

}

void SHT30() {

  // Vext ON

    digitalWrite(Vext, LOW);

    delay(500);

  Sensor.UpdateData();

  if (Humid==0){        // error reading so try again

   Sensor.UpdateData();

  }

if (Humid==0){        // error reading third time lucky

   Sensor.UpdateData();

  }

 

  Temp=Sensor.GetTemperature();

  if (debug==true){

    Serial.print("Temperature: ");

    Serial.print(Temp);

    Serial.write("\xC2\xB0"); //The Degree symbol

    Serial.println("C");

  }

  Humid=Sensor.GetRelHumidity();

  if (debug==true){

    Serial.print("Humidity   : ");

    Serial.print(Humid);

    Serial.println("%");

  }

   

     Wire.end();

     delay(50);

   // Vext OFF

    digitalWrite(Vext, HIGH);

}

// Service routines.......................................................................................

void int64ToChar(byte a[], int64_t n) {

  memcpy(a, &n, 8);

}

void int16ToChar(byte a[], int16_t n) {

  memcpy(a, &n, 2);

}

void floatToChar(byte a[], float f) {

  memcpy(a, &f, sizeof(float));

}

int64_t charTo64bitNum(byte a[]) {

  int64_t n = 0;

  memcpy(&n, a, 8);

  return n;

}

int16_t charTo16bitNum(byte a[]) {

  int16_t n = 0;

  memcpy(&n, a, 2);

  return n;

}

float charTofloatNum(byte a[]) {

  float n = 0;

  memcpy(&n, a, sizeof(float));

  return n;

}`Preformatted text`

Update: moving Radio.IrqProcess(); did not solve the lock up and seemed to make it happen earlier. Coming from ESP32’s , I have never had such a problem that seems to happen every time but after a random time. With a program that is just looping through the same code over and over. Which just got me thinking. random crashing? So i added print statements to see if the program stopped in random sections of code. But it actually stops a certain part of my code every time. Just about here
byte *aStr = new byte[8];
byte *bStr = new byte[8];
byte *cStr = new byte[8];
Normally i just allocate memory with byte aStr[8]={0};
But instead this time i copied the above code from a ESP32 example without understanding what ‘new’ does.
So knowing my code freezes here. I investigated what new does and it allocates a fresh dynamic array on the heap.And that i am supposed to un-allocate it when done.So i guess the heap was getting bigger and bigger until it broke the code. Testing updating code over night, and hopefully it will still be running in the morning.

Yeah, similar problem here. I had to develop a separate code base (from the ESPs) for the ASR processors when I started working with them, but the low power characteristics and integrated solar power management of the ASR/CubeCell were enough to make the effort worthwhile at the time. The game changes quickly though and the new ESP32-S3s claim to have improved low power characteristics, so we’ll see how they go.

After using code below, the code is now worked over night without crashing.
Next I will add code to my second cubcell and leave them outside to see if they can maintain connection in the winter sun and low temperatures.
Solar cubcells are out of stock for my region at the moment.
So can’t test the mesh repeater functionality i have built into my code.
I have a couple of TTGO esp32 lora modules which i will code to replicate the cubcell operation
to test the mesh capability
Next i will add capability for other of the range of sensors.

indent preformatted text by 4 spaces
#include “LoRaWan_APP.h”

#include "Arduino.h"

#include "time.h"

#include <Wire.h>

#include <string.h>

#include "SHT3x.h"

#ifdef __asr650x__

#include "innerWdt.h"

#endif

/*

 * For asr650x, the max feed time is 2.8 seconds.

 * For asr6601, the max feed time is 24 seconds.

 */

#ifdef __asr650x__

#define MAX_FEEDTIME 2800// ms // was 2800

#else

#define MAX_FEEDTIME 24000// ms

#endif

SHT3x Sensor;

#ifndef LoraWan_RGB

#define LoraWan_RGB = 0    //set both to 1 for led to work

#endif

#define RF_FREQUENCY                                868000000 // Hz

#define TX_OUTPUT_POWER                             5        // dBm // WAS 5

#define LORA_BANDWIDTH                              0         // [0: 125 kHz,

                                                              //  1: 250 kHz,

                                                              //  2: 500 kHz,

                                                              //  3: Reserved]

#define LORA_SPREADING_FACTOR                       7        // [SF7..SF12]

#define LORA_CODINGRATE                             1         // [1: 4/5,

                                                              //  2: 4/6,

                                                              //  3: 4/7,

                                                              //  4: 4/8]

#define LORA_PREAMBLE_LENGTH                        8         // Same for Tx and Rx

#define LORA_SYMBOL_TIMEOUT                         0         // Symbols

#define LORA_FIX_LENGTH_PAYLOAD_ON                  false

#define LORA_IQ_INVERSION_ON                        false

#define RX_TIMEOUT_VALUE                            900

#define BUFFER_SIZE                                 255 // Define the payload size here

uint64_t TxLastTime ;         // timestamp last TX

uint64_t TXinterval= 15000;   // time until next TX

uint64_t ThisAwake;           // time spent awake

byte txpacket[BUFFER_SIZE];

byte rxpacket[BUFFER_SIZE];

bool AllTXdone =false;

byte packetList[255];                            // store packets

byte pointer;

float Temp=0;

float Humid=0;

byte TXsize=0;

uint64_t TXchipID=getID();

byte groupID =0;    // set group ID to your mesh group. Only matching ID nodes will repeat

byte action =1;   // Action 0 is following bytes are Voltage, Temperature,Humidity values

uint16_t volts;

int SleepTime ;  //minutes to sleep

int awakeTime ;   //second

byte RecieveSync=0; //

static TimerEvent_t sleep;

static TimerEvent_t wakeUp;

bool BatteryLow;

bool debug=true;      ///**** debug with print statements

RadioEvents_t RadioEvents;

void OnTxDone( void );

void OnTxTimeout( void );

void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );

typedef enum

{

    WAIT_TX_DONE,

    LOWPOWER,

    RX,

    SLEEP_NOW,

    TX

}States_t;

int16_t txNumber;

States_t state;

bool sleepMode = false;

int16_t Rssi,rxSize;

void setup() {

    boardInitMcu( );

    CommonBoot();

    RadioEvents.TxDone = OnTxDone;

    RadioEvents.TxTimeout = OnTxTimeout;

    RadioEvents.RxDone = OnRxDone;

    Radio.Init( &RadioEvents );

   

    Radio.SetChannel( RF_FREQUENCY );

    Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,

                                   LORA_SPREADING_FACTOR, LORA_CODINGRATE,

                                   LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,

                                   true, 0, 0, LORA_IQ_INVERSION_ON, 3000 );

    Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,

                                   LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,

                                   LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,

                                   0, true, 0, 0, LORA_IQ_INVERSION_ON, true );

     Radio.SetSyncWord(0xF2);  

    if (debug==true){

      Serial.println(MAX_FEEDTIME);

      Serial.println("Booting from SetUp");

    }                      

  delay(1000);

  Radio.Rx( 0 );

  state=RX;

  TimerInit( &sleep, onSleep );

  TimerInit( &wakeUp, onWakeUp );

   

}

void loop()

{

  //feedInnerWdt();   // feed watchdog timer

  if ((millis() - TxLastTime> TXinterval)&&(AllTXdone==false)){  

    TxLastTime = millis();            // timestamp the message

    state=TX;

  }

  switch(state)

  {

   

    case TX:

      TXPacket();

       

       break;

    case RX:

       

      break;

    case WAIT_TX_DONE:

       

      break;

    case LOWPOWER:

   

      lowPowerHandler();

        break;

    default:

       

        break;

   Radio.IrqProcess( );

  }

   

}

void TXPacket(){

    if (AllTXdone==true){

      awakeTime=10;    // All done, go into lowpower and sleep in 10 seconds

      SetAwakeTime();

      if (debug==true){

      Serial.printf("And then Sleep for %d Minutes..\r\n",SleepTime);

    }

      delay(1000);

      Radio.Rx(0);

      turnOnRGB(0,0);

      Serial.println();

      Serial.flush();

      state=LOWPOWER;

    }

    else

    {

      if (debug==true){

        Serial.println("Get a TX packet.");

      }

       TXpacketGet();

       if (AllTXdone==false){

        //turnOnRGB(COLOR_SEND,0);

        //turnOnRGB(0x000050,0);// blue help shine through case  

        Radio.Send( (uint8_t *)txpacket,18); // *** packet length is 18

        if (debug==true){

        TXPacketPrint();

       }

        state=WAIT_TX_DONE;  

       }

    }

}

void OnTxDone( void )

{

 

  if (debug==true){

    Serial.print("TX done......\r\n");

  }

  turnOnRGB(0,0);

  awakeTime=20;    // just stay awake for another 20  seconds to see if any other node joins or transmits

  SetAwakeTime();

  Radio.Rx( 0 );

  state=RX;  

     

}

void OnTxTimeout( void )

{

    Radio.Sleep();

    if (debug==true){

      Serial.print("TX Timeout......");

    }

    delay(1000);

    Radio.Rx( 0 );

    state=RX;

}

void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )

{

    Rssi=rssi;

    rxSize=size;

    //turnOnRGB(COLOR_RECEIVED,0);

   

    if (rxSize==18){  // found a potential node packet

      memcpy(rxpacket, payload, size );

      if (rxpacket[6]==groupID){ // group ID matches to add the packet to the repeat que

        RXpacketApend();

        RecieveSync=3;  // reset sycn to keep trying for 2 attempts so could lose contact for 3 hours

        SleepTime=20;   // sycned so sleep and wake together every 20 minutes

        awakeTime=20;    // just stay awake for another 20 seconds to see if any other node joins or transmits

        SetAwakeTime();

      }

    }

  Radio.Sleep( );

  delay(1000);

  Radio.Rx( 0 );

  state=RX;  

}

void TXpacketInsert(){

    pointer=1;     // start at position 1 to insert packet length at 0

    volts = getBatteryVoltage();

    if (debug==true){

      Serial.printf("ChipID:%04X%08X\r\n",(uint32_t)(TXchipID>>32),(uint32_t)TXchipID);

      Serial.printf("Battery:");

      Serial.println((float)volts/1000);

    }

     SHT30();

   

    byte aStr[8]={0};

    byte bStr[8]={0};

    byte cStr[8]={0};

    packetList[pointer]=0; // transmit recieve counter

    pointer++;

    int64ToChar(aStr, TXchipID);

    for (int i=0;i<6;++i) {

      packetList[pointer]=aStr[i];

      pointer++;

    }

    packetList[pointer]=groupID; // Group ID location 6

    pointer++;

    packetList[pointer]=action;  // action location 7

    pointer++;

    int16ToChar(bStr, volts);

    for (int i=0;i<2;++i) {

      packetList[pointer]=bStr[i];

      pointer++;

    }

   

    floatToChar(cStr,Temp);  // pack in temperature in packet

    for (int i=0;i<4;++i) {

      packetList[pointer]=cStr[i];

      pointer++;

    }

    floatToChar(cStr,Humid);

    for (int i=0;i<4;++i) {

      packetList[pointer]=cStr[i];

      pointer++;

    }

  packetList[pointer]=0;   // End terminated ready for appending

  packetList[0]=pointer;  // put the packet length at the start.

  if (debug==true){

  Serial.println("Packet insert OK");

 }

 

}

void TXpacketGet(){

  byte BasePoint=0;

  pointer=0;

  TXsize=0;

  while (packetList[BasePoint+pointer]!=0)  {

   

    TXsize=packetList[BasePoint+pointer]-2;

      pointer++;

      if (packetList[BasePoint+pointer]<2){

        packetList[BasePoint+pointer]++;  // increment it as going to transmit this one

       

        pointer++; // incement to point at packet data

        for (int i=0;i<TXsize;++i) {

          txpacket[i]=packetList[BasePoint+pointer];

          pointer++;

        }

   

        awakeTime=60;    // seconds

        SetAwakeTime();

        return;

      }

   

    BasePoint+=20;

    pointer=0;

  }

TXsize=0;

 if (debug==true){

  Serial.println("Nothing to send");

 }

 AllTXdone=true;

}

void RXpacketApend(){

  byte BasePoint=0;

  pointer=0;

  while (packetList[BasePoint+pointer]!=0){  // look for end zero

 

  bool match=true;

  pointer++; // Now pointing at TX RX count

  pointer++; // Now pointing at Data

  for (int i=0;i<rxSize;++i) {

    if ((packetList[BasePoint+pointer]!=rxpacket[i])&&(i<8)){  // Compare ID's only

      match=false;

    }

    pointer++;

  }

   if (match==true) {                    // packet already in list don't append just add recieved count and return

    if (debug==true){

      Serial.println("RX-packet matched already");

    }

    packetList[BasePoint+1]++;

    return;

   }

 

  //BasePoint+=packetList[BasePoint]; // point to start of next packet and test match again

  BasePoint+=20;

  pointer=0;

  }

  if (BasePoint+rxSize>254){

    Serial.print("Append packet full");

    return;        // if buffer full do not append

  }

  packetList[BasePoint+pointer]= rxSize+2;

  pointer++;

  packetList[BasePoint+pointer]=0; // transmit recieve counter

  pointer++;

  for (int i=0;i<rxSize;++i) {// check for matching ID and payload

    packetList[BasePoint+pointer]=rxpacket[i];

    pointer++;

  }

  packetList[BasePoint+pointer]=0;   // End terminated ready for appending

  if (debug==true){

    Serial.println("New Packet appended at");

    Serial.println( BasePoint);

  }

  packetList[1]=1; // Send this Device packet again to forward it and to confirm it from sender

}

void TXPacketPrint(){

  byte aStr [8]={0};

  byte bStr [8]={0};

  byte cStr [8]={0};

  int pointer =0;

   

  for (int i=0;i<8;++i) {   // get Chip ID

    aStr[i]=txpacket[pointer];

    pointer++;

  }

  int64_t RXchipID = charTo64bitNum(aStr);

  Serial.printf("TX-ChipID:%04X%08X\r\n",(uint32_t)(RXchipID>>32),(uint32_t)RXchipID);

 

  for (int i=0;i<2;++i) {   // get battery voltage from packet

    bStr[i]=txpacket[pointer];

    pointer++;

  }

  volts=charTo16bitNum(bStr);

  Serial.printf("TX-Battery:");

  Serial.println((float)volts/1000);

   for (int i=0;i<4;++i) {      // get temperature from packet

    cStr[i]=txpacket[pointer];

    pointer++;

  }

    Temp= charTofloatNum(cStr);

    Serial.print("TX-Temperature: ");

    Serial.print(Temp);

    Serial.write("\xC2\xB0"); //The Degree symbol

    Serial.println("C");

  for (int i=0;i<4;++i) {    // get Humidity from packet

    cStr[i]=txpacket[pointer];

    pointer++;

  }

 

    Humid= charTofloatNum(cStr);

    Serial.print("TX-Humidity   : ");

    Serial.print(Humid);

    Serial.println("%");

    Serial.println("------------------------");

}

void onSleep(){

 

TimerSetValue( &wakeUp, (SleepTime *60000));

TimerStart( &wakeUp );  

        

}

void SetSleepTime(){

if (debug==true){

  Serial.printf("Sleep for %d Minutes..\r\n",SleepTime);

}

 

  TimerSetValue( &wakeUp, (SleepTime *60000));

  TimerStart( &wakeUp );  

}

 

void SetAwakeTime(){

if (debug==true){

  Serial.printf("Awake for %d Seconds..\r\n",awakeTime);

}

 

//TimerStop(&sleep);

TimerSetValue( &sleep, awakeTime*1000);

TimerStart( &sleep );

}

void onWakeUp(){

  if (debug==true){

  Serial.println("Wake from sleep");

  }

 

  CommonBoot();

   

  delay(1000);

  Radio.Rx( 0 );

  state=RX;

 

}

 

void  CommonBoot(){

//CySysWdtEnable();

//innerWdtEnable(true);

Sensor.Begin();

Serial.begin(115200);

volts = getBatteryVoltage();

if (RecieveSync==0){  // lost sync or no nodes so go into long listen short sleep mode.

    SleepTime=constrain(map(volts,3700,3000,2,90),2,90); // sleep for longer to charge from solar

  }

  else

  {

   SleepTime=30;    // sycnd , so wake every 30 minutes to exchange  data

  }

 

  if(RecieveSync>0){

    RecieveSync--;

  }

 

  TXpacketInsert();

  TxLastTime = millis();            // timestamp the message

 

  awakeTime=60;

  AllTXdone=false;

 

  if (debug==true){

    Serial.println("");

  }

 

  if ((volts)<3000){

    BatteryLow=true;

  }

if ((volts)>3100){

    BatteryLow=false;

  }

  if (BatteryLow==true){

   SleepTime=240;    // battery is flat and risks a brownout WDT trigger so sleep for 4 hours to charge

   awakeTime=10;    // seconds

   RecieveSync=0; // no chance we will wake from recharge with sync so wake as lost sync

   state=LOWPOWER; // Just go lowpower mode and sleep ASAP

  AllTXdone=true;  // Don't even bother looking to TX anything.

  }

  SetAwakeTime();

if (debug==true){

  Serial.println("Common Boot OK");

 }

}

void SHT30() {

  // Vext ON

    digitalWrite(Vext, LOW);

    delay(500);

  Sensor.UpdateData();

  if (Humid==0){        // error reading so try again

   Sensor.UpdateData();

  }

if (Humid==0){        // error reading third time lucky

   Sensor.UpdateData();

  }

 

  Temp=Sensor.GetTemperature();

  if (debug==true){

    Serial.print("Temperature: ");

    Serial.print(Temp);

    Serial.write("\xC2\xB0"); //The Degree symbol

    Serial.println("C");

  }

  Humid=Sensor.GetRelHumidity();

  if (debug==true){

    Serial.print("Humidity   : ");

    Serial.print(Humid);

    Serial.println("%");

  }

   

     Wire.end();

     delay(50);

   // Vext OFF

    digitalWrite(Vext, HIGH);

}

// Service routines.......................................................................................

void int64ToChar(byte a[], int64_t n) {

  memcpy(a, &n, 8);

}

void int16ToChar(byte a[], int16_t n) {

  memcpy(a, &n, 2);

}

void floatToChar(byte a[], float f) {

  memcpy(a, &f, sizeof(float));

}

int64_t charTo64bitNum(byte a[]) {

  int64_t n = 0;

  memcpy(&n, a, 8);

  return n;

}

int16_t charTo16bitNum(byte a[]) {

  int16_t n = 0;

  memcpy(&n, a, 2);

  return n;

}

float charTofloatNum(byte a[]) {

  float n = 0;

  memcpy(&n, a, sizeof(float));

  return n;

}