Saving the lowest value over time

Hi,
I am using the following code, which thanks to some people last night is now doing what I want,
Its time to add another function to it, which I want to run in the setup , I have been thinking about it since last night and Im still not sure how to accomplish what I want to do,

I want to read an input, NthrottleIn, until it has not changed over a period of time, IE 1 second, then make sure that it is within a certain numeric range (im sure i can do that) and if it is, save the value of NthrottleIn to an integer to be used later in the code “Min”.

there is a line
“bNewThrottleSignal = false;” which i have used in two while statements in setup() in order to refresh the input value, which works,

any help is apreciated,
thanks,

Btw the goal is to make a RC ESC for a simple brushed motor, the point of which being the learnign involved and the customizable ESC at the end of it, the end goal is not ismply to control the motor or i would buy an ESC for less than an arduino ,

thanks,

// First Example in a series of posts illustrating reading an RC Receiver with
// micro controller interrupts.
//
// Subsequent posts will provide enhancements required for real world operation
// in high speed applications with multiple inputs.
//
// http://rcarduino.blogspot.com/
//
// Posts in the series will be titled - How To Read an RC Receiver With A Microcontroller

// See also http://rcarduino.blogspot.co.uk/2012/04/how-to-read-multiple-rc-channels-draft.html 

#define THROTTLE_SIGNAL_IN 0 // INTERRUPT 0 = DIGITAL PIN 2 - use the interrupt number in attachInterrupt
#define THROTTLE_SIGNAL_IN_PIN 2 // INTERRUPT 0 = DIGITAL PIN 2 - use the PIN number in digitalRead

#define NEUTRAL_THROTTLE 1500 // this is the duration in microseconds of neutral throttle on an electric RC Car

volatile int nThrottleIn = NEUTRAL_THROTTLE; // volatile, we set this in the Interrupt and read it in loop so it must be declared volatile
volatile unsigned long ulStartPeriod = 0; // set in the interrupt
volatile boolean bNewThrottleSignal = false; // set in the interrupt and read in the loop
int led = 13;
int led2 = 3;
int led3 = 5;
int buzz = 4;
int val = 50;

int Min = 0 ; 
int thresh=50;
int Max =0;
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;
long interval = 30;
int x = 0;
int y =0;


// we could use nThrottleIn = 0 in loop instead of a separate variable, but using bNewThrottleSignal to indicate we have a new signal
// is clearer for this first example

void setup()
{
  // tell the Arduino we want the function calcInput to be called whenever INT0 (digital pin 2) changes from HIGH to LOW or LOW to HIGH
  // catching these changes will allow us to calculate how long the input pulse is
  attachInterrupt(THROTTLE_SIGNAL_IN,calcInput,CHANGE);

  Serial.begin(9600);
  pinMode(led, OUTPUT); 
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
tone (4, 1500, 100);
delay (300);
tone (4, 1500, 100);
delay (300);
tone (4, 1500, 100);


///////////////////////////error loop if rc is higher than zero but not in calibration mode/////////////////
while((nThrottleIn<= 1800)&&(nThrottleIn>= 1000)){
  flash2();
  bNewThrottleSignal = false;
  }
  ////////////////////if RC is high at setup , calibrate HIGH point according to RC max //////////////////  
 if(nThrottleIn> 1800){ 
  Max = nThrottleIn; 
  Serial.println(Max);
   digitalWrite(led2,HIGH);
   delay (300);
   digitalWrite(led2,LOW);
   delay (300);
   digitalWrite(led2,HIGH);
   delay (300);
   digitalWrite(led2,LOW);
   delay (300);
   digitalWrite(led2,HIGH);
   delay (300);
   digitalWrite(led2,LOW);
   
     
   }
   
   
   
     
       

/////////////////if no calibration value was set at startup , set them to 2000 and 1000 by default ////////////////////
 if (Max==0){
  Max = 1950;
 }
 if (Min==0){
  Min = 1000;
 }
 


while(nThrottleIn>1000){
flash1();
 bNewThrottleSignal = false;
  }

}
void loop()
{

      
     //delay(500);
 // if a new throttle signal has been measured, lets print the value to serial, if not our code could carry on with some other processing
 if(bNewThrottleSignal){


   Serial.println(nThrottleIn); 
   Serial.println(val);
   Serial.println(Max);
   Serial.println(bNewThrottleSignal);


   // set this back to false when we have finished
   // with nThrottleIn, while true, calcInput will not update
   // nThrottleIn
   bNewThrottleSignal = false;
 }
 

 
 
////////////scaling the RC inputs to PWM values /////////////////////////
val = map(nThrottleIn,Min,Max, 0, 255);




////////////////buzzer tone control to mimic motor RPM for testing //////////////////////
if (nThrottleIn > 1000){
tone(4,nThrottleIn,1);
}


///////////////////// motor control within normal limits,///////////////////
if ((val > thresh)&&(val<=255)){
analogWrite(led3, val);

}
//////////// turn off motor if throttle is below threshold////////////////////////
if (val < thresh){
  analogWrite(led3, 0);
  }
  
///////////max motor output //////////////////////  
if (val > 255 ){
 analogWrite(led3, 255);
 flash2();
 
 
 }
  
 //////////////////turn of leds during mid range /////////////////////////////// 
if ((nThrottleIn<=1900)&&(nThrottleIn>=1100)){
digitalWrite(led2, LOW); 
digitalWrite(led, LOW);
}  

////////////////////7turn on leds for high and low throttle////////////////////////////
if(nThrottleIn>1900){
  digitalWrite(led, HIGH);
  }
  if(nThrottleIn<1100){
  digitalWrite(led2, HIGH);
  }
 // other processing ...
}

