Max lines of code, codesys CNC ?

Laurits
5 days ago
1 day ago
  • Laurits - 5 days ago

    Testing Codesys CNC.
    SMC Interpolator Throws me an error if my code surpass approximately 32000 lines of code.
    (SMC_CNC_INTERNAL_ERROR)
    What is the max lines of code SMC Interpoltor can handle ?

    I've been thinking breaking the code up into smaller sections, but that gives me a lot problems later if i want to use "Blocksearch" etc.

    I need to run approximately 2000000 lines of code.

     
  • tk096 - 2 days ago

    Hi, is it possible to attach the project and g-code?

     
  • Laurits - 2 days ago

    Hi, okay here's the project, it's a modified version of "CNC Example 10: Programming Dynamic CNC Paths", no need for G Code text file (i have also tried with G code text file, same problem)

    in "PROGRAM PLC_PRG" you can set bStart to true, and the program should start running, go to "PROGRAM CNC" and you can see axis moving.
    lrXpos := IoConfig_Globals.XAixs.fSetPosition;
    lrYpos := IoConfig_Globals.YAxis.fSetPosition;

    Now you can can change the number of movements in the the "PROGRAM PLC_PRG"

    From this number of movements in "program PLC_PRG"
    BUF : ARRAY[0..32010] OF SMC_GEOINFO;
    xp : ARRAY[1..32000] OF REAL;
    yp : ARRAY[1..32000] OF REAL;

    to this number to this number of movements
    BUF : ARRAY[0..132010] OF SMC_GEOINFO;
    xp : ARRAY[1..132000] OF REAL;
    yp : ARRAY[1..132000] OF REAL;

    Now if you start the program again you should see an error in the "sMC_Interpolator: SM3_CNC.SMC_Interpolator;" function block

    Let me know if you can not get it running.

     
  • tk096 - 1 day ago

    Hi, this is a bug in CODESYS Softmotion. Due to this bug the size is limited to a maximum of 32767 elements.
    However, we recommend to use way smaller buffer sizes.
    You could use a small buffer (it should be big enough so that it does not run empty when the interpolator processes the elements). In the beginning you fill the buffer in PLC_PRG until it is full. Afterwards, you start the interpolator. The interpolator processes the elements and removes them as soon as it travels past them. In PLC_PRG you check whether new elements can be stored in the buffer (NOT QUEUE.bFull). If the buffer has space, you generate the next elements and add them to the buffer (SMC_AppendObj()).

    I hope this helps you.

     
  • Laurits - 1 day ago

    Hi, yes now its working, to get "QUEUE.bFull" to work, I've had to set the "QUEUE.nNumReservedEntries" to 3. (I tried different values here, only effect for larger values i can see is the the queue capacity gets smaller.)

    I've noticed the movement is slowing down when it reaches the end of the "fill Up", must be because of the "checkVelocity" can only see the current "QUEUE".
    Any way of solving this ?

        BUF : ARRAY[0..20000] OF SMC_GEOINFO;
        xp : ARRAY[1..100000] OF REAL;  
        yp : ARRAY[1..100000] OF REAL;
    
    
    
    
    
    
    
    
        CASE iState OF 
            000:                    
                IF R_TRIG_bStart.Q THEN 
                    iState := iState + 1;
                END_IF
                bReady := FALSE;
    
                //initialize Queue
                GEO.dT1:=0;
                GEO.dT2:=1;
                GEO.dToolRadius := 0;
                GEO.dVel := 15000;
                GEO.dVelEnd := 15000;
                GEO.dAccel := 2000;
                GEO.dDecel := 2000;
                GEO.iObjNo := 0;
                GEO.piDestPos.dX := 0;
                GEO.piDestPos.dY := 0;
                QUEUE.bEndOfList := FALSE;      
                QUEUE.nPastMarker := -1;
                QUEUE.nWritePos := 0;
                QUEUE.pbyBuffer := ADR(BUF[0]);
                n := 0;
                sMC_CheckVelocities(bExecute:= FALSE);
                SM3_CNC.SMC_SetQueueCapacity(ADR(QUEUE), SIZEOF(BUF));
                QUEUE.nNumReservedEntries := 3;
    
            001:            
                FOR i := 1 TO SIZEOF(xp)/SIZEOF(xp[1]) DO 
                    xp[i] := UDINT_TO_REAL(i) * 0.01;
                    yp[i] := UDINT_TO_REAL(i) * 0.01;   
                END_FOR
                iState := iState + 1;
    
            002:        
                WHILE NOT QUEUE.bFull DO                    // when the Queue is full, wait until it has been processed by the following FBs
                    n := n + 1;
                    GEO.iSourceLine_No := n;    
                    GEO.piStartPos := GEO.piDestPos;        // copy last destination 
                    GEO.iMoveType := LIN;                   // generate linear movement 
                    GEO.iObjNo := GEO.iObjNo + 1;           // calculate number 
                    GEO.piDestPos.dX := xp[n];              // generate position 
                    GEO.piDestPos.dY := yp[n];
                    SMC_CalcLengthGeo(pg := ADR(GEO));      // calculate length of object with the help of the standard function
                    SMC_AppendObj(poq:=ADR(QUEUE), pgi:=ADR(GEO));  //append object to queue 
                    IF n = UDINT_TO_DINT( SIZEOF(xp)/SIZEOF(xp[1])) THEN    // all target positions processed                                   
                        QUEUE.bEndOfList := TRUE;                       
                        iState := iState + 1;
                        EXIT;
                    END_IF
    
                END_WHILE
                sMC_CheckVelocities(bExecute:= TRUE, poqDataIn:= ADR(QUEUE));   
    
                bReady := TRUE; // Send message to smc_interpolator to start 
    
            003:
    
     

    Last edit: Laurits 15 hours ago

Log in to post a comment.