Servo only moves once!

Hey all,

I've rigged up a servo to push a button. It should push it, wait for a frequency counter program to execute a certain number of times, then push again, restart the frequency counter, and so on... For some reason it will only push the button once, then every other time it executes it only restarts the index for the frequency counter. Here is the code, hope someone can help!
Thanks in advance.

#include <FreqCounter.h>
#include <Servo.h> // Include the servo library
Servo servoMotor; // Creates an instance of the servo object
int servoPin = 2; // Control pin for servo motor

void setup() {
Serial.begin(57600); // Connect to the serial port
Serial.println("Frequency Counter");
servoMotor.attach(servoPin); // Attaches the servo on pin 2
}

long int frq;
int i = 0;

void loop() {
if (i > 0) {
Serial.println(i);
i = i - 1;
FreqCounter::f_comp= 8; // Set compensation to 12
FreqCounter::start(500); // Start counting, gatetime 500ms
while (FreqCounter::f_ready == 0) // wait until counter ready
frq=FreqCounter::f_freq; // read result
Serial.println(frq); // print result
char buffer[5];
Serial.print("#S|FRQDATA|["); // This is for Gobetwino Program
Serial.print(itoa((frq), buffer, 10)); // Send all this to Gobetwino
Serial.println("]#");
}

else {
delay(500);
buttonpush();
delay(500);
i = i + 50;
Serial.println("did I do it?"); // Just for troubleshooting
}
}

void buttonpush() {
servoMotor.write(170); // Turn servo to 170 degrees.
delay(600); // Wait to get there.
servoMotor.write(0); // Turn back to 0 degrees.
delay(500); // Wait to get there.
}

You set i to 0 initially. Then, since i is not greater than 0, the else block executes, which moves the servo and increments i by 50 (to 50).

Then, loop runs again. This time, i is greater than 0, so the frequency data is collected, and i is decremented by 1 (to 49).

You should get 50 passes through loop before the servo moves again.

Does the servo move again, after 50 passes?

What does the servo movement have to do with pushing a button? You don't read the state of any switches. What are you measuring the frequency of?

Thanks for looking Paul,

No it doesn't move again after fifty passes, that's where I'm stuck. I'm measuring the frequency output from this directional RFID sensor, it shuts off automatically after a certain amount of time, so I have to push the button again. I have this little arm attached to the servo, it turns and pushes the button.

Does the "did I do it?" message get printed more than once?

If you, you might need to attach the servo before moving it, and detach it after moving it back.

Yeah, "did I do it" prints every fifty times, but the servo won't move again.

It would seem, then, that the frequency counting interferes with the servo library. Does attaching the servo in buttonpush(), and detaching it after the servo's done moving, help?

I had a quick look at the source for servo.cpp, and the link to Arduino Frequency Counter Library.

I believe they both use timer 1 in incompatible ways, i.e. they set it up differently and catch it's interrupts.

So, I don't think this can work.

HTH
GB-)

Servo and FreqCounter both need exclusive use of timer1 so won't work together.

you could control the servo in software using this library: Arduino Playground - Servo

But why not use pulseIn to measure the period and calculate the frequency, see: http://www.arduino.cc/en/Reference/PulseIn

Thanks everyone,

I'll try using the software servo library, I think that should work.

Note that freqCounter does a delayMicroseconds in the interrupt handler and this could disturb the timing of software servo. If your servo glitches with freqCounter, try using pulseIn (with either servo library)

The signal is modulated in such a way that pulseIn won't work. Like a square wave made up of smaller square waves. The smaller waves have a constant period.

WoodlyG, would you try to explain what it is you're trying to do?

It sounds like you don't need a very high quality servo control, in which case you could drive it in a bunch of ways to make it easier to capture and analyse the RFID signal.

For example, if you are willing to sacrifice the PWM outputs of Timer 2 (pin 3, and 11), then you could reprogram Timer 2 to control the servo, and have very little impact on Timer 1 which is used for frequency measurement.

GB

Ah well okay, all I need is to turn the servo to 170 degrees for a quarter of a second or so, and then turn it back. It needs to do this every two minutes.

The signal is modulated in such a way that pulseIn won't work. Like a square wave made up of smaller square waves. The smaller waves have a constant period.

So are you measuring the frequency of the smaller waves, or the number of smaller waves 'within the longer square wave'?

GB-)

The frequency of the larger wave is what changes, number of short pulses per second increases as the frequency of the large waves increases, up to a maximum. Picture a fairly high frequency square wave amplitude modulated with a much lower frequency square carrier. The frequency counter program works really well for this.

you could reprogram Timer 2 to control the servo

There is a servo library that works on timer2 but this won't help because the frequency counter library uses timers 1 and 2.

WoodyG, did you try the software servo library?

Okay, so you are effectively trying to measure the number of smaller (higher frequency) waves modulated within the overall longer (lower frequency) square wave.

If Frequency Counter works for you, then use Timer 2 to drive the pulse for the servo.

While not exactly right , set Timer 2 prescaler to 1024. This gives a servo pulse repetition of 16.4 milliSeconds rather than 20 milliSeconds, but some servo's will still work fine.

Then do analogWrite's of roughly 23 and 40 to swing the servo from 0 to 180.

Depending on the frequency being measured, you might lose a few values when you do

Serial.println(frq);                            // print result
   char buffer[5];
   Serial.print("#S|FRQDATA|[");          // This is for Gobetwino Program
   Serial.print(itoa((frq), buffer, 10));    // Send all this to Gobetwino     
   Serial.println("]#");

As all that printing will consume significant time. But this might not matter to the reult you are trying to get.

HTH
GB-)

If Frequency Counter works for you, then use Timer 2 to drive the pulse for the servo.

You probably posted before seeing the previous post, timer 2 is used by the frequency counter library

You probably posted before seeing the previous post, timer 2 is used by the frequency counter library

Yes I did. I'd gone to look at the source code for FreqCounter, and came back to discover you'd already spotted my error :-[

While FreqCounter is a good fit, I don't think it is essential to use two timers, though it will be a bit more intricate to write. In this case, WoodyG says the modulated frequency is pretty constant, so it should be practical to derive the gate time from the same timer. (I'm a bit busy to write it for a few days.)

Sorry for my mistake WoodyG.

GB

I did, I tried it and it didn't do anything at all for some reason. Windows gave me an error message while unpacking the files, not sure why. Going to try again tomorrow on a computer with visual studio so I can look over the code.