Part of a structured data set won't transmit between 2 RFM69

I need some help sending structured data over RFM69 between 2 nanos w the receiver being an iot 33. With my first several projects using RFM69 radios I did everything by passing strings which was a pain esp since most of my data is usually numbers. After seeing the structured data examples I was excited to incorporate it into my projects as a huge improvement. I'm having trouble sending data between 2 radios - a weather station and inside receiver. Part of the data in a structured set arrives fine and the other part does not. The part that is received correctly is read from mcp9808 sensor for the temp and I track the daily high and low temps in the nano's eeprom. I also collect rain data with rain event and year total and all that comes over without a hitch. Out at the weather station other data is read over a serial link from a pool based nano and includes a pool temp sensor and a water level (wet or dry) and a sump pump (has run?) alert. The RFM69 is driven by the weather sta nano. I can see the pool data is read accurately over the serial at weather nano but when I send it inside only the weather data arrives. The pool data is absent despite being in the same structure. Originally the structured data set was mixed with float, int, and bool data but I've changed it all to int data w/o success. Both nanos use sizeof(int) =4. I've changed the way I parse the data off the serial link many times w/o change. I've stored the serial data in local variables and then used those to pass the data into the structured data set and none of these modifications changes the situation. My most recent change is to move to the int16_t data type - same result. I've even changed the order of the structured variables ... but Weather.pooltemp is always zero even if I "hardwire" a value as a test.

I am using the low power labs RFM69 library and structured data send/receive examples as prototype.


#include <RFM69.h>
#include <RFM69registers.h>
#include <RFM69_ATC.h>
#include <RFM69_OTA.h>
#include <SPI.h>

#define NETWORKID     19   // Must be the same for all nodes
#define MYNODEID      2   // My node ID
#define StationID     10   // Destination node ID

#define FREQUENCY     RF69_915MHZ
#define ENCRYPT       false // Set to "true" to use encryption
#define USEACK        false // Request ACKs or not
RFM69 radio;

//#include <Adafruit_LEDBackpack.h>
#include <Adafruit_MCP9808.h>
Adafruit_MCP9808 MCP9808 = Adafruit_MCP9808();
#include <EEPROM.h>

#define switchPin 8
#define EventDuration 64800000
#define ReportInterval 30000

bool RainSwitch;
bool NewEvent;
bool WriteData;
int Addrs;
unsigned int RainCountEvent;
unsigned int RainCountTotal;
unsigned long RainCountTime;
unsigned long ReportTime;
unsigned long Hightime, Lowtime;

float tmpflt, RainCountConversion = 0.01;
float High, Low, flttmp;
String rx_str;

unsigned long DisplayTime;

typedef struct {
  int16_t         airtemp;
  int16_t         event;
  int16_t         total;
  int16_t         high;
  int16_t         low;
  int16_t         pooltemp; 
  int16_t         poolfull;
  int16_t         pump; 
} DataStructure;

DataStructure Weather;

//Adafruit_7segment matrix = Adafruit_7segment();

void(* resetFunc) (void) = 0;
void setup() {

  Serial.begin(9600);
   
  pinMode(switchPin,INPUT_PULLUP);
  
  if (!MCP9808.begin(0x18)) {
    Serial.println("Couldn't find MCP9808! Check your connections and verify the address is correct.");
    //while (1);
  }
    MCP9808.setResolution(3); 
   
// Use this code to reset the eeprom 
/*Addrs = 0;
EEPROM.put(Addrs,0);
Addrs += sizeof(int);
EEPROM.put(Addrs,180);
//EEPROM.put(10,0);
//EEPROM.put(15,0);

*/
Addrs=0;
//Serial.println(EEPROM.get(Addrs,RainCountEvent));
//Addrs = sizeof(int);
//Serial.println(EEPROM.get(Addrs,RainCountTotal));

EEPROM.get(Addrs,RainCountEvent);
Addrs = sizeof(int);
EEPROM.get(Addrs,RainCountTotal);

//Serial.print("EEPROM RainCountEvent: ");Serial.print(RainCountEvent);Serial.print("      EEPROM RainCountTotal: ");Serial.print(RainCountTotal);Serial.println();
/*  matrix.begin(0x70);
  
  matrix.print(8888);
  matrix.writeDisplay();
  delay(1000);
  matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0);matrix.writeDigitRaw(2,0);matrix.writeDigitRaw(3,0); matrix.writeDigitRaw(4,0);
  matrix.writeDisplay();
*/
    Low = 99.0;
    High = 0;
    
  radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
  radio.setHighPower(); // Always use this for RFM69HCW

ReportTime = 0;
RainCountTime = 0;
RainSwitch=false;
NewEvent=true;
WriteData=false;
 
Serial.println("setup complete");
}

