PDA

View Full Version : Updating HPWM frequently, safe?



peu
- 5th May 2007, 19:06
How often is safe to update the HPWM duty cycle when running a 12f683 at 4mhz?

I see that doing it constantly confuses the uC, so whats the safe "wait period" ?

Thanks!

skimask
- 5th May 2007, 19:43
How often is safe to update the HPWM duty cycle when running a 12f683 at 4mhz?

I see that doing it constantly confuses the uC, so whats the safe "wait period" ?

Thanks!

What do you mean by 'safe' and 'confuses the uC'?

peu
- 5th May 2007, 19:51
What do you mean by 'safe' and 'confuses the uC'?

Hi Skimask,

I mean if I update the HPWM inside the main loop of a program, is it safe to update it every time the loop loops?

From my experimentation (Im controlling LED brightness using this hpwm) if I do this the LED flickers.

On the contrary, if I create a 3 lines new program with just one HPWM line and a loop:gotoloop, the LED does not flicker at all, its stable as it should be.

thanks

skimask
- 5th May 2007, 19:54
Hi Skimask,
I mean if I update the HPWM inside the main loop of a program, is it safe to update it every time the loop loops?
From my experimentation (Im controlling LED brightness using this hpwm) if I do this the LED flickers.
On the contrary, if I create a 3 lines new program with just one HPWM line and a loop:gotoloop, the LED does not flicker at all, its stable as it should be.
thanks

PIC12F683 datasheet, Section 11.3.3

peu
- 5th May 2007, 20:27
here is the gist of the code im running:

@ device pic12f683,INTRC_OSC_NOCLKOUT , wdt_on, mclr_off, protect_off
DEFINE OSC 4
DEFINE ADC_BITS 10
DEFINE ADC_SAMPLEUS 50

ANSEL = %00000010 ' GPIO.1 A/D in, rest digital
TRISIO = %00010010 ' GPIO.1 lectura AD,
cmcon0 = %00000100 ' AD via gpio1 and internal reference
vrcon = %10001010 ' set vref=2.25v

.
.
.

loop:
oldpote=pote
ADCIN 1, pote ' (0-65535)

if oldpote <> pote then
hpwm 1,inverduty,frecu 'these values are calculated in other section

endif
goto loop

maybe the problem is that im using ADC and HPWM simultaneously?

I don't undertand what you implied by reading that section of the DS.

Thanks!

Darrel Taylor
- 5th May 2007, 23:16
.... I don't undertand what you implied by reading that section of the DS. ...

That's just his little way of saying "I don't Know, go read the datasheet or something."<hr>

When an HPWM command executes, it treats it like it's the First time, and sets up every register needed to run PWM with the CCP module.

Changing CCP and TMR2 registers while the CCP is running PWM will cause "false pulses", Cycle Resets or elongation.

It would be nice if there was an HPWM_UPDATE command that only changed the dutycycle, without messing with the other registers. But there isn't.

If you need a totally "Glitch Free" PWM signal, then you'll have to modify the dutycycle manually. You can still use HPWM to set everything up. And then just modify the dutycycle later, after the PWM is running.

If you haven't already, you should get a copy of mister_e's PicMultiCalc.exe

It'll help figure out what values to use for the dutycycles.
http://www.mister-e.org/pages/utilitiespag.html

HTH,

peu
- 5th May 2007, 23:39
Thanks for the reply Darrel, now that explains many things :)

After many tries I managed to make the mister-e app work, it gave me an unregistered class error, but after a little googling I solved, it.

baaaack to the protoboard!

peu
- 6th May 2007, 00:18
well, now I have a new difficulty, trying to understand the calculator :)

Running OSC at 4mhz and PWM at 1khz I get:
http://peu.net/temp/pic-calculator

And I found a post where Mister_e explains how to use it:


'
' 38KHz PWM @ 4MHZ using a PIC16F877
' ----------------------------------
@ __CONFIG _XT_OSC & _LVP_OFF
'
'
TRISC = 0
Duty var byte

'
' PWM SETUP
' =========
' PicMultiCalc says..
' Duty value for 50%=52
' PR2 = 25
' PRESCALLER 1:1
'
'
duty = 52 ' duty value for 50% duty cycle
PR2 = 25 '
T2CON = %00000100 ' timer2 on, prescale 1:1
CCPR1L = duty>>2 ' MSB of duty cycle value
CCP1CON=%00001100 | (dUTY<<5) ' set PWM mode and store the
' 2 LSB of duty
SpinInRound:
goto spininround


If I understand correctly what you posted, I can start the HPWM before the main loop by using for example: HPMW 0,0,1000 and then within the loop adjust just the dutycycle.

Now what I dont understand is how I change the duty cycle, by using the calc I get 1000 values, but the duty variable is defined as BYTE

I could use some help/hint :)

Thanks!

peu
- 6th May 2007, 00:45
well it seems Im having a conversation with myself, instead of busting the few neurones I have left, I used the second option (prescaler 1:16) and I made it work, but the glitches are still there.

I initialized the PMW before the main loop using: HPWM 0,0,1000

and the registers as:
T2CON = %00000110 ' timer2 on, prescale 1:16
PR2 = 62 'per pic calculator

and every time I wanted to adjust the duty cycle I entered the value in the duty variable and called this subroutine:

CCPR1L = duty>>2
CCP1CON=%00001100 | (duty<<5)

As I said...the glitches remain... if I stop reading the ADC they dissapear and the PWM is steady

HELP !

mister_e
- 6th May 2007, 00:50
first you'll have to match the calc values to suit your need. With your current code example (which seems to be one of mine, the calc will give you...
<IMG SRC="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1593&stc=1&d=1178408727">

look at this section of the code

duty = 52 ' duty value for 50% duty cycle
PR2 = 25 '
T2CON = %00000100 ' timer2 on, prescale 1:1
CCPR1L = duty>>2 ' MSB of duty cycle value
CCP1CON=%00001100 | (dUTY<<5) ' set PWM mode and store the
' 2 LSB of duty

52 is showned in the result section and it's to set the duty cycle to 50% as selected in the duty cyle section.

