Shop OBEX P1 Docs P2 Docs Learn Events
Interesting Problem..... — Parallax Forums

Interesting Problem.....

jknightandkarrjknightandkarr Posts: 234
edited 2010-03-13 22:24 in Propeller 1
www.newarkknights.net/myprog%20orig.zip
www.newarkknights.net/myprog%20mod.zip

First off here's my program, the original, functioning normally, the 2nd is slightly different to allow me to change the freq of my tones, which isn't working like it should

P0-11 connected to PPDB's blue leds, 0-11
P12-19 connected to 8 red leds in breadboard
P20 & 21 connected to PPDB's pushbuttons. Buttons 4 & 8 to be exact
P27 connected to a Piezo Speaker then to Ground,

The original program, functions as it should. The red leds scan back & forth, blue all light up in sequence with a tone before each led lights up. The modified program, the Blue leds function as written. I only adjusted those leds btw. The Red led's scan at an increadably slow pace, like one change every 60 seconds or something. This program was already done as desired & I didn't touch it. So why is it going real slow over the changes in the program for the blue leds w/tones when they are run in different cogs??? I reprogramed the original program back in & starts to work normal again, but once the new program is once again written, the red leds don't work as expected. I've tried looking the programs over & notice no problems that should cause it. I had this same problem when writing the original program, once i added the blue leds in cog 2 for the first time, but after some adjustment worked, but this time I don't get it. What is the issue here? Makes no sence to me.

