Pages: [1] 2   Go Down
Author Topic: Measuring the Frequency of a TTL circuit  (Read 5842 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm looking for help in measuring accurately a 20KHZ digital signal, its to read the pulses from a 500 pulse per revolution encoder that at top speed will spin around 1700 RPMs.  Any ideas on how fast the arduino can read a digital signal and how to count them?  (Also need to read two at a time, so will want to connect to more than one pin) 
Thanks!
Logged

0
Offline Offline
Jr. Member
**
Karma: 4
Posts: 65
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Are you doing Quadrature?  Do you need to know the direction of rotation?
Logged

0
Offline Offline
Shannon Member
****
Karma: 200
Posts: 11690
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

One approach is to use the signal to trigger an interrupt (pins 2 or 3) and in the interrupt routine read a timer register.  If the interrupt is set up on signal CHANGE, then you can time the high and low half-cycles separately and get the period and mark-space ratio too.

The standard timer setups on the Arduino are for PWM generation which might not be ideal for this (4us clock step, 8 bit).  Timer 1 can be
configured up to 16 bit and timers can run upto 16MHz. 

If high accuracy is not required pulseIn() might be the function you want.

If you are prepared to wait a bit, count the signal transitions over a measured stretch of time - the longer the time the more accurate you can be.
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It is for a quadrature encoder, however I already have a IC chip that converts the A and B signal into two separate pins for forward and back, so now all I need to do is count those pulses to know the RPM of the motor this encoder is connected to.  (Using it for a PWM output eventually, but for now, just focusing on getting accurate sampling)
Thanks for the replies thus far!  Keep 'em comin'!

**EDIT**
Oh and using an Oscilloscope, have measured the "forward pulses" at about 11khz, hence the need for a quick sample.
« Last Edit: January 27, 2011, 12:16:20 am by tchadwick » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8472
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You can feed the pulse into the TO or T1 pins and have the counter/timer count them for you.

______
Rob

Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Jr. Member
**
Karma: 4
Posts: 65
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am working on a related project right now and using the approach of user Graynomad.  I have a single encoder signal and will use it to clock TIMER1.  Next at a regular interval I can find the count of TIMER1 and know how many pulses have occurred.  I like this approach because the timer does not interrupt the cpu.

However, I think you need to consider what else you will be doing with the Arduino board and what conflicts you will have. For example, I think TIMER1 is used for Arduino PWM (analog) out.  I think TIMER0 is used for the millis() function.  Being a beginner myself you should confirm this information elsewhere as I could be wrong.

I think your motor is at 1320 RPM for 11kHz out.  Also, you will not hit 20kHz if your max speed is 1700RPM. ..maybe you are being conservative in your request to reach 20kHz max.

Do you know what the IC chip is doing?  A quadrature encoder would have two signals coming out of it (from what I understand of course) so if the IC chip is also putting out two signals... what is it doing?  Maybe it is a Schmitt trigger?  Is it changing the logic levels?
Logged

Rural Arizona
Offline Offline
Edison Member
*
Karma: 7
Posts: 1711
Incorrigible tinkerer
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How often do you need to get the RPM data?  The CD4060 can divide the tach signal by as much as 16K in a single chip.  Plus,  by accumulating multiple pulses,  it would remove most of the jitter you'll see if you measure every pulse.

The downside is that there could be an unacceptably long time between the prescaled pulses when the motor is spinning slowly.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

We are using a quadrature encoder, however our IC chip takes the A/B Pulses and outputs on two pins their combined pulse. (ex. Pin 1 is putting out an 11khz pulse telling me that the motor is rotating at about 1300 RPMs in forward motion, while pin2 is kept in a low state.  Vice versa for when the motor rotates backwards, causing pin 1 to go low and pin 2 to start pulsing)  I would go with the Idea from Graynomad, save I do need PWM for driving said motor.  But thanks for the ideas so far!
I was thinking about using this library: http://www.arduino.cc/playground/Main/MsTimer2  And set a sample in the "Loop" portion of the program so that it is continously sampling and every time there is a change in state from low to high (thus eliminating the chance of sampling the same pulse twice) I could increment a counter. Then every 1 second, it outputs the count to the screen.  If this sparks any ideas, let me know.
« Last Edit: January 29, 2011, 02:41:15 pm by tchadwick » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8472
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What is the range of the input frequency and the required display update rate. If it's 0-11k then using a prescaler could be a problem at low freqs as Ran said, unless you only have to update a display (or use the info in whatever way) every few seconds.

_____
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8472
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Just reread your last post

Quote
Vice versa for when the motor rotates backwards, causing pin 1 to go low and pin 2 to start pulsing

Are you saying that this chip swaps the function of the two pins according to the direction  smiley-eek

If so I don't see any easy way to detect this as you have to differentiate between a frequency and a DC level, and at slow speeds especialy there's no real difference.

Can you post a link to the decoder chip spec sheet?

_____
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the replies, I will start digging for the spec sheet on Monday.  In the mean time the decoder chip converts the AB signals, to a speed pulse on pin 1 for forward and if the motor reverses, it stops sending pulses on pin 1 and starts sending pulses on pin 2.  Which should make it easier to sample the incoming data especially while I'm just trying to determine the RPM in one direction (for now  smiley-wink )

**EDIT**

So in forward pin one (TTL)pulses and pin 2 is off.  Then in reverse pin one turns off and pin 2 starts a TTL pulse at a proportional value to RPMs.  Oh and we are using the Arduino MEGA.
« Last Edit: January 29, 2011, 11:14:37 pm by tchadwick » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8472
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So in forward pin one (TTL)pulses and pin 2 is off.  Then in reverse pin one turns off and pin 2 starts a TTL pulse at a proportional value to RPMs.

IMO then that is a seriously bad chip, a pulse pin and direction pin would be better, but anyway,

To do this I think you have to

a) OR the two pins into a single interrupt (using an AND gate or two diodes) and run one of the pins to a digital input. Thus when you get an interrupt you test the input to see which pin was the culprit.
b) use two interrupts, one ISR sets a "direction" global, the other resets it.