void loop() {
  if (Serial.available()) {
      Serial.readStringUntil('^');
      String Strng = Serial.readStringUntil('#');
      if(Strng == "pooldata"){
      Weather.pooltemp=10.0*Serial.parseInt();
      Weather.poolfull=Serial.parseInt();
      Weather.pump=Serial.parseInt();
      
      Serial.println("Pooldata:");
      Serial.println(Weather.pooltemp);
      Serial.println(Weather.poolfull);
      Serial.println(Weather.pump);
      }
   }
  
// Send Weather data
if (millis()>ReportTime+ReportInterval){

MCP9808.wake();

Weather.airtemp = 10*MCP9808.readTempF();              
Weather.event = 100*RainCountEvent*RainCountConversion;
Weather.total = 100*RainCountTotal*RainCountConversion;
Weather.high =  10*EEPROM.get(15, tmpflt);
Weather.low =  10*EEPROM.get(10, tmpflt);


MCP9808.shutdown_wake(1);

  // Trouble shoot output - comment out to send RF format  

Serial.println();
Serial.print("Air Temp: ");
Serial.print(Weather.airtemp);
Serial.println(" degrees F");
Serial.print("Pool: ");
Serial.print(Weather.pooltemp);
Serial.println(" degrees F");
Serial.print("Lowe: ");
Serial.println(Weather.low);
Serial.print("Highe: ");
Serial.println(Weather.high);
Serial.print("Low: ");
Serial.println(Low);
Serial.print("High: ");
Serial.println(High);
Serial.print("Event: ");
Serial.println(Weather.event);
Serial.print("Total: ");
Serial.println(Weather.total);
Serial.print("Full: ");
Serial.println(Weather.poolfull);
Serial.print("Pump: ");
Serial.println(Weather.pump);

radio.send(StationID, (const void*)(&Weather), sizeof(Weather));

if(WriteData){
Addrs = 0;
EEPROM.put(Addrs,RainCountEvent);
Addrs += sizeof(int);
EEPROM.put(Addrs,RainCountTotal);
WriteData=false;
}

//Set Highs and Lows
    if(Weather.airtemp < Low){
         Low = Weather.airtemp;
         Lowtime = millis();}
        
    if(Weather.airtemp > High){
    High = Weather.airtemp; 
    Hightime = millis();}
    
if(millis()> Lowtime + 600000 && millis() < Lowtime + 645000)EEPROM.put(10,Low);
if(millis()> Hightime + 600000 && millis() < Hightime + 645000)EEPROM.put(15,High); 
       
if(millis()> Lowtime + 64800000l)Low=99; // reset in 18h
if(millis()> Hightime + 64800000l)High=0; // reset in 18h

ReportTime=millis();

}

    // check rain switch status
    if(!RainSwitch && digitalRead(switchPin)==LOW){ //only count rain motion once
      RainSwitch=true;
      RainCountEvent += 1;
      RainCountTotal += 1;
      RainCountTime = millis();
      WriteData=true;

      if(NewEvent){     //NewEvent true when it hasnt rained for EventDuration
        NewEvent=false;
        RainCountEvent=1;
      }

//matrix.print(RainCountEvent);        matrix.writeDisplay();
      }
     
    if(digitalRead(switchPin)==HIGH)RainSwitch=false; // no rain detected
    if(millis()>RainCountTime+EventDuration) NewEvent=true; //Next rain detection is a new event.

  
//Reset arduino every 14 d, but not during a rain event
if(NewEvent && millis()> 604800000)resetFunc();
    
/*
//Local display of data on 7 seg matrix

       //Write "Air Temp" to matrix
    matrix.writeDigitRaw(0,119);matrix.writeDigitRaw(1,4);matrix.writeDigitRaw(3,80);matrix.writeDigitRaw(4,0);
    matrix.writeDisplay();
    delay (1250);

    matrix.print(BME280Sensor.readTempF(), 1);
    matrix.writeDisplay();    delay (2000);
    
    //Turn off display
    matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0);matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);
    matrix.writeDisplay();

    delay (1000);

    //Write "Humidity" to matrix
    matrix.writeDigitRaw(0,118);matrix.writeDigitRaw(1,28);
    matrix.writeDisplay();
    delay (1250);

    matrix.print(BME280Sensor.readFloatHumidity(), 1);
    matrix.writeDisplay();    delay (2000);
    
    //Turn off display
    matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0);matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);
    matrix.writeDisplay();

    delay (1000);

    //Write "Pressure" to matrix
    matrix.writeDigitRaw(0,115);matrix.writeDigitRaw(1,80);
    matrix.writeDisplay();
    delay (1250);

    matrix.print(BME280Sensor.readFloatPressure()*0.007500617 ,1);
    matrix.writeDisplay();    delay (2000);
    
    //Turn off display
    matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0);matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);
    matrix.writeDisplay();

    delay (1000);
    
DisplayTime=millis();  //Update display time
*/

}