Now if you want to update the duty cycle, you could use this section


CCPR1L = duty>>2 ' MSB of duty cycle value
CCP1CON=%00001100 | (dUTY<<5) ' set PWM mode and store the
' 2 LSB of duty
in your code you just need to change the value of Duty variable.

The example was for a 16F877, you should have a look at the 12F683 to see if they work the same way.

post your whole code, maybe some register need to be set in a different way. I'll put some effort and open my datasheet as well ;)

peu
- 6th May 2007, 00:55
it seems we posted at the same time, yes the post I used is from an old post of yours I used for reference. Please read my last post and tell if if you have an idea that may help me. Thanks!

mister_e
- 6th May 2007, 01:18
mm, you didn't disable the analog comparator.. maybe it worth to do it first?

i'm about to do something here to see what's happen.

mister_e
- 6th May 2007, 02:07
try this

<font color="#000000"> <font color="#008000">'
' Pic Configuration
' =================
</font>@ __CONFIG _INTRC_OSC_NOCLKOUT &amp; _WDT_ON &amp; _PWRTE_ON &amp; _MCLRE_OFF &amp; _BOD_ON

<font color="#008000">'
' Hardware configuration
' ======================
'
' I/Os
' ----
</font>TRISIO = %00010010
<font color="#008000">'
' ADC's
' -----
</font>ANSEL = %00000010
<font color="#000080">DEFINE </font>ADC_BITS 10 <font color="#008000">' ADCIN resolution (Bits)
</font><font color="#000080">DEFINE </font>ADC_CLOCK 1 <font color="#008000">' ADC clock source (Fosc/8)
</font><font color="#000080">DEFINE </font>ADC_SAMPLEUS 11 <font color="#008000">' ADC sampling time (uSec)
</font>ADCON0.7 = 1 <font color="#008000">' Right justified results

'
' Comparator
' ----------
</font>CMCON0 = 7 <font color="#008000">' Disable comparator
</font>VRCON = 0 <font color="#008000">' CVreff = OFF
'
' CCP
' ---
' PWM Freq=4KHz
' Initial duty cycle set to 50%
' PICMultiCalc says
' 10 Bit resolution when prescaler = 1:1
' MAX duty value 1000
' PR2 = 249
</font>CCP1CON = %00001100 <font color="#008000">' PWM mode
</font>PR2 = 249 <font color="#008000">'
</font>T2CON = %00000100 <font color="#008000">' Start Timer2, Prescaller 1:1

'
' Software variables
' ==================
</font>Duty <font color="#000080">VAR WORD

</font><font color="#008000">'
' Software constants
' ==================
</font>PWM_ON <font color="#000080">CON </font>%00001100
PWM_OFF <font color="#000080">CON </font>0

<font color="#008000">'
' Software/Hardware initialisation
' ================================
</font>GPIO = 0
<font color="#000080">PAUSE </font>50 <font color="#008000">' OSC settle delay
</font>Duty = 0
<font color="#000080">GOSUB </font>SetPWMDuty

<font color="#008000">'------------------------------&lt; Main program &gt;-----------------------------------
'
</font>Start:
<font color="#000080">ADCIN </font>1,Duty <font color="#008000">' read pot
</font><font color="#000080">IF </font>Duty&gt;1000 <font color="#000080">THEN </font>Duty =1000 <font color="#008000">' avoid results &gt;1000
</font><font color="#000080">GOSUB </font>SetPWMDuty <font color="#008000">' Set PWM duty cycles
</font><font color="#000080">PAUSE </font>1 <font color="#008000">' allow few PWM cycles
</font><font color="#000080">GOTO </font>Start
<font color="#008000">'
'---------------------------------------------------------------------------------

'-------------------------------&lt; Subroutines &gt;-----------------------------------
'
</font>SetPWMDuty:
<font color="#008000">' Datasheet recommend to stop PWM, load duty cycles vale
' to avoid possible glitches.
'
'
' stop PWM
' --------
</font>CCP1CON = PWM_OFF
<font color="#008000">'
' load Duty values
' ----------------
</font>CCPR1L = Duty &gt;&gt;2
CCP1CON.5 = Duty.1
CCP1CON.4 = Duty.0
<font color="#008000">'
' Start PWM
' ---------
</font>CCP1CON = CCP1CON | PWM_ON
<font color="#000080">RETURN
</font><font color="#008000">'
'---------------------------------------------------------------------------------
</font>

things to remember, disable the PWM mode, update the duty cycle, start PWM mode and allow few PWM freq cycle.. unless results could be weird.

skimask
- 6th May 2007, 03:54
That's just his little way of saying "I don't Know, go read the datasheet or something."<hr>

True, but the point was exactly as you posted, about the glitches and false pulses, etc. But you spelled it out, so now there's no need to read the datasheet.

Acetronics2
- 6th May 2007, 09:55
That's just his little way of saying "I don't Know, go read the datasheet or something."<hr>
HTH,


Hi, Darrel ,

I do not know if you're right here ...

The fact is I used HPWM without pain for years ... but NOT aboard any '683
and it REALLY seems there's a HARDWARE ( say CCP functionning ) issue.

The µChip section Skimask pointed at shows " PMW module *might* be disabled before changing the dutycycle ". I read some Other Pics Datasheets and this GREY section didn't appear elsewhere ...

IF I'm right, this "funny feature" happens whatever you use, assembler or Basic (!) ... The way HPWM command works doesn't matter here !!!

So, a ( Which other Basic do you think to ??? .... mmmmmh ? ) HPWM_UPDATE command wouldn't solve the question !!!

µChip clearly says : Changing the dutycycle while PWM running (and only dutycycle is enough ) will produce unwanted effects ...

The only way I see to keep ( is it really necessary ??? Good Q.) a "neat" PWM output would be to switch between HPWM, to the last produced fixed freq. and duty, soft PWM ... while disabling CCP, changing Dutycycle and re-enabling the CCP.

Quite a funny little sub to write, no ???


Back to our Friend Skimask ... I really do not know ... if he really doesn't know the "what is wrong".

I'm Ok ... this is not giving the solution, nor ... BUT ... His first answer could have been " Won't work with the '683 ( FINAL POINT )"


