PWM with A/D
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!
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
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
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?
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.
·
· You might have to tweak this a bit, but this should get you close.
·· 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
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?
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.
·
Also, just a general question, does the SX use an eeprom or is the program internally stored in it?
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.
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.
·
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.
·
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.
·