Joe

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I'm going insaine. It's SOOOOOO much fun. lol

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-03-11 05:56
    Any time a program runs with an extra delay of about a minute, there's probably a problem with a WAITCNT where the system clock value is missed and the system clock has to wrap around (32 bits) before the program continues. I'm guessing that, if divide becomes zero, then clkfreq/divide may result in zero and each of the "waitcnt(clkfreq/divide+cnt) will actually take about 50-55 seconds with an 80MHz system clock.

    I know you've got a floor and ceiling on the divide value. It would be possible for one divide value to be zero if one of the WAITCNTs fetches the divide value between the time that the "divide--" is done and the "divide #>= 1" is done. That can happen, but only occasionally.

    Post Edited (Mike Green) : 3/11/2010 6:05:00 AM GMT
  • jknightandkarrjknightandkarr Posts: 234
    edited 2010-03-11 06:33
    What's the best way to avoid/fix it? I've reuploaded the program a few times, tried resets, adjusting the low limit & the divide value, nothing changes the resulting problem.

    Joe

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I'm going insaine. It's SOOOOOO much fun. lol

    Post Edited (jknightandkarr) : 3/11/2010 7:13:55 AM GMT
  • jknightandkarrjknightandkarr Posts: 234
    edited 2010-03-11 18:50
    Well after replacing all my divide vars with a numerical value, the red leds started to funtion correctly, so the problem is definatly the divide vars, but I can't figure out how to get it to function once again.

    Joe

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I'm going insaine. It's SOOOOOO much fun. lol
  • StefanL38StefanL38 Posts: 2,292
    edited 2010-03-11 19:38
    Hello Joe,


    the lower limit for a waitcnt in spin is 385
    any value lower will result in waiting for 55 seconds until the counter matches the missed value again

    so before executing the waitcnt you have to code something like this

      Delay := Var1 / divider
      if Delay < 385
        Delay := 385 
    
      waitcnt(Delay + cnt)
    
    



    best regards

    Stefan
  • jknightandkarrjknightandkarr Posts: 234
    edited 2010-03-11 19:52
    StefanL38 said...
    Hello Joe,


    the lower limit for a waitcnt in spin is 385
    any value lower will result in waiting for 55 seconds until the counter matches the missed value again

    so before executing the waitcnt you have to code something like this

      Delay := Var1 / divider
      if Delay < 385
        Delay := 385 
    
      waitcnt(Delay + cnt)
    
    



    best regards

    Stefan

    Ok. I'll try that. The code i'm using is from the Propeller Education Kit Labs book. Ch 4 I/O & Timing Basics, pg 60. What I don't get is my original program works just fine, but after some mods with another method, an error in anothert shows up.

    Joe

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I'm going insaine. It's SOOOOOO much fun. lol
  • Mike GreenMike Green Posts: 23,101
    edited 2010-03-11 20:03
    1) You can accomplish the same thing with "Delay := (Var1 / divider) #> 385"

    2) When you have a program that works until mods are added, look to the mods and what they do in order to figure out why. It may be timing. If you're using more than one processor (cog), the mods may shift the timing of execution in one cog relative to the other. Maybe there's a problem with a shared value. Who knows?
  • jknightandkarrjknightandkarr Posts: 234
    edited 2010-03-12 04:34
    www.newarkknights.net/MOV04064.MPG

    I had a request for a video of the problem working, so here it it. Meanwhile I'm going to continue to try & figure out the issue.

    Joe

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I'm going insaine. It's SOOOOOO much fun. lol
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-03-12 07:22
    I think the problem is already there in the original version. From my point of view the lines

         elseif ina[noparse][[/noparse]21]==0
              divide--
              divide#>=1
    
    

    are causing the trouble. Remember, you started another COG which uses divide to calculate a waitcnt-value BUUUUT ... divide-- can set divide to 0. If timing is changed between your input-loop and the scanner it can happen that the scanner picks the value just in that moment and before divide#>=1 can set it back to a meaningfull value.

    2 solutions:
    1. Use locks to access the variable - would just make a good training
    2. Use another local variable and do the -- / #>1 with this variable. Then you copy the end-result into divide

    PS: another solution:
    3. let the min-value of divide be 2, then the worst that can happen is that the scanner picks a 1 before the value get's corrected to 2

    Yes ... this was indeed an interesting problem, as the modification did not do much, it only changed the timing to make the error visible.

    PPS:
    · cognew (Scanner, @stack0)
    · divide:=5

    You should also move divide:=5 before cognew, because scanner is using divide. This is not really a problem, as cognew needs much longer to load the spin interpreter, but who knows what changes come next. If you put some code in between cognew and divide:=5 this might become a problem.

    Post Edited (MagIO2) : 3/12/2010 7:31:56 AM GMT
  • jknightandkarrjknightandkarr Posts: 234
    edited 2010-03-12 17:39
    Thanks, I'll trey that.

    Joe

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I'm going insaine. It's SOOOOOO much fun. lol
  • jknightandkarrjknightandkarr Posts: 234
    edited 2010-03-13 02:38
    Mike Green said...
    1) You can accomplish the same thing with "Delay := (Var1 / divider) #> 385"


    Can this line be explained alittle more, specifically what would Var1 represent? The clkfreq? I've tried EVERYthing everyone has suggested, (not including the locks one, I'm not sure what they are), including modifying my Pub surveilance to send only the desired freq to tones.spin & my duration & pin be included in there instead, as well as moving things around in the Pub start & Pub scanner areas, so far NOTHING fixes my issue, the only thing that does is something like going from "waitcnt(clkfreq/divide+cnt)" to something like "waitcnt(clkfreq/10+cnt)".

    Joe

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I'm going insaine. It's SOOOOOO much fun. lol

    Post Edited (jknightandkarr) : 3/13/2010 2:45:27 AM GMT
  • jknightandkarrjknightandkarr Posts: 234
    edited 2010-03-13 03:21
    I JUST now found the exact problem & have solved it. I had to merge both spin files togeather to get my program to work as desired. Why this caused the issue I'm not totally sure, the only thing I can figure is maybe was just too much for the Propeller. That's only a guess though, but I still would like to know more about the

    Delay := (Var1 / divider) #> 385

    and

    Delay := Var1 / divider
      if Delay < 385
        Delay := 385 
    
      waitcnt(Delay + cnt)
    


    code lines for future referance. Thank you to all who tried to help me solve this one!!

    Joe

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I'm going insaine. It's SOOOOOO much fun. lol
  • StefanL38StefanL38 Posts: 2,292
    edited 2010-03-13 11:37
    Hello Joe,

    opening the pdf-manual and do a search for a keyword is always a worth a try

    so searching for "#>" leads you to page 43 telling

    #> --or-- #>= Limit minimum (signed); p 155.

    Limit Minimum ‘#>’, ‘#>=’
    The Limit Minimum operator compares two values and returns the highest value. Limit
    Minimum can be used in both variable and constant expressions. Example:
    X := Y - 5 #> 100

    The above example subtracts 5 from Y and limits the result to a minimum value to 100. If Y is
    120 then 120 – 5 = 115; it is greater than 100 so X is set to 115. If Y is 102 then 102 – 5 = 97;
    it is less than 100 so X is set to 100 instead.

    As you aksed to explain Var1 more.

    It will be MUCH EASIER for you to understand what var1 stands for if YOU post YOUR code containing the waitcnt-commands
    Than I can adapt my explanation to YOUR code

    If you tried almost everything and nothing worked it is REALLY time to attache your code to a posting.
    ANY other way is guessing around in the fog moving forwards as slow as a dying turtle

    best regards

    Stefan
  • jknightandkarrjknightandkarr Posts: 234
    edited 2010-03-13 17:43
    I did post it. I posted the spin files the very first thing in my original post.

    Joe

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I'm going insaine. It's SOOOOOO much fun. lol
  • StefanL38StefanL38 Posts: 2,292
    edited 2010-03-13 20:57
    So I'm sorry,

    I wasn't looking too close at the first posting

    ClkFreq is a constant.

    If the result of clkfreq/divide is smaller than 385 the command waitcnt waits for ca. 53 seconds until te counter matches the value again

    example with easy to follow values

    let's say cnt has value 1000 if the SPIN-interpreter STARTS executing the waitcnt-command
    if you do waitcnt(1010) this value is too small

    until the SPIN-interpreter REALLY executes the waitcnt-command the systemcounter is already at 1385
    so the value 1010 was run over and then the counter will count-up to 2^32 wrap around to zero and count up to 1010
    and this takes 53 seconds

    the waintcnt-command STOPs the cog COMPLETELY until the free running systemcounter matches the value (here 1010) exactly
    there is no comparing like is equal or bigger. the compariing is only is EXACT equal

    best regards

    Stefan
  • jknightandkarrjknightandkarr Posts: 234
    edited 2010-03-13 22:24
    Thanks, much appreciated. I'll attempt to use that in the future, just wish I could figure out why the program refused to work correctly untill I merged them, just so I know what to avoid in the future.

    Joe

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I'm going insaine. It's SOOOOOO much fun. lol
Sign In or Register to comment.