ESP-NOW OnDataRecv problem updating / accessing a global variable value

I would truly appreciate some help on this, I've been working it for hours and am thinking I'm missing something fundamental.

Below I've summarized and abbreviated my code as the actual sketch is about 700 lines; regardless the code below is a representation of what I am facing ...

In my Arduino sketch I have the following defined globally:

enum transmission_Type {
  a,
  b,
  c,
};


enum device_Status {
  blocked,
  unblocked,
  unknown,
};


typedef struct transmission_Structure {
  transmission_Type transmission;
  device_Status status;
} transmission_Structure;


device_Status myDeviceStatus = unknown;

My ESP-NOW's OnDataRecv routine is coded as follows:

void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len) {

    transmission_Structure incomingMessage;

    memcpy(&incomingMessage, incomingData, sizeof(incomingData));

    if (incomingMessage.transmission == a) {

      if (incomingMessage.status == blocked) 
        Serial.print("status is blocked");
      else 
        Serial.println("status is unblocked");
    
      myDeviceStatus = incomingMessage.status;

      if (myDeviceStatus == blocked)
        Serial.print("confirming blocked");
      else
        Serial.println("confirming unblocked");
    
    };
  
}

and I have a routine that is called from within the Arduino loop() routine as follows:


void reportStatus() {
 
    Serial.println(myDeviceStatus);

    if (myDeviceStatus == unblocked) 
      Serial.println("here the status is unblocked");
    else if (myDeviceStatus == blocked)
      Serial.println("here the status is blocked");
    else if (myDeviceStatus == unknown)
      Serial.println("here the status is unknown");
    else 
      Serial.println("here the status is error");
	  
};

In general the sketch runs fine, except for the reportStatus sub routine.

When data is received, what is printed to the serial monitor is, as an example:

status is blocked
confirming blocked
-1163045256
here the status is error

the last two lines are puzzling me, they should be (I would think)
blocked
here the status is blocked

In my real code, I need to take actions in the reportStatus subroutine based on the value of myDeviceStatus, which I cannot do because of the way the results are coming out.

I've also tried adding 'volatile' to the global myDeviceStatus variable definition:

volatile device_Status myDeviceStatus = unknown;

but it didn't make a difference and the value for myDeviceStatus is only updated one place in my program - so not something I thought I would need anyway.

Any help would be appreciated.

I guess that you are doing this in a .h file:

You risk creating a new copy of myDeviceStatus everywhere you include the .h file.

Try something like this declaration in the .h file
extern device_Status myDeviceStatus ;

and define and initialise it in one of the .cpp or .ino files:
device_Status myDeviceStatus = unknown ;

EDIT
See: Header files (C++) | Microsoft Learn and scroll down to the section "What to put in a header file"

Hello

memcpy(&incomingMessage, incomingData, sizeof(incomingData));

incomingData is a pointer, so it makes no sense, in this case, to use sizeof(incomingData)

Do this to understand your error:

Serial.println( sizeof( transmission_Structure ) );
Serial.println( sizeof( uint8_t * ) );

@6v6gt - thank you, but the line

device_Status myDeviceStatus = unknown;

is in my Arduino sketch within the .ino file - it is not in a separate .h file.

@quix thank you, I guess as I said in my original post I am missing something fundamental.

I had been using:
memcpy(&incomingMessage, incomingData, sizeof(incomingData));

and I should have been using
memcpy(&incomingMessage, incomingData, sizeof(incomingMessage));

Thank you for pointing me in the right direction!

Yes, use sizeof(incomingMessage) but it's unclear what the content of incomingData is, and its length (from the len parameter).

If you are sure that the length is the same as the size of the struct (two ints = 4 bytes), then you have nothing else to do.

If however the length is two bytes, then you will have to change the underlying type of the enums :

enum transmission_Type : uint8_t {
  a,
  b,
  c,
};


enum device_Status : uint8_t {
  blocked,
  unblocked,
  unknown,
};

And / or set the size of the fields in the struct :

typedef struct transmission_Structure {
  transmission_Type transmission : 8;
  device_Status status : 8;
} transmission_Structure;

You should add a check to see if the length is correct, before using memcpy

if ( len == sizeof( transmission_Structure ) )
{
   ...
}
else
{
  Serial.println( "Error: size mismatch" );
}

@guix thanks for this, I'll keep it in mind for future projects. However, for this one the length is the same as the size of the struct, and the code is now working fine as is thanks to your earlier help.