Would be kind to leave guns, knives, scissors and umbrellas out before entering the saloon ... just a thought.


Alain

peterdeco1
- 6th May 2007, 10:43
Here is a snippet of code from a motor speed controller for a small electric cart. The HPWM command is constantly repeated and has never caused any problems. In fact, in the beginning, I took the value of the speedpot once and just let the motor run and it caused problems. Intermittently the motor would "jump" into full speed. In spite of double regulation and a lot of filtering, motor noise sometimes caused the HPWM to go OUTPUT HIGH. I know it was motor noise because it never happened when controlling a 12V lamp.

ON:
ADCIN 2, SPEEDPOT 'READ VALUE OF SPEED CONTROL POT
IF SPEEDPOT > 150 Then LET SPEEDPOT = 150 'LIMIT SPEED OF MOTOR
IF LEFTRAMP < SPEEDPOT Then LET LEFTRAMP = LEFTRAMP + 1 'INCREASE SPEED SLOWLY
IF LEFTRAMP > SPEEDPOT Then LET LEFTRAMP = LEFTRAMP - 1 'DECREASE SPEED SLOWLY
Pause 1 'CONTROLS RATE OF SPEED INCREASE/DECREASE
HPwm 1,LEFTRAMP,10000 'OUTPUTS THE DUTYCYCLE CONTROLLED BY SPEEDPOT
IF PORTB.5 = 1 Then ON 'SWITCH PUSHED KEEP MOTOR RUNNING
GOTO START 'STOP EVERYTHING

peu
- 6th May 2007, 15:02
The only way I see to keep ( is it really necessary ??? Good Q.) a "neat" PWM output would be to switch between HPWM, to the last produced fixed freq. and duty, soft PWM ... while disabling CCP, changing Dutycycle and re-enabling the CCP.

The circuit Im using controls the feedback node of a switcher which its used to drive a power LED, any small glitch in the duty cycle is "visible" in the light output.

What puzzles me is the minute I stop using the ADCIN command, all the problems dissapear:

if calibrapin=0 then
ADCIN 1, pote
endif

if I put this calibrapin to 1 the output is steady. When it was bedtime yesterday (yes I keep thinking about problems in bed :) ), I tought: why not use software PWM, that may solve this issue. Well seeing it was suggested here too, makes me want to try it and I will

Regarding the DS section 11.3.3: "The PWM module may generate a premature pulse when changing the duty cycle."

Its the MAY word that puzzles me, I would expect more certainty here.

I still need to test Mister E suggestion, and speaking of it:


mm, you didn't disable the analog comparator.. maybe it worth to do it first?

In fact Im using the internal comparator, thats why I didnt disable it, if you check my 1st code post you will see:
vrcon = %10001010 ' set vref=2.25v

I need to put this value there so I can get more samples from my limited range sensor.

Also I tough it may be simply a reading problem, but this wasnt the case, I filled the available eeprom space with the read values and they were steady.

THANKS for the help guys! Back to the protoboard!


Pablo

T.Jackson
- 6th May 2007, 15:23
ON:
ADCIN 2, SPEEDPOT 'READ VALUE OF SPEED CONTROL POT
IF SPEEDPOT > 150 Then LET SPEEDPOT = 150 'LIMIT SPEED OF MOTOR
IF LEFTRAMP < SPEEDPOT Then LET LEFTRAMP = LEFTRAMP + 1 'INCREASE SPEED SLOWLY
IF LEFTRAMP > SPEEDPOT Then LET LEFTRAMP = LEFTRAMP - 1 'DECREASE SPEED SLOWLY
Pause 1 'CONTROLS RATE OF SPEED INCREASE/DECREASE
HPwm 1,LEFTRAMP,10000 'OUTPUTS THE DUTYCYCLE CONTROLLED BY SPEEDPOT
IF PORTB.5 = 1 Then ON 'SWITCH PUSHED KEEP MOTOR RUNNING
GOTO START 'STOP EVERYTHING

That's called "Closed Loop Control"

peu
- 6th May 2007, 16:03
post your whole code, maybe some register need to be set in a different way. I'll put some effort and open my datasheet as well ;)

mmm I oversought this statement, THANKS!, I will tidy it up a little, Im kinda messy compared to your code postings :)

skimask
- 6th May 2007, 19:15
The µChip section Skimask pointed at shows " PMW module *might* be disabled before changing the dutycycle ". I read some Other Pics Datasheets and this GREY section didn't appear elsewhere ...
And I just downloaded the latest/greatest 12F683 datasheet and it DOESN'T have that statement in there. What's up with that?


µChip clearly says : Changing the dutycycle while PWM running (and only dutycycle is enough ) will produce unwanted effects ...
The only way I see to keep ( is it really necessary ??? Good Q.) a "neat" PWM output would be to switch between HPWM, to the last produced fixed freq. and duty, soft PWM ... while disabling CCP, changing Dutycycle and re-enabling the CCP.
Couldn't you update the duty cycle right after T2 has overflowed? As long as the duty cycle wasn't too low or too high, wouldn't this almost eliminate all false glitches?


Back to our Friend Skimask ... I really do not know ... if he really doesn't know the "what is wrong".
I got a good handle on "what's wrong" 'cause I ran into the same problem with my multi-channel software PWM program I wrote to run a bunch of lights awhile back. And my fix for the problem was to only update the PWM duty cycle for each channel in between cycles, so basically, I ended up with PWM that couldn't do 100% duty cycle, but only about 0%-95% duty cycle. The extra 5% at the top end was used to update the software registers.

Acetronics2
- 6th May 2007, 20:18
Hi, Skimask

Q1) Here is an excerpt ( joined ) ... Peu found it also ... If not in the latest datasheets, might we think the new devices have been modified ???

Q2) I must experiment ... T2 overflow is to try ... Honestly, I would use a SMD 16F628,648,88 or ??, instead, if size is a really a problem ( LOL !!! )

R3) It's the most logical solution ...

Regards
Alain

peu
- 6th May 2007, 21:26
Hi, Skimask