Inside iot 33 code:

#include <Adafruit_LEDBackpack.h>
Adafruit_7segment matrix = Adafruit_7segment();

#include <RFM69.h>
#include <RFM69registers.h>
#include <RFM69_ATC.h>
#include <RFM69_OTA.h>
#include <SPI.h>

#include <WiFiNINA.h> 
#include <WiFiUdp.h>
#include <RTCZero.h>

bool debug = true;

// Addresses for this node. CHANGE THESE FOR EACH NODE!

#define NETWORKID     19   // Must be the same for all nodes3
#define MYNODEID      10   // My node ID
#define WaterRelayNode   4   // My node ID
#define PoolNode   3   // My node ID
#define WeatherSta   2   // My node ID
#define LightNode     8   // Destination node ID
#define DriveNode     7   // Destination node ID

#define FREQUENCY     RF69_915MHZ
#define ENCRYPT       false // Set to "true" to use encryption
#define ENCRYPTKEY    "TOPSECRETPASSWRD" // Use the same 16-byte key on all nodes
 
#define DisplayFreq 5000  //20s
#define NoDataTime 120000  //2m
#define OutputFreq 240000  //3m

#define BellDur 2000 //Bell duration
#define BellSusDur 0     // Suspend bell duration after light toggled on
#define FrntLghtOnTm 300000  //Light on time after bell trigger
#define BellTmOut 0 //no repeat bell during timeout

#define RTCcorrectionInt 521000 //ms for 10s correction
unsigned long RTCcorrectTm;
bool Tmlatch;

#define Night 23
#define Day 7
int Mode = 1;
unsigned long Belltm;

bool doorBell;
bool BellDebug;
unsigned long BellSusTm; 
bool BL; // Bell Latch
bool Light; 
bool LL; // Light latch
bool Sleep;
bool Driveway;
bool TmpHook;

#define LED           9 // LED positive pin
#define GND           8 // LED ground pin
#define BellTrigger 6  //Rings doorbell
#define SoundieButton 4  //Activate
#define SoundiePwr 5  //Power
#define ErrorLED  7 // Button to change doorbell mode

bool Pump;
int minutes;
int hours;
int minutes0;
int hours0;

int m;
int h;
String rx_str = "";
bool PoolsReport; //Pool responded

unsigned long WeatherDataTime;
unsigned long PoolDataTime;
unsigned long DisplayTime;
unsigned long OutputTime;
unsigned long Raintime;

// WiFi Credentials (edit as required)
char ssid[] = "X%_-^(O)^-_%X";      // Wifi SSID
char pass[] = "cmlaml3645!$!";       // Wifi password

char   IFTTT_HOST[] = "maker.ifttt.com";
String urltmp = "/trigger/Test_Event/with/key/cD9P9f9tJGf_-HHyG7V_vEO1ZL9R3qhUTVIIEBRo3Qw?&value1=";
String urldw =  "/trigger/driveway-trigger/with/key/cD9P9f9tJGf_-HHyG7V_vEO1ZL9R3qhUTVIIEBRo3Qw";
String dataString = "?value1=57&value2=25";

typedef struct {
  int16_t         airtemp;
  int16_t         event;
  int16_t         total;
  int16_t         high;
  int16_t         low;
  int16_t         pooltemp; 
  int16_t         poolfull;
  int16_t         pump; 
} WDataStructure;

WDataStructure Weather;

typedef struct {
  float         temp;   
  int           full;  
  bool          pump;
} PDataStructure;

PDataStructure Pool;

typedef struct { 
  bool         wther;  
  bool         relay;
} ErrorDataStructure;

ErrorDataStructure Error;

typedef struct {
  bool        DW;
  float       BattV;  
  float       PnlV;
  int         hr;   
  int         min;  
} DWDataStructure;

DWDataStructure DriveData;

