Hi there. I'm doing a motor control project using the 16F74 to simulate an AC waveform. The waveform generation is working. It uses a table of sine values and uses the HPWM capability of the PIC to generate a pwm waveform which simulates a sine wave. At the moment it's generating into a r-c filter to filter the pwm and smooth the energy into a sine wave. The sine wave is split into 18 20degree segments, each segment is about 922us long.
The issue I'm having is that my 60hz waveform is coming out at about 35hz lol. I have tracked the issue to the execution time of the HPWM. I created a small program which has some of the elements of the program in it to see what the delay is. Without the 'HPWM 1,20,128' test code, the main segment of the program runs in 28us. With the HPWM in, it increases to 448us. This has the tendancy to extend my segment thus making the sine wave slower (Lower F). Is there a way to reduce this time?
Thanks all,
Chay Foss
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Use the static PWM to setup the CCP/PWM and then change PR2. This will may work for you.
#chip16F74
#optionExplicit
#definePWM_Freq2'Set frequency in KHz
#definePWM_Duty50PWMOn'Turn on the PWMDimFrequencyRangeasByteAliasPR2DoForFrequencyRange=1to255wait10msNextLoop
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am getting the 20khz/50% duty cycle coming out as expected. There is no issue there. The issue is that to perform this function before the processor continues with other code.
I don't have my code handy at the moment, but in the end I will need to change the duty cycle multiple times in a short period (Ie: max once per 500us or so) in order to make the application work. I used 128 as a duty cycle examle, but in the end the DC will read a variable like this:
Here is the idea I used to see how long it's taking:
startmain
portc.0 = 1; set check pin true
;other code here
HPWM, 1,20, 128; Set up the hpwm out
portc.0 = 0
wait 10 ms
goto startmain
I monitored portc.0 with a 'scope.
So with the hpwm commented out, the code executed quicly. With it in it was slow-to the point it was extending the intervals set in the other code.
In the final code I will use T1 interrupt to drive the time intervals, and have it variable by presetting T1 to a certain value. At the moment I'm jst tryng to work out this issue though.
When I had it running faster and loading the sine values for DC, it worked great, just slow.
I'll review your suggestions. thanks for the post.
Chay
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The idea is to have a target frequency (Static for now, later variable with an a-d input), and chop it up into 18 'time slots'. Each time slot has a different DC PWM to simulate a point on the sine voltage curve. Pretty cool idea and works well. It's just that my times are being extended. With a 1ms/time slot I'd expect close to a 18ms sine wave, but it's up at 24 or something.
Seems like I need to drill down and just adjust the DC register instead of setting up the whole HPWM again. I'll test to see how fast that is tonight.
The chip I'm working with only has 2 HPWMs but i'm trying to prove the concept before bying a more appropriate chip.
Thanks,
Chay
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That looks too much info for me.
I used hpwm with a 18f25k22 which I think has 2 hpwm pins for dc motor/hbridge inhibit pins
and it worked but not made sine waves to be honest.... and analogue circuits are so much hard sums.
My first thought would be to use read ad to sample half a real sine wave and store in an array
and some math to generate the other half of the wave. Or sample a whole cycle.
I tried to make a faster pic/uno glcd scope by sampling read ad to array then show display.
The array was 320 bytes or some division of the x axis of the glcd.
I use a 328 which has 2K ram. https://www.youtube.com/watch?v=hhTC8z1GIaI
and https://www.youtube.com/watch?v=M-yyBtpA2sY
Last edit: stan cartwright 2020-08-24
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Another suggestion, try adding this to your code somewhere:
#defineHPWM_FAST
With this, HPWM will store the last frequency used. If it is called again with the same frequency, it doesn't recalculate the period or the timer settings needed to give that period. That saves a few cycles. I think it's much the same as HPWMUpdate, as @Anobium suggested.
Last edit: Anobium 2020-08-25
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Please excuse my ignorance in my previous post.
I just thought take say 100 byte samples in am array and a 600hz interrupt to read the array repeatedly and then r-c filter to get 60Hz.
Silly. sorry.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi there. I'm doing a motor control project using the 16F74 to simulate an AC waveform. The waveform generation is working. It uses a table of sine values and uses the HPWM capability of the PIC to generate a pwm waveform which simulates a sine wave. At the moment it's generating into a r-c filter to filter the pwm and smooth the energy into a sine wave. The sine wave is split into 18 20degree segments, each segment is about 922us long.
The issue I'm having is that my 60hz waveform is coming out at about 35hz lol. I have tracked the issue to the execution time of the HPWM. I created a small program which has some of the elements of the program in it to see what the delay is. Without the 'HPWM 1,20,128' test code, the main segment of the program runs in 28us. With the HPWM in, it increases to 448us. This has the tendancy to extend my segment thus making the sine wave slower (Lower F). Is there a way to reduce this time?
Thanks all,
Chay Foss
@Chay.
Not sure I get the issue here. Some code may help me understand. Are the issues?
You may want to consider this approach.
Use the static PWM to setup the CCP/PWM and then change PR2. This will may work for you.
Do you need an interrupt as described here? https://community.cypress.com/docs/DOC-17276
I am getting the 20khz/50% duty cycle coming out as expected. There is no issue there. The issue is that to perform this function before the processor continues with other code.
I don't have my code handy at the moment, but in the end I will need to change the duty cycle multiple times in a short period (Ie: max once per 500us or so) in order to make the application work. I used 128 as a duty cycle examle, but in the end the DC will read a variable like this:
Here is the idea I used to see how long it's taking:
startmain
portc.0 = 1; set check pin true
;other code here
HPWM, 1,20, 128; Set up the hpwm out
portc.0 = 0
wait 10 ms
goto startmain
I monitored portc.0 with a 'scope.
So with the hpwm commented out, the code executed quicly. With it in it was slow-to the point it was extending the intervals set in the other code.
In the final code I will use T1 interrupt to drive the time intervals, and have it variable by presetting T1 to a certain value. At the moment I'm jst tryng to work out this issue though.
When I had it running faster and loading the sine values for DC, it worked great, just slow.
I'll review your suggestions. thanks for the post.
Chay
I'm implementing the ideas in here:
http://ww1.microchip.com/downloads/cn/AppNotes/cn012129.pdf
The idea is to have a target frequency (Static for now, later variable with an a-d input), and chop it up into 18 'time slots'. Each time slot has a different DC PWM to simulate a point on the sine voltage curve. Pretty cool idea and works well. It's just that my times are being extended. With a 1ms/time slot I'd expect close to a 18ms sine wave, but it's up at 24 or something.
Seems like I need to drill down and just adjust the DC register instead of setting up the whole HPWM again. I'll test to see how fast that is tonight.
The chip I'm working with only has 2 HPWMs but i'm trying to prove the concept before bying a more appropriate chip.
Thanks,
Chay
That looks too much info for me.
I used hpwm with a 18f25k22 which I think has 2 hpwm pins for dc motor/hbridge inhibit pins
and it worked but not made sine waves to be honest.... and analogue circuits are so much hard sums.
My first thought would be to use read ad to sample half a real sine wave and store in an array
and some math to generate the other half of the wave. Or sample a whole cycle.
I tried to make a faster pic/uno glcd scope by sampling read ad to array then show display.
The array was 320 bytes or some division of the x axis of the glcd.
I use a 328 which has 2K ram. https://www.youtube.com/watch?v=hhTC8z1GIaI
and https://www.youtube.com/watch?v=M-yyBtpA2sY
Last edit: stan cartwright 2020-08-24
Another suggestion, try adding this to your code somewhere:
With this, HPWM will store the last frequency used. If it is called again with the same frequency, it doesn't recalculate the period or the timer settings needed to give that period. That saves a few cycles. I think it's much the same as HPWMUpdate, as @Anobium suggested.
Last edit: Anobium 2020-08-25
Please excuse my ignorance in my previous post.
I just thought take say 100 byte samples in am array and a 600hz interrupt to read the array repeatedly and then r-c filter to get 60Hz.
Silly. sorry.