Pulse counting on an output pin

Hello all,

This is my first post so just wanted to say these forums have been a massive help to get me where I'm up to with my small collection of Arduinos :slight_smile: So thanks for all the great contributions on here.

I'm developing a sketch to run an Arduino as a stepper control for my motor driver boards. I've got 2 rotary encoders controlling a variable frequency for each motor pulse signal (using the PWM library) to vary speed (steppers not servos!) I've also included a 2 way interface that links to my smart-phone over Bluetooth to an app I've written so this can be operated remotely.

It works really well and the speed of the steppers can be adjusted on the fly so there is the option to ramp acceleration etc. if I decide to dabble with speed curves.

However, I'm stumped at how to count the number of pulses produced on the output pins so I can accurately determine the position of the motors. As I'm using the PWM library I'm avoiding delving into that as it looks fairly complex (I'm a relative noob.) Obviously user input from the variable encoders will change the frequency over time so the number of pulses would be difficult to calculate accurately without timing how long each frequency was active for (which sounds convoluted to me) ... so it makes better sense to actually read the output pin state. The time is irrelevant as I just want to kill the output after it has pulsed X number of times. Sounds simple enough?

I had read that you CAN actually do a digitalRead on an OUTPUT so gave this a try... typically it messed timings up so there was intermittent dropout on the output pin's signal. I assume it was probably a resource/timing issue which steered me to look at interrupts - I'll be honest I've still got a lot to learn!

So I have a couple of questions - and just to be clear this is not an encoder issue. It's the number of pulses on the variable frequency signal output that I want to count.

  1. Can you read an output pin's signal while it is generating a signal - is this advisable for frequencies over say 550hz?

  2. As the control of the number of pulses is more important than adjusting the speed I have been looking at whether I should use Interrupts instead (have never used them so new territory) I was thinking maybe a PinChangeInt internal 'pin change' call sounded like it might be useful as I could just count the number of rising signal edges into my counter? Would this work?

  3. Could anyone clarify that an output pin can be read by either an interrupt or digitalRead. If not then what are my options?

Just want to make sure I'm not barking up the wrong tree. Any help would be much appreciated

Thanks

I had read that you CAN actually do a digitalRead on an OUTPUT so gave this a try... typically it messed timings up so there was intermittent dropout on the output pin's signal. I assume it was probably a resource/timing issue which steered me to look at interrupts

If you had trouble timing/controlling the outputs, you'll have the same trouble counting pulses on the input.

I've never programmed a stepper motor, but there is a stepper library (which I assume will help with your timing issues) and if your software tells the motor to take 3 steps, the software knows the motor took 3 steps.

There aren't timing issues as such. Using the PWM library I can vary frequency fine using my encoder or potentiometer values. The signal on my oscilloscope looks great and it will smoothly increase the stepper motor speed - so my driver is happy with the signal being created. My issue is controlling bursts of X number of pulse signals. i.e. if there is a higher frequency change from the user it just hits the counter value quicker - so it will still be in the correct motor position and I'm able to send a stop message to the signal generator.

