# Continous servo with Ultrasonic sensor

I was wondering if anyone might be able to offer any ideas/advice…

For my project, I am trying to use an ultrasonic sensor (Maxbotix MB1043) with a continuous rotation servo (Hitech HSR-2645CRH) and a simple rotary encoder to try to give feedback for the position to control the movement of a curtain.

Basically, i want the curtain to lower and raise in proportion (or close to that) in relation to how far away a person is standing to the sensor. For example, if the person was >15’ away, the curtain would be all the way up, if they were ~7’ away, it would be half way down, and if they were ~1’ away it would be at its lowest point. If they move closer, the curtain falls, and if they move away, the curtain raises back up…

I fully admit that im pretty weak when it comes to the coding part of arduinos (art student here). i can figure out how to make the servo rotate in one direction, but not back the other way.

My instinct tells me that i need to create some way for the arduino to “remember” a distance (or perhaps a rotary encoder value?) and then compare that to a new distance, but i really dont know how to do that. Ive tried a few things, but unfortunately, what ive tried makes the servo move a tiny bit and stop and then move a little more and stop again.

Ive written and re-writtne the code about a zillion times, so I’ll begin by posting a sort of bare bones version and see where you all can guid me. Any help is greatly appreciated

``````//NOTE Servo Full Stop at 93

#include <Servo.h>
#include <Wire.h>

Servo myservo;  // create servo object to control a servo

//SENSOR

int sonarPin = A0; //pin connected to analog out on maxsonar sensor
int inchesAway; // inches away from the maxsonar sensor
int lastDistance;

const int clkPin = 2; //the clk attach to pin 2
const int dtPin = 3; //the dt pin attach to pin 3
const int swPin = 4 ; //the sw pin attach to pin 4

int buttonState = 0;
int encoderVal = 0;
int counter;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {

Serial.begin(9600);
myservo.attach(7);  // attaches the servo on pin 9 to the servo object

//set clkPin,dePin,swPin as INPUT
pinMode(clkPin, INPUT);
pinMode(dtPin, INPUT);
pinMode(swPin, INPUT);
digitalWrite(swPin, HIGH);

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {
Serial.println(encoderVal);
Serial.println(inchesAway);
//   Serial.println(lastDistance);
//   lastDistance = inchesAway;;
inchesAway = analogRead(sonarPin) * 5 / 25.4; // converts to inches

int change = getEncoderTurn();//
encoderVal = encoderVal + change;
if (digitalRead(swPin) == LOW) //if button pull down
{
encoderVal = 0;
}

if (inchesAway >= 180) {
myservo.write(93);
}

if (inchesAway <= 179 && inchesAway > 168 && encoderVal != 20) {
myservo.write(35);
if(encoderVal = 20){
myservo.write(93);
}
}

if (inchesAway <= 168 && inchesAway > 156 && encoderVal != 40) {
myservo.write(35);
if(encoderVal = 40){
myservo.write(93);
}
}

if (inchesAway <= 156 && inchesAway > 144 && encoderVal != 60) {
myservo.write(35);
if(encoderVal = 60){
myservo.write(93);
}
}

if (inchesAway <= 144 && inchesAway > 132 && encoderVal != 80) {
myservo.write(35);
if(encoderVal = 80){
myservo.write(93);
}
}

if (inchesAway <= 132 && inchesAway > 120 && encoderVal != 1000) {
myservo.write(35);
if(encoderVal = 100){
myservo.write(93);
}
}

if (inchesAway <= 120 && inchesAway > 108 && encoderVal != 120) {
myservo.write(35);
if(encoderVal = 120){
myservo.write(93);
}
}

if (inchesAway <= 108 && inchesAway > 96 && encoderVal != 140) {
myservo.write(35);
if(encoderVal = 140){
myservo.write(93);
}
}

if (inchesAway <= 96 && inchesAway > 84 && encoderVal != 160) {
myservo.write(35);
if(encoderVal = 160){
myservo.write(93);
}
}

if (inchesAway <= 84 && inchesAway > 72 && encoderVal != 180) {
myservo.write(35);
if(encoderVal = 180){
myservo.write(93);
}
}

if (inchesAway <= 72 && inchesAway > 60 && encoderVal != 200) {
myservo.write(35);
if(encoderVal = 200){
myservo.write(93);
}
}

if (inchesAway <= 60 && inchesAway > 48 && encoderVal != 220) {
myservo.write(35);
if(encoderVal = 220){
myservo.write(93);
}
}

if (inchesAway <= 48 && inchesAway > 36) {
myservo.write(35);
if(encoderVal = 240){
myservo.write(93);
}
}

if (inchesAway <= 36 && inchesAway > 24 && encoderVal != 260) {
myservo.write(35);
if(encoderVal = 260){
myservo.write(93);
}
}

if (inchesAway <= 24 && inchesAway > 12 && encoderVal != 280) {
myservo.write(35);
if(encoderVal = 280){
myservo.write(93);
}
}

if (inchesAway <= 12 && inchesAway > 1 && encoderVal != 300) {
myservo.write(35);
if(encoderVal = 300){
myservo.write(93);
}
}

// if (encoderVal == 20 || 40 || 60 || 80 || 100 || 120 || 140 || 160 || 180 || 200 || 220 || 240 || 260 || 280 || 300){
//     myservo.write(93);
//}

}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

int getEncoderTurn(void)
{
static int oldA = HIGH; //set the oldA as HIGH
static int oldB = HIGH; //set the oldB as HIGH
int result = 0;
if (newA != oldA || newB != oldB) //if the value of clkPin or the dtPin has changed
{
// something has changed
if (oldA == HIGH && newA == LOW)
{
result = (oldB * 2 - 1);
}
}
oldA = newA;
oldB = newB;
return result;
}
``````

i can figure out how to make the servo rotate in one direction, but not back the other way.

Then why do you have so much code that is unrelated to the servo?

Typically, a not-really-a-servo will turn one way when the value written to it is below 90, going faster as the value gets smaller, and turn the other way when the value written to it is above 90, going faster as the value gets larger.

``````    if(encoderVal = 20){
``````

Fail.

``````    if(encoderVal = 40){
``````

Fail.

``````    if(encoderVal = 60){
``````

Fail.

``````    if(encoderVal = 80){
``````

Well, you get the idea.

A little, simple, math would greatly reduce the amount of code you have.
A little, simple, math would greatly reduce the amount of code you have.
A little, simple, math would greatly reduce the amount of code you have.
A little, simple, math would greatly reduce the amount of code you have.
A little, simple, math would greatly reduce the amount of code you have.
A little, simple, math would greatly reduce the amount of code you have.
A little, simple, math would greatly reduce the amount of code you have.
A little, simple, math would greatly reduce the amount of code you have.

Storing a value uses one equal sign. (This also returns a result that can be used in an "if" statement but is probably not what you intended.)
Comparing values uses two equal signs.