Determine when a constant signal changes to another constant value
As @AlexR mentioned, the digital 1st order derivative is the most straight forward and probably the most trivial solution to the problem, depending on what your signal looks like and the rate of changes involved between samples. The derivative can then be processed in a sliding window to find where it transitions and where it settles (derivative of constant will be close to zero). With these techniques you can reliably detect constants ONLY if the derivative of the signal is greater than the noise amplitude before the signal settles to its constant value. If the rate of change of the signal is slow (i.e. the sample to sample transitions are on the order of magnitude of your noise) then it will be difficult to detect the constant signal from this method. I scale the signals below to be on the same order of magnitude and also take the absolute value of the derivative.



close all
clear all
%signal
x = [ones(1,5)*255 253 251 ones(1,6)*240 240 230 220 200 193 187 180 170 164 140 130 130 120 110 80 ones(1,10)*70 80 95 112 125 137 140 170 180];

%repeat signal
y = repmat(x, [1 5]);

%max value 2^8
MAX = 255;

%noise amplitude
Namp = 5;

%add noise to signal
y = y+randi(Namp,1,length(y));

%1st order derivative 
c = diff(y,1);

%plots
figure
stem(abs((c)/MAX),'color','b')
hold on
plot(y/max(y))
line([1,length(y)],[0,0],'color','r','linewidth',2)
line([1,length(y)],[Namp/MAX,Namp/MAX],'color','r','linewidth',2)
ww = 4
reg = zeros(1,ww)
for i = 1:length(c)-1
  reg = [reg(2:end) abs(c(i)/MAX)];
  if(reg(1) &gt;Namp/256 &amp; sum(reg&lt;Namp/256)&gt;= 3 )
      line([i-ww+2, i-ww+2],[0 1],'color','g','linewidth',2)
  end
end
title({'Red: Signal', 'Blue: Derivative', 'Green: start of constant signal'})
hold off


The signals generated from the derivative algorithm can be used to make a clean piecewise continuous function as seen below. The delay of which, will be a function of your window size-1 sample. 


Updated code: 

close all
clear all
%signal
x = [ones(1,20)*255 253 251 ones(1,4)*240 255 255 255 255 ones(1,5)*240 240 230 220 200 193 200 220 ones(1,10)*230 210 190 187 180 170 164 140 130 130 120 110 80 ones(1,10)*70 80 95 112 125 137 140 170 180];
%x = [ones(1,5)*130 ones(1,10)*255 ones(1,10)*20];
%repeat signal
y = repmat(x, [1 5]);

%max value 2^8
MAX = 256;

%noise amplitude
Namp =5;

%add noise to signal
y = y+randi(Namp,1,length(y));

%1st order derivative 
c = diff(y,1);
c2 = diff(y,4); 

hold off
%plots
figure
stem(abs((c)/MAX),'color','b')
plot(abs(c2)/MAX,'color','r')
hold on
plot(y/max(y))
line([1,length(y)],[0,0],'color','r','linewidth',2)
line([1,length(y)],[Namp/MAX,Namp/MAX],'color','r','linewidth',2)

ww = 4;
reg = zeros(1,ww);
filtered = []
piecewise =y(1); 
for i = 1:length(c)-1
  reg = [reg(2:end) abs(c(i)/MAX)];

  %if we detect a transition to 0 derivative 
  if(reg(1) &gt;Namp/256 &amp; sum(reg&lt;Namp/256)&gt;= 3 )

      line([i-ww+2, i-ww+2],[0 1],'color','g','linewidth',2)
      piecewise = y(i);
  end
  %if we detect a transition out of 0 derivative 
  if( sum(reg&lt;Namp/256)&gt;= 3 &amp; reg(end) &gt;Namp/256 )
      line([i, i],[0 1],'color','y','linewidth',2)    
      %piecewise = y(i)
  end

  filtered = [filtered piecewise];

end
title({'Red: Signal', 'Stem Plot: Derivative', 'Green: start of constant signal', 'Yellow: end of constant signal'})
hold off

figure
plot(filtered(3:end))
hold on
plot(y)
title({'Red: Signal', 'Blue: Cleaned Signal'})