Q1) Here is an excerpt ( joined ) ... Peu found it also ... If not in the latest datasheets, might we think the new devices have been modified ???


Its indeed modified...!! I just redownloaded the datasheet and the PWM section is more complete now.

check both versions here: http://peu.net/temp/pic12f683_OLD_vs_NEW.zip



Q2) I must experiment ... T2 overflow is to try ... Honestly, I would use a SMD 16F628,648,88 or ??, instead, if size is a really a problem ( LOL !!! )


Well, in my case I have very low space, all my pcb is a 18mm diameter board...

Here is my code, I tidied / commented it so its more readable: http://peu.net/temp/pwm-adc

Thanks!

Darrel Taylor
- 6th May 2007, 23:48
And, You're all correct!

Well, except for that part about me being wrong :eek:

After my last post, I started working on an example for Pablo. It's kind of grown along the way, and is now a candidate for replacement of the HPWM command. IMHO

It pretty much encompasses everything you guys talked about while I was doing it. Plus maybe a bit more.

It's an Include file that gives 1 new command...
@ HPWM10 1, _DutyCycle, _Frequency

It works the same way as the PBP HPWM command, except that it uses 10-bit resolution, works with all CCP modules CCP1-CCP5, And is "Glitch-Free" when changing Frequency or DutyCycle.

Well, at least that's what it's supposed to do. Seems to work pretty good here, but I've only had a day to play with it.

It uses about 250 more words than HPWM, so I don't know how good it will be for a 12F683. But it definately will fit, if the rest of the program isn't too big.

If anyone has any problems, I'd appreciate a "Heads Up".

http://www.pbpgroup.com/files/HPWM10.zip
<br>

peu
- 7th May 2007, 00:02
OMG :)

Im "digesting" the code, just tried it and it compiles to 409words, compact enough for a 12f683

Thanks!!!

mister_e
- 7th May 2007, 00:10
Seems to work pretty good here, but I've only had a day to play with it.
One day to do all that? Wow, some 'over a month TicTacToe brain challenged programmer' will be impressed http://www.mister-e.org/Pics/ROFL

peu
- 7th May 2007, 00:53
I just tested it using this code:



' Pic Configuration
@ device pic12f683,INTRC_OSC_NOCLKOUT , wdt_on, mclr_off, protect_off

' Hardware configuration

' I/Os
TRISIO = %00010010 ' pin1 is ADC , pin4 is the calibration button

' ADC's
ANSEL = %00000010
DEFINE ADC_BITS 10 ' ADCIN resolution (Bits)
DEFINE ADC_CLOCK 1 ' ADC clock source (Fosc/8)
DEFINE ADC_SAMPLEUS 11 ' ADC sampling time (uSec)
ADCON0.7 = 1 ' Right justified results

' Comparator
'CMCON0 = %00000111 ' Disable comparator
'VRCON = %00000000 ' disable
cmcon0 = %00001110 ' Multiplexed Input with Internal Reference CIS=1
vrcon = %10001010 ' set vref=2.25v (from 4v input)

include "HPWM10.pbp"

' definitions
pote var word
Frequency var word ' edited after original post per Darrel suggestion
calibraled var gpio.5

gpio=0
frequency=1000
pause 50 ' coffee break

for pote=1 to 1023

@ HPWM10 1, _pote, _Frequency
pause 10

'gosub flashled

next pote
end

flashled:
high calibraled ' I use this to visually count each loop step
pause 50
low calibraled ' by using it I saw that my switcher starts to
pause 50 ' work at hpwm=4, less than that is too low
high calibraled
pause 50
low calibraled
pause 50
high calibraled
pause 50
low calibraled
pause 700
return


Comments:

I used the flashing led routine to know when my switcher started to work, it started at hpwm=4 which is great, the power led is very dim at this value.

then I removed the flashing routine and something was too fast, because my switcher was off. So I added a little pause in there and it was solved, tried 1, 5 and settled in 10ms where it started to work again.

This is great!, now I will test it with adcin :)

pablo

Darrel Taylor
- 7th May 2007, 01:08
Both DutyCycle and Frquency MUST be WORD variables.

I put it in the comments, but I should have mentioned it in the post too.

That... Frequency con 1000 will cause problems.
<br>

peu
- 7th May 2007, 01:59
I just finished testing it with this code:


' Pic Configuration
@ device pic12f683,INTRC_OSC_NOCLKOUT , wdt_on, mclr_off, protect_off

' Hardware configuration

' I/Os
TRISIO = %00010010 ' pin1 is ADC , pin4 is the calibration button

' ADC's
ANSEL = %00000010
DEFINE ADC_BITS 10 ' ADCIN resolution (Bits)
DEFINE ADC_CLOCK 1 ' ADC clock source (Fosc/8)
DEFINE ADC_SAMPLEUS 11 ' ADC sampling time (uSec)
ADCON0.7 = 1 ' Right justified results

' Comparator
CMCON0 = %00000111 ' Disable comparator
VRCON = %00000000 ' disable
'cmcon0 = %00001110 ' Multiplexed Input with Internal Reference CIS=1
'vrcon = %10001010 ' set vref=2.25v (from 4v input)

include "HPWM10.pbp"

' definitions
pote var word
Frequency var word
calibraled var gpio.5
calibrapin var gpio.4

gpio=0
frequency=1000
pause 50 ' coffee break

loop:

if calibrapin=0 then
adcin 1, pote
if pote>1000 then pote=1000
endif

@ HPWM10 1, _pote, _Frequency
pause 10

goto loop
end


The output is not steady when I use ADCIN, if I enable the calibrapin then it goes to steady mode.

To generate the adcin values I used a 10k pot instead of the sensor Im using for simplicity sakes.

Am I doing something wrong?

Thanks!


Pablo

mister_e
- 7th May 2007, 02:11
Can't tell ya! But as far i remind, the datasheet suggest a maximum impedance of 2.xxx Kohm.

I tested my code on a EASYPIC 4 board with 10K trim pot... seems to work.

Post your schematic but make sure your PSU is well filtered and is strong enough for your need first.

Weird, weird, weird.

Darrel Taylor
- 7th May 2007, 02:21
Oh Great!

