panic mode

MrPLC Admin
  • Content count

    3018
  • Joined

  • Last visited

Posts posted by panic mode


  1. if you are working on a system where product B is monitored by product A, you should have some idea about the purpose of monitoring, what is acceptable deviation and what a suitable response is when that deviation is encountered. that would dictate what values need to be exchanged between A and B. so far it is unclear why there is need for two products (seem to be an unnecessary complication).in some cases this added complexity may be intentional for the sake of redundancy. but as stated not enough is known...


  2. is that correct?
    based on test values in Time_Array[], motors with lowest age are 3 and 5. so they should be the ones started before there is a need to run motors 4,2 and 1. 

    but the last screenshot shows that both pumps 1 and 5 are on while pump 3 is off... this does not look right to me unless i misunderstood the problem or the screenshots of test data and output are not a matching set. because test data shows that pumps 1 and 5 are the largest and the smallest value. the only time both should be on is when demand is so high that all pumps need to be on. but pumps 2 and 3 are not on..

     

    1 person likes this

  3. here is one example in KRL:

    DEF bubble_sort( )
    
    ;declare arrays
    DECL REAL AGE[5] ; array of five REAL values 
    DECL INT INDEX[5] ; same size but type is INT
    
    ; declare also counters and temp variables for swap
    DECL INT i,j,tmp_int
    DECL REAL tmp_real
    
    ; populate arrays before sorting...
    AGE[1]=763.91   
    AGE[2]=8161.8
    AGE[3]=1008.9
    AGE[4]=6731.8
    AGE[5]=450.75
    
    INDEX[1]=1
    INDEX[2]=2
    INDEX[3]=3
    INDEX[4]=4
    INDEX[5]=5
    
    ; now lets sort the values by age
    
    FOR i=1 to 5
      FOR j=i+1 to 5
        IF AGE[i]>AGE[j] THEN
          ; --- swap values for age ---
          tmp_real=AGE[i]
          AGE[i]=AGE[j] 
          AGE[j]=tmp_real
          ; --- also swap value for index ---
          tmp_int=INDEX[i]
          INDEX[i]=INDEX[j]
          INDEX[j]=tmp_int
        ENDIF
      ENDFOR
    ENDFOR
    
    ; example uses runtime variables
    ; therfore halt before program end
    ; to check the values after sorting
    HALT
    
    END
    

    and here are values after sorting:

     

    sorting parallel arrays.png

    and same thing in TwinCat:

     

    sorting parallel arrays in TwinCat.png


  4. create two arrays, call them AGE[] and INDEX[]

    array AGE[] should contain age values of all motors.

    array INDEX[] should simply contain numbers 1,2,3,4,5 before sorting starts.

    then use any sort you like (bubble, insertion, whatever...). every sort algorithm also includes part where sorted values are swapped.

    so your sorter should compare values in array AGE[] as expected (so far so good).

    however (and this is the key), every time values of array AGE[] are swapped, also swap corresponding values in the array INDEX[] at the same time.

    that's it... 

     


  5. photovoltaic is right - no doubt things like this would often not be discussed if most plc programmer would simply go through instruction reference manual for the controller the are using.

    but i would also have to totally agree with Bob... since my response was not just to topic starter and this specific case (using specific CPU). i like to provide general solutions that can be applied everywhere regardless of used controller and used instruction set

    after programming various types of controllers for over 30 years, i have learned to appreciate data manipulation using basic instructions that are bound to be present on every platform  / PLC brand. i don't even recall half of product i have programmed for. btw. on this very forum there are plenty of posts where people are completely stuck and ask for help because they are in desperate need for some 'special' instruction. sadly that is not how real programming works...

    don't get me wrong, i would happily use each and every resource at my disposal but historically when writing code to be used/managed by others (usually quite inexperienced people) it is often much preferred to show how something can be done rather than just do it. that way anyone can manipulate it if needed and apply in every project regardless of instruction set at hand.

    there are many other reasons that are better left for a separate topic. 

     

      

    1 person likes this

  6. this can be implemented in just about any programming language and if you put your mind to it you can do it but ... as mentioned before it would serve no purpose in this case as it only manipulates values and looses track of index. in other words you sort the age values but lose information which of the five values corresponds to which motor. age is just the means to choose correct index so you know which motor to start next time. 

    another thing to keep in mind is execution time. and with PLCs one need to be careful using loops for that (and some other) reason(s). are you familiar with code complexity (big omega)?

    https://www.freecodecamp.org/news/big-omega-notation/

     

     


  7. i guess the goal is to simply find the smallest value when starting one of the units. so for 5 values one should not need more than 4 comparisons.

    // assume value in firt element of ARR[] is the smalest
    
    smallest_unit_number := 1;
    smallest_value := arr[smallest_unit_number];
    
    // then check if there is a smaller one. ..
    if arr[2]<arr[smallest_unit_number] then smallest_unit_number :=2;
    if arr[3]<arr[smallest_unit_number] then smallest_unit_number :=3;
    if arr[4]<arr[smallest_unit_number] then smallest_unit_number :=4;
    if arr[5]<arr[smallest_unit_number] then smallest_unit_number :=5;

    instead of "smallest" you could use "youngest", and instead of array "arr[]" use "AGE" you get something quite readable:

    youngest_motor := 1;
    youngest_age := AGE[youngest_motor];
    
    if AGE[2]<AGE[youngest_motor] then youngest_motor :=2;
    if AGE[3]<AGE[youngest_motor] then youngest_motor :=3;
    if AGE[4]<AGE[youngest_motor] then youngest_motor :=4;
    if AGE[5]<AGE[youngest_motor] then youngest_motor :=5;

    This could of course be done in a loop too, but for such short list it is not necessary


  8. why don't you post your approach and let forum comment on it? are you sure you got corred EDS version? are you sure your network settings are correct? don't say that "you checked them" - post them so we can verify for ourselves if they make sense.


  9. the short answer is no.

    i have shown you one possible path but cannot walk the path for you.

    if you want to program something, you need to learn how yourself or hire someone. at this point i am just repeating what is already stated.

    to create file like that you need to download and install RoboDK, create project, program some motions and then export as HTML.

    to replace position values with data from external server, you need to implement TCP client that connects to that server and polls current values at some interval. 

    that is not the only way to solve it, but it is the one i could have considered.

     


  10. please do not use oversized font. we can see.

    did you read my post?

    the example export contains 95% of what you ask (models, kinematics, 3D scene etc.). all the motions are stored in a lookup table/array. if you feed the live axes values instead of hardcoded array values, you can have robot move in "real" time. of course... to get there some programming is required but using something like proposed approach already solves most of the problems...

    all you need to do is create two things:

    1. server that cab returns robot joint angles when asked by some TCP client. (this will be accessed by browser)

    2. adapt HTML document so it has TCP client that can retrieve the joint values periodically and feed the values to 3D engine that is already in the exported HTML.

    another approach is to do the whole thing from scratch. there are of course other options.

    1 person likes this

  11. yup dangerous (more and more) till the end.... :-D

     

    still no clue about the exact CPU version.

    in general instructions like:

    MOV, MUL, DIV etc are 16-bit (integer)

    DMOV, DMUL, DDIV etc are 32-bit (integer)

    EMUL, EDIV etc are 32-bit (REAL)

    but....

    that is just "in general"....

    as the manual states on some CPUs DDIV could be real (see attachments).

    also the system flags  may be SM4xx but on some CPUs they are M8xxx.

    this clearly demonstrates that finding and reading correct manual is a necessary.

     

    Mitsubishi.png


  12. at least post PLC model when asking for help. this would help identify correct instruction set and documentation.

    SM402 is one of system flags (first scan, always on, always off etc.). 

    second rung creates an oscillator (OUT is normally used for controlling bits, but in this case parameter is a timer number 30). so timer keeps resetting itself. interval is set by K1 but the actual preset value depends on timer and PLC. so check manuals for your PLC to determine of this one is also 100ms timer or something else.

    K1 indicates integer 1 in decimal format. (K129 is 129)

    H1 would be the same but in hexadecimal format (H3A is 0x3A or 58)

    rest should be obvious