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-written the code about a zillion times, so I’ll begin by posting a sort of bare bones version and see where you all can guide me. Any help is greatly appreciated
//NOTE Servo Full Stop at 93
#include <Servo.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.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;
int newA = digitalRead(clkPin);//read the value of clkPin to newA
int newB = digitalRead(dtPin);//read the value of dtPin to newB
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;
}