const long StrtTm[20]={   0,2500,3300,4800,5600,8100,8900,10400,11200,12700,13500,16000,16800,19300,20100,22600,23400,25900,27400,28900};
const long StpTm[20] ={2000,3300,4300,5600,7600,8900,9900,11200,12200,13500,15500,16800,18800,20100,22100,23400,25400,26900,28400,32900};
  

RFM69 radio;
RTCZero rtc;
WiFiClient client;
int status = WL_IDLE_STATUS;

void Update_Time(){
   
  // Variable to represent epoch
  unsigned long epoch;
 
 // Variable for number of tries to NTP service
  int numberOfTries = 0, maxTries = 6;

 // Get epoch
  do {
    epoch = WiFi.getTime();
    numberOfTries++;
  }

  while ((epoch == 0) && (numberOfTries < maxTries));

    if (numberOfTries == maxTries) {
    Serial.println("NTP update timed out!");
    while (1);
    }else {

    // DLS Time zone constant - change as required for your location
    int GMT = -7; 
    rtc.setEpoch(epoch+GMT*3600); //assumes DST
   
   //Adj for standard time
   //DST Dates March and Nov 2021 - 2029
    int DST[9][2]={{14,7},{13,6},{12,5},{10,3},{9,2}, {8,1}, {14,7}, {12,5}, {11,4}};
    int mo = rtc.getMonth();
    int d = rtc.getDay();
    int y = rtc.getYear()-2021;
    if(mo < 3 || mo > 11)GMT=-8;
    if(mo==3 && d < DST[y][0]) GMT=-8;
    if(mo==11 && d >= DST[y][1]) GMT=-8; 
    rtc.setEpoch(epoch+GMT*3600); //reset time

 //   Serial.print("NTP update: ");Serial.print(rtc.getMonth());Serial.print("/");Serial.print(rtc.getDay());Serial.print("/");Serial.print(rtc.getYear());Serial.print(" ");
 //                                Serial.print(rtc.getHours());Serial.print(":");Serial.print(rtc.getMinutes());Serial.print(":");Serial.print(rtc.getSeconds());Serial.println();
    }

      //while (!Serial);
}
void Connect_wifi(){
    
    if (WiFi.status() == WL_NO_SHIELD) {
    // Wait until WiFi ready
    Serial.println("WiFi adapter not ready");
    while (true);
  }

      // Establish a WiFi connection
  while ( status != WL_CONNECTED) {

    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);

    // Wait 10 seconds for connection:
    delay(10000);
  }

  // Print connection status
  // Print the network SSID
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  
  // Print the IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  
  // Print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");

}
//--------------------------------------------------------------------
void setup() {
  
  Serial.begin(9600);
  //while (!Serial);
  matrix.begin(0x70);
  Serial.print("Node ");
  Serial.print(MYNODEID,DEC);
  Serial.println(" ready");  

  Sleep = false;
  
  matrix.print(8888);
  matrix.writeDisplay();
  delay(1000);
  matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0);matrix.writeDigitRaw(2,0);matrix.writeDigitRaw(3,0); matrix.writeDigitRaw(4,0);
  matrix.writeDisplay();

  radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
  radio.setHighPower(); // Always use this for RFM69HCW
  if (ENCRYPT)radio.encrypt(ENCRYPTKEY);

  Pump = false;
  Raintime=0;
  PoolsReport=false;
  DisplayTime = 30000;
  TmpHook = true;
 
  pinMode(LED,OUTPUT);
  digitalWrite(LED,LOW);
  pinMode(GND,OUTPUT);
  digitalWrite(GND,LOW);
  pinMode(BellTrigger,OUTPUT);

  pinMode(SoundiePwr,OUTPUT);
  pinMode(SoundieButton,OUTPUT);
  //digitalWrite(SoundieButton,HIGH);

 //Confirm two-way to Display Node
       if (radio.sendWithRetry(WaterRelayNode, " ", 1))
       {Serial.print("WaterRelay Node responds ");Serial.print(radio.readRSSI());Serial.println();}
        else Serial.println("WaterRelay Node quiet ");

//Confirm two-way to light
          if (radio.sendWithRetry(LightNode, "F", 1))
          {Serial.print("Light Node responds ");Serial.print(radio.readRSSI());Serial.println();}
          else Serial.println("Light Node quiet ");


if(radio.sendWithRetry(PoolNode, (const void*)(&Pool), sizeof(Pool)))
{Serial.print("Pool Node responded ");Serial.print(radio.readRSSI());Serial.println();} else
 Serial.println("Pool Node quiet ");

