Find the error - Code issue to drive CC motor with timer

What should happen if the button is released less than 3 seconds after having been pressed ?

I think you are describing situation in the image below.
In that case it should be considered as noise therefore filtered for all 3 second.

No.

The thing I want to know is what happens if you release, and leave released, the button during the 3 seconds?

On end of motion, the conditions when viewed the way I did will warrant action.

Now you want the button to be up... but if you press it down, do you want another three seconds of motion in the same direction? OR in the opposite? OR not at all, like skip any down what missed its up because the up came early.

a7

Yeah, I got it, and thank you for the help.
I confirm it is working and for the application is more than enough.
Anyway I will also try to study and write the code using rising and falling edges.

BTW for your interests the motor is opening and closing a little door in the bottom part of a wardrobe where it is resting a vacum cleaner robot. It is activating the temporary switch every time it come out for cleaning and back to the charging station inside the wardrobe.

1 Like

Got it, if the button is released and left released the motor has to change direction and start again the 3 second timer

So it is possible that the motor will move CW for less than 3 seconds then CCW for 3 seconds. Is that OK ?

What should happen if the button is pressed during the 3 second CCW period ?

So close. Just say… is that after it has completed threes seconds in one direction?

Are the two symmetrical? So if we figure out what happens to a short press we would also know what would happen for a short release?

Here's two possibilities. Maybe you have to say "that won't happen" but I think it should be accounted for.

In the first response, the motor "gets around" to coming into compliance with the meaning of the input. In the second response, the current motion is immediately suspendered, the motor reverses and runs for three seconds, or more accurately starts running. Three seconds would end it, as would another change in the input level.

a7

look this over

  • check for button press
  • set timer for only as long as motor ran if not 3 sec
// 3 sec motor reverser

int motor1pin1  = 2;
int motor1pin2  = 3;
int isAtHomePin = 4; //detect the button
int Enablepin   = 5; //pin to turn on and off the motor

unsigned long MsecDelay = 3000;
unsigned long msecPeriod;
unsigned long ritardo;

bool Enable;

byte butState;

// -----------------------------------------------------------------------------
void loop ()
{
    unsigned long msec = millis ();

    // check timer
    if (Enable && msec - ritardo >= msecPeriod)  {
        Enable = false;
        digitalWrite   (motor1pin1, LOW);   // stop motor
        digitalWrite   (motor1pin2, LOW);
        Serial.println ("3 second passed");
    }

    // check button press
    byte isAtHome = digitalRead (isAtHomePin);

    if (butState != isAtHome)    {  //case button is pressed
        butState  = isAtHome;   // state change

        if (isAtHome == LOW) { // pulled pin LOW
            Serial.println ("Maggiordomo è uscito");
            digitalWrite   (motor1pin1,LOW);
            digitalWrite   (motor1pin2,HIGH);
        }
        else {
            Serial.println (" button released");
            digitalWrite   (motor1pin1,HIGH);
            digitalWrite   (motor1pin2,LOW);
        }

        // restart timer
        if (Enable)  {      // time motor ran before reversed
            msecPeriod = msec - ritardo;
            ritardo    = msec;
        }
        else
            msecPeriod = MsecDelay;
        Serial.println (msecPeriod);

        ritardo = msec;
        Enable  = true;

        delay (100);             //antibouncing for the button
    }
}

// -----------------------------------------------------------------------------
void setup ()
{
    digitalWrite (motor1pin1, LOW);     // motor stopped
    digitalWrite (motor1pin2, LOW);
    digitalWrite (Enablepin,  HIGH);    // enabled

    pinMode      (motor1pin1, OUTPUT);
    pinMode      (motor1pin2, OUTPUT);
    pinMode      (Enablepin,  OUTPUT);

    pinMode      (isAtHomePin, INPUT_PULLUP);
    butState = digitalRead (isAtHomePin);

    Serial.begin (9600);
}

You are right, option n.2 from your chart is the best solution

OK.