If we take $x[n]$ to be the input and L to be the window length. First we take the 1st order digital derivative of $x[n]$ to get $\hat{x}[n]$

$$\hat{x}[n] = x[n+1]-x[n]$$

and then we examine $\hat{x}[n]$ in an L length window, noting that when the oldest sample in the window is large (signal is transitioning) and the rest of the samples in the window have settled close to zero (signal is constant) we are at an area of interest (we have found a constant signal after a transition). The longer the window L, the more samples you are considering after the transition before you trigger your algorithm. That is, if you know the signal will settle to a constant for a long period of samples, then choose a big L. If you want the output to transition quickly though, choose a smaller L. We know the smallest transition is zero but will be on the order of $N_{amp}$, the amplitude of the noise. If we scale everthing to the maximum amplitude the signal can be, $A_{max}$, then the newest L-1 samples are on the order of $\frac{N_{amp}}{A_{max}}$ and the oldest sample $x[n-L]$ is some value above that by $\epsilon$



We need to capture this mathematically to say: when the first $L-1$ samples are less than or equal to the noise amplitude and the sample L before is larger than the noise amplitude we have gone from a transition to a constant and the output should be the sample at this instance. Intuitively it seems that: 

$$\frac{1}{(L-1)} \sum_{i=0}^{L-1}\frac{|\hat{x}[n]|}{A_{max}} \leq \frac{N_{amp}}{A_{max}}$$

should capture some essence of part of this, but doesn't quite capture that ALL samples in this $L-1$ window should be less than or equal to the noise amplitude. 

it's tricky to capture this if-else statement mathematically. One way to get close to a single equation is to say the areas of interest (green lines in my plot) occur when  

$$r[n] = \frac{\hat{x}[n-L]}{\frac{1}{(L-1)} \sum_{i=0}^{L-1}|\hat{x}[n]|} &gt; 1 + \frac{\epsilon}{N_{amp}}$$  

since the division above expresses: 

$$\frac{\frac{N_{amp}+\epsilon}{A_{max}}}{\frac{N_{amp}}{A_{max}}}$$

This works ok, for example if you say you are only interested in $\epsilon$ greater than 5x your noise amplitude, then you get close, but it misses some transitions. It also seems to behave oddly when the window increases.



That is to say 

$$y[n] = \left\{
\begin{array}{ll}
  x[n], \quad &amp; r[n] &gt; 1 + \frac{\epsilon}{N_{amp}} \\
  y[n-1], \quad &amp; otherwise \\
\end{array} 
\right. $$

code to reflect this math: 

    close all
clear all
%signal
xx = [ones(1,50)*255 253 251 ones(1,50)*240 ones(1,4)*255 ones(1,10)*240 240 230 220 200 193 200 220 ones(1,20)*230 210 190 187 180 170 164 140 130 120 110 80 ones(1,25)*70 ones(1,2)*256 ones(1,25)*70 80 95 112 125 137 140 170 180];
%x = [ones(1,5)*130 ones(1,10)*255 ones(1,10)*20];
%repeat signal
x = repmat(xx, [1 5]);

%max value 2^8
MAX = 256;

%noise amplitude
Namp =5;

%add noise to signal
x = x+randi(Namp,1,length(x));

%1st order derivative 
xhat = diff(x,1);

L = 5;
reg = zeros(1,L);
filtered = [];
y = [];
y(1:L) =x(1:L)

for n = L+1:length(xhat)-1
  LminusOneSum = 0; 
  for i= 1:L-1
    LminusOneSum = LminusOneSum + abs(xhat(n-i))/MAX;
  end
  r(n) =  abs((xhat(n-L))/MAX)/(LminusOneSum*(1/(L)));

  if(r(n) &gt; (1+6))
      line([n-L+2, n-L+2],[0 1],'color','g','linewidth',2)
      y(n) = x(n);
  else
      y(n) = y(n-1);
  end


end
title({'Red: Signal', 'Stem Plot: Derivative', 'Green: start of constant signal', 'Yellow: end of constant signal'})
hold off

figure
plot(y(L:end))
hold on
plot(x)
%plot(r)
title({'Red: Signal', 'Blue: Cleaned Signal'})