//Test Error LED

digitalWrite(ErrorLED, HIGH);
delay(750);
digitalWrite(ErrorLED, LOW);

  Connect_wifi();
 
  rtc.begin();
  Update_Time();

}

//----------------------------------------------------------------------------------------
void loop() {
  
  if( WiFi.status()!= WL_CONNECTED) Connect_wifi();

   
// Check for data on RFM69
  if (radio.receiveDone()){ // Got one!
    Blink(LED,100);
    
if(radio.SENDERID==WeatherSta){
        Weather = *(WDataStructure*)radio.DATA; //assume radio.DATA actually contains our struct and not something else
        if(debug){Serial.print("Rcvd Weather");Serial.print(radio.readRSSI());Serial.println();}
        
      Serial.print("air  Temp =");
      Serial.println(Weather.airtemp);
      Serial.print("pool  Temp =");
      Serial.println(Weather.pooltemp);
      Serial.print(" Event =");
      Serial.println(Weather.event);
      Serial.print(" Total =");
      Serial.println(Weather.total);
      Serial.print(" Low =");
      Serial.println(Weather.low);
      Serial.print(" High =");
      Serial.println(Weather.high);
      Serial.print("poolfull? =");
      Serial.println(Weather.poolfull);
      Serial.print("pump =");
      Serial.println(Weather.pump); 
            
      WeatherDataTime=millis();
      
      if(Weather.pump)Pump=true; // Pump will not go false w/o reset
    }
    if(radio.SENDERID==PoolNode){
        Pool = *(PDataStructure*)radio.DATA; //assume radio.DATA actually contains our struct and not something else
        if(debug){Serial.print("Rcvd Pool ");Serial.print(radio.readRSSI());Serial.println();}
 /*     Serial.print("  Pool Temp =");
      Serial.println(Pool.temp);
      Serial.print(" Pool status =");
      Serial.println(Pool.full);
      Serial.print(" Pump =");
      Serial.println(Pool.pump);
      */
            
      PoolDataTime = millis();
    }

//Driveway
if(radio.SENDERID==DriveNode){
  DriveData = *(DWDataStructure*)radio.DATA;
  if(DriveData.DW)Driveway = true;  //Flag for soundie
  if(Driveway){
    Serial.println();Serial.println("Driveway trigger ....");}
    else{
      Serial.println();Serial.println("Driveway voltage report ....");}
      
  Serial.print("Driveway battery voltage = ");Serial.print(DriveData.BattV);Serial.print("  Panel voltage = ");Serial.println(DriveData.PnlV);
  
  if(rtc.getHours()!=0){
  DriveData.hr = rtc.getHours();
  DriveData.min = rtc.getMinutes();

   Serial.print("Sending Driveway time: Hr-");Serial.print(DriveData.hr);Serial.print("  Min-");Serial.println(DriveData.min);
  delay(500);
  radio.send(DriveNode, (const void*)(&DriveData), sizeof(DriveData));}//respond to DriveNode w time
}

   if(radio.SENDERID==LightNode && radio.DATA[0]==88){
    BellSusTm=millis();
    Serial.println("Bell suspend");
   }

    if (radio.ACKRequested())
    {radio.sendACK();
      Serial.print("ACK sent to node ");Serial.println(radio.SENDERID);
    Blink(LED,100);
  }
     }// end Radio receive code -----------------------

     if (DriveData.DW){ 
      DriveData.DW = false;
   // send webhook on port 80:
    if (client.connect(IFTTT_HOST, 80)){Serial.print("Connected to server ");Serial.println(IFTTT_HOST); }
    else Serial.println("connection failed");

    // make a HTTP request:
    client.println("GET " + urldw + " HTTP/1.1");
    client.println("Host: " + String(IFTTT_HOST));
    client.println("Connection: close");
    client.println(); // end HTTP header
 
    while (client.connected()) {
      if (client.available()) {
        // read an incoming byte from the server and print it to serial monitor:
       char c = client.read();
        Serial.print(c);
      }}
      
    client.stop();
    Serial.println();
    Serial.println(" server disconnected");
      if(debug) Serial.println("sent driveway response w time data sent");
     }

    if(!doorBell &&  Driveway && millis()-Belltm > BellTmOut && millis()>BellSusTm + BellSusDur){
    Belltm = millis();
    Light = true;
    doorBell = true;
    if( !Sleep){
      digitalWrite(SoundiePwr,HIGH); delay(100);
      digitalWrite(SoundieButton,HIGH);delay(100);
      digitalWrite(SoundieButton,LOW);delay(100);
      digitalWrite(BellTrigger,HIGH);
    }
    //Serial.print("Bell criteria met IRsum=");Serial.print(IRsum);Serial.print('\t');Serial.println(millis());
  }
  Driveway = false;

  if(doorBell && millis()-Belltm > BellDur){
    digitalWrite(BellTrigger,LOW);
    digitalWrite(SoundiePwr,LOW); 
    doorBell=false;
  }
   
  if(millis()-Belltm > FrntLghtOnTm)Light = false;

  if(Light && !LL){radio.sendWithRetry(LightNode, "O", 1);LL=true;Serial.println("sent Light ON");} //turn on front light 
  if(!Light && LL){radio.sendWithRetry(LightNode, "F", 1);LL=false;Serial.println("sent Light OFF");} //turn on front light
    

  if(rtc.getHours() >= Day && rtc.getHours() < Night)
  Sleep = false;
  else
  Sleep = true; 

  if(rtc.getHours()==0)Sleep = false; //Dont issue sleep mode until time received


//Set Errors if havent heard from pool or weather stations

if(millis()>NoDataTime+WeatherDataTime){
    Error.wther = true;
 /*   Weather.airtemp=0;
    Weather.pooltemp=0;
    Weather.pres=0;
    Weather.hum=0;
    Weather.event=0;
    Weather.total=0;
    Weather.low=0;
    Weather.high=0;
    Weather.poolfull = true;
    */} else Error.wther = false; 

   
// Relay error sent if no response from transmition

//  Serial.print("PoolTemp: ");Serial.print(PoolTemperature);Serial.print(" AirTemperature: ");Serial.print(AirTemperature);Serial.print(" Humidity: "); Serial.print (Humidity);Serial.print(" Pressure:"); Serial.print(AirPressure);
//Serial.print(" RainE:"); Serial.print(RainE);Serial.print(" RainT:"); Serial.println(RainT);

//Write to matrix every DisplayFreq ms

//Nodata text
//   matrix.writeDigitRaw(0,84);matrix.writeDigitRaw(1,92);matrix.writeDigitRaw(3,94);matrix.writeDigitRaw(4,119);
//   matrix.writeDisplay();


   // Display Routine ------------------------------------------------------------------------------------------------------  
if(millis()>= DisplayTime + StrtTm[0] && millis()< DisplayTime + StpTm[0]){
    
     //Write Time to matrix
    matrix.print(rtc.getHours()*100 + rtc.getMinutes());
    matrix.writeDigitRaw(2, 2);
    matrix.writeDisplay();
}else if(millis()> DisplayTime + StpTm[0] && millis()< DisplayTime + StrtTm[1]){
      matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0); matrix.writeDigitRaw(2, 0); matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[1] && millis()< DisplayTime + StpTm[1]){  
   //Write "Pool" to matrix
    matrix.writeDigitRaw(0,115);matrix.writeDigitRaw(1,92);matrix.writeDigitRaw(3,92);matrix.writeDigitRaw(4,6);matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[2] && millis()< DisplayTime + StpTm[2]){
    matrix.print(Weather.pooltemp/10.0);
    matrix.writeDigitRaw(4,0); //blank last digit
    matrix.writeDisplay();
}else if(millis()> DisplayTime + StpTm[2] && millis()< DisplayTime + StrtTm[3]){
      matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0); matrix.writeDigitRaw(2, 0); matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[3] && millis()< DisplayTime + StpTm[3]){ 
   //Write "Air Temp" to matrix
    matrix.writeDigitRaw(0,119);matrix.writeDigitRaw(1,4);matrix.writeDigitRaw(3,80);matrix.writeDigitRaw(4,0);
    matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[4] && millis()< DisplayTime + StpTm[4]){
    matrix.print(round(Weather.airtemp*10)/10.0);matrix.writeDigitRaw(4,0); //blank last digit
    matrix.writeDisplay();
}else if(millis()> DisplayTime + StpTm[4] && millis()< DisplayTime + StrtTm[5]){
      matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0); matrix.writeDigitRaw(2, 0); matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[5] && millis()< DisplayTime + StpTm[5]){
    //Write "Humidity" to matrix
    matrix.writeDigitRaw(0,118);matrix.writeDigitRaw(1,28);
    matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[6] && millis()< DisplayTime + StpTm[6]){
    matrix.print(0);matrix.writeDigitRaw(4,0); //blank last digit
    matrix.writeDisplay();
}else if(millis()> DisplayTime + StpTm[6] && millis()< DisplayTime + StrtTm[7]){
      matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0); matrix.writeDigitRaw(2, 0); matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[7] && millis()< DisplayTime + StpTm[7]){
    //Write "Pressure" to matrix
    matrix.writeDigitRaw(0,115);matrix.writeDigitRaw(1,80);
    matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[8] && millis()< DisplayTime + StpTm[8]){
    matrix.print(0);
    matrix.writeDisplay();
}else if(millis()> DisplayTime + StpTm[8] && millis()< DisplayTime + StrtTm[9]){
      matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0); matrix.writeDigitRaw(2, 0); matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[9] && millis()< DisplayTime + StpTm[9]){
    //Write "Rain E" to matrix
    matrix.writeDigitRaw(0,118);matrix.writeDigitRaw(1,91);matrix.writeDigitRaw(3,92);matrix.writeDigitRaw(4,121);
    matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[10] && millis()< DisplayTime + StpTm[10]){
    matrix.print(Weather.event);
    matrix.writeDisplay();
}else if(millis()> DisplayTime + StpTm[10] && millis()< DisplayTime + StrtTm[11]){
      matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0); matrix.writeDigitRaw(2, 0); matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[11] && millis()< DisplayTime + StpTm[11]){
    //Write "Rain T" to matrix
    matrix.writeDigitRaw(0,118);matrix.writeDigitRaw(1,91);matrix.writeDigitRaw(3,92);matrix.writeDigitRaw(4,120);
    matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[12] && millis()< DisplayTime + StpTm[12]){
    matrix.print(Weather.total);
    matrix.writeDisplay();
}else if(millis()> DisplayTime + StpTm[12] && millis()< DisplayTime + StrtTm[13]){
      matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0); matrix.writeDigitRaw(2, 0); matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[13] && millis()< DisplayTime + StpTm[13]){
    //Write "Low T" to matrix
    matrix.writeDigitRaw(0,56);matrix.writeDigitRaw(1,92);matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);
    matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[14] && millis()< DisplayTime + StpTm[14]){
    matrix.print(round(Weather.low*10)/10.0); matrix.writeDigitRaw(4,0); matrix.writeDisplay(); //blank last digit
}else if(millis()> DisplayTime + StpTm[14] && millis()< DisplayTime + StrtTm[15]){
      matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0); matrix.writeDigitRaw(2, 0); matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[15] && millis()< DisplayTime + StpTm[15]){      
    //Write "High T" to matrix
    matrix.writeDigitRaw(0,118);matrix.writeDigitRaw(1,4);matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);
    matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[16] && millis()< DisplayTime + StpTm[16]){
    matrix.print(round(Weather.high*10)/10.0); matrix.writeDigitRaw(4,0); matrix.writeDisplay(); //blank last digit
}else if(millis()> DisplayTime + StpTm[16] && millis()< DisplayTime + StrtTm[17]){
      matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0); matrix.writeDigitRaw(2, 0); matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);matrix.writeDisplay();
}else if(millis()>= DisplayTime + StrtTm[17] && millis()< DisplayTime + StpTm[17]){
     matrix.writeDigitRaw(0,113);matrix.writeDigitRaw(1,22);matrix.writeDigitRaw(3,48);
               if(Weather.poolfull)matrix.writeDigitRaw(4,113); //Full
               else matrix.writeDigitRaw(4,121); //Empty
               //else matrix.writeDigitRaw(4,92);
    matrix.writeDisplay();
}else if(millis()> DisplayTime + StpTm[17] && millis()< DisplayTime + StrtTm[18]){
      matrix.writeDigitRaw(0,0);matrix.writeDigitRaw(1,0); matrix.writeDigitRaw(2, 0); matrix.writeDigitRaw(3,0);matrix.writeDigitRaw(4,0);matrix.writeDisplay();

 }else if(millis()>= DisplayTime + StrtTm[18]){ 

    if(Pump){
    matrix.writeDigitRaw(0,115);matrix.writeDigitRaw(1,28);matrix.writeDigitRaw(3,84);matrix.writeDigitRaw(4,115); 
    matrix.writeDisplay();
    }
    
    DisplayTime = millis() + DisplayFreq;
    
}else{}; 

  
if(millis()> OutputTime + OutputFreq){
/*  Serial.print("Outside Temp: ");Serial.println(AirTemperature);
  Serial.print("Air Pressure: ");Serial.println(AirPressure);
  Serial.print("Humidity: ");Serial.println(Humidity);
  Serial.print("Rain Event: ");Serial.println(RainE);
  Serial.print("Rain YTD: ");Serial.println(RainT);
  Serial.print("Tm since last data: ");Serial.println((millis()-Datatime2)/1000);
  Serial.println();
*/


// Write FILL data to Pool Relay via RFM69
if(radio.sendWithRetry(WaterRelayNode, (const void*)(&Pool), sizeof(Pool))){
  Error.relay = false;if(debug)Serial.println("Relay Ack");}
  else {Error.relay = true; if(debug)Serial.println("NoAck from Relay");}

 
OutputTime=millis();
}
 
