bdurbrow / grbl-Mega

An open source, embedded, high performance g-code-parser and CNC milling controller written in optimized C that will run on an Arduino Mega2560
https://github.com/gnea/grbl/wiki
MIT License
35 stars 8 forks source link

Enhancement request - read spindle rpm via i2c for display #8

Open thawkins opened 4 years ago

thawkins commented 4 years ago

I found a cool tachometer project which reads spindle speeds up to 20k optically.

https://www.instructables.com/id/Add-an-Arduino-based-Optical-Tachometer-to-a-CNC-R/

I was thinking that this could be built as a simple project on something like a tiny8, with no display, but allows the tachospeed to be read via i2c, it would then be cool to be able to display that speed on the LCD. im going to build the project on some tinys i have and see if it works, even so it works out of the box on a nano, having a separate arduino handle the tacho stuff makes it easier as all that timing related stuff is handed off.

This could be a useful way to start an i2c based accessory bus, for example a tiny to handle jog wheel decoding etc.

Saur0o0n commented 4 years ago

Definitely spindle RPMs would be nice to see - I've already mentioned that some time ago. Mine, and I guess a lot of others, spindle controller has RPM output (since spindle itself has hall sensor and provide feedback to controller). But this is very simple output, just goes high two times per rotation. So this would require probably dedicated pin with interrupts to count properly. Dedicated extension bus would be nice :) - but Britt already said he hates any kind of lag on LCD/control - and this would definitely lag. Anyway RPMs on display is on my todo list - this should be relatively simple (if there are free interpretable pins) - but with very low priority now.

thawkins commented 4 years ago

I was not thinking of connecting tbe optical reader to the main 2560, but connect the reader to a small arduino such as an attiny85, mini or nano, and have that act as a i2c slave to handle the tachometer counting, and deliver the rpm on request via i2c.

An attiny85 runs at 20mhz, 4mhz faster than the 2560, and its quite big enough to do the rpm counting and handle the i2c slave wire interface. Since its an 8 pin device with an internal clock it can be mounted on the probe head. Im playing with using a tcm5000 ir relective sensor which is both ir diode and ir led in one package, and also pennies.

You can have a second isr that runs at a lower frequency, by dividing a call from the main isr to send a byte once every few seconds that trigers a response from the attiny85, which reads the speed and puts it in a global variable for the display to use.

Saur0o0n commented 4 years ago

I know what you mean exactly. Just mentioned that in the other thread about splitting DRO from Mega, Britt mentioned that he does not like the idea of separate interface bus (what I also proposed) because of latency. But my RPM I planned to connect directly to Mega (but first I have to finish it and finish my other project).

thawkins commented 4 years ago

I was considering also what we could do id the system knew the spindle rpm, not just tbe desired speed but the actual speed, perhaps dynamicaly adjusting automaticaly feed rate if spindle speed dropped.

thawkins commented 4 years ago

https://github.com/nitacku/nI2C

Asyncronous non-blocking i2c library for AVR chips with i2c hardware support. Interupt safe, so can be initiated from the ISR

bdurbrow commented 4 years ago

I've only got a minute right now... but --

This general functionality is on my to-do list. I need it for threading support; so it's going to also get true RPM display and closed-loop RPM control for PWM-driven spindles.

It's also going to get an i2c implementation for accessories; like extra relay drivers or keypad LEDs.

thawkins commented 4 years ago

Ok, i found a simple sensor with an IR LED and an IR photo transistor on it. which has a 3 pin connection, it will use a straight through 3 wire cable (same as servos) and plug in next to the spindle PWM pin on D11. Conveniently the signal and power pins are wired the same way, so no soldering, all pluge and play. The board has a level adjustable comparitor so sensitivity can be adjusted and the output is cleaned up to pure square waves. at $2 for 5 units i'm not going to complain.

see: https://www.lazada.com.ph/products/5pcs-ir-infrared-obstacle-avoidance-sensor-module-for-smart-car-robot-intl-i217989091-s284430507.html

