Guidance to fix fluctuating ADXL345's readings

Dear All,

First of all I apologise as I am not using raspberry pi instead of Arduino. I know this is a Arduino forum and should not be posting here for help, but from all my google search most of the result came from the arduino forum. As such I would like to ask for some guidance regarding the ADXL345 sensor.

I am building a balancing robot. Currently, I am trying to read accelerometer's tilt angle. I am using the adxl345 and using the SPI protocol. I am able to read the raw x, y, z data. However, my data seems to be fluctuating abit(raw data for x and y is not zero, while z is close to 256 sometimes 230+) while stationary on a flat surface. I had tried out different method including adding the build in offset register, and software offset as taught on this link MEMS (Part 1) - Guide to using accelerometer ADXL345 - MORF - Coding And Engineering

I am calculating my pitch and roll based on the below formula

pitch = (atan2(accel.x,sqrt(accel.yaccel.y+accel.zaccel.z)) * 180.0) / PI;
roll = (atan2(accel.y,(sqrt(accel.xaccel.x+accel.zaccel.z))) * 180.0) / PI;

I would also like to mention that, i took the median of 50 raw data before passing it to the calculation of pitch and roll. However, the data still fluctuates. Next, I also tried a averaging filter e.g took the average of 50 raw data before passing it to the calculation of pitch and roll. Similarly, the data still fluctuates. The video posted below does not use software and hardware offset, but include a averaging filter.

Here is a video of my calculated pitch and roll flactuating.
My Video captured on 16 Feb using raw data only
My Video captured on 17 Feb using raw data only
My Video captured on 17 Feb with LPF(Enabled) +HW Offset(Enabled0 + Software Offset(Disabled)

The LPF formula is as such

        float Xg = 0.0, Yg = 0.0, Zg = 0.0;
	Xg = raw_data.x;
	Yg = raw_data.y;
	Zg = raw_data.z;

	//Low Pass Filter - fXg, fYg, & fZg is global variable and stores the new data after filtering
	fXg = Xg * ALPHA + (fXg * (1.0 - ALPHA));
	fYg = Yg * ALPHA + (fYg * (1.0 - ALPHA));
	fZg = Zg * ALPHA + (fZg * (1.0 - ALPHA));

I am more concern about the pitch which uses the x and z axis's data to calculate.
I would like some guidance on whether the behavior in the video I post is normal. Did anyone sucessfully "zero" the readings. The data is taken while the sensor is stationary and flat on the floor.

Thank You!