Why do i have to use AttachInterrupt instead of reading the value

Hi, i've made bicycle counter/speed meter.
In order to check for speed i attached halls sensor to arduino and a magnet to one of the wheels so it drives halls sensor from high to low states.
Now what is i do not understand is that doing it realtime doesnt work (meaning realtime is: each loop (cycle) on arduino it checks for halls sensor state and checks whenever it is changed)
You know: (i write code from memory i dont have access to code rigjt now)
int hsens_state;
int nowstate;
void main()
{
nowstate = digitialRead(pin);
If (nowstate != hsens_state)
{
Do math
hsens_state = nowstate;
}
}

Yet this approach doesnt work due to fact it doesnt find difference between states, like it couldnt read from the pin.

I read about why it cant read these values and people came.with attachinterrupt solution (which wokrs)
But im atruggling why is that realtime approach not reailable?
My arduino is 16 Mhz so it should be suitable to catch HIGH from halls sensor whenever magnet is close enough, yet it doesnt. Can somenone explain me why?
Cheers.

attachinterrupt is useful if the pulses you are measuring are frequent and if your code takes too long to reliably see every change. For a bicycle, I would not expect it to be necessary.

As to why your code isn't working, please post the actual code and a picture of your wiring and specify the components.

Maybe the "do arithmetic" bit takes too long.
Or some other part of the code we cannot see takes too long.

You need the interrupt in this case because you cannot reliably read the input at the exact instant that the magnet is triggering the hall effect sensor. The majority of the time the sensor is not triggered, with only a very short time that it is triggered, and that is very difficult to detect with polling of the input.

This is why i am asking, i dont understand why its not catching the signal. Is it because you need a moving magnet near sensor? I thought that you only have to put the magnet close enough and hall sensor will stay high all the time magnet is there

No we don't know why either, but you have the advantage of being able to see both the software and the hardware.

I thought that you only have to put the magnet close enough and hall sensor will stay high all the time magnet is there

Correct.

Now do the math.

How fast is the wheel rotating. How big is the magnet? How long does the magnet stay in front of the sensor? How fast is your loop repeating?

run this with your hardware and open the serial monitor at 115200 bauds

const byte sensorPin = 2;
byte previousState;

void setup() {
  Serial.begin(115200);
  pinMode(sensorPin, INPUT);
  previousState = digitalRead(sensorPin);
}

void loop() {
  byte currentState = digitalRead(sensorPin);
  if (currentState != previousState) {
    Serial.print(F("State Changed to"));
    Serial.println(currentState == HIGH ? F("HIGH") : F("LOW"));
    Serial.flush();
    previousState = currentState;
  }
}

and spin your wheel. Does the display keep up with what's going on ?

According to my math, if your bike is going 20kph, a 1cm sensing aperture would give you a pulse about 2 milliseconds long. Are you sampling it much faster than that?

I thought having 16 Mhz microcontroller will give me somehow at least 100 K readings per second, sensing length is about 4 mm. I cant remember exact time which is required to read value from the pin but i thought it should be at least 100 times smaller than a spinning magnet at radius of 20 cm, okay everything sounds clear now thanks.

executing a digitalRead takes roughly 5µs. The question is what you do then with the result and how long it takes before you can come and read that value again.

Then it's just simple math to see if you will skip or not the magnet passing in front of the sensor depending on the speed/radius of the wheel and the dimension of the magnet

You don’t have to worry about ‘catching’ the magnet pass if you use interrupts - that’s the point.

The interrupt will maintain your sensor count regardless of what else your code is doing.