// Send temp to phone
if(rtc.getMinutes()==0 && rtc.getHours()>=7 && rtc.getHours()<=22 && TmpHook){
   // send webhook on port 80:
    if (client.connect(IFTTT_HOST, 80)){Serial.print("Connected to server ");Serial.println(IFTTT_HOST); }
    else Serial.println("connection failed");

    // make a HTTP request:

    String url = urltmp + Weather.airtemp + "&value2=" + Weather.pooltemp;
    client.println("GET " + url + " HTTP/1.1");
    client.println("Host: " + String(IFTTT_HOST));
    client.println("Connection: close");
    client.println(); // end HTTP header
 
    while (client.connected()) {
      if (client.available()) {
        // read an incoming byte from the server and print it to serial monitor:
       char c = client.read();
        Serial.print(c);
      }}
      
    client.stop();
    Serial.println();
    Serial.println(" server disconnected");

    TmpHook = false;  
     }
if(!TmpHook && rtc.getMinutes()==1)TmpHook=true;

// Correct RTC 
if(millis()> RTCcorrectTm + RTCcorrectionInt){
  
      if(rtc.getSeconds()<49){
      byte secdelta = rtc.getSeconds() + 10;
      rtc.setSeconds(secdelta);
      RTCcorrectTm = millis();
      //Serial.print("Time Adjust: ");Serial.print(rtc.getHours());Serial.print(":");Serial.print(rtc.getMinutes());Serial.print(":");Serial.print(rtc.getSeconds());Serial.println();
      }
     else
     RTCcorrectTm = RTCcorrectTm + 11000;// move correction 11s ahead    
}
//Update RTC
if(!Tmlatch && (rtc.getMinutes()==29 || rtc.getMinutes()==59)){
  Tmlatch = true;
  Update_Time();
  RTCcorrectTm = millis();
}
if(Tmlatch && (rtc.getMinutes()==0 || rtc.getMinutes()==30)){
  Tmlatch = false;
}