Option b) is simpler and doesn't need any external components, but a) is better if you only have a single interrupt free.

NOTE: this is just for direction, it doesn't handle the counting.

______
Rob
« Last Edit: January 30, 2011, 12:02:46 am by Graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is an attempt at coding, I'm looking for any thoughts for improvement and more importantly for thoughts of implementation.
Thanks ahead of time:
#include <MsTimer2.h>

//Output the value of count to the serial monitor

int buttonstate = 0;
long int counter = 0;
void flash()
{
  Serial.println(counter, DEC);
  counter = 0;
}

void setup()
{
  pinMode(9, INPUT);
  MsTimer2::start();
}

void loop()
{
  buttonstate = digitalRead(9);
  if(buttonstate == LOW)
  {
    buttonstate = digitalRead(9);
    if(buttonstate == HIGH)
    {
      counter++;
    }
  }
}
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8472
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So in this example you are waiting for a button to be pressed, then counting when it's released.

I think this has problems, you're not waiting for the button to be released, simply testing once straight after it was pressed when of course it will still be LOW.

Code:
  if(LOW == digitalRead(9))  {
    while (LOW == digitalRead(9)) {}; // wait for button to be released
    counter++;
  }

This assumes the input is clean and doesn't need debouncing. If you are using a button for initial testing (as the pin name implies) then you will need to debounce it.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I apologize for the naming, but I actually wanted to measure each pulse from the IC chip, so it should be a relatively clean TTL signal not really requiring debouncing (I hope).  My biggest worry is that I will measure a "high" signal twice thus incrementing my timer twice for the same signal.  So I guess you could sum up my entire problem as finding a way to measure the digital frequency with an arduino.
Any ideas for the coding would be great!
« Last Edit: February 02, 2011, 05:32:01 pm by tchadwick » Logged

Pages: [1] 2   Go Up
Jump to: