simpleProblem (but not to me)

Pretty new to C++.

Using Uno and motor controller to control gate motor.

Using Robins style of many things at once and it
did help with the logic of the whole thing.

But .. when I add a simple limit switch function, the
gate wont move.

the limit switch is PULL_UP
so .. when I say

if (digitalRead(Close_Sensor) == LOW)){

it should NOT get past that with the switch
NOt thrown .. but it seems to.

Big favor please .. don't rewrite and say use this. Please tell me
why my code doesn't work.

const int Pot_Setting = A2;        // pin where we get the requested spd
const int Motor_Spd_Pin = 6;       // this is the pin where we send the speed
const int Gate_Direction_Pin = 8;      // this is the pin where we send dir info
const int Closed_Sensor = 12;      // these pins are from the limit switches
const int Open_Sensor = 3;
const int Request_Button = 4;        // this is the open and close button
unsigned long Previous_Time = 0;     // the time var's are for timing the opening
unsigned long Current_Time = 0;      // and closing making sure it isn't stuck
unsigned long Prev_Button_Time = 0;
unsigned long Prev_Close_Time = 0;
unsigned long Prev_Open_Time = 0;
unsigned long Prev_Limit_Time = 0;
int led_pin = 13;

int Gate_Speed = 0;                  // var to hold pot setting
bool Gate_Is_Moving = false;
bool Wanna_Closeit = true;          // open or close variable
bool Button_Was_Pressed = false;     // var for button condition
//******************************
void setup()
{
  pinMode(Gate_Direction_Pin, OUTPUT);         // pin 8
  pinMode(Closed_Sensor, INPUT_PULLUP);        // pin 12
  pinMode(Open_Sensor, INPUT_PULLUP);          // pin 3
  pinMode(Request_Button, INPUT_PULLUP);       // pin 4
  pinMode(Pot_Setting, INPUT);                 // pin A2
  pinMode(led_pin, OUTPUT);
  digitalWrite(led_pin, LOW);

}
//****************************************************************

void loop()
{
  Check_For_Button();
  Obey_The_Button();
  Check_For_Limit();
}

//**************************************************************

void Check_For_Button()
{
  Current_Time = millis();
  if (Current_Time - Prev_Button_Time >= 1300) {  // button is a long relay connection
    if (digitalRead(Request_Button) == LOW) {
      Prev_Button_Time = millis();           
      Button_Was_Pressed = true;
      if (Gate_Is_Moving) {                          // if gate is open when button is pressed
        Gate_Speed = 0;                              // stop it
      }
      else {
        Gate_Speed = analogRead(Pot_Setting);     // set speed according to pot
        Wanna_Closeit = !Wanna_Closeit;              // starting from any stop, flip direction
      }
      if (Wanna_Closeit) {
        digitalWrite(Gate_Direction_Pin, HIGH);   // closing direction
      }
      else {
        digitalWrite(Gate_Direction_Pin, LOW);    // open direction
      }
    }
  }
}


void Obey_The_Button()
{
  if (Button_Was_Pressed) {
    analogWrite(Motor_Spd_Pin, Gate_Speed);
    if (Gate_Speed > 0) {
      Gate_Is_Moving = true;
    }
    else {
      Gate_Is_Moving = false;
    }
    Previous_Time = millis();
    Button_Was_Pressed = false;
  }
}


void Check_For_Limit()
{
  Current_Time = millis();
  if (Current_Time - Prev_Limit_Time >= 1000) {
    if (digitalRead(Closed_Sensor) == LOW){
      if (Gate_Is_Moving) {
        analogWrite(Motor_Spd_Pin, 0);
        Gate_Is_Moving = false;
        Prev_Limit_Time = millis();
      }
    }
  }
}

How are the switches wired ?

Can it be when you give a start signal, immediately you look for limit switch? Mechanical delay is much longer than execution time so stop signal comes before actual movement of the gate. A quick solution to test this idea is to add a delay(1000); right after analogWrite(Motor_Spd_Pin, Gate_Speed);.

Then you can change the code to only react to limit switch at the end of movement.

thanx guys ..

When the limit switch closes, it just connects a UNO pin to ground. I am using INPUT_PULLUP
to keep the pin from floating.

And I am calling, to look for limit switch right after turning on the motor .. but .. the limit
switch is not even close to being closed ... so that shouldn't matter.

I am just learning C++ and am finding it very frustrating. Things that should work, don't

This here is the code that is making the motor not work.

If the limit switch isn't thrown, how can it possibly get into the function to turn the motor off.

void Check_For_Limit()
{
  Current_Time = millis();
  if (Current_Time - Prev_Limit_Time >= 1000) {
    if (digitalRead(Closed_Sensor) == LOW){
      if (Gate_Is_Moving) {
        analogWrite(Motor_Spd_Pin, 0);
        Gate_Is_Moving = false;
        Prev_Limit_Time = millis();
      }
    }
  }
}

Perhaps it's time to do a reality check and see if the limit switch is wired wrong. Most people use a microswitch that is SPDT and if you wired to the common and NC connections, it is closed at the start.

Paul

Just to clarify - when you remove the call to Check_for_limit from the loop(), does your gate swing open when you press the button?

Thanks Paul(s)

I have checked the limit switches and they are good to go .. and as a matter of fact I wrote a little
program ... the only thing it does is turn the motor on if the limit sw is pressed. Works fine.

and yep .. all i have to do is add that little bit of code and the motors don't move.

otherwise ... back and forth they go ...

I do have to take back what I said about the program getting INTO the limit sw function. with some
println lines it appears as though it actually ISNT getting into the limit sw funtion. which makes it
even MORE of a mystery ... now I have no idea why the motors are not running.

MikeAmick:
the limit switch is PULL_UP
so .. when I say

if (digitalRead(Close_Sensor) == LOW)){

I don't like that style of code where two things are crammed into one line.

Read the switch and store the value. Then act on the saved value. That way you can print the value to see if it is what you think it is.

sensorState = digitalRead(Close_Sensor);
Serial.print("Sensor State = ");
Serial,println(Sensor_State);
if (sensorState == LOW ) {
  // etc

When it is working properly you can delete the print statements.

...R

Hey Robin !!!

I rewrote my whole program using your example. I like it.
but this damn problem is killing me.

I just did what you suggested
but it still doesn't work.

funny thing is .. when I run it on my computer, the Serial.println lines tell me that it
is not going into that function.

but ...

when I take the UNO out to the gate, the only way the motor runs is if I comment
out the analogWrite 0 part of the function. So it has to be getting into that func.

if (Current_Time - Prev_Limit_Time >= 1000) {      // some debounce timing
    Sensor_Status = digitalRead(Closed_Sensor);
    if (Sensor_Status == LOW) {                                   // I can NOT figure out how it  
      if (Gate_Is_Moving) {                                           // is getting past limit switch test
        analogWrite(Motor_Spd_Pin, 0);
        Gate_Is_Moving = false;
        Prev_Limit_Time = millis();
      }
    }
  }
}

Please post the complete code for the latest version of your program so I can see everything in context.

...R

when I take the UNO out to the gate,

When you test it on your computer are you isng the same switches and wiring as when you take it out to the gate ?

Here ya go Robin .. pretty much the same as before.

I actually think the code is good. I am beginning to think that
because of the motors, I am getting noise. I think I will read
about decoupling caps and stuff... to see if that helps.

and Bob .. no .. at the computer, its just proto board and push buttons.
the only way to know if a motor is turning is with Serial.print statements.

it actually works on the computer .. just not at the gate.

and it is NOT a wiring problem, checked it many times.

const int Pot_Setting = A2;          // pin where we get the requested spd
const int Motor_Spd_Pin = 6;         // this is the pin where we send the speed
const int Gate_Direction_Pin = 8;    // this is the pin where we send dir info
const int Closed_Sensor = 12;        // these pins are from the limit switches
const int Open_Sensor = 3;
const int Request_Button = 4;        // this is the open and close button
unsigned long Previous_Time = 0;     // the time var's are for timing the opening
unsigned long Current_Time = 0;      // and closing making sure it isn't stuck
unsigned long Prev_Button_Time = 0;  // for debouncing start/stop button
unsigned long Prev_Limit_Time = 0;   // for debouncing limit switch

int Gate_Speed = 0;                  // var to hold pot setting
int Sensor_Status = 0;
bool Gate_Is_Moving = false;         // gate status
bool Wanna_Closeit = true;           // open or close variable
bool Button_Was_Pressed = false;     // var for button condition

//******************************
void setup()
{
  pinMode(Gate_Direction_Pin, OUTPUT);         // pin 8
  pinMode(Closed_Sensor, INPUT_PULLUP);        // pin 12  // note pullup to pins 
  pinMode(Open_Sensor, INPUT_PULLUP);          // pin 3   // from floating
  pinMode(Request_Button, INPUT_PULLUP);       // pin 4
  pinMode(Pot_Setting, INPUT);                 // pin A2
}
//****************************************************************
// This is done using the "doing many things at once" technique
// meaning NOT using any "delay()" .. anywhere
//***************************************************************

void loop()
{
  Check_For_Button();
  Obey_The_Button();
  Check_For_Limit();
  Check_For_Stuck_Gate();
}
//**************************************************************

void Check_For_Button()      // checks for button press and sets a bunch of var's
{
  Current_Time = millis();
  if (Current_Time - Prev_Button_Time >= 1300) {  // loooong debounce
    if (digitalRead(Request_Button) == LOW) {     // was start/stop button pressed
      Prev_Button_Time = millis();                // assign "right now" to prev button time
      Button_Was_Pressed = true;
      if (Gate_Is_Moving) {                       // if gate is moving when button is pressed
        Gate_Speed = 0;                           // stop it
      }
      else {
        Gate_Speed = analogRead(Pot_Setting);     // set speed according to pot
        Wanna_Closeit = !Wanna_Closeit;           // starting from any stop, flip direction
      }
      if (Wanna_Closeit) {
        digitalWrite(Gate_Direction_Pin, HIGH);   // closing direction
      }
      else {
        digitalWrite(Gate_Direction_Pin, LOW);    // open direction
      }
    }
  }
}

void Obey_The_Button()       // this is the only function that can START then motor
{
  if (Button_Was_Pressed) {
    analogWrite(Motor_Spd_Pin, Gate_Speed);      // This can start or stop the motor
    if (Gate_Speed > 0) {
      Gate_Is_Moving = true;
    }
    else {
      Gate_Is_Moving = false;
    }
    Previous_Time = millis();
    Button_Was_Pressed = false;
  }
}

void Check_For_Limit()
{
  Current_Time = millis();
  if (Current_Time - Prev_Limit_Time >= 1000) {      // some debounce timing
    Sensor_Status = digitalRead(Closed_Sensor);
    if (Sensor_Status == LOW) {                        // I can NOT figure out how it  
      if (Gate_Is_Moving) {                          // is getting past switch test
        analogWrite(Motor_Spd_Pin, 0);
        Gate_Is_Moving = false;
        Prev_Limit_Time = millis();
      }
    }
  }
}

void Check_For_Stuck_Gate()
{
  if (Gate_Is_Moving) {                             // if gate is moving more than 
    if (millis() - Previous_Time >= 5000) {         // 5 secs, it must be stuck so   
      analogWrite(Motor_Spd_Pin, 0);                // shut it down
      Gate_Is_Moving = false;
    }
  }
}

Why are you waiting 1300 ms before reading the "Request_Button"? And you only read it once.

Paul

I agree with @PaulS. 50 millisecs should be plenty for debounce, or maybe only 20.

Where you have the comment // I can NOT figure out how it you don't have any code to allow you to see what value the variable Sensor_Status has. You can be 100% certain that the IF statement is working properly with the data it is presented with.

To my mind your code is still rather mixed up.

I would have a short function that reads the switches and the sensors. Then the rest of my code would use the saved values. You have digitalRead()s scattered all over the place. Your function Check_For_Button() is doing a lot of stuff in addition to reading the button. Separate those activities.

I would also only have one short function that calls analogWrite() based on value that has been set elsewhere.

And you set the value of Current_Time in at least two different places when it should only be set once in each iteration of loop().

And, while the compiler won't notice the difference I think you will find it much easier to type camelCase variable names such as currentTime rather than Current_Time.

...R

The reason for the 1300 is .. I am using a 1ch remote control that has a relay in it. While you
are pressing the button the contacts are engaged. Sometimes when it is acting not quite right, I
have a tendency to push the button hard .. lol .. maybe even holding it down a bit. So I made
the debounce time sorta long to compensate for the occasional looooong press.

Robin .. thanks for the suggestions. Like I was saying .. this is basically my first program so it's
no wonder it is showing my inexperience .. grin. I will get better, especially with advice from
experienced programmer like yourself.

I do think that the code is solid (though clunky) .. so I have to find a good tutorial on killing the
noise from the motors.

Thanks for help