Using "MIN" but with more than two numbers...

Hi!

I'm working on this project where I measure light intensity with a BH17150. My problem is that I need to measure like 5 times and then react on the lowest value of the 5.

How can I do that? I have searched like crasy on google without any result. Hope one of you have an advise:)

By the way I use an UNO

Regards
Michael

Can you share datasheet of the product

If it is analog output you can take moving average sample of output. & set value of highest & lowest range for which you wanted to respond.

If you can put datasheet & relevant circuit we can help here.

Here is link for the project:

Here is the code:
/*
This is a simple code to test BH1750FVI Light senosr
communicate using I2C Protocol
this library enable 2 slave device address
Main address 0x23
secondary address 0x5C
connect this sensor as following :
VCC >>> 3.3V
SDA >>> A4
SCL >>> A5
addr >> A3
Gnd >>>Gnd

Written By : Mohannad Rawashdeh

*/

// First define the library :
#include <BH1750FVI.h> // Sensor Library
#include <Wire.h> // I2C Library

uint16_t Light_Intensity=0;
// Call the function
#define LedPin 9 // led connecting to pin D9
BH1750FVI LightSensor;

int SensorValue =0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
// call begin Function so turn the sensor On .
LightSensor.begin();
/*
Set the address for this sensor
you can use 2 different address
Device_Address_H "0x5C"
Device_Address_L "0x23"
you must connect Addr pin to A3 .
/
LightSensor.SetAddress(Device_Address_H); //Address 0x5C
// To adjust the slave on other address , uncomment this line
// lightMeter.SetAddress(Device_Address_L); //Address 0x5C
//-----------------------------------------------
/

set the Working Mode for this sensor
Select the following Mode:
Continuous_H_resolution_Mode
Continuous_H_resolution_Mode2
Continuous_L_resolution_Mode
OneTime_H_resolution_Mode
OneTime_H_resolution_Mode2
OneTime_L_resolution_Mode

The data sheet recommanded To use Continuous_H_resolution_Mode
*/
LightSensor.SetMode(Continuous_H_resolution_Mode);
pinMode(9,OUTPUT) // Connect LED With 100ohm resistor
// to pin D9

}

void loop() {
// put your main code here, to run repeatedly:
// call GetLightIntensity() Function , so the sensor read
//the Intensity Value and send it
Light_Intensity=LightSensor.GetLightIntensity();
delay(1000);

SensorValue=map(Light_Intensity,0,2000,255,0);
SensorValue=constrain(SensorValue,255,0);
analogWrite(LedPin,SensorValue);
// ready to another reading .
}

As you can see the code read the ambient light intensity value and controls the intensity of an led from that value.

Regards
Michael

Hi, you need to Google sorting arduino

That will give you most of the sorting algorithms you need.

Tom.... :slight_smile:

You could write a function to make the 5 readings then you can compare as you go.

eg.

uint16_t min_of_five_readings()
{
uint16_t minValue=0xffff;
uint16_t oneValue;

for(int n=0; n<5; n++)
  {
   oneValue=LightSensor.GetLightIntensity();
   if (oneValue < minValue)
      minValue=oneValue;
  }
return minValue;
}

TomGeorge:
Hi, you need to Google sorting arduino

That will give you most of the sorting algorithms you need.

Tom.... :slight_smile:

You only need to sort if you want the readings in some order; if you only want the lowest, a simple running "min" will suffice.

The example below, takes 5 readings over a 1 second period and the lowest of those readings, is used to set the LED. It could be useful for filtering noise from a sensor reading. Your question did not quite say what problem you are trying to solve but hopefully, the example can give you some ideas.

//globals
const int MAX_INT= 0x7FFF;  //highest positive value for a signed integer

void loop() {
  
  //take 5 readings immediately and use the lowest value
  lowestLight = MAX_INT;  //initialise with a value greater than the highest returned by GetLightIntensity 
  for (int i = 0; i < 5; i++) {
    int lightIntensity = LightSensor.GetLightIntensity();
    lowestLight = min(lowestLight, lightIntensity);
    delay(200);
  }

  SensorValue = map(lowestLight, 0, 2000, 255, 0);
  SensorValue = constrain(SensorValue, 255, 0);
  analogWrite(LedPin, SensorValue);
  
  // ready to another reading . 
}

Hi,
Sorry for the late reply.
Thanks for all the support! Really great with a forum like this!:slight_smile:

I will try to integrate your code suggestions to my code. But I'm not a very experienced programmer so bear with me:)

I will get back to you when I have a result or maybe need more help!

Regards
Michael

Hi again,

First of all, I'm a beginner when it comes to coding....
I have looked at your suggestions and I don't fully understand what going on.
Anyway I have spend the last days going through tutorials on youtube and I have cooked something
together, code is below...please don't laugh:)

The end part of the code, I have alot of serial.print commands. I use these to better see whats going on in the program.

Now a short explanation: The code takes a light mesurement, and call this "value1" Then we wait for a second and takes another measurement and call this "value2"

Then the code figures out what of the 2 values are the lowest, by using if commands.

My problem now is to use the lowest value in the rest of the program where I adjust the led's brightness according to the lowest value. how do I make a variable called "value"?
as you can see I tried to do it this way:
if (value1<value2)
{
int value=value1;

and so on....

whole loop here:

void loop() {
uint16_t Light_Intensity = LightSensor.GetLightIntensity();// Get Lux value
Serial.print("Light: ");
Serial.print(Light_Intensity);
Serial.println(" lux");
Serial.println();

// call GetLightIntensity() Function , so the sensor read
//the Intensity Value and send it
Light_Intensity=LightSensor.GetLightIntensity();

int value1=Light_Intensity;

delay(2000); // wait for 2 seconds

// call GetLightIntensity() Function , so the sensor read
//the Intensity Value and send it
Light_Intensity=LightSensor.GetLightIntensity();

int value2=Light_Intensity;

//Determine what mesurement is lowest of 2

if (value1<value2)
{
int value=value1;
}

else if (value1>value2)
{
int value=value2;
}

else if (value1==value2)
{
int value=value1;
}
Serial.println(value1);
//Adjust LED bightnest according to Lux value

if (value>=0 && value<=4)
{
analogWrite(LedPin,38);
Serial.println("1");
}
else if (value>4 && value<=40)
{
analogWrite(LedPin,64);
Serial.println("2");

}
else if(value>40 && value<=400)
{
analogWrite(LedPin,120);
Serial.println("3");

}
else if (value>400 && value<=4000)
{
analogWrite(LedPin,220);
Serial.println("4");

}
else if (value>4000)
{
analogWrite(LedPin,255);
Serial.println("5");
}
}

By the way, next step for me is probaly to use a timer instead of delays... but small steps:)

Wait guys, I think I just solved it...

instead of:

//Determine what mesurement is lowest of 2

if (value1<value2)
{
int value=value1;
}

else if (value1>value2)
{
int value=value2;
}

else if (value1==value2)
{
int value=value1;
}

I deleted the "int"
And it works for the moment

{
    int value=value1;
  }

That "int" immediately goes out of scope - just use the global

Please get into the habit of using code tags.

AWOL:

{

int value=value1;
  }



That "int" immediately goes out of scope - just use the global


Please get into the habit of using code tags.

I will.
Thanks for the advise!:slight_smile: