Get Minimum Value from Array(Solved!)

:frowning:
I can’t get this to work :frowning:
For some reason my getMin function always returns 0…

Also what can I do if lets say I get two values that are minimum and are equal to each other…
Thanks!

#include<Servo.h>

Servo neck;

int pingPin = 7;

int pos=1;
bool scanned = false;
int distances[5]={};
int angles[]={0,45,90,135,180}; 

void setup() {
  Serial.begin(9600);
  neck.attach(9);
}

void loop() {
  
  scan();   
  delay(100);
      
  
}

int scan(){
  if (scanned == false){
   for(pos = 1; pos <= 5; pos++){
    neck.write(angles[pos]);
    delay(1000);
    distances[pos] = pulse();
    Serial.println(distances[pos]);
   }
  if (pos==5){
    neck.write(90);
    scanned = true;
  }
  }
  
  if (scanned == true){
    neck.write(angles[getMin(distances,5)]);
  }
}

int getMin(int* array, int size){
int minIndex = 0;
 int min = array[minIndex];
 for (int i=1; i<size; i++){
   if (min>array[i]){
     minIndex = i;
     min = array[i];
   }
 }
 return minIndex;
}

long pulse(){
  long duration;
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);
  
  return microsecondsToInches(duration);
  
}

long microsecondsToInches(long microseconds)
{
  return microseconds / 74 / 2;
}

To start with I see that distances is declared as an array of ints but the return value of the pulse() function which you put into it is a long. I don't know what effect that will have but it is inconsistent at best.

Have you tried printing the values in the array before calling getMin() ?

what can I do if lets say I get two values that are minimum and are equal to each other...

What do you want to do ? Maybe save the index of the first value found or the last one found. Possibly set a global variable to indicate that a multiple match has been found but what will you do then ?

You never call getMin (pos never gets to 5 and therefore scanned is never true).

When do you even check the result of getMin ?

As for what to do with two equivalent minimums:

Just make sure your algorithm maintains one of them (practically this often amounts to 'doing nothing')

If having two (or more) equivalent minimums has consequences for your project then as Bob suggests, you're going to have to give us more detail.

for(pos = 1; pos <= 5; pos++){
neck.write(angles[pos]);

arrays in C++ are zero based, not 1 based like in Basic.

check this sketch

int angles[]={65, 45,90,135,180}; 

void setup() 
{
  Serial.begin(9600);
  int x = getMin(angles, 5);  // pass the array and its size
  Serial.print(x);
}

void loop() {}

int getMin(int* array, int size)
{
  int minimum = array[0];
  for (int i = 0; i < size; i++)
  {
    if (array[i] < minimum) minimum = array[i];
  }
  return minimum;
}

arrays in C++ are zero based, not 1 based like in Basic.

Index zero is already accounted for by setting “min” to its value.
The “<=” is more problematical.

@AWOL,
you're right

int getMin(int* array, int size){
int minIndex = 0;
 int min = array[minIndex];
 for (int i=1; i<size; i++){
   if (min<array[i]){
     minIndex = i;
     min = array[i];
   }
 }
 return minIndex;
}

The code works perfectly if I just change ‘min>array_’ to ‘min<array*’ but in that case it doesn’t choose the lowest number, it chooses the highest number…*_

You’ve reversed robtillart’s if logic:

int getMin(int* array, int size){
int minIndex = 0;
 int min = array[minIndex];
 for (int i=1; i<size; i++){
//   if (min<array[i]){             // What you wrote
   if (array[i] < min){             // What Rob wrote
     minIndex = i;
     min = array[i];
   }
 }
 return minIndex;
}

The devil’s in the details.

If I use what Rob wrote it does not work at all, the function just returns 0.

My code returns the value, not the index.

BruceBerrios:
If I use what Rob wrote it does not work at all, the function just returns 0.

Why is that a problem? Your function returns the index of the lowest value in the array, and in the array you're passing to the function, the lowest value is at index 0, so the function appears to be working as designed.

  for(pos = 1; pos <= 5; pos++){ // This ruined me
    neck.write(angles[pos]);
    delay(1000);
    distances[pos] = pulse();
   }

I got it to work by changing pos to zero… Even the most minute things can ruin everything :slight_smile:

Thank you all for taking your time and trying to help!

No, you should have changed “<=” to “<”

Changing <= to < made it run smoother, thank you!

more smoothly

sp.“more correctly”

Post#2… :o