587,383 active members*
3,716 visitors online*
Register for free
Login
Page 3 of 3 123
Results 41 to 57 of 57
  1. #41
    Join Date
    Sep 2009
    Posts
    96
    Naming a file for the Windows os environment
    --------------------------------------------
    Sometimes you want to name a file using more than 1 word
    in the string.
    You can just go ahead and use an underscore instead of a whitespace,
    as in;
    My_new_file_name.txt

    When the program deals with command line for writing to file, Python
    uses the module, 'os.path'.
    This is fine when dealing with path addressing and Long Folder Names
    on the command line, are perfectly ok.

    But when writing to file or creating a file, if the 'string' part,
    that is for 'the file name' has a whitespace in it, the program
    sees this as the end of the command line and stops reading any further
    information on the command line.
    So the file doesn't actually get written at all.

    This little chestnut has been the root cause of many keyboard lives,
    coming to an abrupt and violent end.

    Python has a nerve soothing tool that enables the naming of files with
    the inclusion of whitespace (spacegaps) between words in the file name.
    It is;
    long_file_name

    It's used in an odd kind of way.
    You start with a variable and assign it a string;
    myfilename = 'My name is Fred.txt'
    then you can;
    long_file_name = myfilename
    When you script your command line, include long_file_name, instead of
    the variable name with the 'My name is Fred.txt' string,
    as in;
    file = open('c:/PyNC/my ncv files/'+ long_file_name ,'w')

    Just before the file is written, I included a little 'filetest'
    This is to see if there is already a file present.
    Then it's just a matter of adding a few if statements to ensure the user
    is made aware of any problem, and then if the user wants to overwrite the
    file, then the program can just go ahead and write it.
    I included an extra write command, so that if the user was just thumping
    around and forgot to name their file, a file called 'No name.ncv' is
    going to be written anyway to the 'my ncv files' folder.

    The naming function runs a while loop, so the user can have another
    crack at 'naming' without leaving the loop and having to come back in again
    from the main menu, which would be annoying.
    If any naming operation has been completed, successful is assigned 1, which
    breaks the condition of the loop and your out of there.

  2. #42
    Join Date
    Sep 2009
    Posts
    96
    Display a list of files in a directory /(DIR) /(folder)
    -------------------------------------------------------
    Now we look at the function;
    def getncvList():

    This is a very small function, but my explanation is going to hurt you
    far more than it did me, writing it.

    What we want to do here, is to print to screen a list of the files
    that may be in the folder named 'my ncv files'.

    the heading is;
    =============== THIS IS THE *.ncv FILE LIST ===============

    we start out with;
    ncvlist = os.listdir('c:\\PyNC\\my ncv files')
    this creates a list object containg the values present in the folder.
    The values are the file names.

    itemsindir = len(ncvlist)
    using 'len' tells Python to assign 'itemsindir' a number, which is the amount
    of items or 'file names' present in the list named 'ncvlist'.

    We don't want to do anything with the list if there's nothing in it,
    so;
    if itemsindir == 0:
    then print to screen 'there are no files in my ncv files folder'.
    elif, would then be ignored because it's condition will be false.
    Then it's game over, go straight back to the menu.
    ------------
    If of course there are items in the list, then the elif statement will be true.

    print 0,ncvlist[0]
    The program will begin by printing to screen the first item in the list.
    This is of course situated at position 0 in the list and it will be the
    very first file name in that list.
    But first thing on the command line was to print 0
    The program will need to find out what that is.
    The next line is;
    for i in xrange(1,len(ncvlist)):

    for... This is a looping process command word

    i... 'i' stands for 'instance' and it means;
    any item seen and it doesn't care if it is a name or a number or whatever, as
    long as it's some kind of 'thing' found in the list.

    in 'xrange'.... this is ok to use when you might have a big list. It doesn't waste
    memory space when it isn't being used. The list would be gone, when done with.
    If 'range' were used, then range will fill space with the list when it's called
    and keep it there, in case the list is needed at some other time during a program
    run. We don't want 'range'.

    After the name 'xrange' is it's tool box;
    (1,len(ncvlist)):
    The first tool is where to start and this is .. 1


    The second tool is 'len'.. this means length.
    Python gets the length which is the total number of items present in a list.

    (ncvlist)
    The third tool is the name of the actual list it will look at.

    Now let's say that the list has 6 items or 'i' for 'instances'.

    And again looking back at the line as a whole;
    for i in xrange(1,len(ncvlist)):

    In bernster speak it could be seen as;
    For every 'item' or 'thing' found, using the 'xrange' method, start by
    returning a number for the first 'thing', this number will be 0, then 1 for
    the second 'thing' and so on, until a final instance is reached that is 6, which
    is the total number of items within the list object called ncvlist.

    c=ncvlist[i]
    Now we have a simple variable called 'c' and the value is the 'list' and
    the item in that list is 'i' any instance within the list.
    So this 'i' inside the [] will actually point directly at a file's 'name'.
    And it's going to start by pointing at the first 'name' at position 0

    print i,c
    This is going to print i (the number 0) ,then c (the first file name)

    Then it's going to loop back to look at the next 'thing' 'i' in the list
    which is the next file name and print that out, preceded by the number 1.

    When 6 instances have been printed out, the loop will end by the 'len' condition
    being met.

  3. #43
    Join Date
    Sep 2009
    Posts
    96
    From def getncvList():

    which is to give us back an enumerated list of files within a folder,
    this is the sort of result you would be expected to end up with;

    0 this is a file.txt
    1 this is another file.txt
    2 this is another file.txt
    3 this is another file.txt
    4 this is another file.txt
    5 this is another file.txt

  4. #44
    Join Date
    Sep 2009
    Posts
    96
    You will find the function.... def getimportList():
    practically the same as.... def getncvList():

    getimportList(), enumerates and lists any files found in the import files folder.
    This is the folder where you would place G-code files, ready to be processed.

  5. #45
    Join Date
    Sep 2009
    Posts
    96
    We'll now move on to;
    Load values from a ncv configuration file
    -----------------------------------------
    From the main menu item '5',
    the call for 'def getncvList():' is made.
    At this point, the will be able to see the list of enumerated files,
    present in the folder 'my ncv files'.

    Then, immediately following this is the function call for;
    def userncvChoice():

    You my notice that the cls(), clear screen command is not given between
    the 2 function calls.
    The idea is to keep the list displayed to the user while the function
    userncvChoice(): is running.

    Once again in this function, we don't want the program to attempt to do
    anything at all, if the folder 'my ncv files' is empty, else the program will
    hang up on us.
    So we make a list object named 'ncvlist'.

    Then we do a quick count using 'len', for the number of items in the list.
    Now find out if the number of items is greater than 0
    if itemsindir == 0:
    then;
    elif itemsindir >0:

    For now I'll assume 'elif itemsindir >0:' equated to a 'True' condition;
    The user is now asked to select a file by typing in the number preceding a
    file name.
    The number entered by the user will be a 'string', so it is in text form.

    userchoice = raw_input("select a file to load, by it's number, then press Enter.. :")

    if userchoice.isdigit():
    All 'alpha' and 'digit' characters have a unique coded value,
    Python will simply agree or not, whether the text entered is actually a number.
    If True;
    number = int(userchoice), turn this into a real processable number
    If False, nothing is going happen at all.

    thename = ncvlist[number]
    Here, a new variable 'thename' is assigned the value of the number position
    within the list named 'ncvlist', that is the real number entered by the user.
    Below is what 'thename' would look like when in use.
    thename = ["this is a file name.txt"]
    Notice that the enumeration value is not included as part of the new list object.


    filename = str(thename) this will point to the string only, in 'thename'.
    Below is what 'filename' would look when in use, now without the [].
    filename = "this is a file name.txt"

    choice = filename

    The rest is pretty much straight forward really.

    with open('c:/PyNC/my ncv files/'+ choice ,'r') as fob:
    open the file as a file object, using 'choice', as the file name.

    loaded = fob.readlines()
    Create a variable named 'loaded' that will take on the values of the file
    object 'fob.readlines', then close the file.
    This is what will be written to file

    The next 'with open' has;
    read_data = f.read()
    f.close
    b = read_data
    cls()

    Now print to screen a message for the user.

    Finally;
    with open('c:/PyNC/program files/controlncv.prg','w') as fob:
    fob.writelines (loaded)
    fob.close()
    write the values of the variable 'loaded' to the file and close it.

    and;

    with open('c:/PyNC/program files/controlncv.prg','w') as fob:
    fob.writelines (loaded)
    fob.close()
    print b
    The variable 'b' will be printed to the screen and will appear below
    immediately below the previous message for the user.

    'controlncv.prg' and 'controlncv.prg' would now be ready for use.

  6. #46
    Join Date
    Sep 2009
    Posts
    96
    Import a G-code file
    --------------------
    def getimportList():
    As mentioned earlier the enumeration and listing of files in the folder
    named 'import files', is practically the same as def getncvList():
    The only real difference is the folder's name in the path.
    os.listdir('c:\\PyNC\\import files')

    Onward then to;
    def userimportChoice():

    Once again this is very similar to... def userncvChoice():

    Only this time the function is simpler.
    We ask the user to make a selection by number, the file name is pointed to,
    then trickled down and assigned to 'choice';

    with open('c:/PyNC/import files/'+ choice ,'r') as f:

    The file object is now created and assigned to 'loaded'

    Print a simple message to the user.

    Finally;
    with open('c:/PyNC/program files/parsefile.prg','w') as fob:
    fob.writelines (loaded)
    fob.close()

    The list 'loaded', which is equal to the entire contents of the import file,
    is written to the file named 'parsefile.prg'

    The original G-code file remains perfectly intact, in the 'import files' folder.

    'parsefile.prg' would now be ready for use.

  7. #47
    Join Date
    Sep 2009
    Posts
    96
    Before I move on to theParse():

    I want to look at a very small command that you will have seen
    'scattered', liberally throughout the entire PyNC program.
    This small command is;
    time.sleep()

    However small this little thing seems, it is EXTREMELY POWERFULL.
    It is a 'low level' command.
    Simply put;
    The program will 'wait' a specific amount of 'time', before it continues.
    This commands a 'running count' to occur.
    When you were a kid, if you've played the game 'Hide and Seek', you'll
    know that the kid who's 'it', counts to a hundred then calls out,
    "coming for you, ready or not", or something similar.
    time.sleep() is a command for a CPU running count not dissimilar to this.

    'Well', you may say, 'that ain't so powerful'.

    Here, I have to tell you,
    this is one 'MOTHER' of a command.
    It is not a 'request', as in "I want you to do this".
    It is an explicit 'DEMAND' for action.
    You 'WILL' carry this action out, 'EVEN' if it 'KILLS YOU'.
    You 'WILL', 'OBEY', without 'QUESTION'
    'IF', during the action of carrying out of this command,
    the CPU were to overheat and melt down,
    THEN THAT'S JUST GONNA HAPPEN, THERE WILL BE 'NO' ARGUMENT.
    THIS IS 'NOT', 'NEGOTIABLE' IN ANY 'WAY' OR 'FORM'.
    The 'COMMAND' is at 'ROOT' level.
    When this is given, you 'WILL' do it, end of story.

    I may command time.sleep() to carry out an action, at a speed of;
    1 second divided by 10,000.
    'DO IT' or 'KILL YOU'RE SELF TRYING'.

    If for any reason, you have some other process running on you're
    os. when this command is given, and it stands between the objective
    of the command, by it's use of the CPU, it will be pushed aside.
    The CPU 'WILL' be used to carry out this command before 'ANY' other.
    I kid you, NOT!!.
    Because of this, time.sleep() is in a way, very 'sweet' and very 'helpful'.

    At least that's what a timing count command would do using another language.
    I am not a Python 'Guru' in any way.
    My experience with Python is brief and cursory at best.
    If a real Python expert posts here to tell us that Python 'won't' let
    a CPU melt down occur, this thread could come to an abrupt end.

    The operating system 'must' be able to 'force' the CPU to do our bidding.

    I have of course run some preliminary tests with time.sleep() as to,
    pushing other running instances aside and this works just as I expect it
    should do. So far I don't see a problem.
    When I tell it to process at 4000 instances per second, it does so.
    ====================================
    DON'T PANIC ANYONE!!
    This program is NEVER going to be harming anyone's computer in any way.
    LIMITS OF OPERATION WILL BE ESTABLISHED.
    And if some computer DOES get trashed, it will be MY OWN ONLY.
    I will not post anything unless it is completely harmless.
    I've got a couple or three that could be used as suitable 'crash dummies'.
    I might even dress them up a little for the event so they can go out in style,
    instead of the just heading straight to the trash bin.
    Well, at least not while they can still close or open a logic gate anyway.
    Crikey, I'm not frakk'n heartless.
    ====================================
    It's just that the motherboard CPU, 'MUST' be able to be 'FORCED' to abide.
    Else Python, won't be suitable for the 'main directive' here, which is;
    'Build a software indexer'.

    Wouldn't you know it, I'm as blue as the sky.
    I use it, hear it, but truely, I'm not sure how to spell 'crikey' and blow me,
    if I live a 1/2 hour from Beerwah.
    ..... crikey! blokes, I've got to get out more.

  8. #48
    Join Date
    Sep 2009
    Posts
    96
    Here we arrive at;
    def theParse():

    We have come a long way to get here.

    But, I must write a few things first, before I can proceed further.

    This part of the program is 'the engine'.
    But unlike an actual solid internal combustion engine,
    this must be made fluid.

    The 'naming' of the function 'theParse', is just an example.
    This function could have any 'name' you choose and not only that,
    you can create any number of different 'Parse' like functions.
    You just script each to behave in ways that are unique to the particular
    code that you want to process.

    If you create many different functions for processing code files,
    you could simply add each one to the menu, down at the program's 'main',
    from where you would make a call() to any one of those functions.

    As for the programs that I create for myself, I write them to behave
    in many different ways.
    So I have many 'Parse' like functions.
    I also have some very large ncv configuration files and a lot of them.
    Each gives me the opportununity to process various code file types and do so
    in any way that I care to choose.
    From these, the program's output can be made to vary just slightly or
    very dramatically.
    When you have large ncv files, you don't have to set up you're raw_input flow
    in a way that you have to trawl through every single one of them, every time you
    want to make a slight but significant change.
    You can just add 1 or 2 items to you're menu so that if you're happy with
    the majority of the values you're using and you just want to change say,
    the normal Z height or the milling depth, you could just select 1 item
    and make a change to that only.
    To implement this, you're 'write the value to file' at the end of the
    raw_input can be directed only to the controlncv.prg and updatencv.prg files
    and in doing so you don't change you're 'user ncv file'.
    The program could happily continue to use the new value you just entered.
    When you want to revert to the original settings,
    you can change the 1 setting in the same way or, just reload you're original
    ncv file.

    Now, I decided on building this type of program, because I personally didn't like
    the way that some CAD programs output their G-code to be used with different
    machine indexers and often the code isn't perfectly suitable for 'Mach'.
    Let's face it, Mach doesn't appear in their config., lists anyway.
    When you want to use some code in Mach, you may often need to add code to
    be certain that Mach can give you the result you were looking for. So we see that
    Mach's really isn't at fault when it's given poor code to deal with.

    I decided that I wanted to be able to very easily and quickly
    alter;

    initializing an indexer,
    start coordinates,
    Z axis heights, depths,
    time delays,
    Z feed speeds,
    X,Y mill speeds,
    rapid G0 speeds,
    tool change positions,
    at program's end, axis coordinates.

    The programs I script using the same framework, can be told to ignore words from
    any CAD G-code, like 'F' speed words and replace them with my own from an ncv file.
    The program can dismiss entire G-code lines that don't do what I want.
    From an ncv file I may have chosen the normal Z lift height to be 2 mm.
    If the CAD code says 5 mm, the program can throw them out and replace them.

    If I don't like the way any code is given to the likes of Mach, then the
    program will obediently change the entire file to the way I have commanded
    it to do so using the values seen in a ncv file that I load.
    The program will continue to process code in the exact same way until told to
    do otherwise.
    This is just a matter of selecting a ncv file, then loading it with a keystroke.

    Code can be output by some CAD programs in a very simplistic way.
    The code is output without any Z words, feed speed words,
    start and end coordinates and no tool change coordinates.
    This is no problem at all, and actually opens the door to being able to
    have the program read hand typed code, even when it isn't well written.
    The program can identify commonly made typing errors that I often make myself,
    then correct them while it's processing the file.
    Just one of these irritating things I do is this;
    I have a bad habit of hitting the letter o key instead of the zero '0' key.
    This really is a no brainer and we don't have to be an Einstein to write a
    script to sort that puppy out.
    It's just a matter of taking note of some of the human mistakes we tend to
    often make and write a short argument for each in turn, then just toss them
    into the process flow.
    This could also open another door, as in, conversational programming.
    I haven't had a play with this yet but I may decide to do so later on.

    From the basic and very simple framework for PyNC, you can add any number of
    different;
    Program folders,
    Files,
    Menu items,
    raw_inputs,
    code line searches,
    search extractions,
    'Parse' like functions.

    The program does not have to be restricted to G-code either, as I have already
    done myself recently.
    Your code line searches can be designed to pick up practically any NC words.
    You could have differing groups of search functions within separate functions.
    Meaning you can have many different scenarios for searching code lines.

    You can design your 'parse' like functions to do just about anything that you care
    to imagine with any code.

    Another thing to consider;
    When a code file is imported to the program, it can be pre-processed using a
    'Parse' like function.
    This function could be better described as a filter.
    This would 'rip' into the code, giving each block a characteristic that enables
    quicker processing later on.
    Why not do practically all the math processes, tagging any needed results to
    file lines, then Pickle the entire file, to be retrieved at 'high speed' later on.
    Actions of this nature are common enough with programs.
    In fact many operations may be performed with data that you would normally be
    completely unaware of.

    To describe this point;
    let's say you're using a program and you think that what you want it to achieve
    for you, would be very difficult and time consuming to carry out.
    Then, just when you feel a craving for a coffee grab you,
    to you're surprise, the program rips through the task at a mind numbing speed.
    'That's so cool' you say.
    Yep, you could be right.
    In reality, most of the work has already been done and you just didn't know it.
    The program will have been processing every keystroke, mouse motion or click, you
    had been making, the whole time.
    This is what programs are meant to do for us anyway.

    I can think of this in another way and this is something I have seen and I don't
    know if they still do this, but in like Japan, they used to hold these speed
    competitions, using those ancient abacus calculators.
    You know, the frames with rows of sliding beads.
    The contestants are given a math problem and the idea is to do the calculation,
    then when they're done, they have to call out the answer.
    First one to spit it out, wins.
    These guys and girls are so quick at this, that many of them can not only match the
    speed of some smarty pants armed with an electronic calculator, but they can beat them.
    How can they do that?
    Well, each slide of the beads on the abacus 'IS' the mathematical result.

    The 'actual calculation' for the person keying in the numbers on the electronic
    calculator, won't be done for each process until they finish each keystroke.
    Finally they need to press enter or =.
    When they get to press their final key and before they can call out their
    answer, the judge has already handed over a shiny plastic trophy.
    Much clapping follows and the 'smarty pants' electronic calculator user, gets a polite
    apology from the winner for whipping his sorry butt so thoroughly and gets a small
    encouragement that, with due diligence and a few hundred years he might just win.
    Not:-)

    Pre-processing would massively reduce an 'indexer' process time and let it get
    on with the job of creating the 1/0 stream to send to the port.


    The little PyNC structure is simple and at first glance, doesn't look like it could
    amount to much, if anything at all.
    To be frank, when I look at it, PyNC actually looks pretty insignificant.
    But if we open our minds to a simple 'Truth',
    'simplicity is the key to unlocking complexity'.
    PyNC can be the launching pad for either a small or a powerful monster.

    AS you wish, feel free to tear it apart or reconstruct it any way you choose.

    If I haven't left anything out,
    next we can move on to dealing with some actual code and if anything previous
    has been a bit of a 'brain hurt',
    then like they say, 'you ain't seen nothing yet'.

  9. #49
    Join Date
    Sep 2009
    Posts
    96
    Here is a real working example of 'theParse'
    I have tested this and it works just fine.

    First thing to do is;
    Delete the function 'def theParse():' from the original 'PyNC' program.
    Then copy and paste this entirely new 'def theParse():' in it's place.

    I have included some sample G-code line arguments.
    From that point on,
    if you want to parse entire G-code files successfully,
    you will need to add many more arguments.
    So put you're programming caps on and create many of your own.

    As long as I haven't missed anything,
    all the tools you'll need to accomplish the task should be,
    within 'theParse' structure.

    IF you want to clean up 'raw' G-code files, or alter files to suit a
    particular indexer, such as Mach3,
    with a little creativity, you CAN make 'slight' or 'major' changes
    to any G-code file.

    This 'parse' is just one of many possible 'parse' like structures.
    Using this as a starting point, you CAN do anything with ANY NC file type.


    Code:
    def theParse():
        #=========================================================
        # This section below, is to gather all control values for the parse,
        # from the controlncv.prg file
    #   #=========================================================
        def ncvzDepth():
            with open('c:/PyNC/program files/controlncv.prg','r') as fob:
                getcontrolvalues = fob.readlines()
                fob.close()
                thecontrolncvlist = (getcontrolvalues)
                thencvlist = thecontrolncvlist[1]
                line = "".join (thencvlist)
                dsearch = Find( r' *-*\.*\d\d*\.*\d* *', line)
                if dsearch != "":
                    dstring = (dsearch)
                    dstrip = (dstring).strip()
                    list (dstrip)
                    dword = list (dstring)
                    if dword [0] .isdigit or  dword [1].isdigit:
                        dlistnum = dword [1: ]
                        dstringnum = "".join (dlistnum)
                        dnum = (dstringnum).strip()
                        d = float (dnum)
                        return d
                else:
                    d = " "
                    return d
        #==============================================================
        #==============================================================
        def ncvPlunge():
            with open('c:/PyNC/program files/controlncv.prg','r') as fob:
                getcontrolvalues = fob.readlines()
                fob.close()
                thecontrolncvlist = (getcontrolvalues)
                thencvlist = thecontrolncvlist[2]
                line = "".join (thencvlist)
                dsearch = Find( r' *-*\.*\d\d*\.*\d* *', line)
                if dsearch != "":
                    dstring = (dsearch)
                    dstrip = (dstring).strip()
                    list (dstrip)
                    dword = list (dstring)
                    if dword [0] .isdigit or  dword [1].isdigit:
                        dlistnum = dword [1: ]
                        dstringnum = "".join (dlistnum)
                        dnum = (dstringnum).strip()
                        d = float (dnum)
                        return d
                else:
                    d = " "
                    return d
        #==============================================================
        #==============================================================
        def ncvMill():
            with open('c:/PyNC/program files/controlncv.prg','r') as fob:
                getcontrolvalues = fob.readlines()
                fob.close()
                thecontrolncvlist = (getcontrolvalues)
                thencvlist = thecontrolncvlist[3]
                line = "".join (thencvlist)
                dsearch = Find( r' *-*\.*\d\d*\.*\d* *', line)
                if dsearch != "":
                    dstring = (dsearch)
                    dstrip = (dstring).strip()
                    list (dstrip)
                    dword = list (dstring)
                    if dword [0] .isdigit or  dword [1].isdigit:
                        dlistnum = dword [1: ]
                        dstringnum = "".join (dlistnum)
                        dnum = (dstringnum).strip()
                        d = float (dnum)
                        return d
                else:
                    d = " "
                    return d
        #==============================================================
        #==============================================================
        def ncvzClear():
            with open('c:/PyNC/program files/controlncv.prg','r') as fob:
                getcontrolvalues = fob.readlines()
                fob.close()
                thecontrolncvlist = (getcontrolvalues)
                thencvlist = thecontrolncvlist[4]
                line = "".join (thencvlist)
                dsearch = Find( r' *-*\.*\d\d*\.*\d* *', line)
                if dsearch != "":
                    dstring = (dsearch)
                    dstrip = (dstring).strip()
                    list (dstrip)
                    dword = list (dstring)
                    if dword [0] .isdigit or  dword [1].isdigit:
                        dlistnum = dword [1: ]
                        dstringnum = "".join (dlistnum)
                        dnum = (dstringnum).strip()
                        d = float (dnum)
                        return d
                else:
                    d = " "
                    return d
        #==============================================================
        #==============================================================
        def ncvzLift():
            with open('c:/PyNC/program files/controlncv.prg','r') as fob:
                getcontrolvalues = fob.readlines()
                fob.close()
                thecontrolncvlist = (getcontrolvalues)
                thencvlist = thecontrolncvlist[5]
                line = "".join (thencvlist)
                dsearch = Find( r' *-*\.*\d\d*\.*\d* *', line)
                if dsearch != "":
                    dstring = (dsearch)
                    dstrip = (dstring).strip()
                    list (dstrip)
                    dword = list (dstring)
                    if dword [0] .isdigit or  dword [1].isdigit:
                        dlistnum = dword [1: ]
                        dstringnum = "".join (dlistnum)
                        dnum = (dstringnum).strip()
                        d = float (dnum)
                        return d
                else:
                    d = " "
                    return d
        #==============================================================
        #==============================================================
        def ncvrapiDown():
            with open('c:/PyNC/program files/controlncv.prg','r') as fob:
                getcontrolvalues = fob.readlines()
                fob.close()
                thecontrolncvlist = (getcontrolvalues)
                thencvlist = thecontrolncvlist[6]
                line = "".join (thencvlist)
                dsearch = Find( r' *-*\.*\d\d*\.*\d* *', line)
                if dsearch != "":
                    dstring = (dsearch)
                    dstrip = (dstring).strip()
                    list (dstrip)
                    dword = list (dstring)
                    if dword [0] .isdigit or  dword [1].isdigit:
                        dlistnum = dword [1: ]
                        dstringnum = "".join (dlistnum)
                        dnum = (dstringnum).strip()
                        d = float (dnum)
                        return d
                else:
                    d = " "
                    return d
        #==============================================================
    #   #=======================================================================
    #   # Place calls to the ncv search functions, here;
    #   #=======================================================================
    
    #   #=======================================================================
    #   # Now create some usefull 'macro' style, output lines from 'ncv values'
    #   # It's just a matter of deciding how you want the lines to read.
    #   #=======================================================================
        def theplungeLine():
            floatplungez = ncvPlunge()
            plungez = str(floatplungez)
            plungezletter = " F"
            theplungeline = plungezletter + plungez + '\n'
            return theplungeline
    #   #
        def themilLine():
            floatmill = ncvMill()
            millxy = str(floatmill)
            milletter = " F"
            themilline = milletter + millxy + '\n'
            return themilline 
    #   #
        def thezdepthLine():
            floatdepthz = ncvzDepth()
            depthz = str(floatdepthz)
            depthzletter = " Z"
            thezdepthline = depthzletter + depthz + theplungeLine()
            return thezdepthline
    #   #
        def thezclearLine():
            floatclearz = ncvzDepth()
            clearz = str(floatclearz)
            clearzletter = " G0 Z"
            thezclearline = clearzletter + clearz + '\n'
            return thezclearline
    #   #
        def thezheightLine():
            floatliftz = ncvzClear()
            liftz = str(floatliftz)
            liftzletter = " G0 Z"
            thezheightline = liftzletter + liftz + '\n'
            return thezheightline
    #   #
        def thezdownLine():
            floatrapidz = ncvrapiDown()
            rapidz = str(floatrapidz)
            rapidzletter = " G0 Z"
            thezdownline = rapidzletter + rapidz + '\n'
            return thezdownline 
    
    #   #==================================================================
    #   # Place the full functions for the G-code file line searches, here; 
    #   #==================================================================
        def gSearch():
            gsearch = Find( r'G *\.*\d\d*\.*\d* *', line)
            if gsearch != "":
                gstring = (gsearch)
                gstrip = (gstring).strip()
                list (gstrip)
                gword = list (gstrip)
                if gword [1] .isdigit:
                    gletter = " G"
                    glistnum = gword [1: ]
                    gstringnum = "".join (glistnum)
                    gnum = (gstringnum).strip()
                    g = float (gnum)
                    gout = gletter + gnum
                    return gout,g
            else:
                gletter = ''
                gnum = ''
                g = ''
                gout = ''
                return gout,g
    #   #========================================================
    #   #========================================================
        def mSearch():
            msearch = Find( r'M *\.*\d\d*\.*\d* *', line)
            if msearch != "":
                mstring = (msearch)
                mstrip = (mstring).strip()
                list (mstrip)
                mword = list (mstrip)
                if mword [1] .isdigit:
                    mletter = " M"
                    mlistnum = mword [1: ]
                    mstringnum = "".join (mlistnum)
                    mnum = (mstringnum).strip()
                    m = float (mnum)
                    mout = mletter + mnum
                    return mout,m
            else:
                mletter = ""
                mnum = ""
                m = ""
                mout = mletter + mnum
                return mout,m
    #   #========================================================
    #   #========================================================
        def xSearch():
            xsearch = Find( r'X *-*\.*\d\d*\.*\d* *', line)
            if xsearch != "":
                xstring = (xsearch)
                xstrip = (xstring).strip()
                list (xstrip)
                xword = list (xstring)
                if xword [1].isdigit or xword [2].isdigit:
                    xletter = " X"
                    xlistnum = xword [1: ]
                    xstringnum = "".join (xlistnum)
                    xnum = (xstringnum).strip()
                    x = float (xnum)
                    xout = xletter + xnum
                    return xout,x
            else:
                xletter = ""
                xnum = ""
                x = ""
                xout = xletter + xnum
                return xout,x
    
    #   #========================================================
    #   #========================================================
        def ySearch():
            ysearch = Find( r'Y *-*\.*\d\d*\.*\d* *', line)
            if ysearch != "":
                ystring = (ysearch)
                ystrip = (ystring).strip()
                list (ystrip)
                yword = list (ystring)
                if yword [1] .isdigit or  yword [2].isdigit:
                    yletter = " Y"
                    ylistnum = yword [1: ]
                    ystringnum = "".join (ylistnum)
                    ynum = (ystringnum).strip()
                    y = float (ynum)
                    yout = yletter + ynum
                    return yout,y
            else:
                yletter = ""
                ynum = ""
                y = ""
                yout = yletter + ynum
                return yout,y
    
    #   #========================================================
    #   #========================================================
        def zSearch():
            zsearch = Find( r'Z *-*\.*\d\d*\.*\d* *', line)
            if zsearch != "":
                zstring = (zsearch)
                zstrip = (zstring).strip()
                list (zstrip)
                zword = list (zstring)
                if zword [1] .isdigit or  zword [2].isdigit:
                    zletter = " Z"
                    zlistnum = zword [1:8]
                    zstringnum = "".join (zlistnum)
                    znum = (zstringnum).strip()
                    z = float (znum)
                    zout = zletter + znum
                    linez = z
                    return zout,z
            else:
                zletter = ""
                znum = ""
                z = ""
                zout = zletter + znum
                return zout,z
    
    #   #========================================================
    #   #========================================================
        def iSearch():
            isearch = Find( r'I *-*\.*\d\d*\.*\d* *', line)
            if isearch != "":
                istring = (isearch)
                istrip = (istring).strip()
                list (istrip)
                iword = list (istring)
                if iword [1] .isdigit or  iword [2].isdigit:
                    iletter = " I"
                    ilistnum = iword [1: ]
                    istringnum = "".join (ilistnum)
                    inum = (istringnum).strip()
                    i = float (inum)
                    iout = iletter + inum
                    return iout,i
            else:
                iletter = ""
                inum = ""
                i = ""
                iout = iletter + inum
                return iout,i
    
    #   #========================================================
    #   #========================================================
        def jSearch():
            jsearch = Find( r'J *-*\.*\d\d*\.*\d* *', line)
            if jsearch != "":
                jstring = (jsearch)
                jstrip = (jstring).strip()
                list (jstrip)
                jword = list (jstring)
                if jword [1] .isdigit or  jword [2].isdigit:
                    jletter = " J"
                    jlistnum = jword [1: ]
                    jstringnum = "".join (jlistnum)
                    jnum = (jstringnum).strip()
                    j = float (jnum)
                    jout = jletter + jnum
                    return jout,j
            else:
                jletter = ""
                jnum = ""
                j = ""
                jout = jletter + jnum
                return jout,j
    
    #   #========================================================
    #   #========================================================
        def fSearch():
            fsearch = Find( r'F *\.*\d\d*\.*\d* *', line)
            if fsearch != "":
                fstring = (fsearch)
                fstrip = (fstring).strip()
                list (fstrip)
                fword = list (fstrip)
                if fword [1] .isdigit:
                    fletter = " F"
                    flistnum = fword [1: ]
                    fstringnum = "".join (flistnum)
                    fnum = (fstringnum).strip()
                    f = float (fnum)
                    fout = fletter + fnum
                    return fout,f
            else:
                fletter = ""
                fnum = ""
                f = ""
                fout = fletter + fnum
                return fout,f
    
    #   #=======================================================================
    #   # create variables with initialising code strings if you wish to.
    #   # These can also be assembled using 'additional raw_input' from the user
    #   #=======================================================================
        platform = ' G54\n'
        plane = ' G17\n'
        units = ' G21\n'
        ijdists = ' G90\n'
    
        initialines = platform + plane + units + ijdists
    #   #=======================================================================
    #   # create variables with file end, code strings if you wish to.
    #   # These can also be assembled using 'additional raw_input' from the user
    #   #=======================================================================
        raisez = ' G0 Z15.00\n'
        gotohome = ' G0 X0.00 Y0.00\n'
        endfile = ' M30\n ()\n'
    
        filendlines = raisez + gotohome + endfile
    #   #=========================================================
        # Now open 'parsefile.prg' to read each line (1 at a time)
    #   #=========================================================
        fileIN = open('c:/PyNC/program files/parsefile.prg','r')
        line1 = fileIN.readline()
    
        cont = 0
        initialcontrol = 0
        endoutput =0
    #   #============================================================
    #   # And we need an output file to write to.
    #   # The file will be created in the 'output files' folder.
    #   # To make sure the file is good to go,
    #   # a check is made for a possible 'in use already', exception.
    #   # May as well write some initialising lines to the file,
    #   # at the same time.
    #   #============================================================
        anexception=0
        fob =''
    
        if initialcontrol == 0:
           cont = 1
           initialcontrol = 1
           try:
              fob = open('c:/PyNC/output files/001PyNC.tap','w')
              try:
                 fob.writelines(initialines)
                 print initialines
              finally:
                 anexception=0
           except IOError:
              anexception=1
              pass
    #   #==========================================================
    #   # Now for the 'while' loop
    #   # Pay close attention to the new line indentation,
    #   # from here on in.
    #   # Using these: #       # can help check you're indentation.
    #   #==========================================================
        while line1 != '' and anexception == 0:
    #       # new indent
            line = line1.upper()
    #       #==============================================================
    #       # Place calls to the ncv search functions, here;
    #       #==============================================================
            zdepth = ncvzDepth()
            zclear = ncvzClear()
            zheight = ncvzLift()
            zdownmin = ncvrapiDown()
    #       #==============================================================
    #       # Place calls to word and macro line creation functions, here;
    #       #==============================================================
            plunge = theplungeLine()
            mill = themilLine()
            #==========================
            zdownline = thezdownLine()
            #==========================
            zheightline = thezheightLine()
            #==========================
            zdepthline = thezdepthLine()
            #==========================
            zclearline = thezclearLine()
            #========================== 
    #       #===============================================================
    #       # extract the G-code words from file line searches, here;
    #       #===============================================================
            getg = ''
            lineg = ''
            mygsearch = gSearch()
            if mygsearch != ('',''):
                mygsearchlist = list (mygsearch) 
                getg = mygsearchlist [0]
                thegnum = mygsearchlist [1: ]
                lineg = thegnum[0]
            gpresent = 0
            g = None
            if lineg !='':
                gpresent = 1
                g = lineg
    #       #=======================
            getm = ''
            linem = ''
            mymsearch = mSearch()
            if mymsearch != ('',''):
                mymsearchlist = list (mymsearch) 
                getm = mymsearchlist [0]
                themnum = mymsearchlist [1: ]
                linem = themnum[0]
            mpresent = 0
            m = None
            if linem !='':
                mpresent = 1
                m = linem
    #       #=======================
            getx = ''
            linex = ''
            myxsearch = xSearch()
            if myxsearch != ('',''):
                myxsearchlist = list (myxsearch) 
                getx = myxsearchlist [0]
                thexnum = myxsearchlist [1: ]
                linex = thexnum[0]
            xpresent = 0
            x = None
            if linex !='':
                xpresent = 1
                x = linex
    #       #=======================
            gety = ''
            liney = ''
            myysearch = ySearch()
            if myysearch != ('',''):
                myysearchlist = list (myysearch) 
                gety = myysearchlist [0]
                theynum = myysearchlist [1: ]
                liney = theynum[0]
            ypresent = 0
            y = None
            if liney !='':
                ypresent = 1
                y = liney
    #       #=======================
            getz = ''
            linez = ''
            myzsearch = zSearch()
            if myzsearch != ('',''):
                myzsearchlist = list (myzsearch) 
                getz = myzsearchlist [0]
                theznum = myzsearchlist [1: ]
                linez = theznum[0]
            ypresent = 0
            z = None
            if linez !='':
                zpresent = 1
                z = linez
    #       #=======================
            geti = ''
            linei = ''
            myisearch = iSearch()
            if myisearch != ('',''):
                myisearchlist = list (myisearch) 
                geti = myisearchlist [0]
                theinum = myisearchlist [1: ]
                linei = theinum[0]
            ipresent = 0
            i = None
            if linei !='':
                ipresent = 1
                i = linei
    #       #=======================
            getj = ''
            linej = ''
            myjsearch = jSearch()
            if myjsearch != ('',''):
                myjsearchlist = list (myjsearch) 
                getj = myjsearchlist [0]
                thejnum = myjsearchlist [1: ]
                linej = thejnum[0]
            jpresent = 0
            j = None
            if linej !='':
                jpresent = 1
                j = linej
    #       #=======================
            getf = ''
            linef = ''
            myfsearch = fSearch()
            if myfsearch != ('',''):
                myfsearchlist = list (myfsearch) 
                getf = myfsearchlist [0]
                thefnum = myfsearchlist [1: ]
                linef = thefnum[0]
            fpresent = 0
            f = None
            if linef !='':
                fpresent = 1
                f = linef
    
    #       #=============================================================
    #       # This is the output line variable
    #       #=============================================================
    
            outline = ''
    
    #       #=============================================================
    #       # This section is where you place All line arguments 
    #       #=============================================================
    #       # Below are a few G-code line arguments.
    #       # MANY arguments would be needed for complete success.
    #       # On average, as many as 12 would be needed.
    #       # The 1st arg., gets the user's 'mill speed' added,
    #       # but only for 1 variety of G-code line seen.
    #       # Every argument you create will result in a different output.
    #       #=============================================================
            if gpresent == 1 and g > 0:
                if g < 4:
                    outline = getg+getx+gety+getz+geti+getj+mill
                    fob.writelines(outline)
                    print outline
    
            if gpresent == 1 and g == 0:
                outline = getg+getx+gety+getz+'\n'
                fob.writelines(outline)
                print outline
            if gpresent == 0 and mpresent == 0:
                outline = getg+getx+gety+getz+geti+getj+'\n'
                fob.writelines(outline)
                print outline
            if mpresent == 1:
                outline = getm+'\n'
                fob.writelines(outline)
                print outline
    
    
    #       #===========================================================     
    #       # When all line arguments are done;
    #       # Clear all extraction line variables before the 'loop back'
    #       #===========================================================
            gpresent=mpresent=xpresent=ypresent=zpresent=ipresent=jpresent=fpresent=0
            getg=getm=getx=gety=getz=geti=getj=getf=''
            lineg=linem=linex=liney=linez=linei=linej=linef=''
            g=m=x=y=z=i=j=f=None
            outline = ''
    
    #       # The 'while loop' is now restarted with;
            line1 = fileIN.readline()
    
    #   #=====================================================================
    #   # 'while' looping will end, when there are no more file lines to read.
    #   # The indentation shifts left, (we are no longer in the 'while' loop)
    #   #=====================================================================
        if endoutput == 1 and anexception == 0:
           print filendlines
           fob.writelines(filendlines)
           fob.close()
           print "\n\nThe Import File has been processed.\n\n"
    
        if endoutput == 0 and anexception == 0:
           print filendlines
           fob.writelines(filendlines)
           fob.close()
           print "\n\nThe Import File has been processed.\n\n"
    
        if anexception == 1:
           cls()
           print """ 
    
              'PyNC hasn't crashed'
       This is a 'file open ERROR' message.
    
    The file called '001PyNC.tap', cannot be written to.
    It must be available for writing to at all times. 
    
    Another program may be using it. Probably 'Mach3'.
    If you have loaded '001PyNC.tap' to Mach,
    check that you have.. 'closed G-Code'.
    
    Then, try processing your code file again.
    
    You can rename the file '001PyNC.tap' if you want to.
    You can load the newly named file to Mach, instead of 
    '001PyNC.tap'.
    You can leave that file loaded in Mach.
    
    PyNC will automatically create a new output file'
     
                 """ 
    #=================================================================
    # End of theParse, returning to the menu.
    #=================================================================

  10. #50
    Join Date
    Sep 2009
    Posts
    96
    Here is also a few lines of very 'raw' G-code, you could use to
    see just what 'theParse' will do with it.

    To make use of the G-code,
    open notepad then copy and paste the G-code to it.
    PyNC will open any ASCll file, so you don't have to bother
    changing the .txt file extension, to load it or process it.
    Just save the notepad file as 'whatever name' you choose.
    Then place it into the 'import files' folder in PyNC.
    When you have loaded the file, then processed it,
    look in the folder 'output files' and open the new file named,
    '001PyNC.tap'

    Always open you're files with Windows 'notepad'.
    If windows doesn't recognize the file extension,
    select notepad from the list, that Windows will show you.

    Code:
    G0X158.725876Y131.650635
    G3X128.726044Y131.650635I143.725952J131.650635
    X158.725876Y131.650635I143.725952J131.650635
    G0X206.310410Y161.076309
    G1X206.310410Y181.076157
    X166.310654Y181.076157
    X166.310654Y161.076309
    X206.310410Y161.076309
    G0X49.999989Y100.000000
    G2X99.999985Y150.000000I99.999992J100.000000
    G3X149.999985Y199.999985I99.999985J200.000000
    G1X99.999992Y200.000000
    X99.999992Y225.000000
    X199.999985Y225.000000
    X199.999985Y200.000000
    X249.999985Y200.000000
    X225.000000Y150.000000
    X175.000000Y100.000000
    X112.499992Y110.000000
    X49.999989Y100.000000

  11. #51
    Join Date
    Apr 2010
    Posts
    0
    Since you're working so hard, I'll give you a little hand.

    Run this against a gcode file and see what you get.

    Code:
    import re
    parser = re.compile ("([a-zA-Z]*)([-+]?[0-9]*\.?[0-9]+)")
    
    #==========================================================================
    
    def ParseFile (fileName):
    
    	f = open (fileName,'r')
    	for block in f:
    
    		# Standardise format to compressed, upper-case characters.
    
    		block = block.upper()
    		block = block.translate (None,' \t\n\r');
    
    		# Strip comments. Assumes that there is only one comment per block.
    		# If more than one comment, any code between the first and last
    		# comment will be stripped. 
    
    		if ('(' in block):
    			block = block.partition ('(')[0] + block.rpartition (')')[2]
    
    		# Process non-empty blocks into individual gcode commands.
    
    		ParseBlock (block)
    
    #==========================================================================
    
    def ParseBlock (block):
    
    	for command in parser.findall(block):
    
    		print command[0]+command[1],
    		
    	print
    			
    #==========================================================================
    
    ParseFile ("test.nc")
    You're spending hundreds of lines of code on things that can be done in just a few.

    Hopefully this will give you a push in the right direction.

    That said, I still think you're going to hit a big, brick wall when you try to actually move a machine. I strongly suggest you prototype that bit NOW, so that you don't waste hundreds of hours of your time.

  12. #52
    Join Date
    Sep 2009
    Posts
    96
    As for the Indexer, which is yet to be covered,
    I'm still running time trials with Python's output,
    based on calls to the operating system and although
    my original tests appeared to be ok, I have concerns
    about the binary output speed.
    So far, the tests tend to keep pointing me back to using
    'C' to build the Indexer.
    The goal here of course is to use Python to build the
    Indexer.
    The goals of the first part have been met, so this area
    of the build is at an end.
    If I overcome the problems I'm encountering, I'll begin
    a new thread, where the Indexer processes can be posted
    and examined as usual, in 'extreme' and 'painful' detail.
    But for now, have some fun with PyNC.

  13. #53
    Join Date
    Sep 2009
    Posts
    96
    High Ron,
    From the beginning, I did mention that were easy ways to get results.
    The long way to get there was for those not yet used to Python and that
    many small things may be learned within the detail.
    And you're slice of Python is very cool.

  14. #54
    Join Date
    Sep 2009
    Posts
    96
    As far as my position on the suitability of implementing Python to create a machine indexer is concerned,
    there is a very real possibility that Python may not be a suitable candidate.
    I have spent quite some time working on this, but this is my spare time and
    I don't believe my spare time is wasted.
    If anyone feels they have learned anything from what I have already posted, then this is time well used.
    I will continue to test, until I do run into a solid brick wall.
    I have indeed encountered a wall, but just how tall or solid this is, I am yet to find out.
    I will, however, set myself a limit as to how many times I bang my head
    against it.

  15. #55
    Join Date
    Jan 2010
    Posts
    2141
    I have to admit that I am somewhat (to put it mildly) behind in following your tutorials, but I appreciate them nevertheless, and when time permits I will continue working my way through them.

    (I had no electrical power or Internet service for a whole week due to Hurricane Irene, and so that has set me back quite a bit - and even before then I was nowhere near up to date with all of your posts - but eventually I expect that I'll get on track and catch up).

    I agree with your general sentiment that whether or not you end up with a viable indexer written in python after all is said and done, the driving problem makes it an interesting case to examine and to use as the basis for some tutorials.

  16. #56
    Join Date
    Sep 2009
    Posts
    96
    Hi doorknob,
    Sorry to hear about the bad weather you guys are getting.
    We get our fair share here also from time to time.
    Anyhow, I hope you can find something useful in my posts.

  17. #57
    Join Date
    Sep 2009
    Posts
    96
    I'm gonna leave this thread for now and just before I go,
    there's a couple of small points I need to post.

    The very 'raw' G-code I posted is in fact extremely bad code.
    I would not to attempt to run this G-code on a machine, as it is.
    It is intended to be this way for a reason.

    It is the job of PyNC to rip each G-code file line completely apart.
    Each 'word' element is returned as 2 individual components.

    One component is the actual G-code 'word'.
    The other component is the numerical value that was originally assigned to it.
    Doesn't make sense?
    G-code words, at least the ones I am dealing with, are words having just 1
    letter (alpha character). Each single letter word, is assigned a numerical value.
    In English we have the word "a", as used in this string, "a rusty color".
    The letter "a" is an entire word, even though it contains just 1 element.
    The rest of the line is "rusty color" and this describes an "instance" declared by
    "a" as a singular unit.
    In a way, you could think of a G-code 'word' as a short sentence.
    The 'word', G2, has the 2 elements, G and 2.
    'G' is the actual word and '2' describes the condition for the "instance" which is "g".
    A line or 'block' of G-code words could be thought of as a "paragraph".

    By design, the program is not meant to separate words from one file then dump
    them into another file.
    Each time the 'while' loop runs, each G-code 'word' on a file line is picked up,
    then taken apart, ready to be examined.

    You may decide not to examine some of these 'words' at all, while others you will.
    This is entirely up to you.

    PyNC isn't intended for the purpose of making 'garbage code' look pretty.
    'Pretty garbage' is still 'garbage' after all. "GIGO".

    The idea is to sort through the 'garbage code' and make it useful.
    The code needs to be given start positions, tool lifts, clearances, milling depths,
    feed speeds for every situation, where to park the axes at jobs end, tool change
    options if required and all must be done exactly, without error, based entirely on
    arguing the values of significant words present on each and every line.
    And here's a clue: significant words NOT present on a line and why not?.
    as in;
    if gpresent ==0 and xpresent ==1:
    you might want to do something.

    Some would say;
    "I could just type a few words into that garbage G-code and it'll be good to go".
    Sure;
    Try 50,000 code lines, which is a small file, then multiply this by 50 a day and deal
    with the protocol requirements for various indexers.

    At the moment, when a G1 word is seen to be present on a motion line,
    1 argument applies the milling speed from the .ncv file,
    The next arguments, simply output the other lines.

    You, can give you're PyNC additional arguments to examine other word values.
    Sure I could post every possible argument and there are many,
    but you might be pretty pleased when you hit you're own home runs.

    You might look to the calls to the word search functions as well.
    You can build upon these and return some extremely useful information about the
    word values returned from the searches.
    You could add more variables and 'if' statements to feed them.

    You're output line arguments could look at the additional information giving
    you more ability to decide on the output for a particular code line.
    A seemingly insignificant G-code line can give you a vast quantity of information.

    I threw the program together, based on very small pieces of others that I
    build and use.
    It is a simple framework and a blank canvas, from which you can build upon,
    tear apart or rebuild entirely, any way you see fit.

    The thing I like about Python is that it's fun to play with.
    When I started out as a young bloke, there were cards with punch holes.
    The PC didn't exist, and Windows likewise.
    Alltrans, Fortrans were way cool... not.

Page 3 of 3 123

Similar Threads

  1. Read variable with Python
    By albova in forum LinuxCNC (formerly EMC2)
    Replies: 7
    Last Post: 05-26-2012, 12:53 PM
  2. Building a software Indexer
    By bernster in forum Australia, New Zealand Club House
    Replies: 48
    Last Post: 07-08-2011, 07:41 PM
  3. G-code programming library in python
    By bermanmk in forum G-Code Programing
    Replies: 1
    Last Post: 11-10-2009, 03:24 AM
  4. Indexer software
    By Art Ransom in forum Wood Lathes / Mills
    Replies: 4
    Last Post: 07-15-2008, 11:47 PM
  5. just another python gcode thing
    By cyclestart in forum LinuxCNC (formerly EMC2)
    Replies: 8
    Last Post: 02-18-2008, 03:54 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •