New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improved auto tool changer support #437
Comments
A bit of background on what I'm trying to do: I'm working on getting ATC working for me. I have an AMB FME-W DI spindle (basically a newer version of the old 1050W Kress, with 0-10V speed control and a factory tool changer) connected to a Grbl-driven CNC. The AMB tool changer is driven by 2 pneumatic lines, one unlocks the tool and the other ejects the tool and clears dust. I have an Arduino sitting between my Grbl controller and a pair pneumatic solenoids that send air to the AMB spindle's ATC. For the moment, the tool-change Arduino watches Grbl's spindle speed, spindle reverse, and coolant lines (Grbl's only outputs), and decides when to eject based on those. It works well enough, but it'll never be bulletproof, because there's no way for the tool changing system to provide any feedback at all to Grbl or CNCjs right now. So things like https://www.youtube.com/watch?v=7cLCOPLvp_g will happen. I'd like to find ways to extend CNCjs to make it possible to sanely implement tool changers and get a reasonable user experience out of the whole thing. Part of that will almost certainly involve finding a good way to provide feedback from the ATC controller into my CNCjs tool-change macro so that the controller can say things like "slot 5 is full" or "the tool hasn't ejected yet". Since CNCjs macros don't have any looping or logic constructs right now, and CNCjs doesn't have any obvious way to talk to additional non-gcode devices, this should be a lot of fun. |
Cool, is this router all driven by grbl ? |
The router is all grbl. There's an additional bit of tool-change logic and software running on an Arduino sitting between the grbl board and the spindle. It controls relays that control the pneumatic solenoids that drive the tool changer, a relay that turns power on and off to the spindle, and a bunch of more-or-less optional components that make my life easier, like an LCD display so I can see what RPM it's running at. The tool change code includes safety features that are designed to keep it from ejecting tools while the spindle is spinning, for example. It's a few hundred lines of code. If there's interest, I can package it up and open source it at some point, but it'd be more useful as an example than as actual code to use. |
|
@scottlaird , many thanks. I am retrofitting an oxy fuel cnc machine but it a big one 5m wide and 10 long. |
With a machine that size, I would seriously consider a commercial control like UCCNC. A crash on such a machine could be expensive in all sorts of ways. CNCjs is great for hobbyist and light commercial use, but it has a lot of "moving parts" software-wise, many of which change rapidly and thus do not get the benefit of deep and long-term testing. On my benchtop Taig mill, I have 2 N-m closed loop steppers that can pull 180W each. They are powerful enough to frighten me a bit. With anything as big and powerful as your machine, I think I would want software that is tightly integrated and thus less subject to communication delays between components, and very well tested. |
I want to use 3 phase industrial servo motors for my next VMC machine. Can we get feedback of servo to cncjs or g2core? I think there are two parts of feedback. One is a broad feedback like servo drive is running or in alarm state. Another one is to read and display the coordinates of actual move instead of sent pulses... |
This is kind of getting away from the topic at hand; servos aren't that closely related to tool changing :-) In general, Grbl doesn't have direct support for servos, or for closed-loop motors of any kind, and there's really no way to expand it on existing hardware. However, some drivers can make servos look like steppers and vice-versa. For instance, look at Leadshine's CS-Dxxx closed-loop stepper drivers--they support both a "step and direction" interface (basically, it looks like a stepper) and a "cw/ccw" interface (it looks like a servo). Similarly, a number of Leadshine's servo drivers can also support step and direction, so it'd probably be possible to drive them with Grbl, but I don't know that it'd make a lot of sense given how much they cost. Consider asking on https://github.com/gnea/grbl for generic Grbl questions? |
I have integrated (driver and motor in one package) closed loop steppers on my mill, connected to g2core, which supports ALARM inputs. I got them for about $110 each. They either go the full distance without losing steps, or they go to alarm state. |
Thanks @scottlaird for the answer. Sorry for raising question in wrong thread. BTW, industrial servos also support pulse and direction strategy. So it will run out of the box. The only concern is to receive feedback to controller. I will start a new thread for this now. |
Thanks @MitchBradley for sharing your experience. I will think on it. However my idea is to use fully closed loop servo like siemens or panasonic which will take away lots of hurdles towards a reliable machine. We will talk more on new thread so as not to spoil the main topic of tool changer :) |
Hi @scottlaird CNCjs v1.9.18 is released. Now you can declare global variables without losing all the values. Here are some examples:
To check current values, you can use inline comment to output global variables like this: (global=[JSON.stringify(global)]) All supported JavaScript global objects are listed here. export const GLOBAL_OBJECTS = {
// Function properties
parseFloat,
parseInt,
// Fundamental objects
Object,
Function,
Boolean,
// Numbers and dates
Number,
Math,
Date,
// Text processing
String,
RegExp,
// Structured data
JSON,
}; |
With the newly enhanced evaluate-expression library, it is possible to provide a function interface to communicate with external libraries, so you can create an instance of object to return the state or interact with an external hardware. I will see if there is any chance to do that. Something like command-line options can be used to pass a JavaScript file with exported modules that allows you to connect macros with the underlying system. |
As far as I know, @ahedderich initiated his work for adding auto tool changer support last year, all changed files in the pull request are available at here: master...ahedderich:tool-changer You can first take a look for what he did, I will merge his code in a future release if it is a feasible solution. |
Thanks. I'm building 1.9.18 on the Raspberry Pi connected to my CNC now. It takes a while :-). I should probably figure out how to cross-compile it. |
Despite many tries, I have not succeeded in completely building recent versions of CNCjs on the Pi Zero that runs my mill. It always runs out of memory and dies in the build-prod-web step.
Note: if you are using a version prior to cncjs-1.10, you must say build-prod-app instead of build-prod-server above.
The procedure above avoids running eslint, stylint, and test on the Pi, which are time-consuming and redundant. (Edited on 2019-5-6 to reflect the new name build-prod-server) |
Thanks! That should make life much more pleasant. |
That sequence seems to work fine. I didn't need to create the cnc/cncjs/cncjs-server links because they already existed pointing into /usr/lib/node_modules/cncjs, which was a symlink into my git tree. That took a couple minutes total, vs over an hour on the Pi. Although in its defense, it was out of memory and swapping onto a SD card for most of that. |
Long ago in a galaxy far away, I decided that the first order predictor of a computer's speed is the effective memory bandwidth. CPU clock rate is largely unimportant except insofar as it correlates with memory bandwidth, and when you are swapping, your effective bandwidth goes asymptotically to 0, until you run out of swap space, at which point it is "start over" time. Of course one can invent workloads that behave differently, but for general purpose use, if you know the memory bandwidth and have enough memory, you know the performance. |
I've heard good arguments that the best metric is really the number of cache-miss memory reads per second, which isn't quite the same as memory bandwidth, but they're close enough for today. Especially when swapping. |
The global variables are working great; CNCjs even remembers tool locations across jobs, which is better than I was expecting. I was able to load and unload several tools in succession this evening. |
That's excellent. Does cncjs remembers these locations after power off and restart? Or that is something we need to define in gcode header lines each time? |
@karoria Global variables will not persist in the server once a serial connection is closed. Each time you establish a new serial connection, you will need to run a macro to declare global variables. Note: Reload the browser won't affect global variables stored in the server. |
Got it. Thanks @cheton. Can we automate this process at the time of connection to controller? I am asking this as i am seriously working to make a commercial product from cncjs+g2core. One more concern is to remember program line number at the time of power failure. Any work towards these concerns will be highly appreciated. |
@karoria It is possible to add a new "startup" event that will be triggered when a CNC controller has started, you can send several lines of G-code or run a system script, just like the startup blocks that Grbl runs every time you power on Grbl or reset Grbl. I can add it to the backlog for the next release. |
Thanks @cheton. Can you also suggest some workaround to save last program line sent to controller before power failure? |
Instead of loading and saving globals, you'd be better off wiring up some sort of transactional store (sqllite comes to mind as being relatively easy but not ideal), creating a DB object in the controller startup, and then exposing that via globals. Then instead of storing whatever you want in globals directly, you'd actually be storing it in an external storage system. It'd be more work, but you'd get better correctness without race conditions around power loss and macro execution. I'm not really a Node guy; there might be a solution with fewer dependencies that would make general sense here. There's probably some sort of transactional key-value store that is lightweight enough to make a standard part of CNCjs (or perhaps already a part via transitive dependencies), unlike sqllite which would be kind of a pain to add for all platforms. |
That's a very difficult problem to solve in CNCjs because of uncertainties in how the different system components behave on power failure. A much more robust solution would be to construct a little battery-powered logger device that watches the transmit line to the controller. |
Scottlaird may i have copy of the arduino system you use please ?
|
I'm working on open-sourcing it. I need to jump through a few hoops in order to make my employer happy first, though, before I can release it on github. Mind you, it'll probably be mostly useful as example code, unless you feel like building an exact copy of what I have. There are a few things that could be left out to save money, and some other things that seem to be mostly pointless in practice. It should be possible to clean it up into something that is modular enough to be usable as a off-the-shelf ATC controller, but that's not a big priority of mine this month. OTOH, it's not really all that much code, and it's fairly straightforward, so hopefully it'll be useful as-is. |
Thanks @MitchBradley. Can you elaborate more or give any link regarding battery powered logger? How about connecting external EEPROM to g2core/due? Any how, i will have to struggle interfacing it with data transmission. |
For a logger, pretty much any microcontroller would work. Connect its RX line to the RX line on the Due so it sees the same data as the Due. Keep the last few lines, or simply a line counter, in RAM. Power the micro with a battery connected to a charging circuit so the micro will stay powered for some time after external power drops. When data stops arriving, store the buffered lines in EEPROM or to and SD card, or write then to a display. |
Thanks a lot @MitchBradley for this valuable guidance. I will definitely work on it. |
… executable (#440) * Avoid relative path hell * Folder restructure * Work in progress * Fix incorrect route of user accounts * Enhances the evaluate expression library that enables full support for assignment and sequence expressions (#442) * Enables full support for assignment expression and sequence expression * eslint fixes * [Feeder][Sender] Add global variables support (#443) * [Macro][Sender] Add global variables support * Returns global variables with populateContext() * Update macro variables usage * Update macro variables usage * Supports primitive types and global variables * Enhancement for evaluating expressions (#444) * Enhancement for evaluating expressions * Centralize global objects in one place * Rename context to vars * eslint fixes * Update variables * Update package.json * Update dependencies * Rename cnc to cncjs * Upgrade Three.js from 0.94 to 0.103 * Update resource.json * Fix a warning that the shading option is removed from MeshMaterial * Change the render order * Render cutting tool and cutting pointer in the 3D visualizer * Fix for Marlin controller first-move bug (issue #312) (#449) * Fix eslint errors in 4a4b67b * Update resource.json * [Marlin] Fixed a bug of calling a controller initialization method that has been removed * Fix an issue that dropdown menu gets clipped by container with overflow:hidden property (#445) * Fix a overflow bug in the console widget (#452) * [g2core] Address an issue that spindle will restart after stopping program execution (#428) (#451) [g2core] Address an issue that spindle will restart after stopping program execution (#428) * Add support for specifying mount points in the .cncrc file (#459) (#461) * Add a new event that is triggered when the controller is ready to start (#437) (#460) * Update translation keys * Add a new event that is triggered when the controller is ready to start (#437) * Fix for the bug @cheton found in #454 (comment) (#462) * Rename bin/legacy-cli to bin/cnc * Update .cncrc * Update dependencies * Update dependencies * Update resource.json * Update Dockerfile * Turn into full screen web app on mobile devices (#402) * Update supported Node.js versions
@nesquik011, a partial version of the code is now available at https://github.com/scottlaird/cncatc. As I said before, it's of limited use as-is, but it's now open source under the Apache license. I have a couple pending changes that'll go in soon, but I'm mostly working on finishing assembling the CNC itself right now. Tool-change work is on hold until I finish milling (and then installing) my 1400x1000mm aluminum base plate. |
@scottlaird you gave cncjs new life form :D i am happy you are doing this , and i would love if you share videos of how you setup things , and build the machine , if you dont mind sir , and it would be wonderful if you talked about the ATC itself i wish it could work with many ATCs and machine soon |
Description
I would like cncjs to be able to support the following auto tool changer scenario:
Given a gcode file that looks roughly like this:
And assuming a CNC with an ATC and an appropriate tool change macro, cncjs should be able to:
This still isn't enough to give a great ATC experience--at a minimum, we need to figure out what to do with any tool that is in the changer before the start of milling, and we need to be able to handle aborting halfway through milling without getting completely lost WRT tools, but this is a start.
Versions
How Do You Install CNCjs?
CNC Controller
Hardware
Operating System
The text was updated successfully, but these errors were encountered: