12F683 Maths and code genius reqd.


Closed Thread
Results 1 to 8 of 8
  1. #1

    Lightbulb 12F683 Maths and code genius reqd.

    Dear Members

    I have an 8mhz 12F683 monitoring a 2khz pwm signal. I am using pulsin to determine the high time and at 8mhz I get 5us resolution or 100 units over a 2khz 500us pulse. That's all fine.

    I also have two rail to rail pots being monitored by 8 bits adc's and then multiplied to give 0-100 units resolution.
    Again that's fine.

    I am also using the pic HPWM to duplicate the incoming pwm data stream multiplying the incoming puslin data to provide the 8 bit hpwm data reqd. That's fine.

    What I am doing is modifying the incomming pwm data using the two pots and then sending the modified pwm out of the hpwm.
    The issue is my maths and logic seems horribly complicated.

    Lets take a pwm signal with a high time of 51-90% I want to modify that with one of the pots called AssistPot so that

    The first pot called AssistPot is only reqd to work on signals with a duty of 51-90%
    1) When the pot is at 50% (in the middle) then it has no effect on the signal.
    2) When it is 51-100% I want it to lengthen the pwm high time by 0-100% upto a maximum of 90% duty.
    3) When it is 49-0% I want it to shorten the pwm high time by 0-100% down to a minimum of 51% duty.


    The second pot called RegenPot does something similar but is reqd to only works on signals with a duty of 49-10%
    1) When the pot is at 50% (in the middle) then it has no effect on the signal.
    2) When it is 51-100% I want it to shorten the pwm high time by 0-100% down to a minimum of 10% duty.
    3) When it is 49-0% I want it to lengthen the pwm high time by 0-100% upto to a maximum of 49% duty.

    Now my code below works but feels clunky and I had to add a couple of checks to stop the maths going negative.
    I think there must be a more elegant solution. The RegenPot maths seemed much harder.
    I have it working using the code below and proteus simulates correctly. It also works with my hardware.
    So I'm really looking for improvements, coding tricks or other brilliant insight :?

    Code:
    pulsin CmdPwrIn,1,CmdPwrHigh   'Measures length of Incoming CmdPwr 2khz Pwm Duty High pulse  
            
        If CmdPwrHigh > 50 then  'Assist Requested Duty > 50%
        PwrLevel = CmdPwrHigh - 50
        High Led     'Turn On Red Assist Led
        ADCIN 0,AssistPot           'Get AssistPot Setting 
        AssistPot = (AssistPot * 100) / 255
        If AssistPot > 50 then 
        AssistPot = AssistPot - 50
        Multiplier = 100 + ((AssistPot * 100) / (100 - AssistPot))
        PwrLevel = 50 + ((Pwrlevel * Multiplier)/100)        
        elseIf AssistPot < 50 then 
        AssistPot = 50 - AssistPot
        Multiplier = 100 + ((AssistPot * 100) / (100 - AssistPot))
        PwrLevel = 50 + (PwrLevel-(((Pwrlevel * Multiplier)/100)-Pwrlevel))            
        elseif AssistPot = 50 then
        AssistPot = 0
        PwrLevel = CmdPwrHigh
        endif      
        endif
        
       
        If CmdPwrHigh < 50 then  'Regen Requested Duty < 50%
        PwrLevel = 50 - CmdPwrHigh 
        low Led      'Turn On Green Regen Led 
        ADCIN 1,RegenPot            'Get RegenPot Setting      
        RegenPot = (RegenPot * 100) / 255
        If RegenPot > 50 then 
        RegenPot = RegenPot - 50
        Multiplier = 100 + ((RegenPot * 100) / (100 - RegenPot))
        General16 = ((Pwrlevel * Multiplier)/100) 
        if General16 > 50 then General16 = 50 'Prevents Result Negative Overflow error
        PwrLevel = 50 - General16     
        elseIf RegenPot < 50 then 
        RegenPot = 50 - RegenPot
        Multiplier = 100 + ((RegenPot * 100) / (100 - RegenPot))
        PwrLevel = 50 - (PwrLevel-(((Pwrlevel * Multiplier)/100)-PwrLevel)) 
        elseif RegenPot = 50 then
        RegenPot = 0
        PwrLevel = CmdPwrHigh 
        endif     
        endif
        
        If CmdPwrHigh = 50 then 
        TRISIO.4 = 1  'Turn Off Led  
        PwrLevel = 128   
        else  
        if Pwrlevel > 90 then PwrLevel = 90   'Prevent Assist request Error Duty > 90%
        if PwrLevel < 10 then PwrLevel = 10     'Prevent Regen request Error Duty < 10%        
        PwrLevel = (PwrLevel * 255) / 100     'Calculate HPWM Duty 8 bit data
        endif
    Any Ideas?

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,605


    Did you find this post helpful? Yes | No

    Default Re: 12F683 Maths and code genius reqd.

    I'm neither a math or a code genius and I'm most certainly missing something but how about this (compiles but not tested):
    Code:
    Temp VAR BYTE
    AssistPot VAR BYTE
    RegenPot VAR BYTE
    CmdPwrHigh VAR BYTE
    PwrLevel VAR BYTE
    
    CmdPwrIn VAR GPIO.0
    
    ' 50 counts for 50% dutycyle @2kHz input and 8MHz oscillator
        PULSIN CmdPwrIn, 1, CmdPwrHigh              
    
    ' Read inputs (8bit mode!) and convert values to +/-40 in two's complement.
        ADCIN 0, Temp
        AssistPot = (Temp ** 20480) - 40
        
        ADCIN 1, Temp
        RegenPot = (Temp ** 20480) - 40
    
    '-------------------------------------------------------------------------------
        IF CmdPwrHigh > 50 THEN                     ' Assist pot in play
            PwrLevel = CmdPwrHigh + AssistPot       ' No risk of overflowing a BYTE here
            If PwrLevel > 90 THEN PwrLevel = 90     ' But we need to clamp at 90% for top end...
            If PwrLevel < 51 THEN PwrLevel = 51     ' ...and at 51% for the bottom end. 
        ENDIF
    '-------------------------------------------------------------------------------
        If CmdPwrHigh < 50 THEN                     ' Regen pot in play
            PwrLevel = CmdPwrHigh - RegenPot
            If PwrLevel < 10 THEN PwrLevel = 10     ' Clamp at 10 for the low end
            IF PwrLevel.7 THEN PwrLevel = 10        ' Clamp at 10% if we went negative
            If PwrLevel > 49 THEN PwrLevel = 49     ' Clamp at 49% for the top end.
        ENDIF
    '-------------------------------------------------------------------------------
    /Henrik.

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: 12F683 Maths and code genius reqd.

    I'm afraid that does not work at all as expected.
    Also the increase or decrease should be a percentage of the pot level.
    Thanks for the idea though.

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: 12F683 Maths and code genius reqd.

    Opps sorry Henrik my simulation was not set up correctly your version does seem to be working and is half the size.

    Still looking for any other ideas.

    Thanks Peter

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: 12F683 Maths and code genius reqd.

    How can I simulate/enter this formula in a spreadsheet?
    I want to experiment with the values for the the calculation.
    The special 2's complement maths is making my head explode.
    Thanks

    ADCIN 1, Temp 'Temp = a number between 0-255
    RegenPot = (Temp ** 20480) - 40

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,605


    Did you find this post helpful? Yes | No

    Default Re: 12F683 Maths and code genius reqd.

    Hi,
    Try something like:
    Code:
    =TRUNC((A4*20480/65536)-40)
    Where A4 is the cell in which you put your TEMP value. Now, MS insists on changing the names of the functions depending on what language you're running but I think TRUNC is what you want, as long as you're running an English version of Excel - which I'm not.....here it's called AVKORTA....

    This will give you a result of -39 when TEMP is 0 and 39 when TEMP is 255 and it truncates the result (instead of rounding it) just like it will when run on the PIC.

    We could get it display as a real two's complement number but I'll have to dwell on that for a moment - if needed. In the meantime:
    253 = -3
    254 = -2
    255 = -1
    0 = 0
    1 = 1
    2 = 2
    3 = 3

    And so on.....

    /Henrik.

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: 12F683 Maths and code genius reqd.

    How can i modify the formula to get +/- 20 or +/- 10

    AssistPot = (AssistPot ** 20480) - 40
    RegenPot = (RegenPot ** 20480) - 40

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,605


    Did you find this post helpful? Yes | No

    Default Re: 12F683 Maths and code genius reqd.

    Hi,
    +/- 20: Change 20480 to 10240 (1/2 of 20480) and subtract 20 instead of 40.
    +/- 10: Change 20480 to 5120 (1/4 of 20480) and subtract 10 instead of 40.

    Just think of the ** operator as multiplying by units of 1/65536.

    /Henrik.

Similar Threads

  1. please help with 12f683 pwm code
    By haidar in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 22nd May 2013, 21:25
  2. Problem converting 12F683 code to 12F1840
    By RossWaddell in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 14th March 2013, 01:55
  3. Maths help please
    By Tina10 in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 11th June 2012, 16:45
  4. Maths again...
    By Ioannis in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 21st September 2010, 22:51
  5. Comparator Help reqd
    By Squibcakes in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 28th September 2005, 03:39

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts