Hi all,
Can someone advise best way to convert square waveform of variable duty cycle into a 50% duty cycle?
Regards
Hi all,
Can someone advise best way to convert square waveform of variable duty cycle into a 50% duty cycle?
Regards
On every rising edge, start an output pulse that is 1/2 the time to the next rising edge.
Use pulseIn( ) to measure the high time & low time of the incoming signal, do the math to determine the output needed. Use micros( ) to determine when to switch your output halfway.
Concept is pretty straightforward.
CrossRoads:
On every rising edge, start an output pulse that is 1/2 the time to the next rising edge.
Use pulseIn( ) to measure the high time & low time of the incoming signal, do the math to determine the output needed. Use micros( ) to determine when to switch your output halfway.
Concept is pretty straightforward.
Sorry I meant with discrete logic, but just in case, this is my code:
// period of pulse accumulation and serial output, milliseconds
#define MainPeriod 30
long previousMillis = 0; // will store last time of the cycle end
volatile unsigned long duration=0; // accumulates pulse width
volatile unsigned int pulsecount=0;
volatile unsigned long previousMicros=0;
void setup()
{
Serial.begin(115200);
attachInterrupt(0, myinthandler, RISING);
}
void loop()
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= MainPeriod)
{
previousMillis = currentMillis;
// need to bufferize to avoid glitches
unsigned long _duration = duration;
unsigned long _pulsecount = pulsecount;
duration = 0; // clear counters
pulsecount = 0;
float Freq = 1e6 / float(_duration);
Freq *= _pulsecount; // calculate F
// output time and frequency data to RS232
//Serial.print(currentMillis);
//Serial.print(" "); // separator!
Serial.println(Freq);
//Serial.print(" ");
//Serial.print(_pulsecount);
//Serial.print(" ");
//Serial.println(_duration);
}
}
void myinthandler() // interrupt handler
{
unsigned long currentMicros = micros();
duration += currentMicros - previousMicros;
previousMicros = currentMicros;
pulsecount++;
}
I need to update the code every 30ms, however at frequencies of 50Hz or lower my output is like this:
nan
18.53
nan
18.52
nan
18.53
18.52
nan
18.53
nan
18.53
nan
18.52
nan
18.52
18.53
nan
because the duty cicle is 90% on, 10% off. Any sugestions?
Maybe.... It depends on the characteristics of the pulse train and what "information" you need from it.
If you have a rectangle wave or pulse of a constant frequency, you can convert it to a perfect square wave of one-half the frequency by toggling your output-state on every rising-edge (or falling edge) of the rectangle wave. That's traditionally done with a flip-flop. You don't need a microcontroller on any programming.
If you have a serial data steam, you could detect the data-stream and generate a square wave, but of course the square wave wouldn't contain the serial data.
DVDdoug:
Maybe.... It depends on the characteristics of the pulse train and what "information" you need from it.If you have a rectangle wave or pulse of a constant frequency, you can convert it to a perfect square wave of one-half the frequency by toggling your output-state on every rising-edge (or falling edge) of the rectangle wave. That's traditionally done with a flip-flop. You don't need a microcontroller on any programming.
If you have a serial data steam, you could detect the data-stream and generate a square wave, but of course the square wave wouldn't contain the serial data.
Thank you. the frequency may very from 0 to 2.7KHz. Its the output of a tachogenerator.
It will be processed by the microcontroller, so if i dont need any aditional hardware, brilliant. As it stands I either have to change the above code or add something to the input. The signal source is off for 10% of the time and on for 90%, so while the code triggers fine when it detects the change, the next sampling it will see no change, due to the long on time, hence, outputs zero or "nan"
DVDdoug:
That's traditionally done with a flip-flop. You don't need a microcontroller on any programming.
Im a bit confused as how to wire a flip flop, could you clarify? I searched for a few different types, but coulnt find anything that would convert pulse to square wave.
Unless, of course, you meant a frequency divider that would togle the output on every rising edge of the clock for example. Is that what you meant?
Yes, the desired result is a divide by 2.
Is there some reason you can't just have the Arduino measure from rising edge to rising edge?
polymorph:
Yes, the desired result is a divide by 2.Is there some reason you can't just have the Arduino measure from rising edge to rising edge?
OK, I tought it was a square wave of the same frequency hence I was having trouble visualizing how that would work.
Yes, thats currently what I do, rising or falling edge.
I could just use a 4017 to perform a division by 2 with 50% duty. The problem is I need to double that frequency, otherwise the result will simply take too long to refresh. Thats where the 50% duty will come handy, because I could measure on both the rising and falling edge, hence doubling the frequency. Is there any other way I could archieve this?
I'm a bit confused.
What exactly are you trying to measure? If you measure the time from one rising edge to the next, that tells you the period. No divide by two necessary, no equal duty cycle required.
BTW, a peeve: do you -really- mean 0 RPM as the bottom end? Are you really going to be interested in the difference between 0.01RPM and 0.00001RPM? What is the actual resolution you will be measuring?
casemod:
Thank you. the frequency may very from 0 to 2.7KHz. Its the output of a tachogenerator.
If the problem were as initially stated (in the OP) the solution would be trivially simple - and has already been mentioned.
But this quotation suggests to me that the problem to be solved is different. Varying duty cycles are usually associated with a fixed frequency - it would probably be quite difficult to get a meanigful variation in duty cycle and a varying frequency at the same time.
It seems more likely that the tacho would generate a varying frequency and in that case the duty cycle (if such a thing can be said to exist) is irrelevant.
If I am correct then the following question needs to be answered before any system can be designed "Given that the input is a signal with varying frequency, what output is required and in what way should the output vary in response to the changing frequency?"
...R
polymorph:
I'm a bit confused.What exactly are you trying to measure? If you measure the time from one rising edge to the next, that tells you the period. No divide by two necessary, no equal duty cycle required.
BTW, a peeve: do you -really- mean 0 RPM as the bottom end? Are you really going to be interested in the difference between 0.01RPM and 0.00001RPM? What is the actual resolution you will be measuring?
I am trying to make a multiply by two circuit. 10Hz in, 20Hz out with 50% duty.
So far I have a resolution of 0.244Hz, I need to measure anything that is multiple of that.
Regards
casemod:
I am trying to make a multiply by two circuit. 10Hz in, 20Hz out with 50% duty.
That seems to be a nice succinct description of the problem - but who would have guessed it from the title of your Thread or the content of your first post.
I take it that you want to receive a frequency in the range 0 - 2.7kHz and output a frequency in the range 0 - 5.4kHz.
Would it matter if changes in the output frequency lag a tiny bit behind the changes in the input frequency by the time it takes to do the calculations?
It seems to me you need two small pieces of code. The first one measures the gap between successive inputs and saves the result (N microsecs) in a variable. The measurement might be triggered by a small interrupt routine - but it may be suffiicient to use polling.
The other piece of code repeats at every iteration of loop() and reads the value in the variable and creates a series of pulses with a duration of half the saved value. The Blink Without Delay technique adapted to use micros() should manage that fine.
...R
Supose that I use an encoder has 18PPR which translates to 2700Hz @ 150Hz shaft speed.
The problem I am facing is that with a 10bit variable and a frequency of 150Hz the least significant bit weights about 0.3Hz. I need to output exactly the calculated frequency plus or less 1.17Hz. Any deviations will result in loss of efficiency.
So with a resolution of 0.3Hz plus any erros on the input when calculating the frequency (Currently 0.12Hz at 150Hz) I am afraid i will have to work very efficiently and any errors on the input will likelly cause great output variations.
Do you think this will be feasible at all?
Hang on - are you trying to double the frequency in order to increase resolution?
Maybe you should tell us the bigger (biggest) picture. What exactly are you trying to accomplish?
polymorph:
Hang on - are you trying to double the frequency in order to increase resolution?Maybe you should tell us the bigger (biggest) picture. What exactly are you trying to accomplish?
Not to increase the resolution, but to decrease the time between samples at lower frequencies.
Well, the doubling circuit introduces it's own delay, so you are borrowing two fish to catch one fish.
Think about it - to double the repetition rate, first it must measure the rate. Then output at double that. Then measure the doubled rate. But you already measured it in the first step, you've now introduced a phase delay and introduced sources of error, including the accuracy and resolution of both the initial measuring process and the generation of the doubled rate.
What is the actual minimum speed? It isn't zero. Maybe you need PID tuning rather than shorter time between measurements at low speeds.
polymorph:
Well, the doubling circuit introduces it's own delay, so you are borrowing two fish to catch one fish.Think about it - to double the repetition rate, first it must measure the rate. Then output at double that. Then measure the doubled rate. But you already measured it in the first step, you've now introduced a phase delay and introduced sources of error, including the accuracy and resolution of both the initial measuring process and the generation of the doubled rate.
What is the actual minimum speed? It isn't zero. Maybe you need PID tuning rather than shorter time between measurements at low speeds.
The generated frequency must be as close as possible to the calculated frequency + 1.27hz. and should go doww to zer, altough a lack of accuracy is allowed below 1RPM or 18 encoder pulses per second.
See the previous post about the resolution.
I'm done playing 20 questions. Good luck.
Thank you.
casemod:
Supose that I use an encoder has 18PPR which translates to 2700Hz @ 150Hz shaft speed.The problem I am facing is that with a 10bit variable and a frequency of 150Hz the least significant bit weights about 0.3Hz. I need to output exactly the calculated frequency plus or less 1.17Hz. Any deviations will result in loss of efficiency.
So with a resolution of 0.3Hz plus any erros on the input when calculating the frequency (Currently 0.12Hz at 150Hz) I am afraid i will have to work very efficiently and any errors on the input will likelly cause great output variations.
Do you think this will be feasible at all?
You keep providing different information.
First it was a pulse width modulated signal.
Then it was a tachometer.
Now it is an encoder.
And I can make no sense of what you have said above.
You need to describe the entire process from end to end and then maybe we will begin to understand. If you can't / won't do that it won't be possible to help.
...R