Pulse Generator

Thread Starter

R!f@@

Joined Apr 2, 2009
9,918
As the next project I aimed in making a pulse generator.
555 are too costly. Too many components.
So I went for a 12F675.

It has an ADC, so I believe I can vary the pulse frequency with it.

I need 3 Digital outs.
One for pulse, one for direction and one for Enable.
My aim is to drive a DC motor and Leds. During testing various projects.

I wrote the code.
The ADC is read and the Direction pin can be changed accordingly when the ADC value changes.

I assigned the TMR0 and interrupt routine to pulse the output.

The code was compiled after reading a lot of web pages from google and pdf's.

The prescaler is set for 1:256 with internal RC 4MHz osc.
So the LED is flashing around 5 to 10Hz I think.

Well at least I am getting an out put.

I thought I can assign a value ( corresponding to the value from ADC) and load it the timer0 or somewhere and change the pulse freq. But so far I am lost.

I like the freq to be around 20Hz to 2Khz variation.

Is this possible.
If it is I appreciate some pointers on how I should go about it.
 

shteii01

Joined Feb 19, 2010
4,644
How is you ADC software routine is setup? You read the input voltage and store it as a decimal value? When I did microcontrollers, we used hex values to load the timers.
 

MaxHeadRoom

Joined Jul 18, 2013
28,702
If this is a step/dir controller for a DC brushed motor, the rpm will not be accurately controlled without feedback of some kind?
Max.
 

Thread Starter

R!f@@

Joined Apr 2, 2009
9,918
Don't care about the accuracy. Told you tht this was just for testing purpose.

Just need to know how to load the timer. I have read the prescaler cannot be loaded.

ADC is just used as it is, I think it decimal.
ADC variable is there. I load the ADC value to the variable. Same variable compared to set the direction pin.

Just cannot figure out how change the timer to increase frequency
 

t06afre

Joined May 11, 2009
5,934
Perhaps it is better to use a timer and interrupt to create a timbase signal. Then based on this toggle an IO pin high and low
 

Thread Starter

R!f@@

Joined Apr 2, 2009
9,918
So I changed ADC to ISR and made a delay table based on the ADC value.

So far it is working.
 

Thread Starter

R!f@@

Joined Apr 2, 2009
9,918
I wrote about 200 lines of code.
Now I am getting "not enough ROM space"

Can code be optimized to fit into the little one.

I think it is due too many delay routines I wrote to generate pulses.
It is filled with "void" delays and "if" statements.

The code is basically
when timer overflows it goes to ISR and reads ADC.
main code just reads ADC variable and generates the pulse according to the ADC value.

So like 51 delay and toggling and 51 "IF" statements.

I cannot build due to rom space. So I reduced the frequency delays to 21 frequency range and 21 "if" statements.

Now I can build.

Is there a simple way ?
 

shteii01

Joined Feb 19, 2010
4,644
I wrote about 200 lines of code.
Now I am getting "not enough ROM space"

Can code be optimized to fit into the little one.

I think it is due too many delay routines I wrote to generate pulses.
It is filled with "void" delays and "if" statements.

The code is basically
when timer overflows it goes to ISR and reads ADC.
main code just reads ADC variable and generates the pulse according to the ADC value.

So like 51 delay and toggling and 51 "IF" statements.

I cannot build due to rom space. So I reduced the frequency delays to 21 frequency range and 21 "if" statements.

Now I can build.

Is there a simple way ?
Is the relationship between ADC value and pulse length linear?

If it is linear, you can read ADC value, then plug it into equation to calculate the pulse length.

It seems right now you have a case structure where you describe each individual case:
if ADC value is X, do Y
if ADC value is A, do B
It is perhaps more precise or more literal way to tell the device what to do. However, as you found out, it also consumes a lot more programming space.
 

Thread Starter

R!f@@

Joined Apr 2, 2009
9,918
Ya ! it's easy to tell it what to look for and what to do if found what it is looking for but it does takes a hell lotta coding and space.

I cannot figure out the easy way yet. I am just starting.

Any pointers ?
 

shteii01

Joined Feb 19, 2010
4,644
Ya ! it's easy to tell it what to look for and what to do if found what it is looking for but it does takes a hell lotta coding and space.

I cannot figure out the easy way yet. I am just starting.

Any pointers ?
Like I said, what is the relationship between ADC value and pulse length. Is it linear?
Can you write it in the form y=mx+b:
Pulse Length=Slope(ADC Value)+Some Constant

If you can, then all you need is the formula to calculate the pulse length. And you don't need all the if statements.
 

Thread Starter

R!f@@

Joined Apr 2, 2009
9,918
Aaah!

It can be linear or not I do not care linear or log
I just want the pulse frequency from 0Hz to 20kHz.

The ADC is centered at 500 to 520 value which is the center position of my joystick
A range is given to ( Drive inactive region) cause of the crappy joystick. It does not center sometimes hence a dead region. Any value from 500 to 0 or 520 to 1023 will increase the drive from 0 to 20KHz.
The Max frequency will be at 0 ADC or 1023 ADC value.
 

shteii01

Joined Feb 19, 2010
4,644
Aaah!

It can be linear or not I do not care linear or log
I just want the pulse frequency from 0Hz to 20kHz.

The ADC is centered at 500 to 520 value which is the center position of my joystick
A range is given to ( Drive inactive region) cause of the crappy joystick. It does not center sometimes hence a dead region. Any value from 500 to 0 or 520 to 1023 will increase the drive from 0 to 20KHz.
The Max frequency will be at 0 ADC or 1023 ADC value.
Ok, so:
0 Hz-> ADC 0
20 kHz-> ADC 1023
 

Thread Starter

R!f@@

Joined Apr 2, 2009
9,918
Um no.
U see the joystick is centered so the pot is centered at 2.5V ± 10mV or so. which is 512 ADC value
Hence the dead region ADC value 500 to 520 which there will be no output.

When I pull down the joystick. voltage goes from 2.5V to 0V; which should result in Dir change going low and frequency goes from 0 to 20KHz.

And When I push up the joystick. voltage goes from 2.5V to 5V; which should result in Dir change going high and frequency goes from 0 to 20KHz, again

So basically at ADC value at 0 and 1023 will give 20Khz and 0 out at close to 500 and 520 ADC value

Can you write it in the form y=mx+b:
Pulse Length=Slope(ADC Value)+Some Constant

If you can, then all you need is the formula to calculate the pulse length. And you don't need all the if statements.
I need an example to understand.
Any pointers?
 
Last edited:

jjw

Joined Dec 24, 2013
823
In your first message you said the frequency is 0-20Hz, later 0-20kHz ?
You could do 0-20Hz with your own delay function ( a loop ) which has a delay parameter relative to the ADC value.
 

Thread Starter

R!f@@

Joined Apr 2, 2009
9,918
Could be a typo.

Since I cannot do too many delay loops.

I need to do formula thingy. And if formula works I can do what I originally wanted which is 0 to 20KHz. 0 is not really needed, it could start from 1Hz
 

THE_RB

Joined Feb 11, 2008
5,438
Delay_mS() function is hard coded, so it uses a lot of ROM.

Try changing to VDelay_mS() which uses one function for ALL the delays. That saves tons of ROM.

Also, as I suggested in your other thread, get in the habit of opening up the little bargraph window that shows you the sizes of all your functions. That is a BIG help when trying to reduce your ROM usage.
:)
 

Thread Starter

R!f@@

Joined Apr 2, 2009
9,918
I had 10% free now.

I managed to squeeze in 0 to 20K in 15 steps.
Program is working so now to build it.
 
Top