vlachoudis / bCNC

GRBL CNC command sender, autoleveler and g-code editor
GNU General Public License v2.0
1.57k stars 533 forks source link

Pendant Web Interface - Question #1121

Open qvisionsa opened 5 years ago

qvisionsa commented 5 years ago

I'm writing a new web interface for bCNC Pendant, using bootstrap 4 and font awesome. When testing the interface without using bCNC web server, all looks fine. Using bCNC web server, I miss all icons from font awesome. Is there some configuration parameter that I have to change or add?

Harvie commented 5 years ago

Hi! Thanks for your interest. Please coordinate your efforts with @PCSDIAS at #930 I would love to have nice web pendant with 2D joystick pad that i could easily jog using single finger without looking at phone.

Harvie commented 5 years ago

I miss all icons from font awesome

Please chceck if the icons are served with proper mime-type HTTP header.

PCSDIAS commented 5 years ago

Would it be possible to share with us the html, js and css files?

qvisionsa commented 5 years ago

I wish you a happy new year! Of course! I’m currently designing the interface and I can send you some screenshots and hear from you your thoughts.

Regards

Stelios Malakoudis QVISION SA


Από: PCSDIAS notifications@github.com Στάλθηκε: Δευτέρα, Δεκεμβρίου 31, 2018 22:27 Προς: vlachoudis/bCNC Κοιν.: QVision SA Mail; Author Θέμα: Re: [vlachoudis/bCNC] Pendant Web Interface - Question (#1121)

Would it be possible to share with us the html, js and css files?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/vlachoudis/bCNC/issues/1121#issuecomment-450687746, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AWTTaRV32FOTlY3R9eAE1Lv_flvDphnqks5u-nMjgaJpZM4Zkojh.

qvisionsa commented 5 years ago

This is my first approach for machine control. As you can see, I plan to implement the interface using tabs. The screenshots are for an iphone 6. I would like to hear your suggestions. screen2 screen1

PCSDIAS commented 5 years ago

There is not much to invent in a bCNC GUI. IMHO the original layout has only two problems: 1. resizing does not work very well in the cell phone screen and 2. awkward jogging control. How do you intend to address these issues in your project?

qvisionsa commented 5 years ago

The first problem I will try to solve (and I'm close enough) is resize screen for small devices. The second problem is that the screen space in small devices are not enough for all controls. My approach to use tabs and switching between them with a fingertip, give us the way to have more controls on the web pendant. As soon as I finish coding, I will let you know.

PCSDIAS commented 5 years ago

Dear Stelios Malakoudis

I have shared with you on https://www.dropbox.com/s/giic9he6c2vjci1/bCNCPendant.zip?dl=0 an almost fully functional bCNC Pendant I developed for my needs. I hope it can help on your project. Please, keep aware that I not a programmer by trade. I was just someone trying to find a solution with the available means.

If you want to give it a try, please, save a backup copy of “CNC.PY”, “PENDANT.PY” and “INDEX.HTML” original files before copying my files. I had to patch the “PY” files because I wanted:

  1. to use the GRBL v1.1 new Jogging mode (see https://github.com/gnea/grbl/wiki/Grbl-v1.1-Jogging) and
  2. to be able to store the machine zero in the cell phone instead of in the arduino finite life flash memory.

If you want to implement a 2-D joystick in the way Tomas Mudrunka has suggested elsewhere, I recommend the approach found on https://www.kirupa.com/html5/drag.htm. https://www.kirupa.com/html5/drag.htm

Happy New Year.

Paulo

Em ter, 1 de jan de 2019 às 08:31, Stelios Malakoudis < notifications@github.com> escreveu:

The first problem I will try to solve (and I'm close enough) is resize screen for small devices. The second problem is that the screen space in small devices are not enough for all controls. My approach to use tabs and switching between them with a fingertip, give us the way to have more controls on the web pendant. As soon as I finish coding, I will let you know.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/vlachoudis/bCNC/issues/1121#issuecomment-450721018, or mute the thread https://github.com/notifications/unsubscribe-auth/AaOeh9oUeqwxPj8OMLmzWCzRK_8zNB2Bks5u-zjwgaJpZM4Zkojh .

qvisionsa commented 5 years ago

@PCSDIAS @Harvie Thanks for sharing your solution. IMHO the buttons are very close to each other and are somehow confusing. I try to have distances between the button to avoid accidents. The screenshot bellow is the second tab that I start implementing. The rotary dial will move the gantry (XYZ) according to a step given from a slider. screen shot 2019-01-03 at 02 52 58

Regarding the virtual joystrick, I will give a try to the following: http://yoannmoinet.github.io/nipplejs/#demo

Harvie commented 5 years ago

@PCSDIAS @qvisionsa I don't really have time to work on this, but since there are two of you, i hope you can find some agreement on what has to be done and make single pendant with best ideas of both of you.

I think it would be nice if we can switch between 1D and 2D joystick like this:

http://jeromeetienne.github.io/virtualjoystick.js/examples/basic.html

sometimes i would really love to jog at an angle, especialy when i use jogging to manualy mill away some defects. but i understand it's also important to be able to lock jogging only to single axis. but such joystick code can be reused for both 1D and 2D jogging.

I am looking forward to see what you two can come up with together. i will happily merge such code if it will work.

PCSDIAS commented 5 years ago

@qvisionsa @Harvie Since there is an intention of sharing the final code with the community I think that agreeing in a minimum of constraints and goals beforehand would be beneficial for our success.

Here goes my suggestion.

  1. Pendant must be able to function on the common browsers and mobile operating systems.
  2. The pendant must fit at most on two pages, without need of scrolling left-right or up-down on the target screen.
  3. Pages must be presented in full-screen in order to save space and avoid distraction.
  4. In the case of two pages, the main one must present the most used commands. Less used commands must be left for the secondary page.
  5. Switching from one page to the other must be easily done.
  6. Pages must not use any Internet resource in order to function appropriately.
  7. Buttons must be clearly labeled and distinguishable from each other.
  8. Buttons and informational labels must be seen clearly from 1 meter (3 feet) by people with “normal” vision.
  9. Jog control must actuate on the X and Y directions simultaneously with user option to lock movement in one axis only. The Z axis jogging will be controlled independently from the X and Y axes.
  10. Jog speed commanded by the distance between the joystick actual and rest positions by a non linear law in order to allow slow (fine) and quick (coarse) position adjustments.
  11. '$J=' and 0x85 Ascii Realtime Command must be used to start and cancel jogging. Commands employed to start and stop the jogging movement must be in accordance with the firmware and version that runs on the CNC control board. If possible, code must identify the firmware and select the appropriate jogging method automatically. Otherwise, user input will be required.
  12. A “manifest.json” file must be provided in order allow installation of the pendant as a Web App.
  13. As much as possible, information needed after power-off-on cycling must be stored in the browser, instead of in the arduino flash memory in order to extend its life.

That’s is all I can think of at this moment. Please consider it only as a starting point.

Harvie commented 5 years ago

https://github.com/gnea/grbl/wiki/Grbl-v1.1-Jogging#joystick-implementation

Harvie commented 5 years ago

'$J=' and 0x85 Ascii Realtime Command must be used to start and cancel jogging.

Please note that bCNC also supports Grbl 0.x and Smoothieboard, where this is not available. So there should be fallback for those cases.

Harvie commented 5 years ago

@PCSDIAS you should be able to edit your own comments. click on the three dots in corner of the comment. i've edited that for you.

See: https://github.com/vlachoudis/bCNC/tree/master/bCNC/controllers

There is _GenericController.py file, where i have generic jogging method using G0 Then there is GRBL1.py, where i have overrided that method to use $J= This is how i implement differences between various controllers. If controller does not provide its own jogging method it gets taken from the generic one. Also theres generic grbl, which is inherited to both GRBL0 and GRBL1 unless one of them overrides it.

Now if i call self.app.mcontrol.jog("X%s"%(self.step.get())), different code is executed for smoothieware and different for grbl1. Autodetection is already there. Just put your code to right class and everything will switch automaticaly when you switch controller. Also this makes it WAAAY easier to add support for new controllers.

So if you implement controller specific code it MUST be done this way. I don't want to have crazy if trees in rest of bCNC code. That was just too messy and hard to maintain and i am glad we got rid of that. It took me lot of time to untangle that.

qvisionsa commented 5 years ago

@PCSDIAS @Harvie I read the suggestions written by @PCSDIAS and I think that we can implemented. The problem is what @Harvie suggests. I'm using a xPro v2 controller in my machine. I can't test other controllers. How can we do this? (I should also remind you that I am a newbie in python but I'm trying)

Right now, I'm in the process of testing the rotary dial (as the last screenshot). $J motions are going very well but I can't find a method to stop jogging using 0x85. I read the solution mentioned by @PCSDIAS but it didn't worked for me. I tried to implement the sendHex() function from Sender.py to send 0X85 but it didn't work.

        #----------------------------------------------------------------------
    # Send to controller a gcode or command
    # WARNING: it has to be a single line!
    #----------------------------------------------------------------------
    def sendGCode(self, cmd):
        if (cmd == "$J=0"):
            if self.serial is None: return
            hxCode = '0X85'
            self.serial.write(chr(int(hxCode,16)))
            self.serial.flush()
            return

        if self.serial and not self.running:
            if isinstance(cmd,tuple):
                self.queue.put(cmd)
            else:
                self.queue.put(cmd+"\n")

I didn't test to send it directly like self.serial.write(chr("0X85"))

Do you have any suggestions?

PCSDIAS commented 5 years ago

@Harvie, Thanks for being kind enough to edit my last posts and teaching me how to do. I owe you this. Regarding the Python files stuff you have indicated I am still trying to digest it since I know very little about Python programming. In this way I have the impression that we should concentrate our efforts in solving the problem as much as possible in the pendant itself, i.e. on the “,js”, “.css” and “.html” files on the guest side. Probably, the “pendant.py” file may be patched in order to handle a few new communication needs. This would be my approach, since I really do not feel comfortable to commit myself in doing something that I am not prepared to.

@qvisionsa. Trying to send the stop jogging command was the reason that I joined this discussion. I tried everything I could imagine until I gave up and decided to do it in the other way around. The problem was solved in two fronts.

Firstly, “pendant.py” file was patched to handle a new command, “STOPJOG”, that would cause the bCNC emptying the its command queue and sending the desired “0X85” code to the GRBL. Then the GRBL would empty its command queue and stop.

image

Secondly, the pendant page "script.js" sends “STOPJOG” to bCNC whenever the joystick comes to the rest position.

image

I would risk being wrong, but I suppose you can check this solution in the last files I have shared with you. Please, feel free to ask if this solution does not work for you.

I am aware that above solution is just a solution, not the best solution. Now, I would like to propose what I think is more general and expandable. It consists of adding three new handlers to “Pendant.py” in order to:

  1. inform the CNC board firmware name and version in reply to the page request “/firmware”;
  2. empty the bCNC buffer in reply to the page request "/send?cmd=flush”; and
  3. send an extended-ASCII character to the CNC board in reply to page request "/send?gcode=XHH where HH is the hexadecimal code value.

Paulo.

qvisionsa commented 5 years ago

@PCSDIAS Thank you for sharing your code. I've tested your solution and it didn't worked for me. I will try it again to see if I mistake somewhere. Reading the source code of pendant.py and sender.py, I understand that pendant.py put in queue all the received commands from web interface and then sender.py is responsible to deal with the queue. Please correct me if I'm wrong.

@Harvie @PCSDIAS Is there a method to bypass this queue and send Jog Cancel command for immediate execution?

Harvie commented 5 years ago

Stopjog will not work unless you jog using $J=

PCSDIAS commented 5 years ago

@qvisionsa If I may, I would like to suggest you another course of action. This afternoon I downloaded a fresh copy of bCNC release 0.9.11 and installed it in temporary folder of the PC. In this way I had two parallel bCNC 0.9.11 installations, the old and the new ones. The old installation served the pendant I developed and the new served the original pendant. Except by this difference the new and the old installations worked without any fail. It was not possible to run the two programs simultaneously because I had only one GRBL board available, but I think this is not important for the test purposes. Then I did what I have told you to do.

  1. Stopped the original pendant and closed the new bCNC progran.
  2. Renamed “index.htm” and “Pendant.py” to “index.html.bak” and “Pendant.py.bak” in order to have backup copies. I did not deal with the "CNC.py" file because I was wrong to include it in the zip file. It does not interfere with this issue.
  3. Copied the same files I have sent you in the appropriate folders, except by the "CNC.py".
  4. Restarted the new bCNC installation and opened the pendant in Google Chrome DevTools (https://developers.google.com/web/tools/chrome-devtools/?hl=en-us) in order to watch the message exchange between the bCNC server and the Pendant page. A printscreen follows.
  5. Watched the message exchange between the bCNC and GRBL in the bCNC terminal pane. A printscreen follows
  6. It was possible to start and stop the jogging in all the three axes without fail.

I think at this moment you should put aside the form of the GUI and concentrate on the communication between the pendant page and the bCNC server itself. Repeat the above experience in order to acquire confidence that the method works. After that you can return to the GUI honing.

Chrone DevTools image

bCNC terminal image The numbers enclosed in the curly brackets are just leftovers of the debugging process. Observe how the \x85 character is represented image

I am not aware of the pedant server providing any command to clear the bCNC queue. I have searched the original "Pendant.py" and "index.html" files with no success. That is why I implemented the queue clearing patch in the "Pendant.py" file.

Hope this helps you

Paulo

Harvie commented 5 years ago

It was not possible to run the two programs simultaneously because I had only one GRBL board available

https://github.com/grbl/grbl-sim

PCSDIAS commented 5 years ago

@Harvie Thanks for pointing this out.

qvisionsa commented 5 years ago

@Harvie @PCSDIAS I'm sending the web interface that I'm designing. Is not finished yet... The motion on the rotary dial (second tab) it's only for Y axis. If you think that it's in the right way, please let me know.

My code is in index2.html

Pendant.py have to be amended as

        global webpath

        #handle certain filetypes
        filetype = page.rpartition('.')[2]
        if   filetype == "css": self.do_HEAD(content="text/css")
        elif filetype == "js":  self.do_HEAD(content="application/x-javascript")
        elif filetype == "json": self.do_HEAD(content="application/json")
        elif filetype == "jpg" or filetype == "jpeg" : self.do_HEAD(content="image/jpeg")
        elif filetype == "gif": self.do_HEAD(content="image/gif")
        elif filetype == "png": self.do_HEAD(content="image/png")
        elif filetype == "ico": self.do_HEAD(content="image/x-icon")
        elif filetype == "svg": self.do_HEAD(content="image/svg+xml'") #[+]
        elif filetype == "ttf": self.do_HEAD(content="application/font-sfnt'") #[+]
        elif filetype == "eot": self.do_HEAD(content="application/vnd.ms-fontobject'") #[+]
        elif filetype == "woff": self.do_HEAD(content="application/font-woff'") #[+]
        elif filetype == "woff2": self.do_HEAD(content="application/font-woff2'") #[+]
        else: self.do_HEAD()

        if page == "": page = "index.html"
        try:
            f = open(os.path.join(webpath,page),"rb") #[+]
            self.wfile.write(f.read())
            f.close()
        except IOError:
            self.wfile.write("""<!DOCTYPE html>

@PCSDIAS Tomorrow with fresh mind I will test again your solution.

qvisionsa commented 5 years ago

@PCSDIAS Looking your terminal, I saw that your feed and motion to X axis are small. Have you tested with higher values? Like F1000 and X10

PCSDIAS commented 5 years ago

@qvisionsa The code samples the joystick displacement from the rest position 20 times per second. When the displacement is more than a minimum value a feedrate proportional to it is calculated and the incremental distance that the tool would move with this feedrate in 50 ms is also calculated. A jogging gcode with these feedrate and incremental distance is generated and sent to the GRBL. In my case with a 250mm/min maximum feedrate this distance will never exceed 0.2 mm. The relation between the range/joystick value and the rate is cubic in order to allow fine(slow) and coarse (fast) adjustments. The extreme range/joystick values correspond to a feedrate of 250, my machine maximum. I have to set a minimum value and not zero as the rest position because of the numeric precision. If the memory serves me well, this minimum value is 0.5.

PCSDIAS commented 5 years ago

@qvisionsa "Right now, I'm in the process of testing the rotary dial (as the last screenshot). $J motions are going very well but I can't find a method to stop jogging using 0x85. I read the solution mentioned by @PCSDIAS but it didn't worked for me. I tried to implement the sendHex() function from Sender.py to send 0X85 but it didn't work"

I just found out that the easiest way to send the extended ASCII character “0x85” is to send the percent URL encoded "/send?gcode=%85". Just this.

I have run the pendant you sent on Chrome DevTools. It was not possible to render the button and tab labels written with the awesome font. I suggest using an alternative text just in case the icons are not displayed.

I did not understand what the role of the second tab is.

Chrome DevTools image

Paulo

qvisionsa commented 5 years ago

@PCSDIAS Did you alter the pendant.py as I mentioned? If so, and you're still having problem with font awesome, please un-comment in index2.html the line

and comment out the line

This way, font awesome will be served form CDN and the problem will be solved.

Please give a try an d let me know.

I'm currently testing your code again and I'm in a good point. But I still I have a problem.

qvisionsa commented 5 years ago

@PCSDIAS Did you patched the pentant.py file to support the new MIME types as I mentioned?

PCSDIAS commented 5 years ago

I have forgoten. I am going to try again with the patched pendant.py

PCSDIAS commented 5 years ago

I have patched the file. The awesome fonts are not rendered yet. I fear I do not get which are the lines to comment and uncomment in index2.html.

qvisionsa commented 5 years ago

@PCSDIAS Please replace current code in index2.html with this

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <!-- <link rel="stylesheet" href="css/font-awesome.min.css"> -->
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link rel="stylesheet" href="css/bootstrap4-toggle.min.css">
    <link rel="stylesheet" href="css/bootstrap-slider.min.css">
    <link rel="stylesheet" href="css/jquery.rotaryswitch.css">
    <title>bCNC Pendant</title>
</head>
qvisionsa commented 5 years ago

@PCSDIAS If you want to load font awesome localy, then in pendant.py find

                #handle certain filetypes
        filetype = page.rpartition('.')[2]
        if   filetype == "css": self.do_HEAD(content="text/css")
        elif filetype == "js":  self.do_HEAD(content="application/x-javascript")
        elif filetype == "json": self.do_HEAD(content="application/json")
        elif filetype == "jpg" or filetype == "jpeg" : self.do_HEAD(content="image/jpeg")
        elif filetype == "gif": self.do_HEAD(content="image/gif")
        elif filetype == "png": self.do_HEAD(content="image/png")
        elif filetype == "ico": self.do_HEAD(content="image/x-icon")

and add add

                elif filetype == "svg": self.do_HEAD(content="image/svg+xml'") #[+]
        elif filetype == "ttf": self.do_HEAD(content="application/font-sfnt'") #[+]
        elif filetype == "eot": self.do_HEAD(content="application/vnd.ms-fontobject'") #[+]
        elif filetype == "woff": self.do_HEAD(content="application/font-woff'") #[+]
        elif filetype == "woff2": self.do_HEAD(content="application/font-woff2'") #[+]
PCSDIAS commented 5 years ago

@qvisionsa The awesome fonts finally appeared. image

If you understand that "Command to send" is a gGode command to be sent to the GRBL you should use "/send?gcode=", not "/send?cmd=". I also think you should check how the url encoding is working. I tried to send %85 but the page sent image

Altough button Mist On/Off changes its appearance when clicked, the GUI does not send anyhing to the bCNC server.

Paulo

qvisionsa commented 5 years ago

@PCSDIAS I'm happy that UI is working for you. As I mentioned in my previous comment, the zip file that I shared is not finished. Regarding "Command to send": the prototype index.html says Command Send button. Send button is calling (via onclick) send?cmd. This is why I used this phrase. But we can changed any time if it is wrong. Regarding url encoding: % is special character that is used for url encoding. The value of cmd parameter translates to x85. Correct me if I'm wrong. For my bCNC installation, all parameters comes in this format, even those of prototype index.html

Today I tested again your solution adapted to mine. Finally 0X85 is sent but the machine stops for some time (ms) and continue to send the rest of jog the commands.

Regarding the UI, the displayed numbers are buttons that set current position to 0.

qvisionsa commented 5 years ago

@PCSDIAS Looking your script.js file I've found some funtions (like startJogging() and returnToZero()) that think that are not called. How you use these functions?

Harvie commented 5 years ago

@PCSDIAS Have you tried "SENDHEX 85" command? It works in bCNC commandline. It could make sense to have HTTP api for sending arbitrary HEX characters.

PCSDIAS commented 5 years ago

@qvisionsa “Regarding "Command to send": the prototype index.html says Command Send button. Send button is calling (via onclick) send?cmd.”

You are right. I suggest you to leave it the way it is. It much more useful since user can use it to send bCNC internal commands and g-code as https://github.com/vlachoudis/bCNC/wiki/CommandLine shows.

“Regarding url encoding: % is special character that is used for url encoding. The value of cmd parameter translates to x85. Correct me if I'm wrong.”

Since “Command to send” also works with raw g-codes, I tested it with “G0 X100 F100”. The pendant sent “/send?cmd=g0%2520x100%2520f100 ”. I expected that the spaces would be converted to “%20”, not “%2520”. Anyway, since bCNC executed the g-Code, I do not think this is a problem.

“Today I tested again your solution adapted to mine. Finally 0X85 is sent but the machine stops for some time (ms) and continue to send the rest of jog the commands.”

Is this also true with my solution? If yes, I am in trouble. If not, please, check if when you try to stop jogging the bCNC buffer is cleared firstly and then the famous “\085 is sent to the GRBL.

“Looking your script.js file I've found some funtions (like startJogging() and returnToZero()) that think that are not called. How you use these functions?”

They are called when user starts and stops moving the range/joytick. image

@Harvie “Have you tried "SENDHEX 85" command? It works in bCNC commandline. It could make sense to have HTTP api for sending arbitrary HEX characters.”

Yes, I have tried sending the following commands

Command     Response
“ABOUT”     The about box appears
“G0X100F100”    Command executed and copied to the terminal pane.
“123456”    Popup warning “Invalid Command 123456”.
“SENDHEX 85”    Nothing happens. Silent terminal pane.  I did not monitored the
        GRBL serial line.

Anyway, I am very happy with percent url encoding. It does the job of sending extended char codes. I think this a typical guest side question that has already a native solution. BTW, I am going to propose an update of our list of constraints and goals to reflect what I learned in this process.

Paulo

Harvie commented 5 years ago

I just found out that the easiest way to send the extended ASCII character “0x85” is to send the percent URL encoded "/send?gcode=%85". Just this.

@PCSDIAS perfect, i didn't noticed the mention. So i guess there's no need of STOPJOG command being implemented... But i think it would make sense to add info about controller type to JSON served at /state URL, so pendant can tell if it's possible to use $J= or not.

qvisionsa commented 5 years ago

@Harvie SENDHEX 85 does not return neither “ok” nor “error”. This command it’s sent via sendHex function of sender.py. It’s returning nothing. I tried hard to really empty the cache before sending 0x85 command, but neither of my actions succeeded. I’ Feeling like to hit my head over the wall. Your approach to use controllers overrides, I think is the best. For example, pendant.py must send ‘STOPJOG’ for everyone. Then, according to witch controller is used, sender will executed the appropriate code.

qvisionsa commented 5 years ago

@PCSDIAS you must find a way to test your code with bigger values. I’m using $J=G91Y10F100 and the code is not working well enough. It stops for a moment (with 0x85) and then execute the rest of the commands. This means that the queue isn’t cleared. If you try it with my UI and turn the rotary jog on the second tab really fast, the queue will be filled enough and when try to flush the cache, the cache isn’t flushed.

PCSDIAS commented 5 years ago

@qvisionsa The GUI I sent you allows jogging feedrates up to 250, my CNC maximum. The range/joystick controls the feedrate, not the displacement. It works like a gas pedal or accelerator in a car. If the range/joystick control is brought to the left or right extremity you will get the 250 feedrate. The jogging direction will be set by the sense of the range/joystick movement.

Now speaking about your project.

Would you mind to send me screenshots of bCNC terminal message exchage with GRBL, when the problem happens? If possible, network activity screenshots also. I also would like to know how the jog message parameters are calculated in your own words and a print of the GRBL settings obtained via command $$. The more information the better. Paulo

qvisionsa commented 5 years ago

@Harvie @PCSDIAS I think we are on the wrong way, trying to empty the cache before sending 0x85. As per gnea/grbl instructions, 0x85 command belongs to "Extended-ASCII Realtime Commands" So according gnea/grbl: 0x85 : Jog Cancel

  1. Immediately cancels the current jog state by a feed hold and automatically flushing any remaining jog commands in the buffer.
  2. Command is ignored, if not in a JOG state or if jog cancel is already invoked and in-process.
  3. Grbl will return to the IDLE state or the DOOR state, if the safety door was detected as ajar during the cancel.

So we do not need to empty the cache. And I think that is the wrong cache this one that we try to empty. Because Queue is a python queue in pc memory. The commands that we try to cancel are already to grbl buffer (see 1).

Please correct me if I'm wrong.

PCSDIAS commented 5 years ago

@Harvie I am not an expert on bCNC and know almost nothing about Python. My reasoning is merely practical based on my experience and hands-on work. GRBL has a buffer of 80 chars if remember well. bCNC has a queue also. I do not know the method bCNC uses to feed GRBL, but I suppose that as soon as bCNC detects that the GRBL buffer has room enough to accomodate the first gcode line on its queue sends it to GRBL and erases it. The goal of the bCNC is to supply the GRBL with data without buffer underrun or overrun. Buffer underrun will cause a jerky moviment and buffer overrun will cause loss of data.

This guess was confimed at the beggining of my project when I notíced on the terminal pane that after sending the 0x85 char to stop the jogging the bCNC sent a few extra g-code lines and sttoped. It has been like the bCNC has some kind of memory. At that time I did not know that bCNC has a queue. I searched for an explanation of this behaviour in the code and found the global queue. Then I have got a little piece of code for clearing the queue in StackExchange, patched Pendant.py and sucess.

In the case of jogging the effect of buffer underrun is much worst than the effect of overrun due its impact on a steady movement. The way the Jog command parameters are calculated may leave a few non-executed commands on the bCNC queue after trying to stop. In order to send the stop order to GRBL immediatelly, these commands must be wiped beforehand. The 0x85 command will always be the last one on the bCNC queue.

Sorry for the spelling errors. I write this on a cell phone with the (uninvited and stuborn) help of a spelling checker for Portuguese.

Paulo

qvisionsa commented 5 years ago

@PCSDIAS These are my grbl parameters.

$$
$0=10
$1=255
$2=0
$3=0
$4=0
$5=0
$6=0
$10=19
$11=0.010
$12=0.002
$13=0
$20=1
$21=1
$22=1
$23=0
$24=1000.000
$25=2000.000
$26=250
$27=2.000
$30=1000
$31=0
$32=0
$100=106.670
$101=106.670
$102=800.000
$110=5000.000
$111=5000.000
$112=500.000
$120=80.000
$121=80.000
$122=50.000
$130=803.000
$131=1233.000
$132=60.000
ok
$G
[GC:G0 G54 G17 G21 G90 G94 M5 M9 T0 F0 S0]
ok

Right now, I'm unable to send you the screenshots you asked because I changed quite everything. I ran some manual tests and I saw that 0X85 command is working fine if a jog command is in progress. Otherwise, if you send multiple jog commands, then 0X85 stops the command that is in progress but it is not clearing the machine buffer.

You can try it like this:

  1. From bCNC command (not prom pendant) send $J=G91X100F30
  2. While the command is in progress issue a new one SENDHEX 85 As you will see, jog stops immediatly.

In a second scenario,

  1. Send multiple commands like $J=G91X5F30
  2. Send a SENDHEX 85 while your are in the middle of sending the above commands.

You will see what hapens...

PCSDIAS commented 5 years ago

@qvisionsa Thanks for giving me the chance of demonstrating my point.

Now, let‘s do some calculations with the $J=G91X5F30 g code line.

A feed rate of 30 mm/min and a displacement of 5 mm corresponds to 5*60/30 = 10 seconds. Then this particular jog command will take 10 seconds to be executed i.e. 0.1 commands per second. The GRBL look ahead buffer can hold up to 17 lines of code (https://github.com/grbl/grbl/wiki/Interfacing-with-Grbl#streaming-protocol-simple-send-response-recommended-for-grbl-v09). These 17 lines of code takes 17/0.1 = 170 seconds for execution. In other words if you send more than 17 of these lines in less than 170 seconds the bCNC will have to stop feeding the GRBL buffer since it will be full. In this case bCNC keep these lines in its queue waiting until the GRBL buffer has space enough to accommodate a new g-code line. Same as it happens when you board a plane.

What happens when there are lines in the bCNC queue waiting and you issue a SENDHEX 85 command? bCNC is not aware that this command has priority and should pass by all the others that wait in line in order to feed GRBL, as soon there is space in its buffer. Instead, bCNC puts this priority command at the end of the queue. GRBL will receive it too late to be effective

That is the reason I keep saying that as soon you decide to stop jogging you have to clear the bCNC queue in order to allow GRBL to receive the priority command /0x85 immediately.

Please verify in the following screenshot the two boxes above the Command input Box. The upper one shows the communication between bCNC and GRBL. The lower one shows the buffered commands waiting for room in the GRBL buffer.

image

You can see that there are at least 5 commands in bCNC queue. If the SENDHEX 85 command is sent at this exact time it will take 5*10 = 50 seconds, almost a minute to enter in the GRBL buffer. That’s too long for a jogging operation.

Paulo

PCSDIAS commented 5 years ago

@Harvie I found “bCNC.bat” and ‘bCNC.exe” in the pre-release 0.9.14.29.beta.exe package and tried to run both. Only the last one worked. I suggest removing “bCNC.bat” from the package, if it is not needed anymore.

I also have noticed that the Pendant element below is rendered as image

<div class="pure-g border">
<img src="/canvas?1547037753197?1547037754195?1547037755195?1547037756195?1547037757194?1547037758195?1547037759194?1547037760195?1547037761196?1547037762194?1547037763194?1547037764194?1547037765194?1547037766194?1547037767193?1547037768194?1547037769196?1547037770193?1547037771194?1547037772193?1547037773195?1547037774193?1547037775193?1547037776194?1547037777193?1547037778193?1547037779193?1547037780194?1547037781194?1547037782194?1547037783192?1547037784194?1547037785193?1547037786194?1547037787193?1547037788193?1547037789194?1547037790193?1547037791194?1547037792193?1547037793194?1547037794194?1547037795194?1547037796193?1547037797193?1547037798193?1547037799193?1547037800195?1547037801193?1547037802197?1547037803195?1547037804197?1547037805195?1547037806195?1547037807196?1547037808194?1547037809194?1547037810194?1547037811192?1547037812194?1547037813194?1547037814193?1547037815193?1547037816194?1547037817193?1547037818193?1547037819194?1547037820193?1547037821193?1547037822194?1547037823193?1547037824195?1547037825198?1547037826195?1547037827198?1547037828196?1547037829196?1547037830197?1547037831195?1547037832194?1547037833196?1547037834195?1547037835195?1547037836198?1547037837194?1547037838195?1547037839195?1547037840194?1547037841194?1547037842194?1547037843194?1547037844194?1547037845197?1547037846195?1547037847195?1547037848194" id="cnc-canvas" class="canvas">
</div>

The Python console window shows these message when the pendant is started. The text in portuguese can be translated as "An established connection was aborted by the software on the host computer" image

The DevTools Network Pane shows that the bCNC server does not start replying the canvas requests as soon as the Pendant is initiated.

image

Paulo

Harvie commented 5 years ago

@PCSDIAS .exe is outdated a lot. If you want to develop bCNC, you have to run it straight from git master source code (you have to install python2.7 with tkinter and pip first). See wiki for installation howto. If you don't do this, you will be working on legacy code and there will be conflicts when you try to merge it to upstream.

Once you have this running, you can compile your own .exe using make-bat.exe, but you have to get it running from sources first...

You can get latest development version by "git clone":

image

PCSDIAS commented 5 years ago

@Harvie Please give me a time and do not get me wrong, however, this is demanding much more time than I have for leisure..

Paulo

Harvie commented 5 years ago

@PCSDIAS I managed to test the serial myself, so no need. I removed metions from this thread, so it's not polluted here.

I suggest removing “bCNC.bat” from the package, if it is not needed anymore.

It will be removed one day. But now it should work for legacy reasons. i'll check.

Update: the .bat is working. I guess you just don't have all requirements installed on your system.

qvisionsa commented 5 years ago

@PCSDIAS Thank you very much for your in depth analysis! You're right in almost everything. I didn't take into account the look ahead buffer. GRBL 1.1 has 16 lines of this.

What happens when there are lines in the bCNC queue waiting and you issue a SENDHEX 85 command? bCNC is not aware that this command has priority and should pass by all the others that wait in line in order to feed GRBL, as soon there is space in its buffer. Instead, bCNC puts this priority command at the end of the queue. GRBL will receive it too late to be effective

I think that SENDHEX 85 command it must not go into the bCNC buffer. It must be executed via sendHex function in sender.py. This is a function that writes directly to serial port and is executed out of the bCNC queue priority.

My setup is as follows:

  1. GRBL 1.1f
  2. Python 2.7
  3. Latest bCNC from git
  4. xPro V2 controller

I'm working to finish the dial jog and I will send you the finished code asap. Thank you again!

PCSDIAS commented 5 years ago

@qvisionsa You do not need to believe in me. Install a Serial Sniffer such as https://freeserialanalyzer.com and record the message exchange between bCNC and GRBL.

Even if the cancel jog command passes forward and is sent immediatelly what will happen to the remaining commands waiting in the queue? They will be sent anyway and the movement will not cease.