So edges in the pushbutton signal should

  • stop any motion in progress
  • start three seconds in the direction associated with whatever edge it is

Rising edges start three seconds of CCW motion; if a falling edge comes along during that, it stops and starts three seconds of CW motion.

And vice versa.

I may have CW and CCW mixed up.

I observe that just a normal press of the button (like you are calling for an elevator or entering a number on a microwave) would start the motor going CW, and almost immediately make it stop and start going CCW.

a7

so you're more likely to interrupt and shorten a clockwise rotation while allowing a CCW rotation to complete.

in the code i posted, i measured the duration of the CW rotation and set the CCW rotation to the same value. This is easy enough to delete

Hi Gcjr, thank you for the code.
Today I had the possibility to flash it on the board but motor doesn't move at all.
For the debugging:

  • once I press the button and I keep it pressed ( as it should be in real life), the serial shows the message

"
button released
3000
3 second passed
"
it means that once triggered it goes here:

else {
            Serial.println (" button released");
            digitalWrite   (motor1pin1,HIGH);
            digitalWrite   (motor1pin2,LOW);
        }

It seems correct, however the motor isn't rotating

funny :upside_down_face:

it will only run for as long as the button wsa pressed.

how long did you hold the button down before releasing?

more than 3 sec.

Can you give us the schematic of your wiring pls?

did the motor turn when you pressed the button?
is the motor still Enabled?
please post the code that does this

sure, but it is pretty simple. (apologies for my crafted schematic)
For the sake of clarity so far for testing I'm taking the power supply from Laptop USB through Nano USB port.

1 Like

it doesn't rotate at all.

the code is yours. I did cut and paste...removing the Pull_up config as I have it external.
While the code that is working so far is that one I posted before with @Anthony_P suggestions. Here below:
Now I wish to debug yours tho.

int motor1pin1 = 2;
int motor1pin2 = 3;
int isAtHomePin = 4; //Temp switch input
int Enablepin = 5; // Enable pin to turn ON and OFF the motor
unsigned long ritardo =3000; //change value to adjust motor rotation time
unsigned long msec;
int isAtHome;
int Enable=0;
int direction =0;

void setup() {
    pinMode(motor1pin1, OUTPUT);
    pinMode(motor1pin2, OUTPUT);
    pinMode (Enablepin, OUTPUT);
    pinMode(isAtHomePin, INPUT);
  
  digitalWrite(Enablepin, LOW);
    msec=millis();
  Serial.begin(9600);

}

void loop() {
  isAtHome = digitalRead(isAtHomePin);
  
    if (isAtHome==HIGH && direction != -1 && !Enable) //case button not pressed
       {
         delay (100); //antibouncing for the button
          Serial.println("Robot is at home");
        digitalWrite(motor1pin1,LOW);
        digitalWrite(motor1pin2,HIGH);
        Enable =1;
         direction =-1;
        msec = millis();
        digitalWrite(Enablepin, HIGH);
        }

    if (isAtHome==LOW && direction != 1 && !Enable) //case button pressed
       {
         delay(100); //antibouncing for the button
          Serial.println("Robot is out");
        digitalWrite(motor1pin1,HIGH);
        digitalWrite(motor1pin2,LOW);
         Enable =1;
         direction =1;
        msec = millis();
        digitalWrite(Enablepin, HIGH);
        
        }
  
    if (Enable && (millis()-msec)>ritardo) 
         {
          digitalWrite(Enablepin,LOW);
          Serial.println("Sono passati 3 secondi");
           Enable =0;
         }
  
    }

One thing your original version does is raise and lower Enablepin to turn on and off the motor, while @gcjr just writes HIGH to it in setup(), like there's no need to disable the motor if you write both control pins low.

Try mimicking what made the motor work in your fist version.

a7

Are you really trying to supply the motor from the Vcc of the Arduino?
You really shouldn't and it might be the reason
Pls try to find another power source, that can delever enough power for the motor. The Arduino isn't made for this you're going to break it