Simple code for holding two states with the same value?

So I have two inputs, and when one goes low, I want a counter to increase. No matter how many times this input is then pulled low, the counter does not increment. The counter only increments when input #2 goes low, and again will not keep incrementing until #1 goes low. So it only can increment when a different input is pulled low.

  if (digitalRead(magnet1) == LOW && switchState == 1) //input 1 is low and state variable =1
  {
    switchState = 2; //change state
    count+=5;  //increment
    module1.setDisplayToDecNumber(count, 0x02);
    delay(100);
  }
  
  if (digitalRead(magnet2) == LOW && switchState == 2) //can only increment if switchState=2 and input 2 is low
  {
    switchState = 1;
    count+=5;
    module1.setDisplayToDecNumber(count, 0x02);
    delay(100);
  }

This code does not work. Currently depending on whether I declare switchState as a 1 or a 2, that input just causes the counter to increment indefinitely.

Thanks in advanced!

Please post all your code because the context of your variable scope is important.

If this is in the loop() function, then you need to be aware that the switchstate variable is created every time the loop starts unless you have declared it as ‘static’.

It also sounds like you need to detect a transition on the magnet1 and magnet2 pins, rather than just testing the state.

What, exactly, is connected to these two pins, and what are you trying to accomplish (which is not the same as what you are trying to do)?

The goal is to count the number of half spins a wheel makes. I have two hall sensors above the wheel, and two magnets on the wheel. When one magnet passes the circuit pin 1 is pulled low and I increment the counter by 0.5. When the other magnet passes the circuit pin 2 is pulled low.

I want pin 1 to pull low only if it was not the most recently pulled low pin, and the same for pin 2. That way if the wheel stops near a sensor and wobbles back and forth the counter won't increment more than once, and so that the counter doesn't increment 1000 times when the magnet briefly passes by the sensor, only once.

I have declared all the variables (except unless otherwise shown in the code) outside of the main loop and outside of the setup part. That is the only other code there is.

Thanks again for your help!

and so that the counter doesn't increment 1000 times when the magnet briefly passes by the sensor, only once.

This would be handled by detecting the transition, from LOW to HIGH or HIGH to LOW. Only increment the counter at the transition.

I want pin 1 to pull low only if it was not the most recently pulled low pin

This doesn't make sense. The pin is pulled HIGH or LOW by the magnet passing by. I think what you mean is that you only want to increment the counter if the switch number that changed state is not the same as the switch number that changed state last time.

This is simple to detect. Have a variable keep track of which switch was last activated. If the current switch is not the same switch, increment the counter and make the last switch the current switch. If the current switch is the same switch, ignore it.

This would be handled by detecting the transition, from LOW to HIGH or HIGH to LOW. Only increment the counter at the transition.

Can that be done? I was unaware of this?!

This doesn't make sense.

Sorry for the confusion. This pin is normally pulled up to 5V. When the magnet passes by it is pulled down to 0V. If magnet1 passes by sensor1 it will pull down pin1. Then, if the wheel stops and goes backwards again, magnet1 will pass sensor1 again, however since it was the last magnet to pull it down, I don't want anything to happen. Only if magnet2 pulls pin 2 down first by passing sensor2. Once that happens magnet1 can then pull pin 1 down via sensor1 to increment.

Does that make sense?

Can that be done?

Of course it can. All you need to do is keep track of the state from last time. If the state this time is not the same as the state last time, a transition has occurred (either from HIGH to LOW or LOW to HIGH). All you need to do then is determine if it is the right transition (based on the current state).

Does that make sense?

Sure. All you need to do is keep track of which sensor was counted last time, and don't count if the same sensor is triggered again.

Right, and that was what I tried to do. Alternatively, can you explain why the code I posted doesn't work? Maybe that will help me solve my problem!

Alternatively, can you explain why the code I posted doesn’t work?

Well, to start with, it is not detecting transitions. Ignoring that for a moment, you should have nested ifs. Much easier to understand and debug that compound ifs.

Also, the fact that you did not post all of your code, so we can see how/where switchState is declared was pointed out, but you didn’t respond to that, by posting all of your code.

Here is my updated code. I tried to implement both things you said, nested ifs and going by transitions. Right now this code does nothing. It keeps pin 2 pulled low the entire time for some reason, and pin 1 increases indefinitely when activated.

Here is the entire code.

#include <TM1638.h>

// define a module on data pin 8, clock pin 9 and strobe pin 7
TM1638 module1(8, 9, 7);

unsigned long count = 0;

int sensor1 = 1; //sensor 1 attached to pin 1
int sensor1Last = LOW; //define last state of sensor1, set to LOW
int sensor1Current = LOW; //define current state of sensor1, set to LOW

int sensor2 = 2; //sensor 2 attached to pin 2
int sensor2Last = LOW; //define last state of sensor2, set to LOW
int sensor2Current = LOW; //define current state of sensor2, set to LOW

int switchState = 2;

void setup() {
// display a hexadecimal number and set the left 4 dots
module1.setDisplayToDecNumber(count, 0x02);

pinMode(sensor1, INPUT); //set pin 1 as an input
pinMode(sensor2, INPUT); //set pin 2 as an input
}

void loop() {

sensor1Current = digitalRead(sensor1); //read current state of sensor1
sensor2Current = digitalRead(sensor2); //read current state of sensor2

if ( (digitalRead(sensor1) == LOW) && (sensor1Last != sensor1Current) ) //if sensor1 is low (activated) and sensor1 last state was high
{
if (switchState == 1)
{
switchState = 2;
count+=5;
sensor1Last = sensor1Current; //update sensor1 state
module1.setDisplayToDecNumber(count, 0x02);
delay(100);
}
}

if ( (digitalRead(sensor2) == LOW) && (sensor2Last != sensor2Current) ) //if sensor2 is low (activated) and sensor2 last state was high
{
if (switchState == 2)
{
switchState = 1;
count+=5;
sensor2Last = sensor2Current; //update sensor1 state
module1.setDisplayToDecNumber(count, 0x02);
delay(100);
}
}

Thanks again!

  sensor1Current = digitalRead(sensor1);  //read current state of sensor1
  sensor2Current = digitalRead(sensor2);  //read current state of sensor2

   
  if ( (digitalRead(sensor1) == LOW) && (sensor1Last != sensor1Current) )  //if sensor1 is low (activated) and sensor1 last state was high
  {

Why are you reading each sensor so often?

Try this:

  sensor1Current = digitalRead(sensor1);
  if(sensor1Last != sensor1Current)
  {
     // A transition occurred. Was it HIGH to LOW or LOW to HIGH?
     if(sensor1Current == LOW)
     {
        // We want to count this event if it happened on a different sensor from the last one
        if(switchState == 1)
        {
           count += 5;
           switchState = 2;
        }
     }
  }
  sensor1Last = sensor1Current;

  // Repeat for other sensor

  module1.setDisplayToDecNumber(count, 0x02);

Good news and bad news!

Your code works! The bad news is so did mine, except I was missing a pullup resistor on the circuit! Yours is much simpler though so I thank for that. I was so confused to as why mine didn't work though haha - it did :sweat_smile: