Finding the minimum, middle and maximum values

Hi,
I need to create a function that will find the minimum, middle and maximum from three integers. Does anyone know how to create this or have any links that i can go too.

There are many different ways to do this and they depend a bit on your data structure e.g. individual variables vs array and what you would like to do with them at the end. e.g. are you just interested in the maximum value or do you want to know which of the variables contained the value.

The most basic thing you will need is the if () statements with compare operators.

if ( variable1 > variable2 )
{
  
}

https://www.arduino.cc/reference/en/language/structure/control-structure/if/

Arduino also has some basic math functions that can return the max or min of two values.

https://www.arduino.cc/reference/en/language/functions/math/max/

https://www.arduino.cc/reference/en/language/functions/math/min/

Hi, @jacklythgoee
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".

What model Arduino are you using?
Can you please tell us your electronics, programming, arduino, hardware experience?
Have you programmed an Arduino?

Thanks.. Tom.. :grinning: :+1: :coffee: :australia:

sounds like a median filter.

i've thought there must be an easier way, but i've found that some sort function is needed

Not sure how that's related to the original question. He asked for the ordering of 3 integers.

Either way, you don't need a full sort for a median filter, you just need to sort it enough to have the middle element in place:

In this case, you could sort the 3 elements using a couple of if statements, or if performance doesn't matter, you can just use the sort function:

    int numbers[] {4, 2, 3};
    std::sort(std::begin(numbers), std::end(numbers));
    // numbers[0] contains minimum element,
    // numbers[1] contains middle element,
    // numbers[2] contains maximum element.

This is currently what i have the output is 50 , 50 , 255. i want it to be 50,130,255. can anyone help with this?

int red = 130;
int green = 50;
int blue = 255;

int mMin;
int mMid;
int mMax;

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

  if(red <= green)
  {
    mMin = red;
    mMid = green;
  }
  else if(red >= green)
  {
    mMin = green;
    mMid = red;
  }

  if(green <= blue)
  {
    mMid = green;
    mMax = blue;
  }
  else
  {
    mMid = blue;
    mMax = green;
  }
  Serial.println(mMin);
  Serial.println(mMid);
  Serial.println(mMax);

}

if the required result is just print them in acsendig order you just compare
max = green
if red > max
max = red

if blue > max
max = blue

similar thing for min
min = green
if red < min
min = red

if blue < min
min = blue

find the middle
if (green > min && green < max)
middle = green

if (red > min && red < max)
middle = red

if (blue > min && blue < max)
middle = blue

The numbers are RGB values. and they will be inputted into the serial monitor. Would this still work?

Hello
Take a view here.
https://www.arduino.cc/reference/en/language/functions/math/constrain/

What I have posted is just a rough sketchy sketching not copy & paste = working code.

From your question I conclude that you are a real beginner.
It is absolutely OK to be a real beginner. Everybody here started as a baby that couldn't speak a single word.

To make it work in conjuction with input into the serial monitor is just a matter of coding.
You can think of programming as super-versatile lego-bricks. Much much more versatile than lego-bricks.

The programming-language provides equivalents to superglue, magnets, velcro, adhesive tape and much much more to stick together a lot of more things than you can do with lego-bricks.

Including "adapter-parts" to combine the big baby duplo-lego with the smaller standard-lego and lego-technique parts and combine them at any angle in any lenght, any height, and any width (just mimited by the available memory)

If you look at this real big versatility it becomes clear learning this needs a bit more than two hours.

stay relaxed:
for a job of inputting numbers into the serial monitor and sort the numbers by size is still a beginner job.

Your smartphone has a lot of options too. You have learned the most important ones in a few hours. Imagine a three year old child seeing a smartphone for the first time in its life. If you don't know
press button in the top left-corner to switch on the display and then enter PIN you are completely stumped.

Knowing these basics
tap on an icon to start app Ah!

Knowing the basics the three horizontal lines show up configuration in most Apps ah ! that's the way it works!

Same thing with programming.

learning the basic principles to be able to use the principles in new situations.

And as programming is so versatile there are a bit more basics.
Take a look into this tutorial and report your opinion about it:

Arduino Programming Course

It is easy to understand and has a good mixture between explaining important concepts and example-codes to get you going. So give it a try and report your opinion about this tutorial.

best regards Stefan

Yeah i knew that i couldnt copy and paste so i wrote it into a function

void minMidMax()
{
  mMax = green;
  if(red > mMax)
  {
    mMax = red;
  }
  if(blue>mMax)
  {
    mMax = blue;
  }

  mMin = green;
  if(red<mMin)
  {
    mMin = red;
  }
  if(blue<mMin)
  {
    mMin = blue;
  }

  if(green > mMin&&green<mMax)
  {
    mMid = green;
  }
  if(red>mMin&&red<mMax)
  {
    mMid = red;
  }
  if(blue>mMin&&blue<mMax)
  {
    mMid = blue;
  }
}

Is there a way i can make it shorter?

as I said, my experience is with median filters and need to be efficient. while a common starting point for such a filter is with 3 terms, you'll often want at least to try more. so using something more generic often pays off

here's a simple bubble sort()

