Shop OBEX P1 Docs P2 Docs Learn Events
Touble with Multiple Cogs — Parallax Forums

Touble with Multiple Cogs

heathclfheathclf Posts: 43
edited 2008-11-05 13:46 in Propeller 1
I'm pretty much at my wits end on this one. Let me start by first stating that I am not, by any means a great coder. I'm not bad, and I do enjoy it, but I generally program in order to accomplish something. Right now, I'm having quite a bit of trouble working with multiple cogs. I have gotten them to work for me before, but I think it was beginner's luck, as I am not even sure where my problem lies right now.

Before I state my problem, here's my code, after CON. Sorry to past in VAR and OBJ stuff, but, like I said, I have NO idea where my problem lies. There is more code in the first method, but for the purposes of trouble shooting, it is commented out (and so not shown), and I'm still having trouble:

VAR
byte Factor, LED, rampUp_Coeff, rampDown_Coeff, count, LED_CountDown, stack[noparse][[/noparse]30], servoRampDelay, countDown_flag, inPin, chair

OBJ
Servo : "SingleServoPulse"

PUB main | servoPin, HT, LT, totalTime, maxHigh, MinHigh, peakTime, CntNow, delayCount

countDown_flag := 0
servoPin := 29 ''Which pin Feeds the servo a pulse
LED := 31
totalTime := 20000*80 ''Period of waveform -> 20,000 clock cycles * 80 @ 80MHz = 20ms
rampUp_Coeff := 1
rampDown_Coeff := 10
servoRampDelay := 2
count := 0
inPin := 16
Factor := 1

dira[noparse][[/noparse]servoPin]~~ ''Output Pins
dira[noparse][[/noparse]inPin]~ ''Input Pins
dira[noparse][[/noparse]LED]~~ ''Flashes as a warning

maxHigh := 1200*80
minHigh := 975*80

HT := minHigh ''Amount of Time pulse remains high
LT := totalTime - HT

cognew(LED_Warning, @stack[noparse][[/noparse]0])


PUB LED_Warning

repeat
!outa[noparse][[/noparse]LED]
waitcnt(cnt + 80_000_000)

Just to see if LED_Warning was even coming on, I varied it from what you see above to "outa[noparse][[/noparse]LED]~~", and "outa[noparse][[/noparse]LED]~". It doesn't even execute, evidenced by the LED not acting as it should. What is also very strange is that when I change certain variables, that aren't even used (do to commenting out), my LED will change whether it stays on or off. I.e. if servoRampDelay is 1, and Factor is 2, the LED will come on and stay on. If ServoRampDelay is 1 and Factor is 1, or commented out, my LED will come on for a second (I believe just bc it is pin 31 during programming), but will then turn off immediately.

I'd like to use more than one cog for this, mostly for a learning experience, but also for ease of coding. I believe I've already gotten around it using 1 cog, but it's such a depresssing solution when you have 8! cogs to work with.

Is this a stack problem? I don't see why, as I'm only using Cogs 0 and 1.

Thanks to all you guru's.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-11-03 18:52
    Repeat after me ...

    1) Every cog has its own DIRA register.

    2) When a cog is used to output to an I/O pin, that cog's DIRA register has to enable the I/O pin as an output

    3) When COGNEW / COGINIT is used to start a new cog, that cog's registers are initially zero.

    4) Only code actually running in a cog can affect that cog's registers.
    No other cog can do it (with the exception of the PAR register which only applies to assembly code).
  • BEEPBEEP Posts: 58
    edited 2008-11-03 19:25
    VAR
      byte LED
      long  stack[noparse][[/noparse]30]   '<----------------------------------!!!
    
    PUB main
    
      LED := 31
      cognew(LED_Warning, @stack[noparse][[/noparse]0])
    
    
    PUB LED_Warning
    
      dira[noparse][[/noparse]LED]~~       '<----------------------------------!!!
      repeat
        !outa[noparse][[/noparse]LED]
        waitcnt(cnt + 80_000_000)
    
    
  • heathclfheathclf Posts: 43
    edited 2008-11-04 23:12
    Mike, thanks man. You've helped me before as well.

    BEEP, nothing points the way, quite like an arrow.

    Much gratitude.

    I now have another problem, which will hopefully be just as easy (for someone). I'm very nearly close to done with my program, and what I thought would be very simple, has me stumped. It's a small routine that it supposed to computer RPM's. Here's the code (w/o the debug code), and a short explanation.

    The idea is that a magnet turns a relay on / off. So I have two repeat loops that hold the logic where it is, until both the on and off states have been met. A single pass through the logic is 2 revolutions. After 10 revolutions through the code, I'd like to calculate output the average rpms (which is not exactly as shown, I moved it for debug purposes), in order to lessen error due to calculations.

    Something I noticed was that (cnt - T) was giving me strange, sometimes negative numbers. My RPMs were ~5 to 10 while testing, but the numbers I was getting out were ludicrous.

    Thanks in advance for any help offered.

    
    VAR
      byte inPin, rep
      long rpms, T, outPin
    
    PUB main
    
      rep       := 0
      rpms     := 0
    
      dira[noparse][[/noparse]inPin]~
      dira[noparse][[/noparse]outPin]~~
    
      T := cnt
    
      repeat
        repeat while ina[noparse][[/noparse]inPin] == 1 
        repeat while ina[noparse][[/noparse]inPin] == 0
        rep++
        rpms := (rep * 2 * (cnt - T) / 1_333_333) '=rpm *60 / 80_000_000
        if rep > 10
          T := cnt
          rep := 0
    
    
    



    The RPM's I plan on dealing with are fairly high, I guess; ~20k-80k. It's to monitor a propeller for an RC boat. And Mike, I'm all about simpler and more accurate.

    Post Edited (heathclf) : 11/5/2008 12:28:29 AM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2008-11-04 23:48
    Remember that CNT is a 32 bit unsigned register that wraps around at 2^32-1, but it can also be considered to be a signed 32 bit register (it's all the same). This is particularly true for displays of numbers where most display routines assume that you're using signed values. It's quite possible for CNT - T to get large enough to come out negative (maybe 25-30 seconds).

    It would help to:
    1) use the [noparse][[/noparse] code] [noparse][[/noparse] /code] tags surrounding your code to maintain the indenting

    2) maybe explain a little more why you're doing what you're doing, what kind of speed range you have to deal with, etc.

    3) there's probably a simpler and more accurate way to do what you need
  • heathclfheathclf Posts: 43
    edited 2008-11-05 13:46
    Yup, there's a much better way, and Parallax discusses is in one of their Lab Counter Applications v1.0, found here:

    http://www.parallax.com/Portals/0/Downloads/docs/prod/prop/PE-Lab-Counters-Lab-v1.0.zip

    Here's the code I ripped off of page ~33 or so. It has changed slightly.

    It uses the prop's special purpose registers as a positive edge trigger. This is done automatically, so the cog is free to process something else while the detection occurs. It's pretty slick.

    
      ctrb[noparse][[/noparse]30..26] := %01010 'ctrb module to POSEDGE detector
      ctrb[noparse][[/noparse]8..0] := RPMPin
      frqb := 1 'Add 1 for each cycle
    
      repeat
        phsb~
        waitcnt(clkfreq + cnt)
        RPMs := (phsb)
    
    
    
Sign In or Register to comment.