Thanks for trying it Steve.
It helps to know not all is lost. :)

I think I've got a 683 around here somewhere.

Maybe there's something I missed for the little guys.
<br>

T.Jackson
- 7th May 2007, 02:33
One day to do all that? Wow, some 'over a month TicTacToe brain challenged programmer' will be impressed http://www.mister-e.org/Pics/ROFL

Yes, Mister_e, very impressive indeed. :)

peu
- 7th May 2007, 02:34
Im using this schematic:

http://peu.net/temp/darrelhpwmtest1.jpg

Im using a recently charged Li-Ion (3.635v measured under load using a good multimeter) all is mounted in a protoboard

Using my last posted code the LED flickers, if I press the button it goes steady

Thanks!

mister_e
- 7th May 2007, 02:41
mmm, yeah it works.. but a scope attach to show few glitches... mine too.

Deeper analysis show that flicker go away if i don't turn off the PWM off before updating the duty cycle. So maybe i have those latest silicon version.. and why the datasheet no longer suggest to turn off the PWM module...

aarrrggghh

peu
- 7th May 2007, 02:45
let me join your ARGHHH...

Thanks Steve, at least now I know Im not alone here :)

I ordered some 12f683 samples not so long ago, if they changed something I guess I could test it with a rather new IC. But they are at my office, will check tomorrow if time allows.

Thanks for the continued help guys!

Pablo

mister_e
- 7th May 2007, 03:09
in my code just remove the following line

CCP1CON = PWM_OFF
and also that one

CCP1CON = CCP1CON | PWM_ON

In darrel's include, comment out line 160

MOVE?CB 0, CCP1CON

At least, it work here.. thanks to my scope :D

Now the history don't tell if this will work with ALL PIC #, and with ALL silicone release. Time will tell.

T.Jackson
- 7th May 2007, 03:28
You are a genius Mister_e. Wish I was as smart.

mister_e
- 7th May 2007, 03:30
Don't give up, maybe one day you'll be. Then i could hire you ;)

peu
- 7th May 2007, 03:44
I removed that line from Darrel code and its clearly more stable now, but it still flickers at the lower range of the pot... very strange...

I just modified the code I posted to write to eeprom the lowest pot setting where its stable, the read value was from $007B to $007C but I recorded a couple of $007F and $0068 after 125 readings/writes, my guess for these oscillations was someting in the write cycle because after I stopped reading the led went to steady again, I wish I had a scope...

modified code:


if calibrapin=1 then
if conta < 250 then
write conta, pote.byte1
write conta+1, pote.byte0
conta=conta+2
endif
endif



Pablo

Darrel Taylor
- 7th May 2007, 03:50
Strange indeed.

Well, I've made the changes Steve found and posted it at the same link.

I won't get my scope back till wednesday. (should have waited)
But I'll sure have a good look at it then.
<br>

mister_e
- 7th May 2007, 04:00
mmm, could be a noisy pot as well... using your code and on many low-value ADC.. they are all stable.. no noise, no frlicker.

what happen if you stick a 0.1 uF in parallel with your POT wiper?

Any 0.1uF + 10uF capacitor close to your PIC?

T.Jackson
- 7th May 2007, 04:04
Great thread this. ;)

mister_e
- 7th May 2007, 04:09
O.K. i'll stop here... at least by respect to our members and readers, and because it's not a chit-chat area.

skimask
- 7th May 2007, 04:49
...deleted...for obvious reasons :D

peu
- 7th May 2007, 19:40
mmm, could be a noisy pot as well... using your code and on many low-value ADC.. they are all stable.. no noise, no frlicker.

what happen if you stick a 0.1 uF in parallel with your POT wiper?

Any 0.1uF + 10uF capacitor close to your PIC?

I just tried with a 20 turn 10k linear pot and its the same, once I reach the lower duty cycles the led flickers.
The difference is clearly visible with the multiturn pot, once you go below a certain level it flickers, move the other way a little bit and the flicker goes away

Reading in the flicker position I get this range: from $00BB to $00BF and spurious $009F , $00B4, $00C6, $00E3 at random places
Reading in the steady position I get this range: $00CD to $00CF and no spurious readings

I only read 125 word values into the device own eeprom.
Again Im using a li-ion battery for powering the circuit (3.65v)

Weird isnt it? even weirder is that sometimes when I write the values to eeprom the written values are steady (also visually) but only when writting...

Just in case here is the code I used:


' Pic Configuration
@ device pic12f683,INTRC_OSC_NOCLKOUT , wdt_on, mclr_off, protect_off

' Hardware configuration

' I/Os
TRISIO = %00010010 ' pin1 is ADC , pin4 is the calibration button

' ADC's
ANSEL = %00000010
DEFINE ADC_BITS 10 ' ADCIN resolution (Bits)
DEFINE ADC_CLOCK 1 ' ADC clock source (Fosc/8)
DEFINE ADC_SAMPLEUS 11 ' ADC sampling time (uSec)
ADCON0.7 = 1 ' Right justified results

' Comparator
CMCON0 = %00000111 ' Disable comparator
VRCON = %00000000 ' disable
'cmcon0 = %00001110 ' Multiplexed Input with Internal Reference CIS=1
'vrcon = %10001010 ' set vref=2.25v (from 4v input)

include "HPWM10.pbp"

' definitions
pote var word
Frequency var word
calibraled var gpio.5
calibrapin var gpio.4
conta var byte

gpio=0
conta=0
frequency=1000
pause 50 ' coffee break

loop:

adcin 1, pote
if pote>1000 then pote=1000

if calibrapin=1 then
if conta < 250 then
write conta, pote.byte1
write conta+1, pote.byte0
conta=conta+2
endif
endif

@ HPWM10 1, _pote, _Frequency
pause 10

goto loop
end



Pablo

mister_e
- 7th May 2007, 19:46
O.K. i have to go out. I had the same code, and i didn't have any problem...

when i'll be back, i'll use a lower voltage AND use HighBrightness LEDs.

Wish i could see the same thing....

Still thinking there's an hardware problem...

Darrel Taylor
- 7th May 2007, 23:34
Pablo,

Good new, Bad news.