If I need X number of counts from that signal I can either calculate it in software (which I don't think is going to be reliably accurate due to user changing encoder values during pulse generation) or I can get a read exact count of the number of pulses being generated. I know I could send X number of pulses... but that isn't the way I wanted this to work and I don't think this lends itself to how the PWM library works... not that I fully understand it yet.

Using PWM register to drive the motor is a very bad idea. This is because as you have found getting the feedback is hard. Using PWM effectively turns the stepping motor into a normal one.

What is wrong with doing it properly, that is actually generating the pulses from the computer so you know how many pulses you have generated.

You don't control a stepper motor with PWM. You control a stepper motor driver with a series of step pulses (which are usually very short (10 µsecs) and the speed is determined by the interval between the pulses.

See this Simple Stepper Code as an example.

PWM uses a constant frequency and just varies the mark-space ratio.

And if you are not using PWM you don't need to count the PWM pulses - which makes life much easier.

...R
Stepper Motor Basics

Hi Robin2,

Thanks for that. I'm well aware of how steppers and servos work. However, just because I'm using a PWM library doesn't mean I'm using PWM to control my driver. I'm actually using the PWM library just because I was very quickly able to take the frequency generator element from it and drop it in my sketch to enable my encoder to map and adjust frequency - keeping the pulse lengths the same :slight_smile: so I have quick and easy variable speed control. Higher encoder value = higher frequency. The other reason was as the clock value from the PWM library seems to ignore what the loop is doing and so if far more consistent on the scope read. I initially tried crude pulsing using timers and I seemed to be battling other events in the loop.

So back to my original question - and yes I know I can tackle this by generating my own pulse stream using code - but I was wanting to know if it is possible to read the pin feedback using the Arduino - as I already have a very workable speed control method in place.

If I could count the pulses in the variable frequency this would be easier than after they have been created this would be preferable... but if the consensus is to do it the other way around then I guess I can live with ditching that library and doing it from scratch.

but I was wanting to know if it is possible to read the pin feedback using the Arduino

Yes the output latch of a digital pin can be read by the processor.

Be aware that the digital read takes about 60 clock cycles and so is slow. Using direct port mapping will speed things up considerably.

ditching that library and doing it from scratch.

Sounds good to me.

moominjuice:
I'm actually using the PWM library just because I was very quickly able to take the frequency generator element from it and drop it in my sketch to enable my encoder to map and adjust frequency - keeping the pulse lengths the same :slight_smile: so I have quick and easy variable speed control. Higher encoder value = higher frequency.

Thanks for the clarification. I had not inferred that from your Original Post.

...R

Cheers for the input guys.

I quickly dropped the PWM library and read up a bit more on optimizing time dependent routines and went for the count on pulse generation method and wrote my own from scratch. It's 99.9% doing what I want it to now. Very similar in fact to the simple_stepper_motor code but with a few additions and tweaks. Some useful links there so thanks for that. Might have to look into AccelStepper library... although I do get more satisfaction out of writing my own code.

Grumpy_Mike - great bit of info on PortManipulation. Although I'm not at the end of trying my other methods this could in fact be useful to know if I need to to keep phases precisely in tune with other motors.
Although I'm a bit of a hobbyist I have worked in robotics and automation so like to know exactly what can be achieved from the software/hardware. The Arduino may not be a thoroughbred PLC but it's still pretty amazing how capable it is for the price.

As I'm largely self taught I like to explore why a method I choose isn't viable, rather than just follow examples of something that works. It helps to push the boundaries, find out and realize what limitations are and why, but also in exploring those limitations they pretty much always come in useful for other projects and ideas (or discounting them) Sorry if I sounded a bit stubborn lol.

Thanks again all :slight_smile:

I have counted the number of pwm pulses with two techniques.

One is to setup a timer overflow interrupt on the timer which is generating the pwm for the pin, and to increment a counter when each period completes. You can monitor or control the number of pulses with the count.

Also, if you are using pwm on pin 3 with timer 2, you can use an external interrupt on pin 3 and read the pulses. This is because the Atmega supports something called software interrupts. Once an interrupt is enabled it will be triggered even when the corresponding pin is configured as output. I would expect that this technique will work with other pwm pins and using a pin change interrupt.

Cattledog - you've nailed it!

I had suspected both methods were possible. The first option I'm going to avoid as there is an encoder controlling the frequency then there is the possibility of a mismatch using timers and predictive calculations... although it should work in theory I don't think it would be massively reliable without a lot of extra code.

The second method is confirmation of the alley I was heading up. So that's just given me that option should I need it. I had managed to do this via another method but as I'm using PIN3 & PIN9 I've the option to use hardware timers and I think I could possibly get much better accuracy. Although the stepper does what I'm after I had noticed that the the frequency isn't 100% reliable... although plenty good enough for most applications.

Need to play a bit more and report back my findings.