void calcInput()
{
  // if the pin is high, its the start of an interrupt
  if(digitalRead(THROTTLE_SIGNAL_IN_PIN) == HIGH)
  {
    // get the time using micros - when our code gets really busy this will become inaccurate, but for the current application its
    // easy to understand and works very well
    ulStartPeriod = micros();
  }
  else
  {
    // if the pin is low, its the falling edge of the pulse so now we can calculate the pulse duration by subtracting the
    // start time ulStartPeriod from the current time returned by micros()
    if(ulStartPeriod && (bNewThrottleSignal == false))
    {
      nThrottleIn = (int)(micros() - ulStartPeriod);
      ulStartPeriod = 0;

      // tell loop we have a new signal on the throttle channel
      // we will not update nThrottleIn until loop sets
      // bNewThrottleSignal back to false
      bNewThrottleSignal = true;
    }
  }
    }
    
 void flash2()
 {
   unsigned long currentMillis = millis();
 if(currentMillis - previousMillis > interval) {
   previousMillis = currentMillis;  

    
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
    digitalWrite(led2, ledState);
   } 
   } 
   void flash1()
 {
   unsigned long currentMillis = millis();
 if(currentMillis - previousMillis > interval) {
   previousMillis = currentMillis;  

    
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
    digitalWrite(led, ledState);
   } 
   }

To get the minimum and the maximum during a certain time, the initial value of the minimum and maximum has to be set to the first sample value.

During the interval, check the value if it is higher or lower.

if (x < minimum)
  minimum = x;
if (x > maximum)
  maximum = x;

You can use the macros min() and max().

minimum = min (minimum, x);
maximum = max (maximum, x);

If you don’t want to set the minimum and maximum to the first sample value, it is possible to use a trick. Set the minimum to a high invalid number and the maximum to a low invalid number.
But you need to check them at the end of the interval for the invalid numbers.

int minimum = 30000;
int maximum = -30000;

while( ...)
{
  x = analogRead(...);
  minimum = min (minimum, x);
  maximum = max (maximum, x);
}

if (minimum > maximum)
{
  // something is wrong,
  // the minimum and maximum are not valid.
}

thanks,

i´ll think that over and get back to you , i think you´ve sorted my problem quite nicely,

i think you´ve sorted my problem quite nicely,

One of four, maybe.

Your shift key seems to broken. You need to get a new keyboard.

Your tab key seems to function only intermittently. Use Tools + Auto Format to deal with that.

Your enter key seems to stick now and then, putting too many blank lines in your code. A new keyboard should fix that.

PaulS:

i think you´ve sorted my problem quite nicely,

One of four, maybe.

Your shift key seems to broken. You need to get a new keyboard.

Your tab key seems to function only intermittently. Use Tools + Auto Format to deal with that.

Your enter key seems to stick now and then, putting too many blank lines in your code. A new keyboard should fix that.

What a HELPFUL post......

spruce_m00se:
Saving the lowest value over time

    long int x = 9999; // initialize var to a high number
    if (value < x) {
        x = value; // x contains the lowest value seen to date
    }

PaulS:

i think you´ve sorted my problem quite nicely,

One of four, maybe.

Your shift key seems to broken. You need to get a new keyboard.

Your tab key seems to function only intermittently. Use Tools + Auto Format to deal with that.

Your enter key seems to stick now and then, putting too many blank lines in your code. A new keyboard should fix that.

WhY would YO u even boTHER To po

st . suCh a Stupid mess

age?

WhY would YO u even boTHER To po

st . suCh a Stupid mess

age?

For the same reason you did. You come here looking for help, but you can't even be bothered to use capital letters or make your code presentable.

Ok so you wrote it out of an immature desire to heckle people who for no explainable reason leave negative comments instead of leaving people who want to help to do so .

although the auto format was unknown to me and i like it, so your grumpiness paid off,

Erdin:
To get the minimum and the maximum during a certain time, the initial value of the minimum and maximum has to be set to the first sample value.

During the interval, check the value if it is higher or lower.

if (x < minimum)

minimum = x;
if (x > maximum)
  maximum = x;




You can use the macros min() and max().


minimum = min (minimum, x);
maximum = max (maximum, x);




If you don't want to set the minimum and maximum to the first sample value, it is possible to use a trick. Set the minimum to a high invalid number and the maximum to a low invalid number.
But you need to check them at the end of the interval for the invalid numbers.


int minimum = 30000;
int maximum = -30000;

while( …)
{
  x = analogRead(…);
  minimum = min (minimum, x);
  maximum = max (maximum, x);
}

if (minimum > maximum)
{
  // something is wrong,
  // the minimum and maximum are not valid.
}

my code to test is the following, thanks very much , it is stupidly simple, i cant beleive it was impossible for me to think up ,
Is there a way to use millis to run the while statement for a length of time rather than using a delay at the end and incrementing x?

if(nThrottleIn> 1800){ 
    tone (4,1000,2000);
    delay(2000);
    while(x<10){
      
      y=nThrottleIn;
        if(y>Max){
          Max = y;
          }
        if(y<Min){
          Min = y;
          }
     bNewThrottleSignal = false;
     delay(500);
     x++;
     }
    }

Are you wanting to reading a number of samples in a fixed time using millis() instead of always reading a fixed number as you do now ? If so, then, yes you could use millis.

set a variable to the required interval
set a variable to the start time from millis()
while millis() - start time < interval
  do stuff
end of while

e