-1

Last week I was grateful to receive help programming the Arduino to control two linear actuators.

I need help re-writing the code using the millis () function. I am more than happy to reimburse for time spent on this project. This is my first experience with Arduino and millis () is too involved for me.

The actuators control a set of barn doors in my house. The actuators are programmed to open and close with the push of a button (z-wave relay programmed as 6 second momentary switch). The actuators do not give feedback, so the program is used to control the speed from 0-255 using the PWM ports to make the actuators appear somewhat in sync. They move at three different speeds so that they don't slam when opening and closing. This is where millis () comes in. Right now I am using a delay to control the speed for various amounts of time, but using a delay creates a safety issue since the Arduino cannot do anything during this time.

The reason I need to utilize the millis () function is that I need to be able to make the doors stop and reverse in the event that there is something blocking their path. To accomplish this I will be using a garage door electric eye wired through a homemade circuit board. The output will go low any time the beam is broken and otherwise it will remain high. I'd like the Arduino program to utilize this signal any time the doors are closing and if the beam is broken - make the actuators reverse direction. I realize that without feedback I cannot make the doors open all the way depending on when the beam is broken. I am really not too concerned about that. As long as they stop and reverse for at least a little bit I will be happy. I don't want to crush my kids or pets.

Again, I am more than happy to reimburse anyone willing to help write the code for this. Here is the code I am using now which utilizes the delay function. I'd like this code to be changed to utilize the millis function and also add in programming for the sensor as described above.

/* Program enables momentary direction control of actuator using push button
 */

int RPWM = 10; //connect Arduino pin 10 to IBT-2 pin RPWM
int LPWM = 11; //connect Arduino pin 11 to IBT-2 pin LPWM
int RPWM2 = 5; //connect Arduino pin 5 to IBT-2 pin RPWM
int LPWM2 = 6; //connect Arduino pin 6 to IBT-2 pin LPWM
int downPin = 12; 
int upPin = 13;
int speed1 = 0; // Top speed you can change it between [0-255]
int speed2 = 0; // Low speed you can change it between [0-255]
int speed3 = 0; // Low speed you can change it between [0-255]

void setup() {
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  pinMode(RPWM2, OUTPUT);
  pinMode(LPWM2, OUTPUT);
  pinMode(downPin, INPUT_PULLUP);
  pinMode(upPin, INPUT_PULLUP);
}

void loop() { 
  if(digitalRead(upPin)==LOW){ //check if extension button is pressed
    analogWrite(RPWM, 0);
    analogWrite(RPWM2, 0);
    analogWrite(LPWM, 255); // rotate motor with top speed 
    analogWrite(LPWM2, 245); // rotate motor with top speed 
    delay(3000);               // wait for x sec
    analogWrite(LPWM, 180); // rotate motor with low speed 
    analogWrite(LPWM2, 176); // rotate motor with low speed 
    delay(1500);               // wait for x sec
    analogWrite(LPWM, 80); // rotate motor with low speed 
    analogWrite(LPWM2, 80); // rotate motor with low speed 
    delay(1500);               // wait for x sec
    analogWrite(LPWM, 0);     // uncomment if you want to stop motor now 
    analogWrite(LPWM2, 0);     // uncomment if you want to stop motor now 
  } 


  else if(digitalRead(downPin)==LOW){ //check if retraction button is pressed
    analogWrite(LPWM, 0);
    analogWrite(LPWM2, 0);
    analogWrite(RPWM, 250); // rotate motor with top speed 
    analogWrite(RPWM2, 255); // rotate motor with top speed 
    delay(3000);               // wait for x sec
    analogWrite(RPWM, 165); // rotate motor with low speed 
    analogWrite(RPWM2, 165); // rotate motor with low speed 
    delay(1500);               // wait for x sec
    analogWrite(RPWM, 80); // rotate motor with low speed 
    analogWrite(RPWM2, 80); // rotate motor with low speed 
    delay(1500);               // wait for x sec
    analogWrite(RPWM, 0);     // uncomment if you want to stop motor now
    analogWrite(RPWM2, 0);     // uncomment if you want to stop motor now  
  } 

  else{ //if no button is pushed, remain stationary
    analogWrite(RPWM, 0); 
    analogWrite(LPWM, 0);
    analogWrite(RPWM2, 0);
    analogWrite(LPWM2, 0);
  }
}
5
  • 1
    You should not rely on Arduino code at all, millis or otherwise, for your safety features. More broadly you should not rely on software at all when it comes to not crushing your kids or pets.
    – timemage
    Jan 23 at 14:45
  • Definitely open to other suggestions.... The actuators are only rated 20lbs. I’ve let the doors close on me and it is not bad at all... but, still would prefer the doors not close on things. Jan 23 at 15:05
  • 1
    I'm not sure I'm all that comfortable advising you on this. But, if your actuators are responsible for different directions, it seems at a minimum the door closing on something should mechanically interrupt the power going to the actuator that closes the door and it should probably latch into this interrupted position such that it manual intervention is required to make it operate again.
    – timemage
    Jan 23 at 15:13
  • Each actuator has adjustable overcurrent protection. It works ok to cut power to the actuators if the doors bump into something, but I’m hoping to actually have the doors reverse before bumping into anything. After-all don’t our garage doors rely on software for the same type of safety function? Jan 23 at 15:19
  • Also note - My backup plan if I can’t get this working with the Arduino is to connect the electric eye to a couple of relays that would reverse polarity to the actuators in the event the beam is blocked - causing the doors to reverse direction. This would be one method that avoids using software. Could also cause the doors to close on something if the beam is blocked while the doors are opening... so not ideal! Jan 23 at 15:25
0

You've come to the requirement called non-blocking programming. The gist of it is that your loop() function does little other than call a number of "maybe-do" functions - my name for functions that assess the need to act, and act or not, and return, as quickly as possible. So in pseudo-code, your loop might look something like:

void loop(){
   maybeStartMotor1();
   maybeSlowMotor1();
   maybeStartMotor2();
   maybeSlowMotor2();
   maybeStopMotor1();
   maybeStopMotor2();
   // Call maybe-do()s for ... whatever else might need to happen
}

Your maybe functions would probably look like, e.g.:

maybeSlowMotor1(){ if( millis() - millis_at_motor1_start > DECELTIME2 ) set motor1 to slow speed;

else if( millis() - millis_at_motor1_start > DECELTIME1 ) set motor1 to medium speed;

return; }

Note that my understanding of your mechanical system is limited and the above is meant to describe a software technique, not a solution.

Also note my complete agreement with @timemage's caution against depending on software for your safety interlocks. Your 3rd comment under your question - to directly reverse the doors with photocells and relays - in addition to the software detection and control - provides a necessary redundancy.

I'd also like to refer you to this somewhat more complete description I wrote to answer another, similar, question.

4
  • Thank you for your answer. I am just a total noob to Arduino and this is outside my wheelhouse. Perhaps the simplest solution for me would be to use the electric eye to simply cut power to the actuators in the event the beam is blocked. Reversing direction would be nice, but to have it function properly would require software/programming. Jan 23 at 15:47
  • Use the electric eye / stop actuators first. Then you can work on the software, a little at a time, and not have to do the "would be nice" parts of it up front. With the worst-case covered, you can experiment with the software a little at a time without being able to leave any glaring safety issues.
    – JRobert
    Jan 23 at 16:09
  • That’s what I’ll do. I’d still be more than happy to pay someone to do the programming for me if there are any takers! If I just had something to work with I bet I could get it functioning properly. Jan 23 at 16:22
  • @ChrisGroat, get in touch w/me through my profile.
    – JRobert
    Jan 23 at 19:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.