Vibration motor code adding to proj

I was in a local surplus store and was pleasantly surprised to find a little section full of Arduino related electronics.
I bought a pack of two vibration motors like this
https://whadda.com/product/vibration-motor-module-2pcs-wpm458/

I'm anxious to figure out how to incorporate them into a project.

I'm still new to all this but they have an example code on GitHub.

I'm not really sure how the if statement works. It looks like it counts how many vibrations have occured and if it's less then 16 it keeps going? Then there's a delay and it runs again?
I'm not sure what if(index %2 == 0) does.

Once I figure out how it works I'll try putting it into another project and post that code.
I haven't really tried to code anything with more then one if statement so it's a bit of a learning curve.
The project I want to add it to has servo motors and is powered by a bench power supply. I was thinking I'd run this motor off of a usb power bank. It's 5 volts but it seems like most people advise a "better safe then sorry" approach to this.

const int vibrationPin = 13; // Set connection pin to signal pin of vibration module

// Set the duration of vibration pulses and pauses array in ms, produces ... -- ... (SMS) vibration from old Nokia Phones
const unsigned int melody[] = {125, 125, 125, 125, 125, 325, 250, 250, 250, 325, 125, 125, 125, 125, 125, 125};

void setup() {
  
  pinMode(vibrationPin, OUTPUT); // Set pin as output
  digitalWrite(vibrationPin, LOW); // Set pin low to make sure vibration motor is off
}

void loop() {

  // For index 0->15 (indexes of melody array)...
  for(int index=0; index < 16; index++) {
    
    if(index %2 == 0) digitalWrite(vibrationPin,HIGH); // If index is even, melody duration is pulse, switch vibration motor on
    else digitalWrite(vibrationPin, LOW); // Else, index is odd, melody duration is pause, switch vibration motor off
    delay(melody[index]); // Wait for number of ms of current melody index
  }
  delay(2000); // Wait for 2s (= 2000 ms)

}

https://github.com/WhaddaMakers/Vibration-motor-module/blob/main/WPM458_example/WPM458_example.ino

At the top of the program you will see an array called melody that has 16 elements. Arrays are always indexed from 0... so the elements are 0 - 15.

the for loop counts through the 16 elements...

this will be true if index / 2 has 0 remainder... so every even element 0,2,4,6,8,10,12,14. If it is true then the vibration is turned ON (set the pin HIGH)... it then stays HIGH for a small delay time, given by the value in the array (in milliseconds).

 delay(melody[index]);

On every odd element, it will turn the vibration off (LOW).. and delays for the amount of time in the array.

After all 16 elements, it delays for 2000 ms (2 seconds) then the whole loop starts again.

Thanks, that's more complicated then i thought it would be. I was able to get it wired in and working so now I just gotta work it in to a project.

I tried adding the loop to an old project to see if I could get both running at once.
I might try and make make some sort of boxing simulation or something along those lines.

For now I just put the sample code in with a program that loops a servo motor to rotate up quickly and then down using millis.
The arm goes every 2 seconds but it seems like the vibration motor slows it down to every 4 or 5 seconds.
There was a delay in the original vibration motor code I didn't add but it still it seems like it must be waiting until the vibration is finished before starting over. That's my best guess anyway.

Is there a way to make the vibration motor run independently so it doesn't screw up the servo timing?

#include <VarSpeedServo.h>
VarSpeedServo myservo;
VarSpeedServo myservo2;
const int servoPin = 9;
const int servoPin2 = 6;
const unsigned long evenT_1 = 2000;
unsigned  long previousTime = 0;
unsigned long HIT_a;
const int vibrationPin = 13;
const unsigned int melody[] = {125, 125, 125, 125, 125, 325, 250, 250, 250, 325, 125, 125, 125, 125, 125, 125};

void setup() {
  Serial.begin(9600);

  pinMode(vibrationPin, OUTPUT); // Set pin as output
  digitalWrite(vibrationPin, LOW); // Set pin low to make sure vibration motor is off
  myservo.attach(servoPin);
  myservo2.attach(servoPin2);

  //set initial position
  //myservo.write(115, 50, true);
  myservo.write(170, 50, true);
  myservo2.write(20, 10, true);
  myservo2.write(90, 20, true);
  delay(8500);
}
void loop() {

  Serial.println( millis() );
 

  unsigned long currentTime = millis();
  if (currentTime - previousTime >= evenT_1 ) {
    myservo.write(65, 255, true);
    myservo.write(180, 50, true);
    previousTime = currentTime;
    HIT_a = HIT_a + 1;
    if ( HIT_a >= 40 )
      myservo2.write(20, 10, true);

// Long delay instead of stopping. 
    if ( HIT_a >= 40 ) delay(50000);
  }
//Added vibration motor loop.
  for (int index = 0; index < 16; index++) {

    if (index % 2 == 0) digitalWrite(vibrationPin, HIGH); // If index is even, melody duration is pulse, switch vibration motor on
    else digitalWrite(vibrationPin, LOW); // Else, index is odd, melody duration is pause, switch vibration motor off
    delay(melody[index]); // Wait for number of ms of current melody index
  }

}


You can't really get things running in parallel if you are using delay() statements in your code. These statements are known as "blocking"... that is, everything has to wait while they run.

The better way to do what you want is to use millis() for timing related stuff. This makes things more complicated and it can sometimes be difficult for a beginner to grasp the concept... but it is pretty fundamental to doing anything useful.

The general principle is that instead of delaying, you take a snapshot of the current time with mills(), the keep checking the current time against that snapshot to work out how much time has passed. When it has you do something.

The BlinkWIthoutDelay example in the IDE shows the basic principle of this technique, by flashing the LED.

Once you understand this technique then you can adapt it to your particular example.

So is it just that bottom bit of code that says delay(melody[index]) that's causing the problems?

Does that mean I can't easily use the index at all because they're basically delays?

I'm curious about something.
In the varspeedservo code I have the servo movements set to "true" which as I understand means that the program waits for the servo to complete the move. There doesn't seem to be a delay however when I run it through. Is that because the event time is longer then it takes the servo to complete the action?

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