Programming Error (hall effect sensor)

HI,

Can anyone help me, please?

I just tried my codes with the sensors but it did not work as I wanted. It runs for 10 times with one sensor only. I want both output ones. As if, 3000 time it will ON after contact with first sensor and then wait until it contact with second sensor then turn off .

flow chart will be like,
(Start > Magnetic Sensor 1 ON → Solenoid Valve ON → Magnetic Sensor 2 ON —> Solenoid Valve OFF ) 3000 times.

First of all I declared the global variables

 /*Declaring Global variables*/
int sensor_1_pin = 2;        //hall effect sensor output connected to Ard
int sensor_2_pin = 3;        //hall effect sensor output connected to Ard 

int led = 7;                      //Declared LED 


int sensor_1_value = 0;     
int sensor_2_value = 0;

int cycle = 3000;
int v = 0;

void setup (), has been described as it is simply just declared the pinModes.

/*Declaring Setup  
void setup()
{
  Serial.begin (9600);
  pinMode(sensor_1_pin, INPUT);
  pinMode(sensor_2_pin, INPUT);
  
  pinMode(led, OUTPUT);
}

My main issue is the loop. Last two weeks, I tired a lot to sort it out. there are 3 issues and those stuck me for ages.

Issue 1: when I brings the sensor1 closure to the Magnet, it LED turn on until I remove it but I want to remain it on until the (second sensor) sensor2 come close to the Magnet.

Issue 2: When I brought the sensor1 close to the magnet, it runs for 3000 times until i remove it. But I want the led will turn on and then sensor 2 will be closure and led will turn off. AND OVERALL, it WILL COUNT as 1 CYCLE.

Issue 3: the following code give me value like “Sensor 1 Value = 1” and “Sensor 2 value =1”… No idea why??
Please help.

void loop()
{
//read and store sensor value (1 or 0)
  sensor_1_value = digitalRead(sensor_1_pin);     //Collect Sensor 1 Value from the sensor 1 pin
  sensor_2_value = digitalRead(sensor_2_pin);     //Collect Sensor 2 Value from the sensor 1 pin
  
  Serial.print ("Sensor 1 value = ");                                     
  Serial.println (sensor_1_value);
  Serial.print ("Sensor 2 value = ");
  Serial.println (sensor_2_value);
 
 //if sensor 1 value doesn't match sensor 2 value
  if (sensor_1_value != sensor_2_value)
  { if (v<cycle)
    {//if sensor 1 value is HIGH
      if(sensor_1_value == HIGH)
         {digitalWrite(led, HIGH);
          Serial.print ("Sensor 1 value = ");
          Serial.println (sensor_1_value); }
//if sensor 2 value is HIGH
      else if(sensor_2_value == HIGH)
         {   digitalWrite(led, LOW);
             Serial.print ("Sensor 1 value = ");
             Serial.println (sensor_1_value);}
    } 
v++; }
 sensor_1_value = sensor_2_value;
}

However, I actually, want to get the feedback from the sensor and led will turn on and off according. As when sensor 1 will bring closure to the magnet, it will turn on and then it will remain on until sensor 2 will come closure to the magnet. Similarly LED will remain off until sensor 1 will bring closure. and cycle will count only when the LED is turn on and off once.

Please help.
Please help anybody. I am hopeless. :frowning:

Your code makes no sense. You should read the value of the first sensor. If the state is that of "the magnet is here", then turn the LED on.

Completely independently, read the value of the second sensor. if the state is that of "the magnet is here" AND the LED is on, turn it off.

Decide whether to count when the LED is turned on or when it is turned off. Don't count both changes, though.

It would seem that you don't want to do ANYTHING if the value of the counter is greater than the max, so ALL the code in loop() should be inside an if block.

And v is still a piss-poor name for the cycle counter.

PaulS:
Your code makes no sense. You should read the value of the first sensor. If the state is that of “the magnet is here”, then turn the LED on.

Completely independently, read the value of the second sensor. if the state is that of “the magnet is here” AND the LED is on, turn it off.

Decide whether to count when the LED is turned on or when it is turned off. Don’t count both changes, though.

It would seem that you don’t want to do ANYTHING if the value of the counter is greater than the max, so ALL the code in loop() should be inside an if block.

And v is still a piss-poor name for the cycle counter.

Sir,
I know I am bad in programming. However, as you said previously that to add currentState and newState. I did (as per my knowledge) and it still is not working. could you help me to sort this out please.

void loop()
{
  int newState = 0;
  //Read and store sensor state (1 or 0)
  sensor_1_value = digitalRead(sensor_1_pin);
  sensor_2_value = digitalRead(sensor_2_pin);
  
  Serial.print ("Sensor 1 value = ");
  Serial.println (sensor_1_value);
  Serial.print ("Sensor 2 value = ");
  Serial.println (sensor_2_value);
  
  //if sensor 1 value doesn't match sensor 2 value
  if (currentState==(sensor_1_value==1 && sensor_1_value==1) && (sensor_1_value==0 && sensor_1_value==1))
  if (sensor_1_value != sensor_2_value)
  {
    if (i<cycle)
    {
      if(sensor_1_value == HIGH)             //sensor 1 value is a 1, turn off led
      {
              digitalWrite(led, LOW);
              Serial.print ("Sensor 1 value = ");
              Serial.println (sensor_1_value);
      }
      else if(sensor_2_value == HIGH)         //sensor 2 value is a 1, turn on led
      {
             digitalWrite(led, HIGH);
             Serial.print ("Sensor 2 value = ");
             Serial.println (sensor_2_value);
      }
    } 
   i++; 
  }
 currentState=newState;
}//<-----end of void loop()

You are still trying to deal with both sensors at the same time, as though somehow there was something magic about having two sensors. There is NOT.

The idea, apparently, is that moving the magnet past sensor one should cause the LED to be turned on. Moving the magnet past sensor two should cause the LED to be turned off, and the completion of a cycle to be noted.

If that description is correct, notice that there is nothing in the second sentence that cares a whit about sensor one.

void loop()
{
   if(cycle_count < number_of_cycles_to_complete)
   {
      int currStateOne = digitalRead(sensor_1_pin);
      if(currStateOne != prevStateOne)
      {
         // The magnet just arrived or it just left
      }
      prevStateOne = currStateOne;

      int currStateTwo = digitalRead(sensor_2_pin);
      if(currStateTwo != prevStateTwo)
      {
         // The magnet just arrived or it just left
      }
      prevStateTwo = currStateTwo;
   }
}

Where the comments say “The magnet just arrived or it just left” is where you need to add additional code.

You want to decide whether “the magnet just arrived” matters, of if “the magnet just left” matters. You can make either state important, so long as it is not both states that are handled.

Lets suppose that “the magnet just arrived” is important, and that that state is HIGH. Depending on how the sensor is wired, “the magnet just arrived” might be LOW.

Add this code, after the first comment:

         // The magnet just arrived or it just left
         if(currStateOne == HIGH)
         {
            // The magnet just arrived

            // Turn the LED on
            ledState = HIGH;
            digitalWrite(ledPin, ledState);
         }

After the second comment, you’d have a similar if statement, dealing with currStateTwo. In that block, you’d test that the LED is on. If it is, turn it off AND increment cycle_count.

PaulS:
You are still trying to deal with both sensors at the same time, as though somehow there was something magic about having two sensors. There is NOT.

The idea, apparently, is that moving the magnet past sensor one should cause the LED to be turned on. Moving the magnet past sensor two should cause the LED to be turned off, and the completion of a cycle to be noted.

If that description is correct, notice that there is nothing in the second sentence that cares a whit about sensor one.

void loop()

{
  if(cycle_count < number_of_cycles_to_complete)
  {
      int currStateOne = digitalRead(sensor_1_pin);
      if(currStateOne != prevStateOne)
      {
        // The magnet just arrived or it just left
      }
      prevStateOne = currStateOne;

int currStateTwo = digitalRead(sensor_2_pin);
      if(currStateTwo != prevStateTwo)
      {
        // The magnet just arrived or it just left
      }
      prevStateTwo = currStateTwo;
  }
}




Where the comments say "The magnet just arrived or it just left" is where you need to add additional code.

You want to decide whether "the magnet just arrived" matters, of if "the magnet just left" matters. You can make either state important, so long as it is not both states that are handled.

Lets suppose that "the magnet just arrived" is important, and that that state is HIGH. Depending on how the sensor is wired, "the magnet just arrived" might be LOW. 

Add this code, after the first comment:


// The magnet just arrived or it just left
        if(currStateOne == HIGH)
        {
            // The magnet just arrived

// Turn the LED on
            ledState = HIGH;
            digitalWrite(ledPin, ledState);
        }




After the second comment, you'd have a similar if statement, dealing with currStateTwo. In that block, you'd test that the LED is on. If it is, turn it off AND increment cycle_count.

I think I am still missing some tricks, its still not working. As I am not getting anything properly. Sorry for disturbing you again and again. Please help.

void loop()
{
   if(cycle_counter < cycle_to_complete)
   {
      int sensor_1_value = digitalRead(sensor_1_pin);
      if(sensor_1_value == HIGH)
      {// The magnet just arrived

            // Turn the LED on
            digitalWrite(solenoid_valve, HIGH);
      }

      int sensor_2_value = digitalRead(sensor_2_pin);
      if(sensor_2_value = HIGH)
      {// The magnet just arrived

            // Turn the LED off
            digitalWrite(solenoid_valve, LOW);
      }
   }cycle_counter++;
}
      int sensor_1_value = digitalRead(sensor_1_pin);
      if(sensor_1_value == HIGH)
      {// The magnet just arrived

No, it didn't. You left of the part about the current state not being the same as the previous state.

            // Turn the LED on
            digitalWrite(solenoid_valve, HIGH);

So, you have an LED attached to the solenoid_valve pin? Why all this crap about LEDs when what you want to do is open or close a solenoid? If you want to open and close a solenoid, say so. Don't try to hide that by talking about LEDs.

It makes not a damned bit of difference to the Arduino what is connected to the pin, but it does to me.

      }cycle_counter++;

No code EVER follows a } on the same line.

That code belongs INSIDE the curly brace, not after it.

PaulS:

      int sensor_1_value = digitalRead(sensor_1_pin);

if(sensor_1_value == HIGH)
      {// The magnet just arrived



No, it didn't. You left of the part about the current state not being the same as the previous state.



// Turn the LED on
            digitalWrite(solenoid_valve, HIGH);



So, you have an LED attached to the solenoid_valve pin? Why all this crap about LEDs when what you want to do is open or close a solenoid? If you want to open and close a solenoid, say so. Don't try to hide that by talking about LEDs.

It makes not a damned bit of difference to the Arduino what is connected to the pin, but it does to me.



}cycle_counter++;



No code EVER follows a } on the same line. 

That code belongs INSIDE the curly brace, not after it.

Sir, I actually not hiding anything. I am really dealing with LED (which will work along the solenoid valve to ope and close it). Just use the name as it is related. However, still its not working. Am i missing something? Hopeless… :frowning: and sorry again for quoting you.

void loop()
{
  int prevStateOne = 0;
  int prevStateTwo = 0;
   if(cycle_counter < cycle_to_complete)
   {
      int sensor_1_value = digitalRead(sensor_1_pin);
      if(sensor_1_value == HIGH)
      {// The magnet just arrived

            // Turn the LED on
            digitalWrite(solenoid_valve, HIGH);
      }
      prevStateOne = sensor_1_value;
      int sensor_2_value = digitalRead(sensor_2_pin);
      if(sensor_2_value = HIGH)
      {// The magnet just arrived

            // Turn the LED off
            digitalWrite(solenoid_valve, LOW);
      }
      prevStateTwo = sensor_2_value;
      cycle_counter++;
   }
}

Am i missing something?

Yes. prevStateOne and prevStateTwo need to be global (just as in the State Change Detection example I pointed you to earlier).

You are also still missing the comparison of the current state to the previous state.

But, I think you are getting close.

PaulS:
Yes. prevStateOne and prevStateTwo need to be global (just as in the State Change Detection example I pointed you to earlier).

You are also still missing the comparison of the current state to the previous state.

But, I think you are getting close.

Sir, as you said I am getting closure but I feel so far… far away. Here what I got after make the prevStateOne and prevStateTwo global variables.

Sensor 2 On
Sensor 1 On
Sensor 2 On
Sensor 1 On

uncountable times (led also getting on and off along), even If I hold the magnet with the sensors. Sorry again for quoting and Changing codes are,

void loop()
{
   if(cycle_counter < cycle_to_complete)
   {
      int sensor_1_value = digitalRead(sensor_1_pin);
      if(sensor_1_value == HIGH)
      {// The magnet just arrived

            // Turn the LED on
            digitalWrite(solenoid_valve, HIGH);
            Serial.println ("Senspr 2 ON");
      }
      prevStateOne = sensor_1_value;
      int sensor_2_value = digitalRead(sensor_2_pin);
      if(sensor_2_value = HIGH)
      {// The magnet just arrived

            // Turn the LED off
            digitalWrite(solenoid_valve, LOW);
            Serial.println ("Sensor 1 ON");
      }
      prevStateTwo = sensor_1_value;
      cycle_counter++;
   }
}
      int sensor_1_value = digitalRead(sensor_1_pin);
      if(sensor_1_value == HIGH)
      {// The magnet just arrived

What happened to the comparison of the current state to the previous state? That IS important.

Does HIGH mean that the magnet is present? Or is HIGH the state when the magnet is not present?

You want to change the value of cycle_counter ONLY when the second sensor changes state (to the correct state).

PaulS:

      int sensor_1_value = digitalRead(sensor_1_pin);

if(sensor_1_value == HIGH)
      {// The magnet just arrived



What happened to the comparison of the current state to the previous state? That IS important.

Does HIGH mean that the magnet is present? Or is HIGH the state when the magnet is not present?

You want to change the value of cycle_counter ONLY when the second sensor changes state (to the correct state).

Sir,
High means the magnet is present (i hope it will work) and I actually dont understand how to do the comparison. If possible can you give me a demo or add it in the code itself please.

If possible can you give me a demo or add it in the code itself please.

      int sensor_1_value = digitalRead(sensor_1_pin);
      if(sensor_1_value != prevStateOne)
      {
         // The magnet just arrived or just left...

         if(sensor_1_value == HIGH)
         {
            // The magnet just arrived

PaulS:

      int sensor_1_value = digitalRead(sensor_1_pin);

if(sensor_1_value != prevStateOne)
      {
        // The magnet just arrived or just left…

if(sensor_1_value == HIGH)
        {
            // The magnet just arrived

PaulS:

      int sensor_1_value = digitalRead(sensor_1_pin);

if(sensor_1_value != prevStateOne)
      {
        // The magnet just arrived or just left…

if(sensor_1_value == HIGH)
        {
            // The magnet just arrived

no idea why still its not working :frowning:

void loop()
{
   if(cycle_counter < cycle_to_complete)
   {
      int sensor_1_value = digitalRead(sensor_1_pin);
      if(sensor_1_value != prevStateOne)
      {
      if(sensor_1_value == HIGH)
      {// The magnet just arrived

            // Turn the LED on
            digitalWrite(solenoid_valve, HIGH);
            Serial.println ("Senspr 2 ON");
      }
      }
      if(sensor_2_value != prevStateTwo)
      {
      prevStateOne = sensor_1_value;
      int sensor_2_value = digitalRead(sensor_2_pin);
      if(sensor_2_value = HIGH)
      {// The magnet just arrived

            // Turn the LED off
            digitalWrite(solenoid_valve, LOW);
            Serial.println ("Sensor 1 ON");
      }
      prevStateTwo = sensor_2_value;
      }
      cycle_counter++;
   }
}
      }
      }
      if(sensor_2_value != prevStateTwo)
      {
      prevStateOne = sensor_1_value;

Why are you saving the current state of sensor one as the previous state of sensor one only when the state of sensor 2 has changed?

Get in the habit of using Tools + Auto Format, so you code is properly indented, and these kind of mistakes are easier to see.

PaulS:

      }

}
      if(sensor_2_value != prevStateTwo)
      {
      prevStateOne = sensor_1_value;



Why are you saving the current state of sensor one as the previous state of sensor one only when the state of sensor 2 has changed?

Get in the habit of using Tools + Auto Format, so you code is properly indented, and these kind of mistakes are easier to see.

Now it says, “sensor 2 ON” and the stop, even if i dont bring the sensor closure.

void loop()
{
   if(cycle_counter < cycle_to_complete)
   {
      int sensor_1_value = digitalRead(sensor_1_pin);
      if(sensor_1_value != prevStateOne)
      {
      if(sensor_1_value == HIGH)
      {// The magnet just arrived

            // Turn the LED on
            digitalWrite(solenoid_valve, HIGH);
            Serial.println ("Sensor 2 ON");
      }
      prevStateOne = sensor_1_value;
      }
      if(sensor_2_value != prevStateTwo)
      {
      int sensor_2_value = digitalRead(sensor_2_pin);
      if(sensor_2_value = HIGH)
      {// The magnet just arrived

            // Turn the LED off
            digitalWrite(solenoid_valve, LOW);
            Serial.println ("Sensor 1 ON");
      }
      prevStateTwo = sensor_2_value;
      }
      cycle_counter++;
   }
}

I can't imagine why you print "sensor 2 is on" when sensor one becomes active, and "sensor 1 is on" when sensor two becomes active.

      if(sensor_2_value = HIGH)

= != ==.

You are STILL incrementing cycle_counter at the wrong point. I'm about to give up.

PaulS:
I can’t imagine why you print “sensor 2 is on” when sensor one becomes active, and “sensor 1 is on” when sensor two becomes active.

      if(sensor_2_value = HIGH)

= != ==.

You are STILL incrementing cycle_counter at the wrong point. I’m about to give up.

Yeah i can understand your frustration. I am frustrated too with myself. I will really appreciate if you will help (again) if will not reply I will not QUOTE you anymore. I am sorry. may be for last time,

void loop()
{
   if(cycle_counter < cycle_to_complete)
   {
      int sensor_1_value = digitalRead(sensor_1_pin);
      if(sensor_1_value = !prevStateOne)
      {
      if(sensor_1_value == HIGH)
      {// The magnet just arrived

            // Turn the LED on
            digitalWrite(solenoid_valve, HIGH);
            Serial.println ("Sensor 1 ON");
      }
      prevStateOne = sensor_1_value;
      }
      if(sensor_2_value = !prevStateTwo)
      {
      int sensor_2_value = digitalRead(sensor_2_pin);
      if(sensor_2_value == HIGH)
      {// The magnet just arrived

            // Turn the LED off
            digitalWrite(solenoid_valve, LOW);
            Serial.println ("Sensor 2 ON");
      }
      prevStateTwo = sensor_2_value;
      }
      cycle_counter++;
   } 
}

I put the cycle_counter in the end of if cycle. and now the result is, “sensor 1 on”, “sensor 2 on” without any contact with sensor and then stop. if possible just add what you think with the codes and I wont bother you anymore even if it wont work. SORRY.

I put the cycle_counter in the end of if cycle. and now the result is, "sensor 1 on", "sensor 2 on" without any contact with sensor and then stop

So, let's work on one sensor and one problem at a time.

void loop()
{
   int currStateOne = digitalRead(sensor_1_pin);
   if(currStateOne = !prevStateOne)
   {
      Serial.println("Sensor 1 changed state");
   }
   prevStateOne = currStateOne;
}

If this prints the message at any time other than when the magnets gets close to the sensor or moves away from the sensor, then the sensor is not wired correctly, and no amount of coding can fix that. If it prints the message only at appropriate times, then we can expand on it.

PaulS:
So, let's work on one sensor and one problem at a time.

void loop()

{
  int currStateOne = digitalRead(sensor_1_pin);
  if(currStateOne = !prevStateOne)
  {
      Serial.println("Sensor 1 changed state");
  }
  prevStateOne = currStateOne;
}




If this prints the message at any time other than when the magnets gets close to the sensor or moves away from the sensor, then the sensor is not wired correctly, and no amount of coding can fix that. If it prints the message only at appropriate times, then we can expand on it.

May be I am wrong but still it is showing "Sensor 1 changed state" uncountable times without any touch of sensor. Sorry. My luck is not with me today.

May be I am wrong but still it is showing "Sensor 1 changed state" uncountable times without any touch of sensor. Sorry. My luck is not with me today.

It's telling me that your sensor is wired wrong. How is the sensor wired?