Frequency Read (Multiple Pins)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hello,

   

I have a PSoC 4100 and I'm trying to read in the frequency from 9 pins. I'm limited to using 1 counter and no digital mux. Is there another method around this? Usually I would write a software mux but in this case I can't seem to assign one pin to another.  I have attached the TopDesign to this post.

   

 

   

Thank you.

0 Likes
52 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Your PWM frequency is relatively low, so you could consider doing the measure in software, thus

   
        
  • Read the pin, wait while low
  •     
  • start counter from zero
  •     
  • Read the pin, wait until low
  •     
  • Read counter to get high-time
  •     
  • Read the pin, wait until high
  •     
  • Read counter to get low-time
  •     
  • Calculate frequency and duty-cycle.
  •    
   

In order to minimize programming effort consider using an array of pointers to the pin_Read() functions.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Hi Bob,

   

Thank you for responding. I'm fairly new to PSoC but how do you assign an individual pin to the counter? Btw Frequency count is 1/(ResultHigh - ResultLow), correct?

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

You are not measuring all pins at the same time, so you can keep track with an index on which pin you are working right now. when done, increment the index, when index too large, reset to zero.

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Thank you for replying. I'm not sure I follow your algorithm correctly but attached is the implementation I have:

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Sorry, but I do not want to decrypt C-language in an rtf-file. Can you please post your complete project, so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Ok thank you Bob. Here is the attached project.

   

Rick

0 Likes
lock attach
Attachments are accessible only for community members.
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Better try this...

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Hello Bob, 

   

Thank you for the help. 

   

How is Wait(x) implemented? I've never seen a macro function performed that way. Is it some kind of delay if used as Wait(2) 2 being in seconds?

   

Rick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

How is Wait(x) implemented? 

   

while(condition) Wait();

   

is with the macro definition now the same as

   

while(condition);

   

or

   

while(condition)

   

{

   

}

   

But the first form is better readable and usually does not need a comment.

   

Is it some kind of delay No, it is an empty definition and it does nothing at all

   

Bob

0 Likes
Anonymous
Not applicable

oh, much clear now. One more thing, to calculate the frequency, it is simply the counter number 1/(FreqHigh - FreqLow)?

   

Thanks,

   

Rick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Not quite, the counts in FreqLow are the accumulated High and low-time already. The the input frequency to the counter divided by the counted value gives the signal frequency.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Currently the counters clock is 12MHz. The total count is: TotalCount[Number] = ResultHigh[Number] + ResultLow[Number]. So frequency should be: 12000000/TotalCount[Number] if i'm not mistaken.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

The counter is not reset after measuring ResultHigh[]. So ResultLow[] contains the total count. Should better be renamed to ResultTotal[] to make it quite clear.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

I see. ResultLow is the total count from zero to one of the signal. So will this be able to help me read in any frequency range to the pin?

   

Rick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Not any frequency.

   

Highest freq. is when the counter counted to one, lowest when counted to 65535. So you may choose with the clock which frequency band you want to measure. There is an API to set the clock frequency, see "System Reference Guide" or clock datasheet.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

So with the current settings: 12 MHz clock, 16 bit timer, if the counter counts to 1, the frequency is 12 MHz. But if the counter counts to 65535, the frequency is 183 Hz? By that logic, if I want to read 1 Hz to 65 KHz, I can set the counters clock to 65 KHz. When the counter reads 1, the frequency is 65 KHz and when the counter reads 65535, the frequency is close to 1 Hz. Is that correct?

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

That is right.

   

What is your frequency range you want to measure?

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Somewhere between the range of 0Hz and 200KHz.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

So you will have to fumble around with the clock. But first get it running as your simple solution.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

So I need to read in somewhere between 0 Hz and 500 Hz. By minimizing the counter from 65535 to 500 and setting the clock to 500 Hz, would that give me an accurate measurement.

   

In addition, is there a difference between reading in a frequency and reading in a pulse or are the two terms related?

   

I appreciate all the help you have given me.

   

