Help with Progressive Vibration Motor Activation

Hello,
I am new to programming and have no idea where to start. It would really be awesome if someone could point me in the right direction to write this program file. It should be a simple one for anyone but me, being so new.

1 x Arduino Nano
5 x Mini Vibration Motors controlled by digital outs

What I need to do is activate motor 1 for a specific amount of time, and then activate motor 2...in a sequence, and then restart.

What I would also like to do is have a simple momentary push button to turn the sequence on and off, and also adjust the time each motor runs by a standard deviation

Example
Momentary Button - 1st push - Starts the "Low Setting" sequence
Motor 1 runs from 0.01s - 1.00s
Motor 2 runs from 1.00s - 2.00s
Motor 3 runs from 2.00s - 3.00s
Motor 4 runs from 3.00s - 4.00s
Motor 5 runs from 4.00s - 5.00s
and then start over, continuous loop, with an auto off timer of 10 minutes

Momentary Button - 2nd push - Starts the "Medium Setting" sequence
Motor 1 runs from 0.01s - 0.50s
Motor 2 runs from 0.50s - 1.00s
Motor 3 runs from 1.00s - 1.50s
Motor 4 runs from 1.50s - 2.00s
Motor 5 runs from 2.50s - 3.00s
and then start over, continuous loop, with an auto off timer of 10 minutes

Momentary Button - 3rd push - Starts the "High Setting" sequence
Motor 1 runs from 0.01s - 0.25s
Motor 2 runs from 0.25s - 0.50s
Motor 3 runs from 0.50s - 1.00s
Motor 4 runs from 1.00s - 1.50s
Motor 5 runs from 1.50s - 2.00s
and then start over, continuous loop, with an auto off timer of 10 minutes

Momentary Button - 4th push - Stops all sequences and starts over dormant, ready for "1st Push" to start a new sequence

Any help with this is so much appreciated. This is for a therapy device that I currently have to do by hand in a motion that I think I can automate with the explained sequence.

Thanks so much in advance!
Joe

You need to break the problem down, and solve each part individually... then you can put it all together.

There are a couple of things to consider. At a high level... you have 4 "states", which determine if you are running low, medium, high, or dormant.

Each time a button is pressed you advance to the next state.

I would try and get this working first... you can use a variable to keep track of the states... say 1 (low), 2(med) ,3 (high) ,0(dormant). To start with get the button working and just print the variable out to show movement between the 4 states.

Once you have that working... then you need to consider timing for the motor sequence. BTW can you check the timings you mentioned for med & high... are these supposed to be equal for each step of the sequence ? It will make things easier if they are.

For timing we will use millis() to determine how long each motor has been on. Get the button stuff working first before worrying about that.

And I want to know more about the plan for this part. You do say "controlled", so I assume that means you know that those motors should not be driven directly from an output pin as one might an LED.

And does

Momentary Button - 2nd push - Starts the "Medium Setting" sequence

take effect at any time in the sequence, like if motor 3 was running is motor 4 still next?

Does pressing the button again reset the ten minute timer?

Any questions like that left unanswered will be "answered" by the code you write, and you might not like the answers. Which is just to say get the entire design nailed down before any advanced coding.

a7

so you need some code to recognize a button press (not that it is being pressed) and with each press increment through a series of modes.

each mode affects the time each motor is on, since it looks like those times are 1sec, 0.5 sec and 0.25 sec, as well as an OFF mode

the motor pins can be specified in a const byte array that can be stepped through using for loops, both to initialize each motor pin as an output, as well as turn each motor on/off for the current time value. a simple delay can be used for timing

a switch statement can be used to select the time each motor is on or zero

a for loop is executed each iteration of loop() if the time is not zero and sequences each motor on/off

recognizing a but press requires reading the but state and comparing it to the last state to see if there's a change and updating the last state, calling delay for 10 msec to debounce and perform some action if the button is pressed.

the button pin should be configured as INPUT_PULLUP so that the pin is pulled HIGH by the internal pullup resistor and with the button connected between the pin and ground, pulled LOW when the button is pressed

think it over and post your attempt

Hi,
what kind of motor is this?
Link or datasheet.

Hi @fusion84 ,

welcome to the Arduino-Forum.
You did a good job in your first posting. You wrote down a detailed description of the wanted functionality and you wrote about your knowledge-level.

As a real beginner you should learn fundamental basics about how arduino-programming works
Take a look into this tutorial:

Arduino Programming Course

It is easy to understand and has a good mixture between explaining important concepts and example-codes to get you going. So give it a try and report your opinion about this tutorial.

If you have any additional questions about the tutorial or any other code. Answering specific questions is liked a lot. Of course you can ask any kind of question.
As long as you show some own effort in proceeding you will receive answers.

You made a good first impression with your detailed description of the wanted functionality.
.
.
I allow myself to somehow "judge" about the other postings:

Assuming that you really know almost nothing about programming the other postings are still difficult to understand because these other postings assume that you have some knowledge about programming.

You should expand writing about the steps you have successfully done in your project.
This will help a lot to adjust the answers to your knowledge-level.

Start with
"I successfully installed the Arduino-IDE (Version-number ) "
and add what you have done so far

best regards Stefan

constexpr byte MotorPin1 = 2;
constexpr byte MotorPin2 = 3;
constexpr byte MotorPin3 = 4;
constexpr byte MotorPin4 = 5;
constexpr byte MotorPin5 = 6;
constexpr byte ButtonPin = 7;

enum States { Idle,
              Low,
              Medium,
              High } State = Idle;