I finally found my 12F683 and gave it a go.
I've completely duplicated your problem. Blinking and all.

For some reason it only does it on the 683.
Every other chip I tried seems to work fine.

And the bad news is, I haven't found out why yet. (Operative word, Yet)
It appears to be with the A/D, the readings are all over the place at low voltage input.

I still have many things to try, but just wanted you to know you're not crazy.
And, I WILL find it. (unless somebody beats me to it)
<br>

peu
- 7th May 2007, 23:43
Pablo,

Good new, Bad news.

I finally found my 12F683 and gave it a go.
I've completely duplicated your problem. Blinking and all.

For some reason it only does it on the 683.
Every other chip I tried seems to work fine.

And the bad news is, I haven't found out why yet. (Operative word, Yet)
It appears to be with the A/D, the readings are all over the place at low voltage input.

I still have many things to try, but just wanted you to know you're not crazy.
And, I WILL find it. (unless somebody beats me to it)
<br>

As I see it its only good news :) Thanks for all your efforts!!!

I can't help with your code, is way beyond my actual knowledge, I hope to catch up with it in the future!

Now I patiently wait ;)


Pablo

peu
- 8th May 2007, 03:44
An EE friend of mine (Thanks Doug) told me a new possibility about the cause of the problem:

What if reading the ADC so often does not give it enough time to handle the low voltage values?

(more discussions via chat with my friend)

He points out something interesting, the test program initializes the ADC using:

DEFINE ADC_BITS 10 ' ADCIN resolution (Bits)
DEFINE ADC_CLOCK 1 ' ADC clock source (Fosc/8)
DEFINE ADC_SAMPLEUS 11 ' ADC sampling time (uSec)

But reading the pic basic manual we have:



ADC_SAMPLEUS is the number of microseconds the program waits
between setting the Channel and starting the analog to digital
conversion. This is the sampling time. The minimum number of
microseconds usable is determined by the minimum time for PAUSEUS.
See it’s section for this information.

and the PAUSEUS section says:

For 4mhz Minimum Delay is 24us

So, the initial theory appears to be right, I don't have the protoboard here now, but I will check this tomorrow.


Pablo

Darrel Taylor
- 8th May 2007, 07:31
I tried every AD oscillator / Sample time possible, and it made no difference.
Even with the A/D input tied directly to ground, it was getting crazy readings between 0 and 20.

After I tried it with a 12F675 (without the CCP) and got the same results,
I finally figured out that I had removed the big cap on the power lines on this protoboard.
Probably needed it for something else. Doh!

After putting a 100uf cap across the power supply, everything calmed down again.
It's still not perfect, but I think that has alot to do with the breadboard.

So then to really stabilize things I added an averaging routine, and I think that's about as close as we're going to get.

First make sure you have enough capacitance on your power lines (I think mister_e already suggested that).

Then add this to the bottom of the program
' -=-=-=-=-=-= Average Analog values -=-=-=-=-=-=-=-=-=-=
Avg VAR WORD
AvgCount CON 16
spread CON 20

Average: ' Smooth data
IF ABS (pote - Avg) > spread then
Avg = pote
else
Avg = (Avg*(AvgCount-1)+pote)/AvgCount
pote = Avg
endif
Return

And also, just after the ADCIN statement, add this
gosub Average

HTH,

mister_e
- 8th May 2007, 19:20
it's getting interesting... i have everything on hand, will do some test here.

