Shop OBEX P1 Docs P2 Docs Learn Events
program keeps locking up/crashing — Parallax Forums

program keeps locking up/crashing

laser-vectorlaser-vector Posts: 118
edited 2010-11-06 21:33 in Propeller 1
hi all,

im having a little issue where i have started 3 cogs,

two of them drive a stepper motor and are constantly reading their speed variable which is pumped into waitcnt(clkfreq/speed + cnt)

at the same time there is a serial interface (PreambleCommandIndex) that can update these variables via command input and read them back as a status screen (status command "?").

im not sure if im sharing the variables correctly as the two motor driver processes are very high priority and the serial interface is very low.

if im running the motors fast (over 500 steps per second) and i type in the command to read out the variables sometimes it will lock up and do funny things.

the code i have is kind of long, its something i just threw together in the last couple of days so its not very well commented (some comments are incomplete/false) ill fix these soon!, i can explain anything if needed:
CON
  _CLKMODE      = XTAL1 + PLL16X
  _XINFREQ      = 5_000_000                      
  highpinX       = 19
  lowpinX        = 16
  highpinY       = 23
  lowpinY        = 20
OBJ

  NUM     : "numbers"
  Debug   : "fullduplexserial" 
          
VAR
  Long DirX, DirY
  Long idx, stpIdxX, stpIdxY, stpDelay, stepspeedX, stepspeedY, stepcnt      
  Long RXbyte, Data  
  Long stack0[70], Stack1[50], Stack2[50]   
  Long LimitMaxX, LimitMaxY
  byte Estop
  Long AsciiNumbers
  Long PositionX, PositionY
  Long INDSpeedX, INDSpeedY, INDLimitX, INDLimitY, INDDirectionX, INDDirectionY, INDPosX, INDPosY
PUB main | c
       Num.Init                                ' initilize numbers
       Debug.Start(31, 30, 0, 9600)            ' configure serial communication
       LimitMaxX := INDLimitX := 500
       LimitMaxY := INDLimitY := 500                             
       DirX := INDDirectionX := 1
       DirY := INDDirectionY := 1
       StepSpeedX := INDSpeedX := -1
       StepSpeedY := INDSpeedY := -1
       PositionX  := INDPosX := 0
       PositionY  := INDPosY := 0
       cognew(PreambleCommandIndex, @Stack0)   ' main loop to compile and distribute value of DataLong       
       cognew(StepDriverX, @stack1)      
       cognew(StepDriverY, @stack2)
       
PUB StepDriverX|T                  
             
      dira[highpinX..lowpinX]~~              
      repeat       
        repeat while EStop == False and StepSpeedX => 0
          repeat while StepSpeedX == 0                                
          if DirX == 1
           StepFwdWaveX            
           waitcnt(clkfreq/StepSpeedX + cnt)                         
          if DirX == 0        
           StepRevwaveX                                      
           waitcnt(clkfreq/StepSpeedX + cnt)
        if stepspeedX == -1
          outa[highpinX..lowpinX]~
       
PUB StepDriverY|T                 
            
      dira[highpinY..lowpinY]~~              
      repeat                        
        repeat while EStop == False and StepSpeedY => 0
          repeat while StepSpeedY == 0                       
          if DirY == 1
           StepFwdWaveY           
           waitcnt(clkfreq/StepSpeedY + cnt)                         
          if DirY == 0        
           StepRevwaveY                                        
           waitcnt(clkfreq/StepSpeedY + cnt)
       if stepspeedY == -1             
         outa[highpinY..lowpinY]~
             
