Finding the max and min value of sensor reading

so when there is no strain deltaMax and deltaMin will be zero.

I expect that not to be true as there will probably noise. At least your sketch should be able to cope with that.

OK I understand the problem better.

  • A solution is to make a reference measurement in the setup() function and use that to determine UP/DOWN in the loop()
  • another solution is to hard code such reference values
  • another solution is to determine up/down direction from the array of 10 measurements.
  • there are many (heuristic) ways to do this e.g. compare 1st and last measurement is a first order indication.

Hi again,

Well I defined a variable average_offset in void offset()...so now i have a fixed average offset value form first 10 readings.

void setup() 
{
  Serial.begin(9600);
  pinMode(10, OUTPUT); 
  pinMode(11, OUTPUT);
  offset();
}
void offset(){
  for (int i = 0; i< numReadings; i++)
  {
    total_offset-=readings[i];
    readings[index] =analogRead(A0);
    total_offset+=readings[i];
    index++;
  }
  average_offset=total_offset/numReadings;
}

Then when i apply the strain in up /down direction i can see that the led for up and down turns on..However I do have a small problem for the case of no strain.
In case of no strain ; average,max,min values are nearly same [+-5 acceptable].

 if(sensorMax-sensorMin <=3 && deltaMax<=10 &&deltaMin>=-10){       //nostrain
    digitalWrite(10,LOW);
    digitalWrite(11,LOW);
  }

 if(average<average_offset){                                        //DOWN
    digitalWrite(11,LOW);
    digitalWrite(10,readings[index]);
  }
 if(average>average_offset){                                        //UP
    digitalWrite(10,LOW);
    digitalWrite(11,readings[index]);
  }

this is the serial uutput of no strain case [DMAX=sensorMax-average ,DMIN=sensorMin-average A_OFF:average_offset AVG=running average ]

SENS: 579 DMAX: 0.40 DMIN: -0.60 A_OFF: 568.00 MIN: 578 MAX: 579 AVG: 578.4
SENS: 578 DMAX: 0.60 DMIN: -0.40 A_OFF: 568.00 MIN: 578 MAX: 579 AVG: 578.4
SENS: 579 DMAX: 0.60 DMIN: -0.40 A_OFF: 568.00 MIN: 577 MAX: 579 AVG: 578.0
SENS: 579 DMAX: 1.00 DMIN: -1.00 A_OFF: 568.00 MIN: 577 MAX: 578 AVG: 577.6
SENS: 578 DMAX: 0.40 DMIN: -0.60 A_OFF: 568.00 MIN: 577 MAX: 578 AVG: 577.4

but UP led is blinking because average_offset < average..therefore for no strain case LEDs dont show correctly...

2nd part ; I want to return the new average_offset each eg-.5 minutes is it possible? i should maybe take a look at time interrupts.

thanks in advance

keep it simple.

void offset()
{
  total_offset = 0;
  for (int i = 0; i< numReadings; i++)
  {
    total_offset += analogRead(A0);
  }
  average_offset = total_offset/numReadings;
}

try this variation // and please please add spaces: InEnglishYouUseSpacesTooForReadabilitySoWhyNotInC++? :wink:

#define LED_DOWN 10
#define LED_UP 11
if (sensorMax-sensorMin <= 3 && deltaMax <= 10 &&deltaMin >= -10) {       //nostrain
    digitalWrite(LED_DOWN , LOW);
    digitalWrite(LED_UP , LOW);
}
else if (average < average_offset) {                                        // DOWN
    digitalWrite(LED_DOWN , readings[index]);
    digitalWrite(LED_UP , LOW);
  }
else if(average > average_offset ) {                                        //UP
    digitalWrite(LED_DOWN , LOW);
    digitalWrite(LED_UP, readings[index]);
  }

2nd part ; I want to return the new average_offset each eg-.5 minutes is it possible? i should maybe take a look at time interrupts.

have a look at blink without delay example how you can schedule a certain action with time. However as you want to be sure that there is no strain at the moment of recalibration you should consider a user action - e.g. make a pin high - and then read the new calibration until the pin is low.

Hello again,

if (sensorMax-sensorMin <= 3 && deltaMax <= 10 &&deltaMin >= -10) {       //nostrain
    digitalWrite(LED_DOWN , LOW);
    digitalWrite(LED_UP , LOW);
}
else if (average < average_offset) {                                        // DOWN
    digitalWrite(LED_DOWN , readings[index]);
    digitalWrite(LED_UP , LOW);
  }