Thank you,

   

Rick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

is there a difference between reading in a frequency and reading in a pulse A pulse is the high-time only while the frequency is the repetition value of the pulse.

   

The higher the count is, the more precise is the measurement: Take the example of a count of 10 +-1 and a count of 100 +-1

   

So the count clock should be as high as possible.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Alright, so the 65 KHz clock is high enough to get a precise measurement between 0 Hz and 500 Hz. Now, to calculate the duty cycle would be [Thigh/(Tlow + Thigh) ] * 100?

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Do not mix the words "Count" and "Clock"!

   

The duty cycle is the high-time in relation to the total time, hence (tHigh /tTotal)*100.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Thank you for your help Bob. You have made this subject a lot clearer for me. I hope to stay in contact with you if I ever have any PSoC 4 related questions.

   

Thank you,

   

Rick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

You are always welcome, Rick!

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Hello Bob, I have a new question dealing with frequency. I need to read an exact measurement such as 3.25 Hz or 83.56 Hz. Where do I begin? Do I make some variables floating?

   

Rick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Do not be afraid of using float or double, the ARM M0 core is fast enough to handle that!

   

You will need a precise crystal time base because the internal oscillator is not accurate enough,

   

for these low frequencies the best approach will be to count a ~10kHz frequency and read / reset the counter at every rising edge of the (conditioned) input signal. This can be made interrupt driven when the solution works.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Thanks for responding Bob. 

   

Can I get away with using the internal oscillator? I'm not allowed to use an external oscillator. When you say 10KHz do you mean by setting my counters clock to 10KHz? Also, can you elaborate on how to implement with interrupt?

   

Thanks,

   

Rick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Also, can you elaborate on how to implement with interrupt? Later, when you got it to work without interrupts. 😉

   

 

   

Bob

0 Likes
Anonymous
Not applicable

So I changed my frequency variables to float32 and can now read in an exact frequency with decimal. But heres the catch: i can only read exact values from 1 to 280...it seems that anything below 1 it cannot read and anything above 280 the read frequency is off by 1 and gradually increases if the frequency is higher.

   

p.s. the counters clock is 65.535 KHz, 16 bit timer

   

Rick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

p.s. the counters clock is 65.535 KHz, 16 bit timer  I don't believe that!

   

Can you please post your complete project, so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.

   

 

   

Bob

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Yes, here is the project.

   

Rick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

What is the lowest frequency you need to measure and what is the highest?

   

 

   

Bob

0 Likes
Anonymous
Not applicable

I need to measure between 0 Hz and 1-2 KHz.

   

 

   

Rick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

There is no 0Hz. What is the lowest frequency?

   

 

   

Bob

0 Likes
Anonymous
Not applicable

If not zero then .1 Hz...

   

*******  .1 Hz not 1 Hz

   

Rick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

So you will get maximum count within 0.1 seconds. To avoid rounding errors best is to use a fraction of sysclock which is 24MHz in your project.

   

Using 480kHz as input clock to the counter will count to 48000 within 0.1s. Sounds ok.

   

An input frequency of 2kHz would result in a count of 480kHz / 2kHz = 240. +- 1 count will be in the range of 1% error, so this is ok too.

   

The period of the counter does not need to be set, because you are restarting the counter with every measure. So keep that at its maximum. A count overflow would only indicate a too low frequency. You may read the counter state to see if it has overflown.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Bob,

   

Do you recommend a 12 MHz sysclock? I switched over from 24 to 12 and when i make small frequency measurements such as 8 Hz I read 7. Also, for Hertz less than 7, can i continue counting until there is a change from HIGH to LOW and/or LOW to HIGH? I would just have to take into consideration the number of overflows and add them to the total counter right? By the way how do you read Overflow Pin?

   

 

   

Rick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

I do not recommend a 12MHz clock.

   

Overflow triggers an interrupt which you can handle.

   

Check to calculate your readings in float, so you will not get an integer number.

   

 

   

Bob

0 Likes