PUB PreambleCommandIndex | c                   '"c" is to index through the data array, "t" is the loop true/false flag                                      
       
        Repeat
          DEBUG.RXFLUSH
          WAITCNT(CLKFREQ/1000 + CNT)          ' start Main data acqusition loop, execution is now localized within this loop only         
          RXbyte := Debug.RXcheck              ' setting rxbyte to the value in rxcheck's serial buffer
          Case RXbyte
            "O" :
              Debug.Str(String("O"))
              
            "?" :
              debug.tx($00)             
              debug.tx($0d)             
              Debug.Str(String("************SYSTEM INFORMATION************"))
              debug.tx($0d)
              debug.tx($0d)
              Debug.Str(String("GLOBAL SETTINGS"))
              debug.tx($0d)
              Debug.Str(String("E Stop Status: "))
              If Estop == 0                  
                   Debug.Str(String("FALSE"))
              ELSE
                   Debug.Str(String("TRUE"))                
              debug.tx($0d)
              debug.tx($0d)
              Debug.Str(String("CHANNEL X SETTINGS"))
              debug.tx($0d)
              Debug.Str(String("Position:             "))
              'Debug.str(num.tostr(INDPosX, num#dec))
              debug.tx($0d)
              Debug.Str(String("Maximum Speed Limit:  "))
              WAITCNT(CLKFREQ/10 + CNT) 
              Debug.str(num.tostr(INDLimitX, num#dec))
              Debug.Str(String(" Steps/Second"))                    
              debug.tx($0d)
              Debug.Str(String("Current Speed Setting:"))
              IF StepSpeedX == -1
                 Debug.Str(String(" DEACTIVATED!"))
              ELSE
                WAITCNT(CLKFREQ/10 + CNT) 
                Debug.str(num.tostr(INDSpeedX, num#dec))
                Debug.Str(String(" Steps/Second"))
              debug.tx($0d)
              Debug.Str(String("Travel Direaction:     "))
              Case DirX
                 1 :
                   Debug.Str(String("Positive"))
                 0 :  
                   Debug.Str(String("Negitive"))
               other :
                   Debug.Str(String("N/A"))                          
              debug.tx($0d)
              debug.tx($0d)
              Debug.Str(String("CHANNEL Y SETTINGS"))
              debug.tx($0d)
              Debug.Str(String("Position:             "))
              'Debug.str(num.tostr(INDPosY, num#dec))
              debug.tx($0d)
              Debug.Str(String("Maximum Speed Limit:  "))
              WAITCNT(CLKFREQ/10 + CNT) 
              Debug.str(num.tostr(INDLimitY, num#dec))
              Debug.Str(String(" Steps/Second"))                    
              debug.tx($0d)
              Debug.Str(String("Current Speed Setting:"))
              IF StepSpeedY == -1
                 Debug.Str(String(" DEACTIVATED!"))
              ELSE
                WAITCNT(CLKFREQ/10 + CNT) 
                Debug.str(num.tostr(INDSpeedY, num#dec))
                Debug.Str(String(" Steps/Second"))
              debug.tx($0d)
              Debug.Str(String("Travel Direaction:     "))
              Case DirY
                 1 :
                   Debug.Str(String("Positive"))
                 0 :  
                   Debug.Str(String("Negitive"))
               other :
                   Debug.Str(String("N/A")) 
              repeat 5
               debug.tx($0d)
             PreambleCommandIndex 
 
              
            "D" :
              Debug.Str(String("D"))
              Repeat
               RXbyte := Debug.RXcheck              ' setting rxbyte to the value in rxcheck's serial buffer
               If RXbyte => 0
                 Case RXbyte
                   "X" :
                     Debug.Str(String("X"))
                     ASCIIToNum(1)
                     INDDirectionX := AsciiNumbers <# 1
                     DirX := AsciiNumbers <# 1 
                   "Y" :
                     Debug.Str(String("Y"))
                     ASCIIToNum(1)
                     INDDirectionY := AsciiNumbers <# 1
                     DirY := AsciiNumbers <# 1                      
                   "Q" :
                     PreambleCommandIndex
                  OTHER :
                    Debug.Str(String("!"))   
                    PreambleCommandIndex
                PreambleCommandIndex           
            "L" :
              Debug.Str(String("L"))
              Repeat
               RXbyte := Debug.RXcheck              ' setting rxbyte to the value in rxcheck's serial buffer
               If RXbyte => 0
                 Case RXbyte
                   "X" :
                     Debug.Str(String("X"))
                     ASCIIToNum(4)
                     INDLimitX := AsciiNumbers 
                     LimitMaxX := AsciiNumbers 
                   "Y" :
                     Debug.Str(String("Y"))
                     ASCIIToNum(4)
                     INDLimitY := AsciiNumbers 
                     LimitMaxY := AsciiNumbers
                   "Q" :
                     PreambleCommandIndex
                  OTHER :
                    Debug.Str(String("!"))   
                    PreambleCommandIndex
                PreambleCommandIndex
                                  
            "G" :               
              Debug.Str(String("G"))
              Repeat
                RXbyte := Debug.RXcheck
                If RXbyte => 0
                  Case RXbyte
                    "X" :
                      Debug.Str(String("X"))
                      ASCIIToNum(10)
                      INDSpeedX := AsciiNumbers <# LimitMaxX   
                      StepSpeedX := AsciiNumbers <# LimitMaxX
                    "Y" :
                      Debug.Str(String("Y"))
                      ASCIIToNum(10)
                      INDSpeedY := AsciiNumbers <# LimitMaxY
                      StepSpeedY := AsciiNumbers <# LimitMaxY
                    "Q" :
                     PreambleCommandIndex   
                   OTHER :
                     Debug.Str(String("!"))                             
                     PreambleCommandIndex    
                 PreambleCommandIndex                          

            "S" :
              Debug.Str(String("S"))
              Repeat
                RXbyte := Debug.RXcheck
                If RXbyte => 0
                  Case RXbyte
                    "X" :
                      Debug.Str(String("X"))
                      INDSpeedX := -1                     
                      StepSpeedX := -1
                    "Y" :
                      Debug.Str(String("Y"))
                      INDSpeedY := -1
                      StepSpeedY := -1
                    "Q" :
                     PreambleCommandIndex   
                   OTHER :
                     Debug.Str(String("!"))                             
                     PreambleCommandIndex    
                 PreambleCommandIndex
                        
            "!" :
              Debug.Str(String("!"))
              EStop := True
              INDSpeedX := -1
              StepSpeedX := -1
              INDSpeedY := -1
              StepSpeedY := -1
              PreambleCommandIndex
                           
            "I" :
              Debug.Str(String("I"))              
              EStop := False
              PreambleCommandIndex
              
PUB ASCIIToNum(DecimalCount) | C, N 
       
        AsciiNumbers := 0
        C := 0
        data := 0                   
        Repeat         
          RXbyte := Debug.RXcheck            
          If RXbyte => 0
            case RXbyte
              "0".."9" :
                AsciiNumbers := AsciiNumbers * 10 + (RXbyte - "0")  <# 1_000_000_000                                               
              $0D   :
                c := (DecimalCount - 1)
              "Q" :                 
                PreambleCommandIndex  
             other :
               Debug.Str(String("!"))
               return                 
            if c => (DecimalCount - 1)                               
               return                     
           C++
               
PUB FormLong(bytecnt) | C                                 ' constructs an array from incoming serial data
             
        data := FALSE         
        C := 0                                            ' setup, counter reset = 0
        Repeat                                            ' then repeat this part while T flag is true                                             
          RXbyte := Debug.RXcheck                         ' retreive byte from serial buffer                                       
          If RXbyte => 0                                  ' if rxbyte is true there is a byte from the buffer in it, Go Get It!! 
             If RXbyte == $0D                             ' if a carriage return was sent          
               Repeat C From 0 To (bytecnt - 1) <# 3      ' loop while looking for false bytes in the array                                             
                If Data.byte[C] == -1                     ' if fase byte exsists
                 Data.byte[C] := 0                                                           
               Return                                     ' --> Return to caller                                 
             Data.byte[C] := RXbyte                       ' then data[array#] = serial data byte (next pass array# "c" will = + 1 )                                          
             RXbyte := -1                                 ' reset rxbyte to false, go back and loop until rxcheck's buffer passes byte to rxbyte, OR>                          
             If c == (bytecnt - 1)                        ' if the last long in Data[last-array#] is not false                                   
               Return                                     ' incriment the byte position indxer/counter
           C ++ 

{--------------------------CHANNEL Y--------------------------} 
PRI stepFwdX

  PositionX ++
  INDPosX := PositionX
  stpIdxX := ++stpIdxX // 4                    ' point to next step
  outa[highpinX..lowpinX] := XSteps[stpIdxX]                ' update outputs
  

PRI stepRevX

  PositionX --
  INDPosX := PositionX 
  stpIdxX := (stpIdxX + 3) // 4                ' point to previous step
  outa[highpinX..lowpinX] := XSteps[stpIdxX]                ' update outputs
  

PRI stepFwdWaveX

  PositionX ++
  INDPosX := PositionX 
  stpIdxX := ++stpIdxX // 4                              
  outa[highpinX..lowpinX] := XStepsW[stpIdxX]                         
  

PRI stepRevWaveX

  PositionX --
  INDPosX := PositionX 
  stpIdxX := (stpIdxX + 3) // 4                         
  outa[highpinX..lowpinX] := XStepsW[stpIdxX]                        
  

PRI HalfStepFwdX

  PositionX ++
  INDPosX := PositionX 
  stpIdxX := ++stpIdxX // 8                               
  outa[highpinX..lowpinX] := XStepsH[stpIdxX]                         
  

PRI HalfStepRevX

  PositionX --
  INDPosX := PositionX 
  stpIdxX := (stpIdxX + 7) // 8                           
  outa[highpinX..lowpinX] := XStepsH[stpIdxX]                         
    

PRI pauseX(ms) | c

  c := cnt                                   ' sync with system counter
  repeat until (ms-- == 0)                   ' repeat while time left
    waitcnt(c += clkfreq / 1000)             ' wait 1 ms
   
{--------------------------CHANNEL Y--------------------------}
PRI stepFwdY

  PositionY ++
  INDPosY := PositionY 
  stpIdxY := ++stpIdxY // 4                    ' point to next step
  outa[highpinY..lowpinY] := YSteps[stpIdxY]                ' update outputs
  

PRI stepRevY

  PositionY --
  INDPosY := PositionY
  stpIdxY := (stpIdxY + 3) // 4                ' point to previous step
  outa[highpinY..lowpinY] := YSteps[stpIdxY]                ' update outputs
  

PRI stepFwdWaveY

  PositionY ++
  INDPosY := PositionY
  stpIdxY := ++stpIdxY // 4                              
  outa[highpinY..lowpinY] := YStepsW[stpIdxY]                         
  

PRI stepRevWaveY

  PositionY --
  INDPosY := PositionY
  stpIdxY := (stpIdxY + 3) // 4                         
  outa[highpinY..lowpinY] := YStepsW[stpIdxY]                        
  

PRI HalfStepFwdY

  PositionY ++
  INDPosY := PositionY
  stpIdxY := ++stpIdxY // 8                               
  outa[highpinY..lowpinY] := YStepsH[stpIdxY]                         
  

PRI HalfStepRevY

  PositionY --
  INDPosY := PositionY
  stpIdxY := (stpIdxY + 7) // 8                           
  outa[highpinY..lowpinY] := YStepsH[stpIdxY]                         
    

PRI pauseY(ms) | c

  c := cnt                                   ' sync with system counter
  repeat until (ms-- == 0)                   ' repeat while time left
    waitcnt(c += clkfreq / 1000)             ' wait 1 ms
   
DAT

  XSteps       byte  %0011, %0110, %1100, %1001                               ' full step
  XStepsW      byte  %0001, %0010, %0100, %1000                               ' Wave
  XStepsH      byte  %0001, %0011, %0010, %0110, %0100, %1100, %1000, %1001   ' Half step
  YSteps       byte  %0011, %0110, %1100, %1001                               ' full step
  YStepsW      byte  %0001, %0010, %0100, %1000                               ' Wave
  YStepsH      byte  %0001, %0011, %0010, %0110, %0100, %1100, %1000, %1001   ' Half step

Thanks for any ideas or help!!!!!

Comments

  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2010-11-06 16:10
    laser-vector,

    My intuition makes me think that the Stack space allocated for PreambleCommandIndex is not large enough.
  • laser-vectorlaser-vector Posts: 118
    edited 2010-11-06 16:23
    That definitely made a huge difference, it used to crash after the 3rd - 5th status update.

    i made Long stack0[250], Stack1[100], Stack2[100]
    and it still crashes but its after like 30 updates!

    thanks for the help so far!!
    is there something im forgetting to clear after a status update?
  • kuronekokuroneko Posts: 3,623
    edited 2010-11-06 17:13
    is there something im forgetting to clear after a status update?

    Maybe, maybe not. But the reason for these lockups is primarily due to recursion. Worst example is PreambleCommandIndex. From within the case statement you keep calling yourself in a number of locations. That will eventually eat up your stack. You'll have to find a better way of returning to the top of the method.
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2010-11-06 21:33
    laser-vector,

    Making use of QUIT within the PreambleCommandIndex PUB instead of calling PreambleCommandIndex again will help, but it won't solve the case where the ASCIIToNum(DecimalCount) PUB calls PreambleCommandIndex
Sign In or Register to comment.