else if(average > average_offset ) {                                        //UP
    digitalWrite(LED_DOWN , LOW);
    digitalWrite(LED_UP, readings[index]);
  }

This part is not consistent..Well when there is no strain I get

SENS: 621 DMAX: 0.80 DMIN: -0.20 A_OFF: 621.80 MIN: 621 MAX: 622 AVG: 621.2
SENS: 622 DMAX: 0.80 DMIN: -0.20 A_OFF: 621.80 MIN: 621 MAX: 621 AVG: 621.0
SENS: 621 DMAX: 0.00 DMIN: 0.00 A_OFF: 621.80 MIN: 621 MAX: 621 AVG: 621.0
SENS: 621 DMAX: 0.00 DMIN: 0.00 A_OFF: 621.80 MIN: 621 MAX: 621 AVG: 621.0

which fullfills all cases for no stain..However when I apply strain in up or down dsirection and hold it for a second the max and min values come close therefore the boths leds getting off like there is no strain..I need to find a specific condition for no strain case..

Additionally, reagarding coming back to void offsett in order to define new offset value every 5 minutes i tried this ;

int updateCounter = 0;

 if (updateCounter++ >20) {
    offset();
    updateCounter = 0;
  }

after e.g 20 loops [around ]1 minute it goes back to void offset() and defines the average_offsett again and yeap it works at least now i am able to see my max min average and average offset value..but the only problem is led condition in no strain case .

Hello again,

Regarding my enquiry, I have progressed a bit more now there is only one problem left!..

I am now able to read sensor,take average the sensor readings, finding max and min value of sensor readings and now i also can see the standard deviation of sensor readings..Moreover,I can also save a average_offset value from 1st reading and every 5 minutes this value is renewed in order to find the direction of strain...The only problem left : I can not determine the case for no strain!

when there is no strain ;
Sensor reading ,max,min,average_offset and average values are nearly same--standard deviation is nearly zero..
Up Direction ;
average value decreases so if (average_offset > average ) then its UP
Down Direction ;
average value increases so if (average_offset < average ) then its DOWN

but for both UP and DOWN cases when i hold it for a while; Sensor reading ,max,min, and average values are coming closer so I dont have any option to define a condition for no stain case...

any idea?

thanks in advance..

you should only do the calibration if there is no strain.
If you do it while in the up position that would become the no strain.

 if ((abs(average_offset - average) < smallThresshold)  && ((millis() - lastTime) > 300000UL)) calibrate();

...hi, i'm new to arduino and programming. i want to find the maximum reading of a sensor. i made it worked but the problem is i want to get the maximum of all the values and not only of certain number of reading. can you help?thanks in advance.. :slight_smile:

...want to get the maximum of all the values...

use code similar as proposed in answer 2/3 - Finding the max and min value of sensor reading - #3 by anatolyk69_gmail.c - Sensors - Arduino Forum -
create a variable that holds the max value so far.
initialize it with the first reading and
update it when needed after each new reading of the sensor.

...hi again!!
sorry, i'm really new to this. isn't the "INBUF" in answer 2 represents the number of readings to be compared?
suppose i have this very simple one and i want to serial.print the maximum reading and the current reading at the same time. thank you very much!

const int ledPin = 13;      // led connected to digital pin 13
const int sensorPin = A0; // the piezo is connected to analog pin 0

// these variables will change:
int sensorReading = 0;      // variable to store the value read from the sensor pin

void setup() {
 pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
 Serial.begin(9600);       // use the serial port
}

void loop() {
  // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(sensorPin);
  
  Serial.println(sensorReading);         
  delay(100);  // delay to avoid overloading the serial port buffer
}

try this, I removed all the comments so you only need to read the code.

const int ledPin = 13;     
const int sensorPin = A0;
int sensorReading = 0; 
int maxReading = 0;

void setup() 
{
 pinMode(ledPin, OUTPUT);
 Serial.begin(9600);
}

void loop() 
{
  sensorReading = analogRead(sensorPin);
  if (sensorReading > maxReading) maxReading = sensorReading;
  
  Serial.print(maxReading);         
  Serial.print('\t');         
  Serial.println(sensorReading);
  
  delay(100); 
}

wow..thank you very much for the help!!!stupid me, it was just that simple. :stuck_out_tongue:

thanks again!!!:slight_smile:

sometimes you have to walk long and winding roads to come to a simple solution - I know it I've been there (even recently;)