unsigned long StateStartTime = 0;

void Pattern(unsigned long elapsed, unsigned long M1Start,
             unsigned long M1End, unsigned long M2End, unsigned long M3End,
             unsigned long M4End, unsigned long M5End) {
  elapsed = elapsed % M5End;  // Repeat the pattern

  if (elapsed < M1Start) {
    digitalWrite(MotorPin5, LOW);
  } else if (elapsed < M1End) {
    digitalWrite(MotorPin5, LOW);
    digitalWrite(MotorPin1, HIGH);
  } else if (elapsed < M2End) {
    digitalWrite(MotorPin1, LOW);
    digitalWrite(MotorPin2, HIGH);
  } else if (elapsed < M3End) {
    digitalWrite(MotorPin2, LOW);
    digitalWrite(MotorPin3, HIGH);
  } else if (elapsed < M5End) {
    digitalWrite(MotorPin3, LOW);
    digitalWrite(MotorPin4, HIGH);
  } else if (elapsed < M5End) {
    digitalWrite(MotorPin4, LOW);
    digitalWrite(MotorPin5, HIGH);
  }
}

constexpr unsigned long Second = 1000ul;
constexpr unsigned long Minute = Second * 60;
constexpr unsigned long TenMinutes = Minute * 10;

void setup() {
  pinMode(MotorPin1, OUTPUT);
  pinMode(MotorPin2, OUTPUT);
  pinMode(MotorPin3, OUTPUT);
  pinMode(MotorPin4, OUTPUT);
  pinMode(MotorPin5, OUTPUT);

  pinMode(ButtonPin, INPUT_PULLUP);
}

void loop() {
  switch (State) {
    case Idle:
      digitalWrite(MotorPin1, LOW);
      digitalWrite(MotorPin2, LOW);
      digitalWrite(MotorPin3, LOW);
      digitalWrite(MotorPin4, LOW);
      digitalWrite(MotorPin5, LOW);
      if (digitalRead(ButtonPin) == LOW) {
        StateStartTime = millis();
        State = Low;
      }
      break;

    case Low:
      Pattern(millis() - StateStartTime, 10, 1000, 2000, 3000, 4000, 5000);
      if (digitalRead(ButtonPin) == LOW) {
        StateStartTime = millis();
        State = Medium;
      }
      if (millis() - StateStartTime > TenMinutes)
        State = Idle;
      break;

    case Medium:
      Pattern(millis() - StateStartTime, 10, 500, 1000, 1500, 2000, 3000);
      if (digitalRead(ButtonPin) == LOW) {
        StateStartTime = millis();
        State = High;
      }
      if (millis() - StateStartTime > TenMinutes)
        State = Idle;
      break;

    case High:
      Pattern(millis() - StateStartTime, 10, 250, 500, 1000, 1500, 2000);
      if (digitalRead(ButtonPin) == LOW)
        State = Idle;
      if (millis() - StateStartTime > TenMinutes)
        State = Idle;
      break;
  }
}

Thanks, you make some very good points. I assume Arduino coding, like anything else, has a lot of posters requesting someone else do just do it for them, when in reality, the poster should give a valued attempt before reaching out. I probably tried to tackle too much at once, but I am in a bit of a hurry, as this device is to alleviate a time-sensitive issue. However, with that said, it has motivated me to dig in and start from the beginning, or at least close to the beginning and work my way up.
Thanks for holding accountability

I agree, one thing at a time. And yes, good catch on the deviation. I was thinking/typing too fast.
millis() makes much more sense, thanks for that

So based on some other forum questions, I am thinking this will work, and that I will be able to drive these motors straight from the Nano, using the I/O to pull a n-mosfet to ground, no?

Good point on when to start the sequence if already in a sequence. Let me think on that for a bit, but my first reaction would be to start the new sequence at motor #1, regardless of what motor is currently engaged in the current sequence setting

Man! This is great! I can't wait to try it. This looks like a huge amount of thought and work you put in, and I really appreciate it. I have a few parts on order that are a few weeks out. Once I complete the mock up of the build and run this code, I will let you know how it goes.
Thanks a ton again!

Yes, you found a good source for that. That is the model circuit, the key detail is use of a logic level MOSFET.

Someone can point out a good choice.

Have you posted a link to the stat sheet or information about the motors? The MOSFET just has to handle the current they will require.

a7

@johnwasser

what is the reason for you to left out almost any comment that would explain the details to a beginner?

MOS-FETs are sensitive to electrostatic discharge. One slurp with plastic soles over a carpet then touching a PIN of a MOSFET and "zing" MOS-FET destroyed.

Depending on the current a usual transistor like BC337 (can handle 800 mA) might be a choice too.
Logic level MOS-FET is important. LOGIC-LEVEL means the MOS-FET must be "turned to fully conductant" with 3.3V with RD-Onresistance as low as 0,1 Ohm already at 3.3V

A "threshold" voltage of 3V is too high
My recommendation MOS-FET type IRF3708

The all and everywhere used IRF520 / IRF540 are NOT suitable at 3.3V.

best regards Stefan

working through the Programming Tutorial I linked above might take you 20 hours of real time.
So if you take 4 hours per day to learn programming. You are through within one week.

Anyway you should post at which stage of preparing the Arduino IDE you are.

best regards Stefan

If you have some LED's and resistors you can use those to simulate the MOSFETs and motors.

I tried to use meaningful identifiers to make the sketch mostly self-documenting. If anyone needs an explanation of any part of the sketch they don't understand, I would be glad to answer specific questions.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.