digitalread() wrong when using analogwrite()

Hello,

I want to determine a direction with two slightly shifted high/low signals S1, S2 (hall sensors)
and give a pwm output.

Now I have following problem: the measurment of the direction is always correct until I write a PWM output on another pin. Then the measurment is sometimes wrong.

If I write the PWM with a second Arduino, the measurement of the first Arduino is always correct.

Now to the code:

So if S2 jumps to HIGH and S1 is already HIGH,
or if S2 jumps to LOW and S1 is already LOW -> forward motion

attachInterrupt(digitalPinToInterrupt(S2), check_state, CHANGE);

void check_state()
{
  tFlag = true;
  state1 = digitalRead(S1); // volatile variables
  state2 = digitalRead(S2);
}

if tFlag == true

I call in the loop function:

void check() {

  if ( state1 == state2 && state2 != state2_temp)
  {
    // forward motion 
    // measure something on each change of signal 2 when forward motion
  {
}

which works perfectly fine till I analogWrite a PWM in the loop function, then I get the forward motion sometimes wrong.

I would guess that writing the PWM takes some time and when it performs digitalRead() the signal already changed again?

Maybe someone has a clue, or at least a better idea for the code?

Thanks!

EDIT: I just found out it works fine if I use PIN 18 (TX1) and 21 (SCL) for S1 and S2 on a Arduino Mega 2560 but not with others Pins (e.g. 18 and 20) and I have the same problem when I use a Arduino nano?

How close together are those sensors? How much time in between triggering?

The handling of the PWM signal (which I understand to be a timer interrupt) may delay the handling of the interrupt of your sensor. Also the digitalRead() function takes quite some time - it's much faster to read the respective registers directly (that way you can read both pins in one go, which takes maybe 2-3 clock cycles, instead of something like 50 cycles per digitalRead).

The signal of the sensors are shifted for 4.5 degrees. There are 20 pulses during one full 360 degree turn, where one full turn usually takes 1 second. So if Signal 2 goes to HIGH, Signal 1 should be still HIGH for 1/360*4.5 = 12.5ms.

Thanks, any tips how to call the register directly to read both pins in one go? (Never did something like that)

And how can it be that it works on the mentioned pins and on the others not?

Thanks.

I don't think all pins on the ATmega have interrupts, that may be a difference already.

Hi,
Welcome to the forum.

Can you post your entire code please?

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

What are your sensors, do you have pull-up or pull-down resistors?

Thanks.. Tom.. :slight_smile: