Shop OBEX P1 Docs P2 Docs Learn Events
PWM with A/D — Parallax Forums

PWM with A/D

PhilldapillPhilldapill Posts: 1,283
edited 2009-01-14 23:00 in General Discussion
Hey all, I'm pretty new to the SX, but have used the propeller for a good bit of time now. There are some things that the propeller is great at, and others where it is just overkill. This is one of those overkill scenarios, so I'm trying out the SX.

What I want to do, is use the SX to output a PWM signal. To control the signal, I want to have two potentiometers - one to control frequency, and the other should control the duty cycle. My thinking is, use the SX to read either the resistance, or the voltage level on the pots, and with these values, change the frequency and duty cycle. These values should be updated continuously, or at least 10 times a second. The PWM frequency at maximum, will be set to 45kHz.

Is there any code for this? Like I said, I'm new to the SX and don't really know any code for it just yet, but I figure that if there is code out there that does something similiar, or part of this, I could use it for my project and learn at the same time.

Thanks everyone!

Comments

  • BeanBean Posts: 8,129
    edited 2009-01-08 21:40
    Phil,
    With the SX48 it would be pretty easy because you could use one of the two 16-bit hardware counters to generate the PWM and read the two pots in with the ANALOGIN command in SX/B.

    With the SX20/28 you would have to do everything in an interrupt routine. Generate PWM and·unwind the ANALOGIN command in the interrupt. This will limit the PWM frequency, but it can be done.

    The SX48 could do more even at a much slower clock (4MHz), the SX28 would need a much faster clock to have the same performance (> 20MHz).

    Which did you want to use ? Is 8-bit PWM good enough or do you need more bits than that ?

    P.S. The SX48 running @ 4MHz could do 8-bit PWM @ > 15 KHz. The SX28 running @ 20Mhz could do 8-bit PWM + analogin @ about 1 KHz.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ·The next time you need a hero don't look up in the sky...Look in the mirror.




    Post Edited (Bean (Hitt Consulting)) : 1/8/2009 9:50:16 PM GMT
  • PhilldapillPhilldapill Posts: 1,283
    edited 2009-01-08 23:21
    Thanks for the detailed reply, Bean. I assume this is what you are talking about?
    http://www.parallax.com/Store/Microcontrollers/SXChips/tabid/138/CategoryID/15/List/0/SortField/0/Level/a/ProductID/354/Default.aspx

    On the product page, the chip mentions the internal oscillator being from 32kHz to 4MHz. I assume this is a fairly precise oscillator that is set in program? The Propeller, as you know, has an internal RC oscillator, but it's not accurate at all and varies from chip to chip...

    If I were to use the SX48, what components would I need to use? I'm sure voltage regulation circuitry would be in order. I need the frequency to be adjustable from 0-45kHz, but if the SX can't do that AND do analog input, I might have to use a PIC. However, I like Parallax and want to support them, so I'd like to go with the SX.

    By the way, what I said in the previous post about wanting to update at 10Hz - scratch that. 4Hz update would work just fine, I think. 8-bit PWM would also work well. That gives a resolution of better than 0.4%, so I'd be very happy with that. Would it be possible to start the PWM routine, stop after a certain amount of time/cycles, check the analog inputs, adjust accordingly, restard the PWM and repeat? This way everything could be hard coded and there would be no need for interupts. That is, IF the time spent with the PWM inactive is FAR less than the time spent active.

    What do you think about that approach?
  • BeanBean Posts: 8,129
    edited 2009-01-08 23:38
    Phil,
    Yes, that is the SX48. The protoboard would be good to get started with:
    http://www.parallax.com/Store/Microcontrollers/BASICStampModules/tabid/134/txtSearch/SX48/List/1/ProductID/362/Default.aspx?SortField=ProductName%2cProductName

    Everything below is assuming you are using the SX48.
    The internal oscillator is +/- 8%. Better than the Prop, but not good enough for serial comm.

    The SX48 running at 20MHz (external resonator) would do 78KHz @ 8-bit. Using the internal 4MHz clock it would be 15.6KHz.

    The PWM will be generated by one of the two hardware timers, so the only thing the SX has to do is read the two pots and adjust the timer values.

    The only hardware you will need to read the pots is 2-resistors and 1-cap per pot. You will wire the pot as a voltage divider. See the help file under the ANALOGIN command.

    Once the hardware timer is put into PWM mode, you only need to set the R1, and R2 values. These are 16-bit value that represent the ON time and the OFF time. To get below 305 Hz you can use the timer prescalers.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ·The next time you need a hero don't look up in the sky...Look in the mirror.


    ·
  • BeanBean Posts: 8,129
    edited 2009-01-08 23:54
    Phil,
    · You might have to tweak this a bit, but this should get you close.
    DEVICE SX48, OSCHS1
    FREQ 20_000_000
     
    PWMOut    PIN RB.6 OUTPUT ' Fixed pin for Timer1 output
     
    Pot1In    PIN RE.0 INPUT
    Pot1Out   PIN RE.1 OUTPUT
    Pot2In    PIN RE.2 INPUT
    Pot2Out   PIN RE.3 OUTPUT
     
    freqValue VAR BYTE
    dutyValue VAR BYTE
    tempW     VAR WORD
    onTime    VAR WORD
    offTime   VAR WORD
     
    PROGRAM Start
     
    Start:
    
     
      TIMER1 PWM
    
     
      DO
    
     
        PAUSE 100 
     
        ANALOGIN Pot1In, Pot1Out,freqValue
        ANALOGIN Pot2In, Pot2Out,dutyValue
     
        ' Here is the tricky bit... Take the freqValue (0-255) and dutyValue (0-255)
        '  and calculate an onTime and offTime value.
        tempW = freqValue + 1
        tempW = 65535 / tempW
        onTime = tempW */ dutyValue
        offTime = tempW - onTime
     
        TIMER1 R1,onTime
        TIMER2 R2,offTime
      LOOP
    END
    
    

    ·· This will have a frequency range of 305Hz to 78KHz.

    ···You will probably have to handle 0% and 100% duty cycle as a special case. I'm pretty sure R1 and R2 cannot be zero.

    Bean.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ·The next time you need a hero don't look up in the sky...Look in the mirror.




    Post Edited (Bean (Hitt Consulting)) : 1/9/2009 12:00:44 AM GMT
  • PhilldapillPhilldapill Posts: 1,283
    edited 2009-01-09 05:23
    Bean, I've actually decided against the use of pots, and instead, I'm going to use four buttons to adjust duty/freq.

    I'm thinking I'll use three pins for this - 1 pin for the "row", 1 pin for the "column" and 1 pin for the "buttonactive" state. All three pins will have pull down resistors. That last "button active" is to identify that a button was pressed. All buttons will·pull this pin up·through a diode when any are pressed.

    I assume this bit of code could easily be modified, so that it scans·the "button active" pin for it to be high, then when it does, detects what pin was pressed, and from there, adjust the frequency/duty?
  • BeanBean Posts: 8,129
    edited 2009-01-09 11:41
    Phil,
    The easiest way would be to just connect the four buttons to four pins and the other side of the button to ground. Then use the internal pullup resistors.

    One thing that you have to watch is when you change R1 or R2, if the counter is already past the new setting, the timer will have to wrap-around before it changes state.

    For example let's say the old R1 value was 1000, and the timer is currently at 700, the new R1 is 500. When you set the new R1 the counter will have to wrap-around past 65535 and back to 500 before the PWM turns off.

    There are two ways to handle this. One is to clear the timer when you update R1 and R2. The other is to wait until the timer matches R2, then change R1 and R2.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ·The next time you need a hero don't look up in the sky...Look in the mirror.


    ·
  • PhilldapillPhilldapill Posts: 1,283
    edited 2009-01-10 03:03
    Bean, what kind of precision can I get using this method? i.e. If my maximum frequency is 45kHz, what would the frequency step be?

    Also, just a general question, does the SX use an eeprom or is the program internally stored in it?
  • soshimososhimo Posts: 215
    edited 2009-01-10 17:59
    I'm curious, you said you want to use the SX/B because the propeller is overkill, but you can accomplish the same thing with a 555 timer (and about 20 dollars cheaper too). Is there are reason you wanted to generate a PWM with the chip rather than go with a dedicated timer? You can still control duty cycle and frequency using pots. If you want preset values you just use
    a rotary switch which will switch in and out the proper R1||R2 ratio for duty cycle and frequency - or you could use a potentiometer. I've used that set up very successfully. You can even hook it up in a configuration that it can be enabled and disabled - this can be controllable from a uprocessor. That would leave the uprocessor to deal with the high level logic of - should I be transmitting or not (it was for a 48khz carrier signal) and not waste processing bandwidth on bit bashing a PWM.
  • BeanBean Posts: 8,129
    edited 2009-01-10 19:56
    The precision changes with the frequency. At the low end you have much more precision than at the high end.

    For example if you are using a 20MHz clock/resonator:

    At 1KHz you would divide by 20,000 so resolution 1/20000 or .005%.
    At 10Khz you would divide by 2,000 so resolution if 1/2000 or 0.05%.
    At 45KHz you would divide by 444 so resolution is 1/444 or 0.22%.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ·The next time you need a hero don't look up in the sky...Look in the mirror.


    ·
  • tailgatortailgator Posts: 3
    edited 2009-01-14 22:16
    Hey, Bean! Waitaminit.. I am currently reworking a linear table project, and even though I'm not really SX savvy, I expected to use the PWM cammand to output pwm to an H-ladder discrete design to drive 12VDC motors. I planned on using the Interrupt handler primarily for quad-decoding 2 encoder for moter syncing. Are you saying I can't use PWM in this fashion? I am not micropositioning, but driving two threaded rods about 8 feet long, and I need torque more than speed. will 8-bit PWM from the PWM command even work?
  • Lord SteveLord Steve Posts: 206
    edited 2009-01-14 22:33
    tailgator,

    Would you start your own thread for your question, please?· That way it's easier to search the forums if someone else wants to do something similar to what you want to do (especially if you name your thread well).· Also, it doesn't hijack phildapill's thread.

    Thanks.
    ·
  • BeanBean Posts: 8,129
    edited 2009-01-14 23:00
    Tailgator,
    Since you are a new member I will answer here. But as Steve said, you should start a new thread.

    The SX/B PWM command meant to be used to create an analog voltage by connecting the output pin to a resistor and a cap.
    The type of PWM generated by the PWM command is NOT recommended for driving a motor. It is a series of very quick pulses, not the long pulses required by a motor driver.
    Plus your SX/B program stops at the PWM command, and PWM is not generated all the time.

    It is best to either use a simple interrupt routine or if you are using the SX48, use one of the hardware timers.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ·The next time you need a hero don't look up in the sky...Look in the mirror.


    ·
Sign In or Register to comment.