gnea / grbl

An open source, embedded, high performance g-code-parser and CNC milling controller written in optimized C that will run on a straight Arduino
https://github.com/gnea/grbl/wiki
Other
4k stars 1.6k forks source link

Need help with taking out Current XYZ position for DAQ #560

Closed akym closed 4 years ago

akym commented 5 years ago

I am trying to browse through the code, I want to extend grbl to output the current X,Y,Z position for a DAQ, I tried finding the code but I am newbie with grbl and couldn't find it, if anyone has done something similar, please let point me where I would need to do it. Extended question (unrelated to grbl): Even if i find the code to continuously stream the current position over to DAQ through a DAC converter, will it hamper the speed or execution of the grbl?

bdurbrow commented 5 years ago

Can you be more specific with what you are trying to do? I don't see how the current position would interact with an analog signal?

Anyway...

grbl stores it's current position in the sys_position array (it's an array of int32_t, and it's units are in machine steps). It's updated by the stepper ISR, so you have to be careful accessing it. This is how I do it; however, you may need to adjust this code to meet your application:

` static inline float readAxisPosition_MachinePosition(uint8_t axisIndex) { int32_t current_position[N_AXIS]; // Copy current state of the system position variable uint8_t oldSREG = SREG; cli();

ifdef COREXY

  memcpy(current_position,sys_position,sizeof(sys_position));  
#else
  current_position[axisIndex] = sys_position[axisIndex];
#endif

SREG = oldSREG;

return system_convert_axis_steps_to_mpos(current_position, axisIndex); }

static inline float readAxisPosition_WorkPosition(uint8_t axisIndex) { int32_t current_position[N_AXIS]; // Copy current state of the system position variable uint8_t oldSREG = SREG; cli();

ifdef COREXY

  memcpy(current_position,sys_position,sizeof(sys_position));  
#else
  current_position[axisIndex] = sys_position[axisIndex];
#endif

SREG = oldSREG;

float workCoordanateOffset = gc_state.coord_system[axisIndex]+gc_state.coord_offset[axisIndex]; if (axisIndex == TOOL_LENGTH_OFFSET_AXIS) workCoordanateOffset += gc_state.tool_length_offset;

return system_convert_axis_steps_to_mpos(current_position, axisIndex) - workCoordanateOffset; }

`

In answer to your other question: yes, streaming will slow down grbl... how much and if it matters depends on how you do it, and what the parameters of your application are.

I would suggest spending the extra few $$$ to go to an Arduino Mega 2560 (clones are available for under $8USD on eBay, but if you can afford it, I do recommend a genuine one, as proceeds from hardware sales helps to support the Arduino project).

There's a port for the Mega here: https://github.com/gnea/grbl-Mega

That port also supports the RAMPS card, FWIW...

If speed is critical, I might suggest streaming via SPI; and then doing secondary processing on another processor. Alternatively, capture the step and direction pulses going to the stepper drivers and manage a separate set of accumulators on another processor (preferably a fast one, like an Arduino Zero - a SAMD21 running at 48Mhz, or an Adafruit Metro M4 - a SAMD51 running at 120Mhz; just be aware that the processor that grbl is running on is likely a 5V board and those SAMD boards run at 3.3v max).

akym commented 5 years ago

Thanks first of all for the reply. My 'XY Problem' is i will be using grbl for positioning a sensor on two translation stages, i will stream preset G codes. Sensor data is acquired on DAQ which only reads analog as you aptly put, so I want to hook a DAC to convert the position in some known voltage intervals which then my DAQ s/w can interpret. I think you have helped me already by giving starting pointers, I will try this out and if it works or not, will let you know. Knowing this problem now, if you could think of any better solution, please let me know. I will be definitely testing this on Arduino Mega and as per your suggestion, I will definitely buy the genuine one.

bdurbrow commented 5 years ago

Hmm... can I ask what the sensor is? Or, more to the point, would the Arduino's built-in ADC be a sufficient data acquisition system, or is an external device actually required?

akym commented 5 years ago

I am using an external DAQ (Datascan 7320), that is why, I need to know the location where the sensor is taking data from, so to sync data with locations, I wanted to try doing this. The DAQ software can identify discrete voltages and translate them into a position, so things are sorted at the DAQ end.

I am already asking too much, but I couldn't implement the code you gave, I want to execute this location out script at end of each line of Gcode, how to do that?

bdurbrow commented 5 years ago

Stock, out-of-the-box Grbl is not well suited to this; however I did add an expansion interface for adding custom M codes to the version that I’m working on. I hope to have a pre-beta release out shortly, so if you can wait a few days I might have a solution for you.

cri-s commented 5 years ago

You can output 10bit voltage using pwm with just a low pass filter, cap and resistance. Use a digital output to signal data valid and another that indicate if the pwm value is x or y. In case you want z too, use 2 different resistors and one ADC input to check 4 states of digital output.

Britt notifications@github.com schrieb am Sa., 17. Nov. 2018, 20:43:

Stock, out-of-the-box Grbl is not well suited to this; however I did add an expansion interface for adding custom M codes to the version that I’m working on. I hope to have a pre-beta release out shortly, so if you can wait a few days I might have a solution for you.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/gnea/grbl/issues/560#issuecomment-439642496, or mute the thread https://github.com/notifications/unsubscribe-auth/AJEOls22s7K-y_154p0tfPAPczKcx9Qsks5uwGbKgaJpZM4YfyeN .

