Pulse Generator

Discussion in 'Programmer's Corner' started by R!f@@, Apr 3, 2014.

  1. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,750
    759
    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.
     
  2. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,387
    497
    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.
     
  3. MaxHeadRoom

    Expert

    Jul 18, 2013
    10,521
    2,369
    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.
     
  4. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,750
    759
    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
     
  5. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    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
     
  6. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,750
    759
    So I changed ADC to ISR and made a delay table based on the ADC value.

    So far it is working.
     
  7. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,750
    759
    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 ?
     
  8. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,387
    497
    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.
     
  9. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,750
    759
    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 ?
     
  10. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,387
    497
    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.
     
  11. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,750
    759
    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.
     
  12. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,387
    497
    Ok, so:
    0 Hz-> ADC 0
    20 kHz-> ADC 1023
     
  13. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,750
    759
    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

    I need an example to understand.
    Any pointers?
     
    Last edited: Apr 10, 2014
  14. jjw

    Member

    Dec 24, 2013
    173
    31
    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.
     
  15. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,750
    759
    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
     
  16. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    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.
    :)
     
    R!f@@ likes this.
  17. MrChips

    Moderator

    Oct 2, 2009
    12,436
    3,360
    Are you using floating point arithmetic? That takes up a lot of space.
     
  18. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,750
    759
    I don't think it IS floating point.
     
  19. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,750
    759
    I had 10% free now.

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