Reset is not working

Hi
After 5 sec max u should go to 0 but is not.


float u = analogRead(1);
float threshold = 500.0;
// float threshold = 500.0;
static float max_u = 0.0;
static unsigned long timer_start = 0;
static bool holding = false;

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

}
void loop() {


  if (u > threshold) {
    max_u = max(max_u, u);       // Capture u max
    timer_start = millis();      // Reset the 5-sec timer
    holding = true;
  }

  if (holding) {
    if (millis() - timer_start < 5000) {
      // Output or act upon max_u
    }
    else {
      holding = false;         // Release after 5 seconds
      max_u = 0.0;             // Reset
    }
  }
  //  Serial.print("  u= "); Serial.print(  u);
  Serial.print("  u= "); Serial.print( analogRead(1));
  Serial.print("   max_u= "); Serial.println(  max_u);
}

I think analogRead() returns an int not a float.

You should not access hardware outside of functions. I suggest to print the value of the actual variable u at the start of loop().

There is also a flaw; because u is never updated in loop() below if will always be true (once it is true).

and hence timer_start will constantly be updated and if (millis() - timer_start < 5000) will never be true.

Try uncommenting the previous line so you a see what @tom321 means. This line prints the value that u should have, not the value it really has

You are right!

Hi, @tom321
What have you got connected to A1?
A schematic would help.

Why should it go to 0?

Tom.... :smiley: :+1: :coffee: :australia:

it does not matter much.

C++ performs integral-to-floating conversion and integrals in the analogRead() range are properly represented as float, there is no loss of information.

true - just in case this is needed, here is why :

u is a global with a non-constant initializer (a function call), so it undergoes what is called dynamic initialization (the compiler cannot set the value at compile time in flash memory as it would with a constant), which the compiler arranges to happen at runtime during a generated startup sequence, before main() is entered.

The startup code runs the dynamic initialization of globals first, then calls main(). On Arduino, main() then calls init(), then setup(), then enters the loop() cycle. The init() call is what configures the timers, the ADC prescaler, and other hardware needed for analogRead() to function.

The problem is the ordering: u's initializer fires during the startup sequence, before main() runs and therefore before init() configures the ADC. So when analogRead(1) is called to initialize u, the ADC hardware has not yet been set up.

The practical consequence is that u gets possibly initialized with a garbage or meaningless reading, not a valid measurement from pin A1. The call doesn't crash, but the value is unreliable, just some artifact of the possibly uninitialized ADC state.

@tom321 ➜ move that in setup, it will be called post initialization of the hardware and then the value will be reliable.

I have just verified out-of-curiosity:

void setup()
{
  Serial.begin(115200);
  float y = 0x023F;  // 0x023F = 575,   y = 0x440FC000
  Serial.println(y, 2); //shows:
  //----------------------------
  long int *ptr;
  ptr = (long*) &y;
  long m = *ptr;
  //-------------------
  Serial.println(m, HEX);//440FC000
  //------------------------
  float y2;
  memcpy(&y2, &m, 4);
  Serial.println((int)y2, DEC); //show: 575
}

void loop() {
}

formal reasoning is better than just one example :)

A 32-bit float (IEEE 754) has a 23-bit mantissa, but with the implicit leading 1 bit it carries 24 bits of integer precision β€” meaning it can represent every integer exactly up to 2^24, which is 16,777,216.

analogRead() on an Arduino returns a 10-bit value: 0 to 1023 (or 4095 on some). That is nowhere near 16 million, so every integer in that range maps to an exact float representation. The mantissa has more than enough bits to hold it without rounding. No information is lost in the conversion.

If you were reading, say, a 32-bit sensor value, the story would be very different β€” integers above 16,777,217 start losing their least significant bits as the float can no longer represent them exactly, and you would need a real double (53-bit mantissa, exact up to 2^53) or stay in integer arithmetic entirely.