Wait for external signal before executing G-Code command

Hello everyone, 

I'm using the Repetier Firmware on an Arduino Due along with the RADDS Board. However, the Arduino only controls an extruder and not the stepper motors for the respective axes or a heated bed. The Arduino receives a binary signal from the outside via a pin.

My goal is to have the extruder execute the next G-code command every time there's a signal change from the outside. Even if it's just a G0 command and it doesn't extrude, it should "execute" the command upon the signal change. While waiting for a new signal, the extruder should maintain temperature and extrusion speed. Ideally the board should not wait for feedback from the extruder (as in the case of the M109 command). It should blindly execute the commands as soon as a signal comes from outside.

Where in the code do I write that a new G-code command should be executed upon a new signal? I've been unsuccessful so far.

Thanks in advance!

Comments

  • Guess you should look in commands.cpp for
    Commands::executeGCode

    which is the starting function to execute a function regardless from the source. But you must still run periodical actions so maybe better add it e.g. in
    Commands::commandLoop()
    where it gets called. Search also other occurences where it gets called.
  • Thanks for the quick answer.


    The G-Code im sending via Repetier Host looks like this:
    M104 S200 	;Set temperature
    M109 S200
    G28 		;Home all axis or named axis.
    M82 		;use absolute distance for extrusion
    G90 		;Use absolute coordinates
    G92 E0		;zero the extruded lengt
    G1 F500 E0
    G1 E10
    G1 E15
    G0 E20

    Currently my CommandLoop ist looking like the code below, i didnt change the commandloop, i just added my parts.
    Im sending signals at 10-second intervals to the Arduino, but the Extruder doesnt do anything.
    (The Configuration.h and the pins.h are all set up). I also dont get any feedback from the Repetier Host. 
    bool lastTriggerState = false;  //im AS Code mit einem Signal 1 anfangenbool TriggerState = false;
    void Commands::commandLoop() {
      TriggerState = digitalRead(28);  delay (5);
        // while(true) {#ifdef DEBUG_PRINT    debugWaitLoop = 1;#endif    Printer::breakLongCommand = false; // block is now finished    if (!Printer::isBlockingReceive()) {#if SDSUPPORT        if (sd.sdmode == 20) {            if (PrintLine::linesCount == 0) {                sd.pausePrintPart2();            }        }        if (sd.sdmode == 21) {            if (PrintLine::linesCount == 0) {                sd.stopPrintPart2();            }        }#endif        GCode::readFromSerial();        GCode* code = GCode::peekCurrentCommand();        // UI_SLOW; // do longer timed user interface action        UI_MEDIUM; // do check encoder        if (code) {#if SDSUPPORT            if (sd.savetosd) {                if (!(code->hasM() && code->M == 29)) // still writing to file                    sd.writeCommand(code);                else                    sd.finishWrite();#if ECHO_ON_EXECUTE                code->echoCommand();#endif            } else#endif                      if (TriggerState = !lastTriggerState) {            Commands::executeGCode(code);            code->popCurrentCommand();            lastCommandReceived = HAL::timeInMilliseconds();            lastTriggerState = TriggerState;          }                        } else {            if (PrintLine::hasLines()) { // if printing no need to reset                lastCommandReceived = HAL::timeInMilliseconds();            }            if (HAL::timeInMilliseconds() - lastCommandReceived > 2000) {                lastCommandReceived = HAL::timeInMilliseconds();                Printer::parkSafety(false); // will handle allowed conditions it self            }        }    }        else {        GCode::keepAlive(Paused);  //Warum paused?, weil erste if Bedingung nur true ist, wenn keine user interaktionen stattfinden        UI_MEDIUM;    }
        Printer::defaultLoopActions();    //}}
  • The code above got a bit messy in terms of formatting, so here it is again.



    void Commands::commandLoop() {

      TriggerState = digitalRead(28);
      delay (5);

        // while(true) {
    #ifdef DEBUG_PRINT
        debugWaitLoop = 1;
        Printer::breakLongCommand = false; // block is now finished
        if (!Printer::isBlockingReceive()) {
    #if SDSUPPORT
            if (sd.sdmode == 20) {
                if (PrintLine::linesCount == 0) {
                    sd.pausePrintPart2();
                }
            }
            if (sd.sdmode == 21) {
                if (PrintLine::linesCount == 0) {
                    sd.stopPrintPart2();
                }
            }
            GCode::readFromSerial();
            GCode* code = GCode::peekCurrentCommand();
            // UI_SLOW; // do longer timed user interface action
            UI_MEDIUM; // do check encoder
            if (code) {
    #if SDSUPPORT
                if (sd.savetosd) {
                    if (!(code->hasM() && code->M == 29)) // still writing to file
                        sd.writeCommand(code);
                    else
                        sd.finishWrite();
    #if ECHO_ON_EXECUTE
                    code->echoCommand();
                } else
               
              if (TriggerState = !lastTriggerState) {
                Commands::executeGCode(code);
                code->popCurrentCommand();
                lastCommandReceived = HAL::timeInMilliseconds();
                lastTriggerState = TriggerState;
              }
                   
            } else {
                if (PrintLine::hasLines()) { // if printing no need to reset
                    lastCommandReceived = HAL::timeInMilliseconds();
                }
                if (HAL::timeInMilliseconds() - lastCommandReceived > 2000) {
                    lastCommandReceived = HAL::timeInMilliseconds();
                    Printer::parkSafety(false); // will handle allowed conditions it self
                }
            }
        }
       
        else {
            GCode::keepAlive(Paused);  //Warum paused?, weil erste if Bedingung nur true ist, wenn keine user interaktionen stattfinden
            UI_MEDIUM;
        }

        Printer::defaultLoopActions();
        //}
    }
  •   delay (5);
    is not necessary. 

    As a test replace
    TriggerState = digitalRead(28);
    with
    TriggerState = ! TriggerState;

    to see if it would still execute. Should apart the fact  that you broke sd write. If it now works it is only that line not getting changing signals.

    Did you define pin 28 as input pin in setup?

    Also note that with this throtteling host/server might create timeouts, also I hope that busy would still get send preventing it.
  • thanks again for the fast reply.

    Yes, ive already definde pin 28 in setup as input.
    I've tried a program that counted incoming signals, and everything worked fine there. So, TriggerState = digitalRead(28); is working, but I'll give it a try the way you've written it, just to be sure.
    Next up im gonna uncomment all the debugs in Repetier.h and look into the possible debug messages.

    If you got any other ideas, why its not working, pls letme know  :)

  • Right after connecting to the extruder, the log shows 'busy: processing'. I always get this, regardless of whether I send signals or not. For the log, see below.
    I suspect something might be wrong with the buffers, but I couldn't find anything. I've also tried increasing the buffer sizes.

    10:25:24.573 : OpenGL version:4.6.0 NVIDIA 471.41
    10:25:24.573 : OpenGL renderer:Quadro P600/PCIe/SSE2
    10:25:24.573 : Using fast VBOs for rendering is possible
    10:25:28.497 : Printer reset detected - initializing
    10:25:28.498 : start
    10:25:28.498 : Info:PowerUp
    10:25:28.712 : N1 M110*34
    10:25:28.712 : N2 M115*36
    10:25:28.712 : N3 M105*36
    10:25:28.712 : N4 M114*35
    10:25:28.712 : N5 M111 S6*98
    10:25:28.722 : N6 T0*60
    10:25:28.722 : N7 M20*22
    10:25:28.724 : N8 M80*19
    10:25:29.715 : XY jerk was too low, setting to 25.42
    10:25:29.716 : Z jerk was too low, setting to 1.77
    10:25:29.719 : Free RAM:81480
    10:25:29.904 : SD init fail
    10:25:29.909 : SD initialization failed.
    10:25:29.909 : Do not reformat the card!
    10:25:29.913 : Is the card correctly inserted?
    10:25:29.917 : Is chipSelect set to the correct value?
    10:25:29.921 : Does another SPI device need to be disabled?
    10:25:29.921 : Is there a wiring/soldering problem?
    10:25:29.925 : errorCode: 32
    10:25:29.926 : SelectExtruder:0
    10:25:29.930 : FlowMultiply:100
    10:25:29.930 : ok
    10:25:29.934 : ok 2
    10:25:29.954 : N9 M220 S100*104
    10:25:29.954 : N10 M221 S100*81
    10:25:29.954 : N11 M111 S6*87
    10:25:29.955 : FIRMWARE_NAME:Repetier_1.0.4 COMPILED:Dec 20 2023 FIRMWARE_URL:https://github.com/repetier/Repetier-Firmware/ PROTOCOL_VERSION:1.0 MACHINE_TYPE:Mendel EXTRUDER_COUNT:1 REPETIER_PROTOCOL:3
    10:25:29.955 : Cap:PROGRESS:1
    10:25:29.955 : N12 T0*9
    10:25:29.955 : Cap:AUTOREPORT_TEMP:1
    10:25:29.955 : Cap:HOST_RESCUE:0
    10:25:29.955 : N13 M155 S1*82
    10:25:29.956 : Cap:EEPROM:0
    10:25:29.956 : Cap:AUTOLEVEL:0
    10:25:29.956 : Cap:Z_PROBE:0
    10:25:29.958 : Cap:SOFTWARE_POWER:0
    10:25:29.958 : Cap:TOGGLE_LIGHTS:0
    10:25:29.958 : Cap:PAUSESTOP:1
    10:25:29.962 : Cap:PREHEAT:1
    10:25:29.962 : Cap:EMERGENCY_PARSER:1
    10:25:29.966 : PrinterMode:FFF
    10:25:29.966 : ok 3
    10:25:31.956 : busy:processing
    10:25:33.955 : busy:processing
    10:25:35.954 : busy:processing

Sign In or Register to comment.