Fixed-point Exponential Moving Average filter with given cutoff frequency
You should scale your analog input to match your desired resolution, it's better to have bigger resolution (specially when dealing with IIR filters), I don't know the reason of returning y>>N, probably the scaling problem is there, I would implemented it like this:

int low_pass_EMA_fixed_point(int x, int y, int alpha_scaled, int Q, int N)
{
  int32_t y_temp;
  y_temp = (alpha_scaled*(x&lt;&lt;N))+((1&lt;&lt;Q)-alpha_scaled)*y;
  return (int)(y_temp &gt;&gt; Q);
}


Also a good practice is test your filter with an impulse to check if it was implemented correctly before using the actual data.

EDIT: tested this program with onlinegdb.com (the printf are used to copy the result into octave):

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

#define NUM 1024

int low_pass_EMA_fixed_point(int x, int y, int alpha_scaled, int Q, int N);

int main()
{
    int alpha_scaled = 1097; //Q12
    int Q = 12;
    int N = 2;
    static int x[NUM];
    int y = 0;

    x[0] = 1024; //input in Q10
    printf("y=[");
    for(int i=0;i&lt;NUM;i++)
    {
        y = low_pass_EMA_fixed_point(x[i], y, alpha_scaled, Q, N);
        if(i == NUM-1)
        {
            printf("%d];",y); //print the last output
        }
        else
        {
            printf("%d,",y);
        }
    }
    return 0;
}

int low_pass_EMA_fixed_point(int x, int y, int alpha_scaled, int Q, int N)
{
  int32_t y_temp;
  y_temp = (alpha_scaled*(x&lt;&lt;N))+(((1&lt;&lt;Q)-alpha_scaled)*y);

  return (int)(y_temp&gt;&gt;Q);
}


And I'm getting this frequency response in octave: