Continuous Rotation Servo + PIR Sensor Help!

While what retrolefty says might be true (I don't have a continuous rotation servo to test it), the usual way to make a continuous rotation servo move is to use the Servo::writeMicroseconds() method, as I've mentioned before.

The argument for writeMicroseconds() defines the direction and speed of rotation. A value of about 1500 will cause the servo to stop.

A larger value, up to about 2200, will cause it to rotate in one direction. The farther from 1500, the faster the rotation.

A smaller value, down to about 800, will cause it to rotate in the other direction. The farther from 1500, the faster the rotation.

The actual stop point and minimum and maximum values will need to be determined experimentally.

While what retrolefty says might be true

It is.
Don't forget that "Servo.write" ultimately just calls "Servo.writeMicroseconds" anyway, it's just that the latter potentially gives finer control.

(If you call the "write" method with a "angle" value greater than 544, it simply falls through the mapping that would otherwise occur, and calls the "writeMicroseconds" method directly, so a writeMicroseconds (1500) is exactly the same as "write(1500))

So for example in my code i replace this code:

 void reverotation() {
    digitalWrite(servoPin,HIGH);
    delayMicroseconds(1800);
    delay(20);
    digitalWrite(servoPin,LOW);
 }

for this one?

 void reverotation() {
    Servo::writeMicroseconds(1800));
 }

Or even simply:

void reverotation() {
    myServo.write (1800);
 }

(there is one closing parenthesis too many in your code)

The Servo::writeMicroseconds() notation refers to the implementation of the writeMicroseconds() method of the Servo class. To actually call that method, you need an instance of the class.

Servo myServo;
myServo.writeMicroseconds(1500);

Alright, i revised the code according to the tips i got, but where do i write Servo.myServo;?

I tried implementing it at the start of the code but it's giving me a "Servo does not name a type" error..

Here is the revised code, along with the place i tried to place Servo.myServo; in:

 int timer = 500;
 int alarmPin = 0;
 int alarmValue = 0;
 byte rotated = 0;
 Servo myservo;

 void setup () {
 Serial.begin (9600);
 pinMode(alarmPin, INPUT);
 myservo.attach(9)
 delay (20);
 }

 void loop (){
 alarmValue = analogRead(alarmPin);

if ( (alarmValue < 100) && (rotated = 0) ){
  rotation();
  byte rotated (1);
 }
else if ( (alarmValue > 1000) && (rotated = 1) ){
  reverotation();
  byte rotated (0);
 }
else
  norotate();
 
 
 delay(timer);

 Serial.println (alarmValue);

 delay (20);

 }

void rotation() {
    Servo::write (1200);
 }

void reverotation() {
    Servo::write (1800);
 }

void norotate() {
    Servo::write (1500);
 }

#include <Servo.h>

but it's giving me a "Servo does not name a type" error

Big clue.

void rotation() {
    Servo::write (1200);
 }

Bzzzzt.
Read PaulS' last reply.

 byte rotated (1);

You're creating a byte variable, initialising it, then microseconds later it goes out of scope and disappears.
Put it above "setup"

Alright, i fixed the mistakes above and arrived at:

#include <Servo.h>

 int timer = 500;
 int alarmPin = 0;
 int alarmValue = 0;
 Servo myservo;
 byte rotated = 0;

 void setup () {
 Serial.begin (9600);
 pinMode(alarmPin, INPUT);
 myservo.attach(9);
 delay (20);
 }

 void loop (){
 alarmValue = analogRead(alarmPin);

if ( (alarmValue < 100) && (rotated = 0) ){
  rotation();
 }
else if ( (alarmValue > 1000) && (rotated = 1) ){
  reverotation();
 }
else
  norotate();
 
 
 delay(timer);

 Serial.println (alarmValue);

 delay (20);

 }

void rotation() { 
    myservo.write (1200);
 }

void reverotation() {
    myservo.write (1800);
 }

void norotate() {
    myservo.write (1500);
 }

Now (i think) i only need to adress one final issue:

byte rotated(1)

You're creating a byte variable, initialising it, then microseconds later it goes out of scope and disappears.
Put it above "setup"

I placed it above the "setup" code every time, but i wanted to find a way to make the arduino software know if the door was opened or closed, so i assumed this was the way to do it. I defined "rotated" as 0 in the beggining, to indicate to the software the door starts off as closed. Then, after the PIR sensor detects movement, its supposed to command the servo to rotate to open it, then change the "rotated" byte to 1.

I think im a bit confused about this though, just a tiny bit :stuck_out_tongue:

if ( (alarmValue < 100) && (rotated = 0) ){

Grab that clue by 4 and give yourself several good whacks. You've been told many times that you need == here, not =.

Ow, that kinda hurt >.<

Alright i changed it, but it's still not fixing my problem :\

How do i signal the arduino that the door opened using a sort of flag system?

Ask yourself "How does the Arduino know the state of the door when it gets reset?"

How do i signal the arduino that the door opened using a sort of flag system?

You have the right idea. You need to set the value of rotated at the correct point in the code, though.

Ask yourself "How does the Arduino know the state of the door when it gets reset?"

When the Arduino board is reset, it...kinda doesn't know? It assumes the door is closed again, even if it's opened? Because i...declared the door as being closed >.<

If im understanding this correctly, that is. I hope i am :expressionless:

EDIT: So the value isn't being set at the correct point?

You modified the code, and didn't repost it. Now you want us to guess whether initialization is performed correctly, or not?

Going from the last code you posted, though, it is not.

When you declared the global variable rotated, it gets a default value, or you assign it one. Later in the code, you check the value that is stored in that variable, but you never assign a new value.

When you open the door, you need to assign a value. When you close the door, you need to assign a value.

When the Arduino resets, for whatever reason, that value is lost. The Arduino won't know whether the door is open or closed.

If it is necessary for it to know that, you need to persist the setting, in EEPROM.

Even better though, would be to use limit switches to sense when the door is open or closed. If is is closed, and needs to be open, open it until the open limit switch detects that the door is open. If it is open, and needs to be closed, close it until the closed limit switch detects that the door is closed.

PaulS:
You modified the code, and didn't repost it. Now you want us to guess whether initialization is performed correctly, or not?

Going from the last code you posted, though, it is not.

When you declared the global variable rotated, it gets a default value, or you assign it one. Later in the code, you check the value that is stored in that variable, but you never assign a new value.

When you open the door, you need to assign a value. When you close the door, you need to assign a value.

When the Arduino resets, for whatever reason, that value is lost. The Arduino won't know whether the door is open or closed.

If it is necessary for it to know that, you need to persist the setting, in EEPROM.

Even better though, would be to use limit switches to sense when the door is open or closed. If is is closed, and needs to be open, open it until the open limit switch detects that the door is open. If it is open, and needs to be closed, close it until the closed limit switch detects that the door is closed.

It is not necessary for the arduino to know whether the door is open or not, seeing as this code is going to be used in a one time only presentation. If the arduino was to reset by an outside effect, one could close the door and reboot the board, so yeah. (It is a miniature scale house, after all)

When you declared the global variable rotated, it gets a default value, or you assign it one. Later in the code, you check the value that is stored in that variable, but you never assign a new value.

So how can i assign a new value? I assumed i had to include byte rotated(x) in the code after i instruct the door to move? If that's not the correct way, which one is?

" byte rotated(x) " declares a new variable called "rotated, and assigns it the value "x".
This locally overrides the variable called "rotated" declared above "setup", but value is destroyed when it goes out of scope, i.e at the next "}"

If you miss off the "byte" part, and write "rotated = x;" instead, then you don't create a new variable, and you use the global one, and because this can't go out of scope, it never gets destroyed, so "survives" from one incarnation of "loop" to the next.

Alright, progress :smiley:

Okay, here is the revised code:

#include <Servo.h>

 int timer = 500;
 int alarmPin = 0;
 int alarmValue = 0;
 Servo myservo;
 byte rotated = 0;

 void setup () {
 Serial.begin (9600);
 pinMode(alarmPin, INPUT);
 myservo.attach(9);
 delay (20);
 }

 void loop (){
 alarmValue = analogRead(alarmPin);

if ( (alarmValue > 1000) && (rotated == 0) ){
  rotation();
  rotated = 1;
 }
else if ( (alarmValue < 100) && (rotated == 1) ){
  reverotation();
  rotated = 0;
 }
else
  norotate();
 
 
 delay(timer);

 Serial.println (alarmValue);

 delay (20);

 }

void rotation() { 
    myservo.write (1200);
    delay(1000);
 }

void reverotation() {
    myservo.write (1800);
    delay(1000);
 }

void norotate() {
    myservo.write (1500);
    delay(2000);
 }

A couple of problems:
On the original PIR sensor sketch, 1023 == no movement and 18 == movement detected on the serial monitor, but now on the new sketch, they reversed positions :S Any idea as to what caused this?
Also, the values keep fluctuating, as in, even when the PIR is facing a wall, its detecting motion :S
Thoughts?

EDIT: Nevermind, faulty wiring

Which means it works perfectly now :smiley:

Thanks for putting up with my idiot ways, YET AGAIN.

Until next time, see ya :smiley:

Alright, progress

Feels good to finally get it working, doesn't it?

I'd suggest that, knowing what you know now, you go back and re-read this entire thread. I think you'll see that we had to tell you some things more than once.

Not that there's necessarily a problem with that, if you don't understand something. But, if you don't understand, ask questions, don't just ignore the advice.

I know that it is worth exactly what you paid for it, sometimes, but, often the advice given here really is good.