//Set error LED
if(Error.wther || Error.relay) digitalWrite(ErrorLED, HIGH); else digitalWrite(ErrorLED, LOW);

}//End Main
void Blink(byte PIN, int DELAY_MS)
// Blink an LED for a given number of ms
{
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
  delay(DELAY_MS);

}

Sending ALL your code is like taking your clothes off in front of strangers!

It all works - except Weather.pooltemp, Weather.poolfull, Weather.pump are zeros even though I confirmed their values outside prior to the send.

Ideas? Appreciate the help. I've spent so much time trouble shooting this and can't see whats wrong.

Ultimately I'd like to use the structured data concept to share data between devices where both can modify data and pass it to the other in a 2-way communication.

Did you try to print what you receive?

for (byte i = 0; i < radio.DATALEN; i++) {
  Serial.print((byte)radio.DATA[i], HEX);
  Serial.write(' ');
}

May be on the sender side put easily recognizable values in the struct members

And check if radio.DATALEN is the same as the struct size

Thanks for the suggestion which I followed. The size of Weather is the same on both ends, and the values received are just as expected. There is nothing wrong with the data structure. Here's the problem ... when my laptop is outside connected to the nano to trouble shoot, all is well. When I leave and plug the nano into a 5v transformer to the USB input - the serial leads are shorted or have too much noise (or floating ground issue?) - and the serial data is not transmitted. Serial.available() test is never true and thus the pool data is not read or loaded into the structure. Since there is always a fresh power up when I leave - the values are zero when I get inside. I was tipped to the problem by the .pump flag which once set inside does not reset. When I canned in values to debug it set the flag true so I knew the transmission had worked at least once. Solution will be to power the device by other than by the USB port. If I could have the hours back I've spent on this issue .... ? Oh well.

Seems indeed like bad grounding / interferences.

If I could have the debugging time back, I’ll be so much younger :wink: but that is also how you get better