void
sort (
    int     vec [],
    int     nData )
{
    int  t;
    for (int j = nData-1; j > 0; j--) {
        for (int i = 0; i < j; i++)  {
            if (vec [i] > vec [i+1])  {
                t         = vec [i];
                vec [i]   = vec [i+1];
                vec [i+1] = t;
            }
        }
    }
}

this will work when you want more than 3 LEDs

1 Like

This only works if the numbers are not the same. Is there a way around this? @StefanL38

Shorter code:

void sort3(const uint8_t (&in)[3], uint8_t (&out)[3]) {
  const uint8_t order = ((in[1] < in[0]) << 0) |  //
                        ((in[2] < in[1]) << 1) |  //
                        ((in[0] < in[2]) << 2);
  constexpr static uint8_t indices[][3]{
      {0, 1, 2},  // 000
      {1, 2, 0},  // 001
      {2, 0, 1},  // 010
      {2, 1, 0},  // 011
      {0, 1, 2},  // 100
      {1, 0, 2},  // 101
      {0, 2, 1},  // 110
  };
  out[0] = in[indices[order][0]];
  out[1] = in[indices[order][1]];
  out[2] = in[indices[order][2]];
}

Longer code but probably faster (measure this before you decide if speed is important to you):

void sort3_2(const uint8_t (&in)[3], uint8_t (&out)[3]) {
  if (in[0] < in[1]) {    //   [0] < [1]
    if (in[1] < in[2]) {  //   [0] < [1] < [2]
      out[0] = in[0];
      out[1] = in[1];
      out[2] = in[2];
    } else {                // [0] < [1] ≥ [2]
      if (in[0] < in[2]) {  // [0] < [2] ≤ [1]
        out[0] = in[0];
        out[1] = in[2];
        out[2] = in[1];
      } else {  //             [2] ≤ [0] < [1]
        out[0] = in[2];
        out[1] = in[0];
        out[2] = in[1];
      }
    }
  } else {                //   [1] ≤ [0]
    if (in[2] < in[1]) {  //   [2] < [1] ≤ [0]
      out[0] = in[2];
      out[1] = in[1];
      out[2] = in[0];
    } else {                // [2] ≥ [1] ≤ [0]
      if (in[0] < in[2]) {  // [1] ≤ [0] < [2]
        out[0] = in[1];
        out[1] = in[0];
        out[2] = in[2];
      } else {  //             [1] ≤ [2] ≤ [0]
        out[0] = in[1];
        out[1] = in[2];
        out[2] = in[0];
      }
    }
  }
}

ye i have no clue how to even understand this. Where do the values even go lmao.

void sort3(const uint8_t (&in)[3], uint8_t (&out)[3]) {
  const uint8_t order = ((in[1] < in[0]) << 0) |  //
                        ((in[2] < in[1]) << 1) |  //
                        ((in[0] < in[2]) << 2);
  constexpr static uint8_t indices[][3]{
      {0, 1, 2},  // 000
      {1, 2, 0},  // 001
      {2, 0, 1},  // 010
      {2, 1, 0},  // 011
      {0, 1, 2},  // 100
      {1, 0, 2},  // 101
      {0, 2, 1},  // 110
  };
  out[0] = in[indices[order][0]];
  out[1] = in[indices[order][1]];
  out[2] = in[indices[order][2]];
}

void setup() {
  Serial.begin(115200);
  while (!Serial);

  const uint8_t colors[]{130, 50, 255}; // red, green, blue
  uint8_t sorted[3]; // min, mid, max
  sort3(colors, sorted);
  Serial.print("min: ");
  Serial.println(sorted[0]);
  Serial.print("med: ");
  Serial.println(sorted[1]);
  Serial.print("max: ");
  Serial.println(sorted[2]);
}

void loop() {}

Here is another solution based on the compiler macros for max and min.
The compiler will evaluate the macros at compile time and if all values are known reduce them to numerical values, otherwise the values will be computed during runtime.

int red = 130;
int green = 50;
int blue = 255;

int mMin;
int mMid;
int mMax;

#define maxOfThree(x, y, z)     max(max(x,y),z)
#define minOfThree(x, y, z)     min(min(x,y),z)
#define midOfThree(x, y, z)     ((x+y+z) - maxOfThree(x, y, z) - minOfThree(x, y, z))


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

  mMin = minOfThree( red, green, blue );
  mMid = midOfThree( red, green, blue );
  mMax = maxOfThree( red, green, blue );

  Serial.println( mMin );
  Serial.println( mMid );
  Serial.println( mMax );
}

void loop()
{

}

This is a poor reason for using macros. The compiler will inline functions when it makes sense to do so.
ES.31: Don’t use macros for constants or “functions”

@PieterP That is not the reason for using macros. I was just having fun and wanted to show another way to do this. You can do the same thing with functions. I actually wrote some functions first and then looked at the source code for the max and min function.

@PieterP I heard your scream. :slight_smile:

@jacklythgoee Turn the macros into functions so nobody needs to scream at you. Have a look at the link Peter provided. It is good advice.

1 Like

:grin:

(for the uninitiated: the C++ Core Guidelines suggest the following:)

Enforcement: Scream when you see a macro that isn’t just used for source control (e.g., #ifdef)