Sensor speed controller servo issue

Hi,

I'm new to Arduino and have only made a few projects, so can someone help me with this code? I'm trying to built a system where a sensor will judge the distance of an object, and based on that distance it will send the distance to a 4-digit display and change the speed of the servo:

#include <TM1637.h>

const int trigPin = 9;
const int echoPin = 10;

const int CLK = 2;
const int DIO = 3;
TM1637 tm1637(CLK, DIO);

long duration;
int distance;

int servo = 4;
int pulse = 500;

void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
tm1637.init();
tm1637.set(BRIGHT_TYPICAL);
delay(1500);
pinMode (servo, OUTPUT);
}

void loop() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);

digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

duration = pulseIn(echoPin, HIGH);

distance= duration*0.034/2;

Serial.println(distance);

int digitOne = distance / 10;
int digitTwo = distance % 10;

tm1637.display(1, digitOne);
tm1637.display(2, digitTwo);
tm1637.display(3, 12);

delayMicroseconds(pulse);
if ((distance) == 5) {
delay(500);
}

if ((distance) == 7) {
delay(400);
}

if ((distance) == 9) {
delay(300);
}

if ((distance == 11)) {
delay(200);
}

if ((distance == 13)) {
delay(100);
}

if ((distance == 15)) {
delay(0);
}
}

The code actually does something, but you forgot to tell us what it does.

You expect the code to do something. Presumably is does not do what you want, but you forgot to tell us how what it does differs from what you want.

Its hard to tell you without knowing what the problem is.

I think I see the problem with the servo. First with normal servos you don't control speed you just set positions and second your code never does anything with the servo anyway.

Steve

I read somewhere that if you differ the delay time, that makes the servo appear to go faster or slower. That is what I was trying to do with all the if statements at the end. When I uploaded the code to my Arduino Uno, nothing happened at all, the 4-digit display didn't even light up.

jt123yeet:
I read somewhere that if you differ the delay time, that makes the servo appear to go faster or slower. That is what I was trying to do with all the if statements at the end. When I uploaded the code to my Arduino Uno, nothing happened at all, the 4-digit display didn't even light up.

If you are wanting to change the apparent speed of the servo.

Changing the apparent speed of the servo by using delays would be to incrementally rotate the servo and for each increment increase the time between increments

For an example of moving servo slower than usual, see File->Examples->Servo->Sweep

In the future, would you mind making it easier to read your code by auto-formatting it and putting it in code brackets by pressing on this icon: </>

I found this library that might help you:

Read up on it and give it a try.

Good luck,

-- DH

You need to look at the Sweep and Knob examples in the IDE to learn how to use a servo.

If you use code from the Sweep example you will see there are delays in it. THOSE are the delays you need to change to alter the apparent speed of the servo.

  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       //// change the number in THIS delay to alter speed
  }

but you do need all the rest of the code to get the servo to move at all.

Initially I would just try Sweep as it is and just get the servo moving. Change the delay(15)s to other numbers and reload to see the effect. Then you'll know what you're aiming for.

Steve

jt123yeet:
I read somewhere that if you differ the delay time, that makes the servo appear to go faster or slower. That is what I was trying to do with all the if statements at the end. When I uploaded the code to my Arduino Uno, nothing happened at all, the 4-digit display didn't even light up.

Hi

There's quite a lot going on here so let's see if we can break the big problem down inti more solvable chunks

  1. Check we are talking to the display. Add the following function:-
void displayTest() {
  for(int i = 0; i < 4; i++) {
    tm1637.display(i,i);
    delay(1000);
  }
  delay(3000);
  tm1637.clearDisplay();
}

Then add this line after your delay(1500); statement in setup()

displayTest();

This will prove that you can talk to the display and that things are displaying in the correct place. If nothing happens check your wiring carefully.

  1. Is the distance sensor working. First of all are you seeing anything on the serial monitor? If so does it make sense? i.e. if you point it at an object 30cm away does it show a value somewhere around 30? if not check your calculations. Try changing your equation to:-
 distance = duration*34/2000);

N.B. duration should be an unsigned long to match what pulseIn() returns.

If it continuously shows 0 even though your target object is within range check your wiring.

As you only seem to be interested in short distances you may want to read the reference page on pulseIn() to set the timeout value so it doesn't spend too much time waiting for return echoes. N.B. duration should be an unsigned long to match what pulseIn() returns.

  1. There are two types of servo commonly used with the arduino i) fixed rotation which moves from 0 to 180 degrees on command and ii) Continuous rotation which rotates either forward or backwards at a speed controlled by the pulse width modulation. As your talking about servo speed I'm wondering if you are using a continuous rotation version?

To drive a servo you need to provide it with a pulse width modulated square wave. The easiest way to do this is to use the servo library provided with the arduino IDE.

To do this add the following lines to your code

// At the top of the code

#include <Servo.h>
Servo myServo;

// In setup();

myServo.attach(servo);

// In loop when you want to change the servo position or speed


myServo.write([i]position[/i]);

// [i]position[/i] varies from 0 to 180 where 0 is fully anticlockwise and 180 is fully clockwise for the fixed rotation version servo
// and 0 is max speed anticlockwise, 90 is stopped and 180 is max speed clockwise for the continuous rotation version servo.

N.B. Do not power more than one small (e.g. SG90) servo from the arduino as taking too much current from the arduino will damage it. This is especially true if using two continuous rotation servos to drive a small vehicle.

Finally you are comparing distance to fixed values in your code e.g.

if ((distance) == 5) {
delay(500);
}

As distance is continuously varying it is very likely most of the time it will be either greater than or less than a particular value rather than actually equal to it. You should test that it falls in a range of values e.g.

if ((distance < 5) & (distance > 0)) {
  // Do something because it's very close
}
if (distance < 7) & (distance => 5)) {
  // Do something because it's getting near
}

Note that 0 is a special case which is returned by pulseIn() when it times out and actually indicates a distance beyond maximum range (controlled by the timeout parameter in pulseIn() which defaults to 1sec if not set).

Hope this gives you some guidance to help you get your code working.

Ian