I'm trying to make a vibration motor(pin 11) vibrate based on how close an object is to an ultrasonic distance sensor(pins 2 and 3). the vibration motor vibrates even when nothing is close to the sensor.
long readUltrasonicDistance(int triggerPin, int echoPin)
{
pinMode(triggerPin, OUTPUT); // Clear the trigger
digitalWrite(triggerPin, LOW);
delayMicroseconds(2);
// Sets the trigger pin to HIGH state for 10 microseconds
digitalWrite(triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPin, LOW);
pinMode(echoPin, INPUT);
// Reads the echo pin, and returns the sound wave travel time in microseconds
return pulseIn(echoPin, HIGH);
}
void setup()
{
Serial.begin(9600);
pinMode(11, OUTPUT);
}
void loop()
{
Serial.println(0.01723 * readUltrasonicDistance(3, 2));
if (0.01723 * readUltrasonicDistance(3, 2) < 20) {
analogWrite(11, 255);
Serial.println("1");
}
else {
if (0.01723 * readUltrasonicDistance(3, 2) < 30) {
analogWrite(11, 200);
Serial.println("1");
}
else {
if (0.01723 * readUltrasonicDistance(3, 2) < 45) {
analogWrite(11, 150);
Serial.println("2");
}
else {
if (0.01723 * readUltrasonicDistance(3, 2) < 60) {
analogWrite(11, 150);
Serial.println("3");
}
else {
if (0.01723 * readUltrasonicDistance(3, 2) < 100) {
analogWrite(11, 100);
Serial.println("4");
}
else {
if (0.01723 * readUltrasonicDistance(3, 2) < 150) {
analogWrite(11, 50);
Serial.println("5");
}
else {
if (0.01723 * readUltrasonicDistance(3, 2) < 300) {
analogWrite(11, 10);
Serial.println("6");
}
else {
analogWrite(11, 0);
Serial.println("7");
}
}
}
}
}
}
}
}
Try printing the ACTUAL return from readUltrasonuicDistance before doing the calculation!!!!
Then go back to where the distance value is read and display the real value returned so you can see the value when there is no echo. To fix, read the documentation relating to "pulseln().
Consider setting the I/O pin states once in setup, and not nesting ifs to the n'th degree by using else if, only updating the analogWrite value when it changes, like so:
const byte triggerPin = 3;
const byte echoPin = 2;
unsigned long readUltrasonicDistance() {
digitalWrite(triggerPin, LOW); // Clear the trigger
delayMicroseconds(2);
// Sets the trigger pin to HIGH state for 10 microseconds
digitalWrite(triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPin, LOW);
// Reads the echo pin, and returns the sound wave travel time in microseconds
return pulseIn(echoPin, HIGH);
}
void setup() {
Serial.begin(115200);
pinMode(11, OUTPUT);
pinMode(triggerPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
int analogVal;
static int old_analogVal = -1;
char c;
float dist = 0.01723 * readUltrasonicDistance();
if( dist < 20 ) {
analogVal = 255;
c = '1';
} else if( dist < 30 ) {
analogVal = 200;
c = '1';
} else if( dist < 45 ) {
analogVal = 150;
c = '2';
} else if( dist < 60 ) {
analogVal = 150;
c = '3';
} else if( dist < 100 ) {
analogVal = 100;
c = '4';
} else if( dist < 150 ) {
analogVal = 50;
c = '5';
} else if( dist < 300 ) {
analogVal = 10;
c = '6';
} else {
analogVal = 0;
c = '7';
}
if( analogVal != old_analogVal ) {
Serial.println(dist);
analogWrite(11, analogVal);
Serial.println(c);
old_analogVal = analogVal;
}
}
It makes the code easier to read, allowing you to notice things like having the same analogWrite value for distances < 45 and < 60, and printing the same character for distances <20 and < 30. And you won't get an endless stream of output on the serial monitor, only when the distance changes to a new range.
And, possibly most importantly, you won't be endlessly resetting the analogWrite PWM value even when the distance range doesn't change.
Oh, and this does set the analogWrite value to 0 on pin 11 when the distance is sufficiently large.
You aren't by chance just hooking the vibration motor directly up to pin 11, are you? If so, stop NOW.
Hi,
thank you so much! this code works very well. Minor problem though: every time the ultrasonic sensor "pings" the vibration motor vibrates for half a second. do you know why?
there is a diode between the vibration motor and the Arduino
Hi,
Thanks for the warning - is this because of the current draw of the motor? If so I've checked the specifications of my motor and it seems like it has a max draw of 25mA, which is under the 40mA of the nano.