combined bytes wont shift.

The code below is something I am investigating, its being built on a mega and put together on visual micro and the latest Arduino IDE.

The problem is that I cant seem to get the integer that I have split to 4 bytes (intVal) and written to the DS1302 to come back out and merge into one 32 bit integer (merge_var)

the issue I have is byte0 byte1 add up but byte2 and byte3 do things I dont understand.

This has beat me. I think the error is in the bit shifting line or it's the wrong type maybe.

Anyway for those interested the idea is to put a form timestamp quantified in minutes on the rtc SRAM so if the power is lost the arduino wont allow the machine to come on till a specified time has elasped.
it does this by comparing when it was last on. but as I'm measuring time in minutes I need to split this to 4 bytes.

#include<DS1302RTC.h>
#include<TimeLib.h>

DS1302RTC RTC(27, 29, 31);

#define DS1302_GND_PIN 33
#define DS1302_VCC_PIN 35


void setup() {
	
  digitalWrite(DS1302_GND_PIN, LOW);
  pinMode(DS1302_GND_PIN, OUTPUT);
  digitalWrite(DS1302_VCC_PIN, HIGH);
  pinMode(DS1302_VCC_PIN, OUTPUT);
  
		Serial.begin(9600);
delay(100);
}

void loop() {
  uint32_t intVal =0b11110000111100001111000011110000;
  
  union {
  uint32_t splitInt;
  byte byteVal[4];
} intAsBytes;

intAsBytes.splitInt = intVal;

  RTC.writeEN(true);
if(RTC.writeEN())
    Serial.println("ready");
  else
    Serial.println("No write");
	
RTC.writeRTC(DS1302_RAM_START+(0x0F << 1),intAsBytes.byteVal[0]);
RTC.writeRTC(DS1302_RAM_START+(0x10 << 1),intAsBytes.byteVal[1]);
RTC.writeRTC(DS1302_RAM_START+(0x11 << 1),intAsBytes.byteVal[2]);
RTC.writeRTC(DS1302_RAM_START+(0x12 << 1),intAsBytes.byteVal[3]);

uint32_t merge_var = 0;
unsigned char byte0,byte1,byte2,byte3 = 0;
byte0 = RTC.readRTC(DS1302_RAM_START+(0x0F << 1));
byte1 = RTC.readRTC(DS1302_RAM_START+(0x10 << 1));
byte2 = RTC.readRTC(DS1302_RAM_START+(0x11 << 1));
byte3 = RTC.readRTC(DS1302_RAM_START+(0x12 << 1));
 merge_var =  (byte0) | (byte1 << 8) | (byte2 << 16) | (byte3 << 24);
 
  
while(true);
}

Thanks for the reply, could you elaborate for me. I'm relatively new. Are you referring to the union that is splitting the integer into 4 for writing to the SRAM or making a new union to merge the 4 bytes once read?

Also maybe you help my understanding but I thought if you shifted a variable 24<< then it would take the place of bits 24-32 if put into a 32 bit unsigned integer. I thought they shift into the positions: 1-8 byte0, 9-16 byte1, 17-24 byte2, 24-32 byte3.

Is that not so?

Also maybe you help my understanding but I thought if you shifted a variable 24<< then it would take the place of bits 24-32

If you left-shift a 32 bit variable 24 bits, then the least significant eight bits of the original variable will occupy bits 24 to 31.

But that's not what you're doing.

The problem is that I cant seem to get the integer that I have split to 4 bytes (intVal) and written to the DS1302 to come back out and merge into one 32 bit integer (merge_var)

If you want to bitshift and not use the union to recombine, you need to recast the bytes which are currently being bit shifted to oblivion

uint32_t merge_var = 0;
unsigned char byte0,byte1,byte2,byte3 = 0;
merge_var =  byte0 | uint32_t (byte1) << 8 |uint32_t (byte2) << 16 | uint32_t (byte3) << 24;

Thanks for all the responses, I understand now and have recast the bytes. I didnt realise the shifting is done in the byte3-1 which are only 8 bits. so of course there's no where to go in each byte.
This has really interested me in unions and reading into it I'm going to attempt to see if I can build an array to understand them a bit better tomorrow. I am assuming a union is more efficient and or elegant solution?
I realise there are many ways of doing this.