Sorry, i was suppose to do it yesterday :D :(

peu
- 8th May 2007, 19:30
well I hope you find something because I tried adding a 100uF capacitor in the power lines or in parallel with the wiper and my problems remain, even after adding the averaging routine provided by Darrel.

I even started looking for other pic alternatives :( in case this can't be solved...

Thanks again

mister_e
- 8th May 2007, 19:33
still working @ 3.x Volt?

peu
- 8th May 2007, 19:34
yes Sir, using a 3.6v li-ion batt


Pablo

mister_e
- 9th May 2007, 01:38
O.K. can you try to program you pic with the .HEX in attachment and let me know what's happening now?

Finger crossed...

peu
- 9th May 2007, 02:00
O.K. can you try to program you pic with the .HEX in attachment and let me know what's happening now?

Finger crossed...

it uses the circuit I provided right? will test it tomorrow and let you know. Thanks!!!

mister_e
- 9th May 2007, 02:01
Yup it's the same circuit. CalibraPin is also implemented.

Here, it's working, no flicker or else... 'till now

peu
- 9th May 2007, 17:07
yes it flickers, but this one instead of graduating continuously goes in steps, and the calibrapin button does nothing, at least nothing I can see or read.

Thanks!

mister_e
- 9th May 2007, 23:06
can you try something because it's working really fine here... use another ADC channel, like GP4, or GP5.

peu
- 9th May 2007, 23:15
can you try something because it's working really fine here... use another ADC channel, like GP4, or GP5.

what do you mean by using another ADC? change the my test program to read in another port ?

thanks

mister_e
- 9th May 2007, 23:24
In your example you used ADCIN 1,pote to read GP1. Change it to ADCIN 5,pote. Sure you'll need to change your hardware and some regisers settings as well.

Next step will be to use a TIMER interrupt instead.

peu
- 9th May 2007, 23:54
In your example you used ADCIN 1,pote to read GP1. Change it to ADCIN 5,pote. Sure you'll need to change your hardware and some regisers settings as well.

Next step will be to use a TIMER interrupt instead.

I will do two things, 1st etch a pcb for the circuit and test it again, second try with a 16F628A

I let you know. thanks!

peu
- 12th May 2007, 06:46
made the etched pcb and only tried it with Mister_e hex file and it worked without flickerings. Im not sure if its supposed to smooth or in steps, I see steps.

More tests on monday. Thanks!!

mister_e
- 12th May 2007, 09:55
steps are normal with my HEX. but good news! and thanks to report your results. Sure many code before my last one will now work as designed.

Acetronics2
- 24th April 2009, 18:22
Hi, Darrel,

I just try tu make HPWM10 work aboard a 12F683 ...

and get the following Message ( MPASM compiler ) :

Error[108] C:\PROGRAM FILES\MICROCHIP\MPLAB IDE\PROJETS\SPEEDCOMM.ASM 185 : Illegal character (1)

the illegal character is ... the PWM Channel !!!

@ HPWM10 1, _DutyCycle, _Frequency

I used the example " straight out of the box ...

do you have any idea ???

Alain

Acetronics2
- 24th April 2009, 18:26
re,

The idea is : change "HPWM10.pbp" into "HPWM.bas", for the include command.

Alain

Darrel Taylor
- 25th April 2009, 01:48
Error[108] C:\PROGRAM FILES\MICROCHIP\MPLAB IDE\PROJETS\SPEEDCOMM.ASM 185 : Illegal character (1)
There had to be more errors than that.
The others might have had more clues, but it appears that PBP couldn't find the file.

Are you saying that you renamed it to HPWM.bas but still had INCLUDE "HPWM10.pbp"?

confused. :confused:
<br>

Acetronics2
- 25th April 2009, 09:37
There had to be more errors than that.
The others might have had more clues, but it appears that PBP couldn't find the file.

Are you saying that you renamed it to HPWM.bas but still had INCLUDE "HPWM10.pbp"?

confused. :confused:
<br>

Hi, Darrel,

Hoooo ... bad evening ! was HPWM10.pbp into HPWM10.bas.

the goal was to transform a R/C pulse into a corresponding 10 bits PWM @ 10 kHz ... and drive a "Diesel engine" sound machine.

Have a nice week end.

Alain

Acetronics2
- 12th May 2009, 17:36
Hi, Darrel

I Was a bit surprised by those lines :




Line Address Opcode Label Disassembly

359 166 00BD MOVWF 0x3d
360 167 084C MOVF _HP_Channel, W
361 168 3C05 SUBLW 0x5
362 169 1C03 BTFSS STATUS, 0
363 16A 2975 GOTO L00001
364 16B 3001 MOVLW 0x1
365 16C 008A MOVWF PCLATH
366 16D 084C MOVF _HP_Channel, W
367 16E 0782 ADDWF PCL, F
368 16F 297A GOTO _GetCH_2
369 170 2975 GOTO L00001
370 171 297A GOTO _GetCH_2
371 172 297A GOTO _GetCH_2
372 173 297A GOTO _GetCH_2
373 174 297A GOTO _GetCH_2
374 175 0813 L00001 MOVF CCPR1L, W
375 176 00C0 MOVWF _HP_Temp
376 177 0815 MOVF CCP1CON, W
377 178 00C1 MOVWF _HP_Temp??HIGHBYTE
378 179 297A GOTO _GetCH_2
379 17A 0840 _GetCH_2 MOVF _HP_Temp, W
380 17B 00A0 MOVWF BANK0_START
381 17C 01A1 CLRF 0x21
382 17D 3002 MOVLW 0x2
383 17E 205A CALL SHIFTL



are those 6 times " GOTO _GetCH_2 " ( L368 , 370 - 373 , 378 ) something " regular " ???


the source for 12F683 @ 8 Mhz internal is :



@ __config _INTRC_OSC_NOCLKOUT &_FCMEN_OFF &_IESO_OFF & _WDT_ON &_PWRTE_ON & _MCLRE_OFF & _CP_OFF

OSCCON = %01110111 ' Internal Clock 8 Mhz

CMCON0 = 7
VRCON = 0
ADCON0 = 0
ANSEL = 0

DEFINE OSC 8 'Declare 8 Mhz operation
DEFINE PULSIN_MAX 4500


' PINS DEFINITIONS

Signal var GPIO.3
Drive var GPIO.2

GPIO = 0
TRISIO = %00001000


' VARIABLE DEFINITIONS

speed var Word ' assign Word variable to speed demand
w1 var Word ' Table output

DutyCycle VAR WORD
Frequency VAR WORD
Temp VAR WORD


include "HPWM10.bas"

LOW Drive ; Set CCP1 pin to output low

Frequency = 10000

'************************************************* *****************************
'MAIN LOOP
main:


pulsin Signal,0,speed ' Read servo pulse ( Inverted !!! )

'************************************************* *****************************
' Throttle amount topped to 100 and reduced to 25 steps

if speed > 300 then
speed = ( speed - 300 )MIN 100
else
speed = ( 300 - speed )MIN 100
endif

speed = speed >> 2

'************************************************* *****************************
' Conversion logarithmique 10 bits - 800 maxi à 10 khz


lookup2 speed, [0,0,161,277,378,467,543,611,670,721,766,804,836,86 7,893,_
933,950,965,978,990,1000,1009,1017,1023,1023 ],w1

'************************************************* *****************************
' !!! Passer en " HPWM 10 " !!!

if w1 <> DutyCycle then DutyCycle = w1

@ HPWM10 1, _DutyCycle, _Frequency

goto main

END



Regards

Alain

Darrel Taylor
- 12th May 2009, 19:47
Hi, Darrel

I Was a bit surprised by those lines :
...
are those 6 times " GOTO _GetCH_2 " ( L368 , 370 - 373 , 378 ) something " regular " ???
The lines showing the same labels is the result of Disassembling.
There are actually 6 different labels, with the code in-between optimized out since the chip doesn't have 5 CCP modules.

It comes from this section ...

;----- Get Current DutyCycle ------------------------------------------------
Branch HP_Channel,[GetCH_Done,GetCH_1,GetCH_2,GetCH_3,GetCH_4,GetCH_5]

GetCH_1:
ASM
ifdef CCP1CON
MOVE?BB CCPR1L, _HP_Temp
MOVE?BB CCP1CON, _HP_Temp + 1
goto _GetCH_Done
endif
endasm
GetCH_2:
ASM
ifdef CCP2CON
MOVE?BB CCPR2L, _HP_Temp
MOVE?BB CCP2CON, _HP_Temp + 1
goto _GetCH_Done
endif
endasm

The GOTO's are created by the Branch statement.
And it looks like this in the .LST file ...
016B 3001 M movlw (jmptbl) >> 8
016C 008A M movwf PCLATH
016D 084C M movf _HP_Channel, W
016E 0782 M addwf PCL, F
016F M jmptbl
016F 297A M goto _GetCH_Done
0170 2975 M goto _GetCH_1
0171 297A M goto _GetCH_2
0172 297A M goto _GetCH_3
0173 297A M goto _GetCH_4
0174 297A M goto _GetCH_5
0175 M L00001
0175 M _GetCH_1
0175 0813 M movf CCPR1L, W
0176 00C0 M movwf _HP_Temp
0177 0815 M movf CCP1CON, W
0178 00C1 M movwf _HP_Temp + 1
0179 297A 00326 goto _GetCH_Done
017A M _GetCH_2
017A M _GetCH_3
017A M _GetCH_4
017A M _GetCH_5
017A M _GetCH_Done

Since the labels are all at the same address, the disassembler chooses the first label it finds at that address (_GetCH_2).

Acetronics2
- 14th May 2009, 08:47
Hi, Darrel

Tanks for your explanation

Alain

Samoele
- 25th October 2009, 15:49
Hello,

I would have two different frequency on CCP1 and CCP2 pin the first is 100HZ and second is 20Khz-40KHz. I use 1MHz quartz for clock and HPWM10 command from D.T. I use PIC16F876.
I have on both CCP pin HPWM10 command with frequency 100hz and different duty. This working ok. When changed frequency on CCP1 to 1KHz then is frequency on both pin unchanged and very unstable
When change one HPWM10 command to normal 8 bit HPWM then stay result unchanged.
what I did wrong?

here is first part of my program:




INCLUDE "ALLDIGITAL.pbp"

Cifra var byte
Cifra1 var byte
Maska1 var byte
Maska2 var byte
W var byte
i var byte
time var byte
PR var byte
VU var word
VD var word
Duty VAR word
Duty1 VAR word
FREQUENCY var word
FREQUENCY1 var word

LED var PORTC.4
LEDDis1 var PORTA.0
LEDDis2 var PORTA.1
tipka1 var porta.2
tipka2 var porta.3
tipka3 var porta.4
BUZ var porta.5
enable1 var portc.0
b0 var byte
b1 var byte
b2 var byte
b3 var byte
impulz var WORD
minuta var byte
key var byte
pavza var word

bp var byte

TRISA=%11111100
TRISB=%00000000
TRISC=%00000000


clear
include "HPWM10.pbp"
LOW PORTC.1
LOW PORTC.2
PWM_ON CON %00001100
PWM_OFF CON 0
time=6
FREQUENCY=93 '
FREQUENCY1=1000
low led
gosub zvok
eeprom 0,[31]
eeprom 2,[55]
high enable1
high led
pause 100
low led




INTCON = %00100000
OPTION_REG = %10001000

On Interrupt Goto ISR
INTCON = %10100000
w=0


Main:

gosub tipka
gosub timing
read 0,b2
gosub tpwm
@ HPWM10 2,_IMPULZ,_FREQUENCY
read 2,b0
gosub ppwm
@ HPWM10 1,_duty,_FREQUENCY1
Gosub Priprava
goto Main

ppwm: b1=b0-50
lookup2 b1,[100,200,300,400,500,600,700,800,900,1000],duty
return

tpwm: b3=b2-30
lookup b3,[0,31,16,6,21,46],duty1
return

Darrel Taylor
- 25th October 2009, 17:28
With 16F876's, both CCP modules use the same Timer in PWM mode (TMR2).
If you change the frequency of one, the other one changes too.

With a 4 Mhz crystal, the minimum HPWM frequency is 245 Hz.
Since you are using a 1 Mhz crystal, you can get down to 62 Hz, but you have to specify the frequency as if it were running at 4 Mhz.

If you want 100 Hz, then specify 400 Hz in the HPWM10 command.
93 is way below the minimum.
<br>

Samoele
- 26th October 2009, 06:45
Frequency of 100 Hz is not a problem. In the case that I use PIC16F886 asking whether the command HPWM10 set timer TMR1 and TMR2 for each channel?
Can you write the registry settings for the PIC16F886?

tnx
Samo

Darrel Taylor
- 26th October 2009, 19:41
Even on a PIC16F887, the CCP modules can only use Timer2 in PWM mode.
So both PWM channels will operate at the same frequency.

So I guess the answer to your question is ...
HPWM10 only changes Timer2, not Timer1.
<br>

jamie_s
- 30th November 2009, 09:08
Darrel,

Whats required to have 'glitch free' operation but with 8 bit PWM, can the include file be easily modified for 8 bit, or should i just multiply my desired 8 bit dutycycle by 4?

jamie_s
- 30th November 2009, 12:45
Also, just testing on 16F887, at 4mhz,

@ HPWM10 1,_OUTDUTY,300 results in a PWM frequency of 10khz according to my o'scope ???
I see the duty cycle changing, but the freq is around 9-10khz?

Darrel Taylor
- 30th November 2009, 20:40
The frequency must be a variable.
You can't pass a constant as the parameter.

And just shift left 2 (<<2) to use 8-bit values.

hth,

Christopher4187
- 16th June 2015, 14:46
Old thread but very relevant to my issue.

Can I use HPWM10:

1. On an 18F87J50?
2. And have it glitch free?
3. To make a pulse train that's 140mS long and have varying duty cycles within the pulse train?

In other words: 300uS on, 200uS off, 300uS on on, 200uS off, 130uS on, 370 uS off, 300uS on, 200uS off, 130uS on, 370uS off, 170uS on, 330uS off, 130uS on, 370uS off, etc.

Each bit is 500uS and I don't need to modify anything while the packet is being sent; I can modify right before the next one is sent.

Art
- 18th June 2015, 19:55
If by “glitch free” you mean free of any resolution error, not every frequency or duty cycle you want to generate will be.
for any particular frequency, you need the pic’s clock frequency to tell you that.
This online PWM calculator can tell you:
http://www.micro-examples.com/public/microex-navig/doc/print_097-pwm-calculator.html

whether or not you can change it for arbitrary duration for every pulse like that would be a tough one,
I don’t think that’s possible, but might be wrong.

Depending what else the chip has to do, it might be possible to use timer1 overflow that way.