I have integrated code in my fork to setup pin D11 as a falling edge triggered ISR PIN, and that ISR just increments a static global int. Code is in two new files ("tachometer.cpp" and tachometer.h") to minimize changes elsewhere, a single config option has been added to config.h to enable the tach and set the number of pulses per revolution.

I need to find a way to get a fixed time period call to the read function to calculate the RPM. I will start testing by just feeding a fixed frequency square-wave into pin 11, from my bench waveform generator, that will allow me to do most of the work initial on a bare naked Mega Card without the RAMPS or CNC rig.

I will give you a shout when its working and you guys can pull it across.

bdurbrow commented 4 years ago

I'm not sure that sensor is going do quite what you want... it's a proximity sensor. I think you might have better results with a photo-interrupter such as is sold as end-stop switches for 3D printers and a disc with a hole or slot cut in it attached to the spindle; or perhaps a hall-effect sensor and a couple of magnets attached to the spindle.

Nonetheless, it'll be interesting to find out how well it performs.

Timer 5 is unused at the moment; and I was intending to use it for this purpose. Generally speaking; the approach I think I'm going to take is to recalculate the RPM on every tach pulse; and have the time counter be a saturating one. Avoiding some race conditions is a little tricky; and hard to explain in a comment... so I'm just going to do an implementation of it and include it in the October update.

thawkins commented 4 years ago

I checked the components, they are general purpose IR LED and PhotoTransister. I have already tested it with a rotating spindle and osiloscope and i can see quite a stable pulse train as i vary the motor speed, so i dont think it will be an issue.  While the board is sold as a proximity sensor ( its actualy sold as a line follower for robot cars),  the circuit has nothing in it that makes it unique to that application, its almoat identicsl to the circuit on the two arduino tacho projects i looked at, my only concern is it keeping up with the pulse rates, and since its using an lm358 for the comparitor it should not have any problem, I may have to shield the sensor cable to keep noise out, or put an attiny at the mast head to handle the pulse counting. If it does not work out i will just use a direct ir led and phototransistor, i have some tcrt5000 arrays that i have also tested, but this little board is cheap, easily available and convienent, and effectivly buffers and conditions the output signal to TTL levels. Sent from Samsung tablet. -------- Original message --------From: Britt notifications@github.com Date: 10/3/19 9:04 AM (GMT+08:00) To: bdurbrow/grbl-Mega grbl-Mega@noreply.github.com Cc: Tim Hawkins tim.thawkins@gmail.com, Author author@noreply.github.com Subject: Re: [bdurbrow/grbl-Mega] Enhancement request - read spindle rpm via i2c for display  (#8) I'm not sure that sensor is going do quite what you want... it's a proximity sensor. I think you might have better results with a photo-interrupter such as is sold as end-stop switches for 3D printers and a disc with a hole or slot cut in it attached to the spindle; or perhaps a hall-effect sensor and a couple of magnets attached to the spindle. Nonetheless, it'll be interesting to find out how well it performs. Timer 5 is unused at the moment; and I was intending to use it for this purpose. Generally speaking; the approach I think I'm going to take is to recalculate the RPM on every tach pulse; and have the time counter be a saturating one. Avoiding some race conditions is a little tricky; and hard to explain in a comment... so I'm just going to do an implementation of it and include it in the October update.

—You are receiving this because you authored the thread.Reply to this email directly, view it on GitHub, or mute the thread. [ { "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "https://github.com/bdurbrow/grbl-Mega/issues/8?email_source=notifications\u0026email_token=AAADRSOTJWZDJY3IHVRN2O3QMVALXA5CNFSM4IZBHYFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEAGU4SY#issuecomment-537742923", "url": "https://github.com/bdurbrow/grbl-Mega/issues/8?email_source=notifications\u0026email_token=AAADRSOTJWZDJY3IHVRN2O3QMVALXA5CNFSM4IZBHYFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEAGU4SY#issuecomment-537742923", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } } ]

thawkins commented 4 years ago

Note i have already implemented most of the code, you need to moving average the rpm value over at least 4 seconds to eliminate jitter. Sent from Samsung tablet. -------- Original message --------From: Britt notifications@github.com Date: 10/3/19 9:04 AM (GMT+08:00) To: bdurbrow/grbl-Mega grbl-Mega@noreply.github.com Cc: Tim Hawkins tim.thawkins@gmail.com, Author author@noreply.github.com Subject: Re: [bdurbrow/grbl-Mega] Enhancement request - read spindle rpm via i2c for display  (#8) I'm not sure that sensor is going do quite what you want... it's a proximity sensor. I think you might have better results with a photo-interrupter such as is sold as end-stop switches for 3D printers and a disc with a hole or slot cut in it attached to the spindle; or perhaps a hall-effect sensor and a couple of magnets attached to the spindle. Nonetheless, it'll be interesting to find out how well it performs. Timer 5 is unused at the moment; and I was intending to use it for this purpose. Generally speaking; the approach I think I'm going to take is to recalculate the RPM on every tach pulse; and have the time counter be a saturating one. Avoiding some race conditions is a little tricky; and hard to explain in a comment... so I'm just going to do an implementation of it and include it in the October update.

—You are receiving this because you authored the thread.Reply to this email directly, view it on GitHub, or mute the thread. [ { "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "https://github.com/bdurbrow/grbl-Mega/issues/8?email_source=notifications\u0026email_token=AAADRSOTJWZDJY3IHVRN2O3QMVALXA5CNFSM4IZBHYFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEAGU4SY#issuecomment-537742923", "url": "https://github.com/bdurbrow/grbl-Mega/issues/8?email_source=notifications\u0026email_token=AAADRSOTJWZDJY3IHVRN2O3QMVALXA5CNFSM4IZBHYFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEAGU4SY#issuecomment-537742923", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } } ]

bdurbrow commented 4 years ago

Well, if it's working... then it's working. 😄

my only concern is it keeping up with the pulse rates,

Well, 6000 RPM is only 100hz, so...

thawkins commented 4 years ago

I will get the final work done this weekend, i hope to finish my build and then use it to cut 6mm aluminium plates for my next build ( a 400x700mm machine, with nema 23 motors).

Im probaly going to start looking at an esp32 build, they are ridiculously cheap, and i can create a millable pcb to carry the cpu, the rest is just terminals, leds and pullup resistors.

There are a couple of grbl esp32 projects

bdurbrow commented 4 years ago

ESP32 is definitely an interesting target... and although it doesn't have as many IO pins as a Mega2560; what it does have is a couple of really fast SPI ports - which makes it practical to run things like the LCD or even the direction pins off of shift registers. The keypad and override pots I'd probably run off of a dedicated MCU - a Mega328pb (available for under $1.50) interfaced to the main ESP32 via SPI should do the job (I find that keypresses are less sensitive to latency than the jog wheel or LCD update is; but, of course, YMMV). I think the '328pb's SPI port can be driven at 20mhz in slave mode...

bdurbrow commented 4 years ago

I have an implementation that I think works... but... I'm sitting in a diner at the moment; and my mill is at home; so I can't test it right now....

thawkins commented 4 years ago

I have an implementation now that indefinatly works, i have been testing it by feeding square-wave pulses into the D11 pin from my function generator and it is producing the correct rpm rates now, including the 5 sample moving average. It uses timer 5 to do the calculations and a ISR connected to the D11 Pin to increment the counter, the IRS only increments a number so its very fast and does not impact other functions. Its checked into my fork. Files are Tachometer.[cpp/h] PinChange.h as new files, changes made in config.c and main.c, change in report.c, at the moment it outputs an "RPM:xxxxx" value in the string returned by "?". The code needs a little tidy up before i deploy.

I'm working on the sensor, the little board i had has a fairly aggressive low pass filter on it (presumably to help cut noise) so it loses pulses at higher frequencies, i'm making another sensor using a TCRT5000 and a couple of resistors which is showing promise, nice clean pulses, at high speeds again i'm cheating on the test, im pulsing the photo-diode with a pulse-train from the frequency generator using the ir led on another tcrt5000 as a sender.

I'm playing with a suitable reflective target on the spindle, aluminium foil on-top of Matt black tape does remarkably well i wrap a turn of the black-tape onto the ER11 Colette holder barrel above the flats for the spanner, and then put a slice of aluminum foil on that to cover half the circumference, and then wrap clear scotch tape around that to protect it. That seems to create a nice clean pulse in the tcrt5000.

I have ordered a roll of 3m reflective tape designed for warning signs etc, that claims to have reflect a far higher percentage of light than a simple metal surface. we will see what happens when that arrives.

thawkins commented 4 years ago

re esp32 and second mcu, total agree, in fact that is something im looking at. we just need an i2c protocol for all the actions. a nano or mini is also ridiculously cheap and can easily handle all the io. I have seem some pedant designs where the grbl input is streamed through another arduino, and jog commands etc are inserted inline. there are quite a few async i2c implementations around, which can stream at 400khz, that should be fast enough. I had thought of putting all the direction and enable pins on an i2c extender and only have the step driven directly. if you are changing direction the planner is going through deceleration anyway. enable is very low frequency change.

I have been looking at a project that puts a bunch of encoders on a 16bit i2c extender, which seems to work. displays are available on i2c too.

thawkins commented 4 years ago

I have the results from the sensor test, the tcrt5000 board works just fine at a distance of 2 cm from the collet holder surface.

See the video of my test: https://youtu.be/lyzM81cLp8w

This is tbe board im using, im using the digital output not tbe analog one. The board has a raw sensor analog output as well as tbe digital output from tbe comparitor.

See: https://www.ebay.com/itm/10-PCS-Infrared-reflective-Switch-IR-Barrier-Line-Track-sensor-TCRT5000-NEW/181880131566?epid=1146100871&hash=item2a58e68fee:g:sJQAAOxy63FS~N7K

The reflective tape im using actualy came with my tachometer, but the same type on ebay is

https://www.ebay.com/itm/Super-Reflective-Tape-for-Laser-Photo-Tachometer-RPM-Measurement-Tach-2-Strips/311026373148?epid=1255495715&hash=item486a9dd21c:g:nvMAAOSwq7JT0~y6&redirect=mobile

You only need about a 2cm x 2cm piece on an er11 collet. You may be able to find it much cheaper elsewhere.

bdurbrow commented 4 years ago

I grabbed some of those off of Amazon just to test with; except my version doesn't have the adjustment pot. I also grabbed some of those ones mentioned earlier (the proximity sensor version).

The motor on my MaxNC10 that I'm using as a testbed had been retrofitted with a brushless motor for large RC airplanes; and although it does work; getting the ESC to arm and getting repeatable speeds out of it for any given PWM value is... difficult. The ESC that's on it seems to be trying to auto-learn the "throttle" settings; and it's getting it wrong half of the time (this in spite of the fact that my oscilloscope confirms that the Arduino is outputting the correct waveform).

So, I think I'm going to try to cook up an adapter plate and fit one of those cheap Chinese 500 watt brushless spindles to it. The spindle motor that I'm looking at for this has a fan of sorts mounted to the top of it; and the outside is smooth and spins with the spindle shaft. I figure that this will make a good place to mount a tachometer sensor; and I'm going to try a variety of things for it to pick up - acrylic paint (one of the sensor modules was marketed as being a black line sensor for a line following robot; so I figure if I give it a black line... ???), reflective tape like you have a link to (I think I still have some here from my Harbor-Freight photo tachometer), and perhaps some metallic foil stickers from one of the office supply stores (you know, like the kind that your elementary school teacher would give you for turning in your homework on time).

Now that power is back on (you may have heard that our electric utility company - PG&E - decided to turn off power for most of the state of California this week due to low humidity, high winds, and their general lack of maintenance of the infrastructure) I'm getting caught back up on stuff and barring any unforeseen events, I hope to get the October update pushed to GitHub this week.

thawkins commented 4 years ago

I dont think the reflective tape is that important, anything that creates a large enough contrast in infra red will do, aluminum foils and scotch tape would probaly do the trick. If you are not goingbtonuse the tcrt5000, then make sure you put a divider between the emmitter and the sensor, the tcrt has one built into tbe package, but crosstalk between tbe two is an issue.

I have a spindle like the one you describe, note that tbe top fan is not fixed ridgidly onto the spindle shaft, and tends to slip against it, its just pushed onto the top shaft and secured with a circlip. So unless you fix it ontonthe shadt its wont make a reliable speed monitoring point. I 3d printed a 52mm collar and that mounts the tach board. Having a 3d printer makes life so much easier.