MeJasonT commented 5 years ago

Hi Akym, This was my solution to getting information out of grbl https://forum.arduino.cc/index.php?topic=578683.0 loading pwm outputs so that you can measure them using a daq will cause you a lot of pain. You would need to buffer the outputs so you had a stronger signal to measure. I'm not 100% sure why you are trying to get coordinates by producing analogue voltages, the resolution will be rubbish. measuring PWM is also a really naff idea in my book, I tried it to get the spindle speed but it was too flaky. Or perhaps it was my code.

Have you thought of any other routes to take that will provide you with your solution

There are two types of person who use this forum those into robotics and programming and those of a more technical nature wanting to build a milling machine to make stuff as they are more technical. Its hard to explain your hardware requirements to a programmer. I've worked with them for years. we are talking all the way back to the generation of IBM 286's and Acorn model B programmers. Luckily Brit sounds techy, he knows that the new micros are 3.3v compatible instead of 5v.
Do a sketch/block diagram in a paint program like MSpaint or something so we can get our heads around what you want to achieve - I get the impression you want to sync with an encoder, problem being you wont be able to correct GRBL on the fly you will only see its missed steps. As a crazy thought you could intercept the message and send a new constructed message with the correct location feedback.

I'm still waiting for the day I can type grbl/gnea into google and it says use this M0 whatever breakout board, download code from git (here) and your off. So far loads of info for the Uno based GRBL but gnea is still in the world of the coders. The more mechanical amongst us are wanting more features, options and toys and hoping the upgrade will be like magic - the controller will require a full electronics overhaul to work with 3v and expose a lot of peripheral components to external high frequency noise. I tried following the trend but it went from the mega to M0 and beyond on a monthly basis without any open source hardware ideas to back it up.

bdurbrow commented 5 years ago

@MeJasonT -

Well, given that he really does want analog output; and that the ADC on the atmega isn't good enough for his sensor; perhaps one or several of these would work for him:

https://www.adafruit.com/product/935

MeJasonT commented 5 years ago

If his project has to have analogue output and he has considered all other options of getting coordinates out of grbl then the MCP4725 is the perfect choice and can easily be configured to use the I2C pins. I guess even the Uno could be reconfigured to allow interfacing with An4 & An5. I am using one myself to output spindle speed for my variable frequency drive. I don't know if he will suffer from a time delay between receiving values. I know he suggested having analogue outputs but its worth finding out why he has chosen to display coordinates using analogue values. For to achieve a spindle output from grbl, i have gone down the road of pwm to voltage conversion, outputting a representative frequency of the spindle speed (not pwm) then using pulse and tone sketches etc to read the frequency. i finally ended up getting the data from the horses mouth so to speak. It has no detriment to grbl's operation.

bdurbrow commented 5 years ago

@MeJasonT -

I still don't know what the sensor in question actually is... so I don't know if it's a requirement to use the DAQ system he's currently got, or if the Arduino ADC can do it. If the Arduino ADC can do it, then it's a fairly simple matter to feed the sensor into one of the analog inputs of a RAMPS card, and stream the data to a SD card; or send it directly out the serial port.

Cooking up a custom M code to do this (using the grbl-mega fork I'm working on) is not hard.

@akym - perhaps you could clarify which sensor, exactly, you are using, so we can look up it's datasheet? Or if it's some custom sensor that doesn't have a datasheet, can you describe it's outputs (i.e, is it a voltage output, a current loop output, what sampling rate is needed - I presume not much, given the specs of the Datascan 7320 - how many channels need to be digitized, etc).

akym commented 5 years ago

Thanks a ton guys for the valuable feedback. I am looking into every resource you guys are sending.

The sensor in question is custom made hall effect sensor, mounted on 2 linear translation stages, the output would be an analog voltage(0 to +10V), which will be acquired on external data acquisition system(DAQ). At any given instance only one sensor is will be mounted so it will be connected to DAQ on one channel. We are already using quite a few channels, the plan is to acquire it with 16bit, DAQ is autoscaling for -10V to +10V. Current sampling/writing frequency is 1/14. The position signal should be sent out to 2 different channels and will be acquired with 14 bit. There are only 40 discrete positions for X and Y coordinates, so I think the resolution won't be a problem for my application. As I mentioned earlier, the DAQ software can identify these voltage readings and translate them into positions (which is preprogrammed based on the GCode and sensor path).

@bdurbrow I will try to implement this on my own and if it doesn't work out, I will wait a few days for your solution.

bdurbrow commented 5 years ago

Well, FWIW I just uploaded a pre-beta version of my grbl fork over here (scroll down all the way to the bottom): https://github.com/gnea/grbl-Mega/issues/77

I think that by using a voltage divider you can use the built-in ADC on the atmega2560; there's two free analog pins on a RAMPS card on AUX1. You could then build a custom M-code to sample your sensor - have a look at grbl_expansion_interface.h in my pre-beta fork that I linked to above. To read the ADC, I've also got a couple of functions in pins_arduino_mega.h. There's functions for sending data out the serial port in serialprint.h.