Did you not get compiler warnings to let you know that your shifts would fail? If not, you should turn up the warning level in Preferences.

/Users/john/Documents/Arduino/sketch_sep22a/sketch_sep22a.ino: In function 'void setup()':
/Users/john/Documents/Arduino/sketch_sep22a/sketch_sep22a.ino:8:56: warning: left shift count >= width of type
   long merge_var =  (byte0) | (byte1 << 8) | (byte2 << 16) | (byte3 << 24);
                                                        ^
/Users/john/Documents/Arduino/sketch_sep22a/sketch_sep22a.ino:8:72: warning: left shift count >= width of type
   long merge_var =  (byte0) | (byte1 << 8) | (byte2 << 16) | (byte3 << 24);
                                                                        ^
/Users/john/Documents/Arduino/sketch_sep22a/sketch_sep22a.ino:8:8: warning: unused variable 'merge_var' [-Wunused-variable]
   long merge_var =  (byte0) | (byte1 << 8) | (byte2 << 16) | (byte3 << 24);

Test sketch:

void setup() {
  Serial.begin(9600);

  byte byte0 = 0x12;
  byte byte1 = 0x34;
  byte byte2 = 0x56;
  byte byte3 = 0x78;
  long merge_var =  (byte0) | (byte1 << 8) | (byte2 << 16) | (byte3 << 24);
}

void loop() {}

I thank you again for all the replies.
I did some swatting up on all the relevant topics. I had got it working the easy way but I wanted to master arrays and unions so I stuck at it, A couple of late nights and I worked it out in the end.
Just wanted to post my workings for you and say thanks. A great introduction to a great community.
Suggestion to the code always welcome. Amazing how long a tiny code can take to condense.

//----------------------------------SRAM WRITE Function---------------------------------------------------//
void sramWrite(uint32_t intVal){


	union {
		uint32_t splitInt;
		byte byteVal[4];
	} intAsBytes;

	intAsBytes.splitInt = intVal;

	RTC.writeEN(true);
	if(RTC.writeEN())
	Serial.println("ready");
	else
	Serial.println("No write");

	for (int i=0;i<4;i++){
	RTC.writeRTC(DS1302_RAM_START+(i << 1),intAsBytes.byteVal[i]);
	}

}

//------------------------------------SRAM READ Function-----------------------------------------------//

uint32_t sramRead()
	{

	union {
		uint8_t readBuffer[4];
		uint32_t merge_var;
		}result;

	for (int x=0;x<4;x++){
		result.readBuffer[x]= RTC.readRTC(DS1302_RAM_START+(x << 1));
		}

	uint32_t ram_read = result.merge_var;
	return ram_read;
	}

Like this:

union LongIntOr4Bytes {
  uint32_t longInt;
  byte bytes[4];
};

//----------------------------------SRAM WRITE Function---------------------------------------------------//
void sramWrite(uint32_t intVal) {

  union LongIntOr4Bytes longOrBytes;

  longOrBytes.longInt = intVal;

  RTC.writeEN(true);
  if (RTC.writeEN())
    Serial.println("ready");
  else
    Serial.println("No write");

  for (int i = 0; i < 4; i++) {
    RTC.writeRTC(DS1302_RAM_START + (i << 1), longOrBytes.bytes[i]);
  }

}

//------------------------------------SRAM READ Function-----------------------------------------------//

uint32_t sramRead()
{
  union LongIntOr4Bytes longOrBytes;

  for (int x = 0; x < 4; x++) {
    longOrBytes.bytes[x] = RTC.readRTC(DS1302_RAM_START + (x << 1));
  }

  return longOrBytes.longInt;
}

Just to confirm, by doing this am I creating another instance of that union and using it as a template to create a new union of data types. or is it re using the first union again data types and data?

dgog71:
Just to confirm, by doing this am I creating another instance of that union and using it as a template to create a new union of data types. or is it re using the first union again data types and data?

Defining the union doesn't create any instances so it doesn't use any space. Each function declares an instance of the union as a local variable so those take up four bytes for as long as the function is running.