Shop OBEX P1 Docs P2 Docs Learn Events
Am I using cognew/cogstop correctly? — Parallax Forums

Am I using cognew/cogstop correctly?

turbosupraturbosupra Posts: 1,088
edited 2014-11-03 11:47 in Propeller 1
I am having a problem where my second cog method (coolantPwmOut) was hanging when I it was supposed to go into lower power mode (when ina[I_KeyOn] == 0) with a waitcnt, so I decided to try and stop the cog/method when ina[I_KeyOn] == 0 and restart it when ina[I_KeyOn] == 1. Neither way is working, so I must be doing something wrong.

The method is supposed to put at a 2.3hz square wave signal that varies in duty cycle based on an adc input value. When ina[I_KeyOn] == 1, the method will hang somewhere, I'm not sure where because when I plug in the usb to serial into my laptop, it resets the prop and upon reset it works correctly and outputs the square wave signal. Is there a way to stop the prop from resetting when you plug the ftdi into a usb port on a computer? I could troubleshoot it possibly if I could stop that.

The code is attached if anyone would be kind enough to give me a critique so that I can learn.

Thank you.

Comments

  • StefanL38StefanL38 Posts: 2,292
    edited 2014-11-01 23:42
    Hi Brad,

    it is a specialty of me to first get an overview about a project.
    and after that starting to develop a solution that is as simple as possible.

    I'm not willing to debug your code as it is - to find the point where you have to insert something
    from behind to re-re-reswitch a signal to get it on.

    Maybe there are good reasons to code it exactly the way you coded it. But I don't know.
    So please explain it to me.

    Did I understand right a potentiometer is connected to the ADC (MCP3208).
    You are reading in the potentiometer-position.
    Depending on the potentiometer-value you are calculation the On-Time and Off-Time of the duty-cycle.
    Then the pwm-signal is created through a method running in its own cog?


    There is a lot more code in your examplefile which I do not understand with a quick reading.
    Are there any addtional conditions that make the code around the basic thing described above nessesary?
    To me the code looks pretty complicated and therefore difficult to maintain.
    So my first suggestion is to strip down the code to the pure function.

    If there are any addtional conditions please describe them from a functional point of view.

    Like somebody that knows nothing about coding but knows exactly what a control-unit should do

    example "if switch A is in position 2 do this. If switch B and switch C is in position 4 do that...."

    Additonal comments:
    Instead of using floating-point constants I would use integervalues.

    Your constants have two digits behind the decimal point.

    example

    c_100FahrenheitOn = 87

    So your value would be multiplied with 87 and then divided by 100. Rounding is automatically included in integerdivision

    You defined constants for On and for Off
    the Off-constant-value is simply 100 - OnConstantValue

    you could use the expression "100 - OnConstantValue" where you are calculating with it
    or if you would like to have a Off-constants on ist own

    c_100FahrenheitOn = 87
    c_100FahrenheitOff = 100 - c_100FahrenheitOn

    this will assure that the sum is always 100

    I guess that you measured the pwm-frequency.
    2.3Hz is a pretty low PWM-frequency. Is there a special reason why the frequency must be that low?
    to me it seems very unuasual to have such a low pwm-frequency.

    What kind of thing is the receiver of this pwm-signal you are creating?

    best regards
    Stefan
  • turbosupraturbosupra Posts: 1,088
    edited 2014-11-02 05:53
    Hi Stefan,

    It is reading a varistor, when I bench test I use a potentiometer, so yes it is connected to the MCP3208 and yes depending on that adc value, the PWM on/off time is calculated based on the constants. Unfortunately it is not linear, so I can't have a constant value that I can use in place of the constants list.

    The only switch that matters in this case is the position of I_KeyOn.

    I will try the math suggestion you've made, that sounds good to me.

    The 2.3hz is out of my control, that was set by the receiving device and is a requirement. The receiver is an automotive dash.

    I've never had a cog hang like that when coming out of a low power mode, maybe the lower power waitcnt was the wrong way to go about that, so I'm happy to try cogstop/cognew if that is the proper way to do that. I've never used the cogstop command before.

    To remove float math, I will be doing this

    I was using this
    pwmOutputHertzToClkCycles := (f.fdiv(f.ffloat(clkfreq), 2.45)) ' clkfreq / 2.45 = 32653061
    

    but will now use this
    pwmOutputHertzToClkCycles := (((clkfreq) / 245) / 10) ' = 32653
    


    For onTime I was using this
    onTime := f.fmul(c_70FahrenheitOn, pwmOutputHertzToClkCycles) ' (0.99 * 32653061) = 32326530  or ((32653061 * 99) / 100) = 32326530  or ((((3265306 / 10) * 99) / 100) * 10) = 3236530
    

    but will now use this
    ' (((32653          *     99) = 3232647) * 10) = 32326470
                  onTime := ((pwmOutputHertzToClkCycles * c_70FahrenheitOn) * 10)
    

    For offTime I was using this
    offTime := f.fmul(c_70FahrenheitOff, pwmOutputHertzToClkCycles) '(0.01 * 32653061) = 326530
    

    but will now use this
    ' (((32653 * 1) = 32653) * 10) = 326530
    [code]              offTime := ((pwmOutputHertzToClkCycles * c_70FahrenheitOff) * 10)
    


    How does that look? Also, do you have any insight to why the cog/method is hanging? Is there a way to connect the terminal without having it reset the propeller altogether? Whenever I reset it, it works properly.

    Attached is the code the way you suggested it should be written. I'm still unsure about the part as to whether the proper format would be to put the cog into a low power mode, or to stop it and restart it when I need it. What do you think?
  • ChrisGaddChrisGadd Posts: 310
    edited 2014-11-02 14:05
    From what I can tell, the cognew / cogstop works fine.

    I suspect the problem is in your case statement:
      if (adcTHW <> 0)                                                           
        if (adcTHWBlock == false)                                                
          [b]case -1[/b]
            ((adcTHW < 4096) AND (adcTHW => 3350) AND (adcTHWBlock == false)):   
              onTime := ((pwmOutputHertzToClkCycles * c_70FahrenheitOn) * 10)    
              offTime := ((pwmOutputHertzToClkCycles * c_70FahrenheitOff) * 10)  
                                                                                 
            ((adcTHW < 3350) AND (adcTHW => 3250) AND (adcTHWBlock == false)):   
              onTime := ((pwmOutputHertzToClkCycles * c_75FahrenheitOn) * 10)    
              offTime := ((pwmOutputHertzToClkCycles * c_75FahrenheitOff) * 10)  
    
    Case -1 is evaluating every one of your expressions as true.

    Perhaps something along the lines of:
          if adcTHWBlock == false
            case adcTHW
              4096 .. 3350:
                                    ' (((32653        *       99) = 3232647) * 10) = 32326470
                onTime := ((pwmOutputHertzToClkCycles * c_70FahrenheitOn) * 10)
                                    ' (((32653          *     1) = 32653) * 10) = 326530  
                offTime := ((pwmOutputHertzToClkCycles * c_70FahrenheitOff) * 10)
    
              3349 .. 3250:
                                    ' (((32653          *     98) = 3199994) * 10) = 31999940 
                onTime := ((pwmOutputHertzToClkCycles * c_75FahrenheitOn) * 10)
                                    ' (((32653          *     2) = 65306) * 10) = 653060
                offTime := ((pwmOutputHertzToClkCycles * c_75FahrenheitOff) * 10)
    
              3249 .. 3150:
                onTime := ((pwmOutputHertzToClkCycles * c_80FahrenheitOn) * 10)    
                offTime := ((pwmOutputHertzToClkCycles * c_80FahrenheitOff) * 10)
                  
              3149 .. 3050:
                onTime := ((pwmOutputHertzToClkCycles * c_85FahrenheitOn) * 10)    
                offTime := ((pwmOutputHertzToClkCycles * c_85FahrenheitOff) * 10)
    
              3049 .. 2950:                                  
                onTime := ((pwmOutputHertzToClkCycles * c_90FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_90FahrenheitOff) * 10)
    
              2949 .. 2850:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_95FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_95FahrenheitOff) * 10)
    
              2849 .. 2740:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_100FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_100FahrenheitOff) * 10)
    
              2739 .. 2625:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_105FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_105FahrenheitOff) * 10)  
    
              2624 .. 2530:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_110FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_110FahrenheitOff) * 10)
                  
              2529 .. 2420:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_115FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_115FahrenheitOff) * 10)
                  
              2419 .. 2330:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_120FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_120FahrenheitOff) * 10)
                  
              2329 .. 2210:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_125FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_125FahrenheitOff) * 10)
                  
              2209 .. 2120:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_130FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_130FahrenheitOff) * 10)  
     
              2119 .. 2010:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_135FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_135FahrenheitOff) * 10)  
                  
              2009 .. 1915:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_140FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_140FahrenheitOff) * 10)  
    
              1914 .. 1810:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_145FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_145FahrenheitOff) * 10)  
    
              1809 .. 1715:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_150FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_150FahrenheitOff) * 10)  
    
              1714 .. 1605:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_155FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_155FahrenheitOff) * 10)  
                                                                            
              1604 .. 1490:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_160FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_160FahrenheitOff) * 10)  
    
              1489 .. 1400:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_165FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_165FahrenheitOff) * 10)  
    
              1399 .. 1300:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_170FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_170FahrenheitOff) * 10)  
    
              1299 .. 1225:                                                             
                  onTime := ((pwmOutputHertzToClkCycles * c_175FahrenheitOn) * 10)  
                  offTime := ((pwmOutputHertzToClkCycles * c_175FahrenheitOff) * 10)  
    
              1224 .. 1160:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_180FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_180FahrenheitOff) * 10)  
    
              1159 .. 1075:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_185FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_185FahrenheitOff) * 10)  
    
              1074 .. 990:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_190FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_190FahrenheitOff) * 10)  
    
              989 .. 910:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_195FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_195FahrenheitOff) * 10)  
    
              909 .. 810:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_200FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_200FahrenheitOff) * 10)  
     
              809 .. 710:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_205FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_205FahrenheitOff) * 10)  
    
              709 .. 610:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_210FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_210FahrenheitOff) * 10)  
    
              609 .. 510:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_215FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_215FahrenheitOff) * 10)  
    
              509 .. 460:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_220FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_220FahrenheitOff) * 10)  
    
              459 .. 410:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_225FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_225FahrenheitOff) * 10)  
    
              409 .. 360:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_230FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_230FahrenheitOff) * 10)  
    
              359 .. 310:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_235FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_235FahrenheitOff) * 10)  
    
              309 .. 260:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_240FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_240FahrenheitOff) * 10)  
    
              259 .. 210:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_245FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_245FahrenheitOff) * 10)
                  
              209 .. 160:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_250FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_250FahrenheitOff) * 10)
                    
              159 .. 10:                                                            
                onTime := ((pwmOutputHertzToClkCycles * c_255FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_255FahrenheitOff) * 10)
    
    Or perhaps even:
    ' ...                                                                 
      getConstant                                                         
      onTime :=  ((pwmOutputHertzToClkCycles * getConstant) * 10)         
      offTime := ((pwmOutputHertzToClkCycles * (100 - getConstant)) * 10) 
    ' ...                                                                 
                                                                          
    PRI getConstant                                                       
                                                                          
      case adcTHW                                                         
        4096 .. 3350: return c_70FahrenheitOn                             
        3349 .. 3250: return c_75FahrenheitOn                             
        3249 .. 3150: return c_80FahrenheitOn                             
        3149 .. 3050: return c_85FahrenheitOn                             
        3049 .. 2950: return c_90FahrenheitOn                             
        2949 .. 2850: return c_95FahrenheitOn                             
        2849 .. 2740: return c_100FahrenheitOn                            
        2739 .. 2625: return c_105FahrenheitOn                            
        2624 .. 2530: return c_110FahrenheitOn                            
        2529 .. 2420: return c_115FahrenheitOn                            
        2419 .. 2330: return c_120FahrenheitOn                            
        2329 .. 2210: return c_125FahrenheitOn                            
        2209 .. 2120: return c_130FahrenheitOn                            
        2119 .. 2010: return c_135FahrenheitOn                            
        2009 .. 1915: return c_140FahrenheitOn                            
        1914 .. 1810: return c_145FahrenheitOn                            
        1809 .. 1715: return c_150FahrenheitOn                            
        1714 .. 1605: return c_155FahrenheitOn                            
        1604 .. 1490: return c_160FahrenheitOn                            
        1489 .. 1400: return c_165FahrenheitOn                            
        1399 .. 1300: return c_170FahrenheitOn                            
        1299 .. 1225: return c_175FahrenheitOn                            
        1224 .. 1160: return c_180FahrenheitOn                            
        1159 .. 1075: return c_185FahrenheitOn                            
        1074 .. 990:  return c_190FahrenheitOn                            
        989 .. 910:   return c_195FahrenheitOn                            
        909 .. 810:   return c_200FahrenheitOn                            
        809 .. 710:   return c_205FahrenheitOn                            
        709 .. 610:   return c_210FahrenheitOn                            
        609 .. 510:   return c_215FahrenheitOn                            
        509 .. 460:   return c_220FahrenheitOn                            
        459 .. 410:   return c_225FahrenheitOn                            
        409 .. 360:   return c_230FahrenheitOn                            
        359 .. 310:   return c_235FahrenheitOn                            
        309 .. 260:   return c_240FahrenheitOn                            
        259 .. 210:   return c_245FahrenheitOn                            
        209 .. 160:   return c_250FahrenheitOn                            
        159 .. 10:    return c_255FahrenheitOn                            
    


    Try making test programs to understand behaviors. Here's one that demonstrates the cognew / cogstop, as well as case.
    con 
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000                                          ' use 5MHz crystal
    
    var
      long  stack[20]
      long  cog
      
    obj             
      fds : "fullduplexserial"                                       ' use Parallax Serial Terminal
    
    pub main   
    
      fds.start(31,30,0,115200)
      waitcnt(cnt + clkfreq)
      cog := -1
      fds.tx($00)
      
      repeat
        if (ina[0] == 1)
          if cog == -1
            cog := cognew(newcog, @stack)
            if cog > -1
              fds.str(string("Starting newcog",$09," cog ID = "))
              fds.dec(cog)
              fds.tx($0D)
        else
          if cog <> -1
            cogstop(cog)                              
            cog := -1
            fds.str(string("Stopping cog",$0D))
      
    pub newcog
    
      repeat
        waitcnt(cnt + clkfreq)
        fds.str(string("newcog running",$0D))
        case -1
          1 and 2 : fds.str(string("1 & 2",$0D))
          3 and 4 : fds.str(string("3 & 4",$0D))
          5 and 6 : fds.str(string("5 & 6",$0D))
          7 and 8 : fds.str(string("7 & 8",$0D))
          9 and 0 : fds.str(string("9 & 0",$0D))
    
  • StefanL38StefanL38 Posts: 2,292
    edited 2014-11-02 14:45
    Hi Brad,

    I have an additional question: how did you recognize the code is hanging?

    did you wait for at least 54 seconds if the code was hanging? if it starts working it's a "cnt-has-ran-ahead-problem"

    This means WaitCnt stops the cog completely until the expression-value matches the actual cnt-value. if cnt as already ahead of the expression
    it will take 54 seconds until the next match.

    There is a minimum of 385 clockticks which SPIN needs to evaluate an expression lime

    ClockTicks := ...
    WaitCnt ( ClockTicks + cnt)

    if ClockTicks is smaller than 385 the WaitCnt waits 54 seconds.

    If you have more code between calculating ClockTicks and the WaitCnt-Command the minimum is higher.
    So did you check if the value of ClockTicks in your code is always high enough?

    To avoid resetting you would have to disconnect the RTS or the DSR-line. But when disconnected you could not download new code into the Propeller-Chips RAM nor the EEPROM
    downloading code requires a reset.

    Some of the calculations you coded are wrong

    example your old code was
    pwmOutputHertzToClkCycles := (f.fdiv(f.ffloat(clkfreq), 2.45)) ' clkfreq / 2.45 = 32653061
    

    the new code must come to the same result which is achieved through multiplying 2.45 with 100 to get the same digits without digits behind floating point
    2.45 * 100 = 245

    So a division by 245 instead of 2.45 leads to a result that is 100time smaller than by dividing with 2.45
    so after dividing by 245 there must be a multiply by 100

    ClkFreq is usually 80.000.000
    So 80.000.000 / 2.45 = 32653061

    and the same result if you calculate
    80.000.000 / 245 * 100 = 32653061

    actually your new code does

    80.000.000 / 245 / 10 = 32653

    this result is 1000 times smaller than it should be

    best regards
    Stefan
  • turbosupraturbosupra Posts: 1,088
    edited 2014-11-02 19:19
    I did not know that, thanks for that heads up. The method way looks very applicable.

    I will play around with the test programs, as I want to feel confident in using those built in commands correctly.


    ChrisGadd wrote: »
    From what I can tell, the cognew / cogstop works fine.

    I suspect the problem is in your case statement:
      if (adcTHW <> 0)                                                           
        if (adcTHWBlock == false)                                                
          [b]case -1[/b]
            ((adcTHW < 4096) AND (adcTHW => 3350) AND (adcTHWBlock == false)):   
              onTime := ((pwmOutputHertzToClkCycles * c_70FahrenheitOn) * 10)    
              offTime := ((pwmOutputHertzToClkCycles * c_70FahrenheitOff) * 10)  
                                                                                 
            ((adcTHW < 3350) AND (adcTHW => 3250) AND (adcTHWBlock == false)):   
              onTime := ((pwmOutputHertzToClkCycles * c_75FahrenheitOn) * 10)    
              offTime := ((pwmOutputHertzToClkCycles * c_75FahrenheitOff) * 10)  
    
    Case -1 is evaluating every one of your expressions as true.

    Perhaps something along the lines of:
          if adcTHWBlock == false
            case adcTHW
              4096 .. 3350:
                                    ' (((32653        *       99) = 3232647) * 10) = 32326470
                onTime := ((pwmOutputHertzToClkCycles * c_70FahrenheitOn) * 10)
                                    ' (((32653          *     1) = 32653) * 10) = 326530  
                offTime := ((pwmOutputHertzToClkCycles * c_70FahrenheitOff) * 10)
    
              3349 .. 3250:
                                    ' (((32653          *     98) = 3199994) * 10) = 31999940 
                onTime := ((pwmOutputHertzToClkCycles * c_75FahrenheitOn) * 10)
                                    ' (((32653          *     2) = 65306) * 10) = 653060
                offTime := ((pwmOutputHertzToClkCycles * c_75FahrenheitOff) * 10)
    
              3249 .. 3150:
                onTime := ((pwmOutputHertzToClkCycles * c_80FahrenheitOn) * 10)    
                offTime := ((pwmOutputHertzToClkCycles * c_80FahrenheitOff) * 10)
                  
              3149 .. 3050:
                onTime := ((pwmOutputHertzToClkCycles * c_85FahrenheitOn) * 10)    
                offTime := ((pwmOutputHertzToClkCycles * c_85FahrenheitOff) * 10)
    
              3049 .. 2950:                                  
                onTime := ((pwmOutputHertzToClkCycles * c_90FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_90FahrenheitOff) * 10)
    
              2949 .. 2850:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_95FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_95FahrenheitOff) * 10)
    
              2849 .. 2740:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_100FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_100FahrenheitOff) * 10)
    
              2739 .. 2625:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_105FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_105FahrenheitOff) * 10)  
    
              2624 .. 2530:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_110FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_110FahrenheitOff) * 10)
                  
              2529 .. 2420:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_115FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_115FahrenheitOff) * 10)
                  
              2419 .. 2330:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_120FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_120FahrenheitOff) * 10)
                  
              2329 .. 2210:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_125FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_125FahrenheitOff) * 10)
                  
              2209 .. 2120:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_130FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_130FahrenheitOff) * 10)  
     
              2119 .. 2010:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_135FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_135FahrenheitOff) * 10)  
                  
              2009 .. 1915:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_140FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_140FahrenheitOff) * 10)  
    
              1914 .. 1810:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_145FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_145FahrenheitOff) * 10)  
    
              1809 .. 1715:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_150FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_150FahrenheitOff) * 10)  
    
              1714 .. 1605:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_155FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_155FahrenheitOff) * 10)  
                                                                            
              1604 .. 1490:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_160FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_160FahrenheitOff) * 10)  
    
              1489 .. 1400:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_165FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_165FahrenheitOff) * 10)  
    
              1399 .. 1300:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_170FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_170FahrenheitOff) * 10)  
    
              1299 .. 1225:                                                             
                  onTime := ((pwmOutputHertzToClkCycles * c_175FahrenheitOn) * 10)  
                  offTime := ((pwmOutputHertzToClkCycles * c_175FahrenheitOff) * 10)  
    
              1224 .. 1160:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_180FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_180FahrenheitOff) * 10)  
    
              1159 .. 1075:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_185FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_185FahrenheitOff) * 10)  
    
              1074 .. 990:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_190FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_190FahrenheitOff) * 10)  
    
              989 .. 910:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_195FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_195FahrenheitOff) * 10)  
    
              909 .. 810:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_200FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_200FahrenheitOff) * 10)  
     
              809 .. 710:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_205FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_205FahrenheitOff) * 10)  
    
              709 .. 610:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_210FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_210FahrenheitOff) * 10)  
    
              609 .. 510:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_215FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_215FahrenheitOff) * 10)  
    
              509 .. 460:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_220FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_220FahrenheitOff) * 10)  
    
              459 .. 410:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_225FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_225FahrenheitOff) * 10)  
    
              409 .. 360:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_230FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_230FahrenheitOff) * 10)  
    
              359 .. 310:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_235FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_235FahrenheitOff) * 10)  
    
              309 .. 260:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_240FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_240FahrenheitOff) * 10)  
    
              259 .. 210:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_245FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_245FahrenheitOff) * 10)
                  
              209 .. 160:                                                             
                onTime := ((pwmOutputHertzToClkCycles * c_250FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_250FahrenheitOff) * 10)
                    
              159 .. 10:                                                            
                onTime := ((pwmOutputHertzToClkCycles * c_255FahrenheitOn) * 10)  
                offTime := ((pwmOutputHertzToClkCycles * c_255FahrenheitOff) * 10)
    
    Or perhaps even:
    ' ...                                                                 
      getConstant                                                         
      onTime :=  ((pwmOutputHertzToClkCycles * getConstant) * 10)         
      offTime := ((pwmOutputHertzToClkCycles * (100 - getConstant)) * 10) 
    ' ...                                                                 
                                                                          
    PRI getConstant                                                       
                                                                          
      case adcTHW                                                         
        4096 .. 3350: return c_70FahrenheitOn                             
        3349 .. 3250: return c_75FahrenheitOn                             
        3249 .. 3150: return c_80FahrenheitOn                             
        3149 .. 3050: return c_85FahrenheitOn                             
        3049 .. 2950: return c_90FahrenheitOn                             
        2949 .. 2850: return c_95FahrenheitOn                             
        2849 .. 2740: return c_100FahrenheitOn                            
        2739 .. 2625: return c_105FahrenheitOn                            
        2624 .. 2530: return c_110FahrenheitOn                            
        2529 .. 2420: return c_115FahrenheitOn                            
        2419 .. 2330: return c_120FahrenheitOn                            
        2329 .. 2210: return c_125FahrenheitOn                            
        2209 .. 2120: return c_130FahrenheitOn                            
        2119 .. 2010: return c_135FahrenheitOn                            
        2009 .. 1915: return c_140FahrenheitOn                            
        1914 .. 1810: return c_145FahrenheitOn                            
        1809 .. 1715: return c_150FahrenheitOn                            
        1714 .. 1605: return c_155FahrenheitOn                            
        1604 .. 1490: return c_160FahrenheitOn                            
        1489 .. 1400: return c_165FahrenheitOn                            
        1399 .. 1300: return c_170FahrenheitOn                            
        1299 .. 1225: return c_175FahrenheitOn                            
        1224 .. 1160: return c_180FahrenheitOn                            
        1159 .. 1075: return c_185FahrenheitOn                            
        1074 .. 990:  return c_190FahrenheitOn                            
        989 .. 910:   return c_195FahrenheitOn                            
        909 .. 810:   return c_200FahrenheitOn                            
        809 .. 710:   return c_205FahrenheitOn                            
        709 .. 610:   return c_210FahrenheitOn                            
        609 .. 510:   return c_215FahrenheitOn                            
        509 .. 460:   return c_220FahrenheitOn                            
        459 .. 410:   return c_225FahrenheitOn                            
        409 .. 360:   return c_230FahrenheitOn                            
        359 .. 310:   return c_235FahrenheitOn                            
        309 .. 260:   return c_240FahrenheitOn                            
        259 .. 210:   return c_245FahrenheitOn                            
        209 .. 160:   return c_250FahrenheitOn                            
        159 .. 10:    return c_255FahrenheitOn                            
    


    Try making test programs to understand behaviors. Here's one that demonstrates the cognew / cogstop, as well as case.
    con 
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000                                          ' use 5MHz crystal
    
    var
      long  stack[20]
      long  cog
      
    obj             
      fds : "fullduplexserial"                                       ' use Parallax Serial Terminal
    
    pub main   
    
      fds.start(31,30,0,115200)
      waitcnt(cnt + clkfreq)
      cog := -1
      fds.tx($00)
      
      repeat
        if (ina[0] == 1)
          if cog == -1
            cog := cognew(newcog, @stack)
            if cog > -1
              fds.str(string("Starting newcog",$09," cog ID = "))
              fds.dec(cog)
              fds.tx($0D)
        else
          if cog <> -1
            cogstop(cog)                              
            cog := -1
            fds.str(string("Stopping cog",$0D))
      
    pub newcog
    
      repeat
        waitcnt(cnt + clkfreq)
        fds.str(string("newcog running",$0D))
        case -1
          1 and 2 : fds.str(string("1 & 2",$0D))
          3 and 4 : fds.str(string("3 & 4",$0D))
          5 and 6 : fds.str(string("5 & 6",$0D))
          7 and 8 : fds.str(string("7 & 8",$0D))
          9 and 0 : fds.str(string("9 & 0",$0D))
    
  • turbosupraturbosupra Posts: 1,088
    edited 2014-11-02 19:26
    Hi Stefan,

    I did wait 54 seconds and watched on the scope for an output signal. Nothing happened, so I waited a few more minutes, still nothing. I've had that timing issue bite me too many times before not to try that.

    The low power waitcnt has always been waitcnt(clkfreq + cnt) so it loops once a second.

    I may put switches on those pins if I need to continue troubleshooting this, but since I simplified the program and removed the round object and the float object, it has been working properly today. I want to continue to test it for a few more days before I can say with confidence that it is not hanging anymore, and then hopefully try and identify why it was hanging so that I can learn from this.

    The reason I made it 1000 times smaller is because it then simplifies that piece of code and it simplifies the case variables
           ' (((32653          *     99) = 3232647) * 10) = 32326470
                  onTime := ((pwmOutputHertzToClkCycles * c_70FahrenheitOn) * 10)
    

    The above value is 1000 times bigger than it was because c_70FahrenheitOn would be 99 instead of .99 and then I multiply it by 10 in the end, so it's a wash. This allowed me to cut down on the number of math operations by 2 or 3 and kept me from going over signed int roll over (2^31) so that is why I did it that way. If there is a better way, I'd love to learn it.


    StefanL38 wrote: »
    Hi Brad,

    I have an additional question: how did you recognize the code is hanging?

    did you wait for at least 54 seconds if the code was hanging? if it starts working it's a "cnt-has-ran-ahead-problem"

    This means WaitCnt stops the cog completely until the expression-value matches the actual cnt-value. if cnt as already ahead of the expression
    it will take 54 seconds until the next match.

    There is a minimum of 385 clockticks which SPIN needs to evaluate an expression lime

    ClockTicks := ...
    WaitCnt ( ClockTicks + cnt)

    if ClockTicks is smaller than 385 the WaitCnt waits 54 seconds.

    If you have more code between calculating ClockTicks and the WaitCnt-Command the minimum is higher.
    So did you check if the value of ClockTicks in your code is always high enough?

    To avoid resetting you would have to disconnect the RTS or the DSR-line. But when disconnected you could not download new code into the Propeller-Chips RAM nor the EEPROM
    downloading code requires a reset.

    Some of the calculations you coded are wrong

    example your old code was
    pwmOutputHertzToClkCycles := (f.fdiv(f.ffloat(clkfreq), 2.45)) ' clkfreq / 2.45 = 32653061
    

    the new code must come to the same result which is achieved through multiplying 2.45 with 100 to get the same digits without digits behind floating point
    2.45 * 100 = 245

    So a division by 245 instead of 2.45 leads to a result that is 100time smaller than by dividing with 2.45
    so after dividing by 245 there must be a multiply by 100

    ClkFreq is usually 80.000.000
    So 80.000.000 / 2.45 = 32653061

    and the same result if you calculate
    80.000.000 / 245 * 100 = 32653061

    actually your new code does

    80.000.000 / 245 / 10 = 32653

    this result is 1000 times smaller than it should be

    best regards
    Stefan
  • StefanL38StefanL38 Posts: 2,292
    edited 2014-11-03 07:48
    Hi Brad,

    I was asking in the forum for code that could be used as "set and forget" pwm-dutycycle.

    There was a very quick answer and I tested the code.
    I modified it that it works with a frequency of 2.42 Hz

    The modifying is somehow quick and dirty but works

    The 0-100% dutycycle-version needs a cog but all you have to do

    if you want to change the dutycycle-percentage is

    a single call of method "PWMctrx3(pwmpin,testfreq,DutyPercentage)"

    So all the hassle about how to switch on/off the pwm-pin is over

    see democode attached

    best regards

    Stefan

    additional comment:

    this is an example how giving an overview leads to a better/easier solution.
    If you have a viewing-point on a higher level you can see the "easy to go path" that was hidden behind the "Am I using cogstop correct" bushes

    That's the reason why I'm almost everytime asking for an overview = what do you want do do in the end?
  • turbosupraturbosupra Posts: 1,088
    edited 2014-11-03 11:47
    Hi Stefan. The additional comment is noted. I can't wait to try this out when I get home, thank you.
Sign In or Register to comment.