Store position to eeprom

My idea is to add three additional M codes 

1-store current position ( X , Y ,Z)  to eeprom and store it as position N for example
maybe the code can look like this : M** S1  
as S 1 means store to position 1 (i think 3 positions will be enough )

2-show the stored coordinates in position N for example sending M*** S1 will send the coordinates stored in position and will show M*** S1 x... y... z...

3-move to position N for example sending M**** S1 will move the printer to coordinates stored in position 1

I think this will help a lot when using Repetier for cnc routing (for storing zero points and other necessary points)  or for example to store the position while layer change so we can resume a print if the printer powered off accidentally 

actually I tried to find out how to add eeprom addresses to the firmware and add new M codes and make this idea but I think I don't have enough programming skills to do this yet

I hope you can help me doing this or maybe you can start the development of this idea and I can help with trying on my printer or what ever I can do to help

And finally Thank you a lot for your works with all this flexible and reliable firmware ...

Comments

  • You mean like
    - M401 - Store x, y and z position.
    - M402 - Go to stored position. If X, Y or Z is specified, only these coordinates are used. F changes feedrate for that move.

    Ok, only 1 memory space and no list of position. I would not store these in eeprom, ram is enough.
  • Thank you for your answer
    My idea was just to continue the job even if the printer/router accidentally powered off

    can I make this thing using custom events system ?
    I tried to find out how to use the custom events files but things was not very clear to me !

  • Yes, with event system you can write such things easily. It is described in event.h how it works but if you are not so familiar with C++ and preprocessor macros, which are used to implement it it is much harder.

    When I get time I need to write a longer tutorial over this.

    What you need it to implement the M gcode parser and add your own gcodes there. On github you see some examples for this. Check the laser sample which also implements own gcode. Also Felix Pro 1 ha sown events but also a lot more stuff for tweaking, so maybe not best example to learn.
  • Ok thank you again
    I will keep trying to make this thing work until its done (I hope to !!)
    and as you said this feature need a better tutorial because it is one of the most things that make this firmware so flexible .
  • just uploaded an empty template for G/M codes to my Github.
    Hope that helps you to start.

    https://github.com/RAyWB/Additions-for-Repetier-Firmware/tree/master/CustomEventsEmpty

    @Repetier :
    Roland you can also take it to the samples if you want to
  • @RAyWB
    Thank you so much you helped me a lot with the whole custom event idea 

    so I have to build new functions that use the pre-defined variables used in the firmware ?
    should I find variables and functions from the firmware files ?  for example the function to store a new eeprom variable ,or to move ,or any other possible operation in the firmware .

    (sorry if I am asking things that you consider it basics , but it's a little bit hard to find out things without help , I am trying to understand as possible as I can how each operation in this firmware works or at least what I need)
  • so if you use the empty template i uploaded just take a look at

    https://github.com/repetier/Repetier-Firmware/tree/development/src/SampleEventSystems/Laser PWM and DAC

    so you can figure out how it works, the empty template might be a good starting point for you

    regarding eeprom modification it might get a little tricky to do it from custom events as there are multiple
    points to be considered. I´m not really shure at the moment  how to handle that .
    Unfortunately too busy to check it within the next few days


  • ok thank you
    I checked it and I think I need to learn more about c++ programing in the next days
  • @RAyWB
    I think the empty customevents.h you created needs this 

    extern bool Custom_GCode(GCode *com);
    extern bool Custom_MCode(GCode *com);

    also I want to ask you about what I hace done 

    this is the custom M function in customeventsimpl.h I created

    //#########################################################################################
    //#### MCode addition/replacement
    //#########################################################################################
    float memoryX1 = IGNORE_COORDINATE;
    float memoryX2 = IGNORE_COORDINATE;
    float memoryX3 = IGNORE_COORDINATE;

    float memoryY1 = IGNORE_COORDINATE;
    float memoryY2 = IGNORE_COORDINATE;
    float memoryY3 = IGNORE_COORDINATE;

    float memoryZ1 = IGNORE_COORDINATE;
    float memoryZ2 = IGNORE_COORDINATE;
    float memoryZ3 = IGNORE_COORDINATE;



    bool Custom_MCode(GCode *com)
    {

      switch(com->M) {


        case 480:
          #if EEPROM_MODE !=0
           if(com->hasP()){
             case 1:
              realPosition(memoryX1,memoryY1,memoryZ1);

              HAL::eprGetFloat(epr_memoryX1,memoryX1);
              HAL::eprGetFloat(epr_memoryY1,memoryY1);
              HAL::eprGetFloat(epr_memoryZ1,memoryZ1);


                Com::config(PSTR("X1"),memoryX1);
                Com::config(PSTR("Y1"),memoryY1);
                Com::config(PSTR("Z1"),memoryZ1);

             break;

             case 2:
              realPosition(memoryX2,memoryY2,memoryZ2);

              HAL::eprGetFloat(epr_memoryX2,memoryX2);
              HAL::eprGetFloat(epr_memoryY2,memoryY2);
              HAL::eprGetFloat(epr_memoryZ2,memoryZ2);

                Com::config(PSTR("X2"),memoryX2);
                Com::config(PSTR("Y2"),memoryY2);
                Com::config(PSTR("Z2"),memoryZ2);

             break;

             case 3:
              realPosition(memoryX3,memoryY3,memoryZ3);
              
              HAL::eprGetFloat(epr_memoryX3,memoryX3);
              HAL::eprGetFloat(epr_memoryY3,memoryY3);
              HAL::eprGetFloat(epr_memoryZ3,memoryZ3);

                Com::config(PSTR("X3"),memoryX3);
                Com::config(PSTR("Y3"),memoryY3);
                Com::config(PSTR("Z3"),memoryZ3);

             break;
             }
             #else Com::printErrorF(Com::tNoEEPROMSupport);
             #endif

        break;


      default:
         return false;
      }
      return true;
    }



    also in customevents.h i added the following 

    extern bool Custom_GCode(GCode *com);
    extern bool Custom_MCode(GCode *com); 


    static float memoryX1;
    static float memoryX2;
    static float memoryX3;

    static float memoryY1;
    static float memoryY2;
    static float memoryY3;

    static float memoryZ1;
    static float memoryZ2;
    static float memoryZ3;

    #define epr_memoryX1        400
    #define epr_memoryX2        401
    #define epr_memoryX3        402

    #define epr_memoryY1        403
    #define epr_memoryY2        404
    #define epr_memoryY3        405

    #define epr_memoryZ1        406
    #define epr_memoryZ2        407
    #define epr_memoryZ3        408


    #undef EVENT_UNHANDLED_M_CODE(c)
    #define EVENT_UNHANDLED_M_CODE(c) Custom_MCode(c)


    but it's giving me an error wile compiling !! 
    I didn't expect to make work from the first time but here is my first try to just save the coordinates 
  • sorry, as i wrote yesterday :

    "
    regarding eeprom modification it might get a little tricky to do it from custom events as there are multiple
    points to be considered. I´m not really shure at the moment  how to handle that .  "

    couldnt find  something like   Com::config   , also the numbers for your memory, where do they come from?

    look at the eeprom files in firmware  may be that helps.

    usually compile error shows where  error is located
  • first sorry for the early question (before digging more in the code I wrote)
    I found many errors that I solved but still have much things to correct

    The Com::config function is in printer.cpp / printer::showconfiguration function 
    I thought I can use it the same way used to print for example Baudrate in line 1869

    and regarding to the numbers for the memory I didn't dig enough yet but I used these numbers just because they are not used in position definitions in the start of eeprom.h i knew there must be a way to chose these numbers

    Thank you again for answering me and sorry for taking your time 
  • ok, youre modifying the old 0.92 version.
    you should use developmentbranch to have event system. it´s different.
  • Hello again 
    today I got something working

    I modified the two custom events files to implement the three M-codes I need
    M482 P* to move to saved position *
    M481 P* to show saved position *
    M480 P* to save the current position to position * in eeprom 

    in M480 I used the following algorithm

    -save current position to ram (using Printer::realposition(x,y,z) )
    -move the saved values to eeprom 
    -print values saved in ram (just for debugging)
    -print values saved in eeprom 

    and I get wrong printed values from ram and the same values form the eeprom (I think no problem with saving values to eeprom)

    could it be a problem with the usage of Printer::realposition() ??

    please check out the files I wrote https://github.com/taalabash/REPETIER-custom-events
  • now it's giving me right answers

    I just fixed the eeprom positions you asked about before to make positions increases in 4 bits step (I think this is needed to handle a float number)
    I will test it on the printer and give feedback
    please tell me if you have comments or suggestions 
  • edited June 2017
    i suggest one important change :
    replace my name by yours as you coded it and it´s public in github ;-)

    there is no need to comment out 
    //#undef EVENT_UNHANDLED_G_CODE(c)
    //#define EVENT_UNHANDLED_G_CODE(c) Custom_GCode(c)

    as it´s empty it does nothing

    for me your code looks clean and straight forward and if it works , just keep it

    BUT i´m not shure if there is a need to increase eeprom protocol version  and i think the number range you use is
    reserved for extruders :

    see EEPROM.h

    #define EEPROM_EXTRUDER_OFFSET 200
    // bytes per extruder needed, leave some space for future development
    #define EEPROM_EXTRUDER_LENGTH 100

    so if i´m correct extruder2 would "scratch "your numbers

    that´s why i suggest to increase the numbers
    last number i found is  1052    so if you leave some space may be 1200 is a good start point.




  • just one question :
    from my point of view the functions are very useful for cnc , but how do you want to handle your intended use
    quote:
    My idea was just to continue the job even if the printer/router accidentally powered off

    how do you manage to write position to eeprom when accidentally powered off?

    when printing, how to find the breakpoint?
  • thank you so much
    for future use what is the last number that arduino can use in eeprom ??

    regarding to accidentally power off 
    I was thinking about two methods

    1- to add M480 in layer change script in the slicer software so I can know at least the last z height

    2- to add a mini ups system (gives the printer some seconds only ) ,and when power is of the printer stops and save the position and turn off the battery
    as the battery will power only the arduino board not the whole printer and but that needs more understanding of the printer functions especially the functions that controls the buffer

    these are just ideas until now maybe I can find some thing better 

    for me it's the first real addition to the printer firmware so I am working a little bit slowly because I need some time to understand each function and use it
  • arduino Mega has 4096 bytes EEPROM so last number is 4095.

    quote:
    for me it's the first real addition to the printer firmware so I am working a little bit slowly because I need some time to understand each function and use it

    don´t think youre working slowly...   as i had(have) to learn coding more or less from scratch to be honest i have to say i still don´t understand all the functions of the firmware.
    it took me weeks to understand the possibilities of custom events
  • regarding a "trigger" to M480...
    what power supply do you use?
    you could check a pin status in function timer100ms.
    just triggering the pin on a defined voltage level to run the M480
  • I tested the three codes on the printer and they are working well (I repaired the eeprom positions as you said)

    I am using a pc power supply

    do you mean to sense power decreasing ? will that give the printer enough time to stop and store position ?

    I used  "Commands::waitUntilEndOfAllMoves()" in the start of M480, will this function wait the whole buffer to get empty or just the current move ?

    and is there a command that immediately stops the printer moves without a reset ?
  • i mean a mix of sensing power decrease and ups system.
    not shure about  the buffers , but that wouldn´t matter.
    I´m just thinking of buffering the arduino by a combination of Diode/huge capacitor and sensing the 12V line.
    via analog input.
    But from experience i know the pc power supplies don´t like huge caps during power up.
    and arduinos don´t like slow power up... so i have to think about that.
    May be a small step-down converter helps.. they are available on low budget.
    I´ll check that tomorrow, i have a couple of them lying around, also some huge caps...



  • just a little question about custom events you created

    I noticed that you modified G00/G01 by adding them to custom events files 
    did you removed the original G00/G01 from commands.cpp ?
    can we modify a predefined Gcode by just adding it to the custom events files ? or we should remove the original Gcode function from commands.cpp ?
  • there is no need to remove from original,
    customized stuff is executed before the original, so the original will not be executed.
    thats the advantage of the custom events, you can just copy the original and modify it for your needs
    without changing original firmware code. so it´s also safe for updating to future versions
  • sorry for asking so much questions but I am learning a lot from this conversation
    can I use the GCode::executeFString() function as the following : 

    GCode::executeFString(PSTR("M** P" X " T" Y ))

    as X and Y are variables stored in eeprom or ram for example
    will the firmware understand the code as : M** PX TY  ?
    if yes , could X and Y be any type (int, float, or char) ?

    I cant find any similar usage of this function in the firmware (or in your custom files)
  • edited June 2017
    no, this is not possible to do with variables.
    what is the intended use?

  • for example : M104 S<stored value> T <stored extruder number>

    it's hard to rewrite what M104 do if want to use it in a custom event
  • why rewrite m104?
    may be there is a misunderstanding, the original parts of commands still work.
    for example if there is a  m104 in custom events  the modified one gets executed
    if there is not a modified one the original one gets executed.


  • @ASH This feature looks interesting and is something I could also make use of.

    I'd be willing to collaborate on this to get it implemented. It would be interesting to see where you have gotten with this already.

    Do you have a repo where you are performing this work?
  • Ignore my previous comment, the full thread wasn't visible on mobile when I was looking earlier.
  • @wiccan2
    actually I added new M codes to save up to three positions in the eeprom and are ready to use
    but the emergency restore is not ready yet and needs more work in hardware and software so you can use Mcodes I added to save and restore positions

Sign In or Register to comment.