I want to control a cat door with a servo. The servo will stop and turn back to its previous position when it hits resistance. I tried with "millis()" but it did not work (see the code below). I found an example with 1-ohm, 5-watt metal film resistor here, but I am wondering if there is a possible solution with some code changes.
Any ideas?
#include <Adafruit_ILI9340.h>
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 95; // variable to store the servo position
unsigned long currentTime;
unsigned long previousTime;
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
}
void loop() {
for (pos = 95; pos >= 10; pos -= 1) { // goes from 95 degrees to 10 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(40); // waits 40ms for the servo to reach the position
}
Serial.println("The door is open");
delay(4000);
////////////////////////////////Check for resistance///////////////////////////////////
currentTime = 0;
previousTime = 0;
for (pos = 10; pos <= 95; pos += 1) { // goes from 10 degrees to 95 degrees
previousTime = millis();
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(30); // waits 30ms for the servo to reach the position
currentTime = millis();
if (currentTime - previousTime >= 31) {
for (int currentPos = pos; currentPos <= 10; currentPos -= 1) {
myservo.write(currentPos); // tell servo to go to position in variable 'currentPos'
delay(30);
}
currentTime = 0;
previousTime = 0;
delay(2000);
}
}
delay(4000);
}
I assume with "servo" you mean a standard RC-Servo.
This servo has three wires
minus plus signal towards the servo
Arduino-->-->-->-->-->-->--Servo
How the heck shall the Arduino know about the servo has hit a resistance??
There is nothing electrically or electronically there to do so.
There is no feedback at all from servo to Arduino.
So just with code it is impossible
One way to detect resistance is measureing the Servo's current
Another way would be to have a sensor that senses door fully opened.
Then you would check if sensor gives signal "door fully opened" after the normal open time
If the sensors gives no signal you can conclude door not fully opened.
Both ways have feedback from the servo towards the Arduino
A half-solution would be to shut off the power of the servo after openeing-time
but maybe the servo can't hold its position with power off
IMHO letting the servo-motor get hot is a very bad idea.
It will take 2 to 5 minutes until the temperatur-rise is high enough to detect it with a temperature-sensor.
If I remember right you want to use this for an automatic cat-door.
So your cat has to stay 2 to 5 minutes "locked" in a half-open door? And if the servo burns through for hours if you are not at home?
If the cat can be hurt by a half open door you have to re-design the mechanic that keeping the cat catched in the doors mechanic can never happen!
The electronic-interface-effor will be the same as using a current-sensor. With a current-sensor you can stop the servo in less than a second.
Hello again,
It works with 1-ohm, 5-watt, (1R0) resistor and You can use it for different projects. Here comes a test example (see the code below).
#include <Adafruit_ILI9340.h>
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos; // variable to store the servo position
int currentPos;
int sensorValue = 0;
int sensorPin = A0;
int treshold = 2;
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
pinMode(INPUT, A0);
}
void loop() {
for (pos = 10; pos <= 95; pos += 1) { // goes from 10 degrees to 95 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
sensorValue = analogRead(sensorPin);
Serial.print("sensorValue: ");
Serial.println(sensorValue);
delay(30); // waits 30ms for the servo to reach the position
if (sensorValue >= treshold) {
Serial.println("Back to previous position");
Serial.print("pos: ");
Serial.println(pos);
for (currentPos = pos; currentPos >= 11; currentPos -= 1) {
myservo.write(currentPos); // tell servo to go to position in variable 'currentPos'
delay(30);
}
Serial.print("currentPos: ");
Serial.println(currentPos);
sensorValue = 0;
delay(5000);
break;
}
}
delay(4000);
}
myservo.write(pos); // tell servo to go to position in variable 'pos'
sensorValue = analogRead(sensorPin);
Serial.print("sensorValue: ");
Serial.println(sensorValue);
delay(30); // waits 30ms for the servo to reach the position
Im thinking there will be a current spile each time you move the servo. You should probably wait until the servo reaches its destination before checking the current:
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(30); // waits 30ms for the servo to reach the position
sensorValue = analogRead(sensorPin);
Serial.print("sensorValue: ");
Serial.println(sensorValue);