Build Your Own Non-Linear Response

It is common to control the speed of a pump based on a sensor reading.  But what if you want the pump speed to change at a different rate at different parts of the sensor range?  If the response isn’t approximated by an equation, you can break down the response in to segments and use a new equation for each segment.  That is exactly what is done here.


The code is just a series of nested if statements to find which segment to use, then calculates the slope and intercept of the segment to get to the output (y) value:

//steps through a series of 7 numbers (x values) to find which one starts the interval containing the input
//calculates the slope for the given interval based on the ((delta y)/(delta x))
//calculates the y intercept using y=mx+b (plugging in m, x and y, solving for b)
//calculates the y value using y=mx+b (plugging in m, x, and b, solving for y)
//Rev0 February 25, 2015 sparkygeek.com
int interval; //this var was just for testing
float m; //slope
float b; //y intercept
float x; //incoming number
float y; //result
float x0; //first datapoint on x-axis
float x1; //second datapoint on x-axis
float x2; //third datapoint on x-axis
float x3; //fourth datapoint on x-axis
float x4;
float x5;
float x6;
float x7;
float x8;
float y0; //first datapoint on y-axis
float y1;
float y2;
float y3;
float y4;
float y5;
float y6;
float y7;
float y8;
// copy values over so remainder of code stays the same
x := Pump1.Xin;
x0 := Pump1.Xmin;
x1 := Pump1.x1;
x2 := Pump1.x2;
x3 := Pump1.x3;
x4 := Pump1.x4;
x5 := Pump1.x5;
x6 := Pump1.x6;
x7 := Pump1.x7;
x8 := Pump1.Xmax;
y0 := Pump1.Ymin;
y1 := Pump1.y1;
y2 := Pump1.y2;
y3 := Pump1.y3;
y4 := Pump1.y4;
y5 := Pump1.y5;
y6 := Pump1.y6;
y7 := Pump1.y7;
y8 := Pump1.Ymax;

if( x < x1 ){
 interval = 0; 
 m := (y1-y0)/(x1-x0);
 b := y1-m*x1;
 }
 else 
  if ( x < x2 ){
  interval = 1;
  m := (y2-y1)/(x2-x1);
  b := y2-m*x2;
  }
  else 
   if ( x < x3 ){
   interval = 2; 
   m := (y3-y2)/(x3-x2);
   b := y3-m*x3;
   }
   else 
    if ( x < x4 ){
    interval = 3;
    m := (y4-y3)/(x4-x3);
    b := y4-m*x4;
    }
    else 
     if ( x < x5 ){
     interval = 4;
     m := (y5-y4)/(x5-x4);
     b := y5-m*x5;
     }
     else 
      if ( x < x6 ){
      interval = 5;
      m := (y6-y5)/(x6-x5);
      b := y6-m*x6;
      }
      else 
       if ( x < x7 ){
       interval = 6;
       m := (y7-y6)/(x7-x6);
       b := y7-m*x7;
       }
       else 
        if ( x < x8 ){
        interval = 7;
        m := (y8-y7)/(x8-x7);
        b := y8-m*x8;
        }
y := m*x+b;
return y;
This entry was posted in Industrial Automation and tagged , , , . Bookmark the permalink.