bdring / FluidNC

The next generation of motion control firmware
Other
1.63k stars 388 forks source link

Support for GPIO expander MCP23017/MCP23S17 #153

Closed dzervas closed 3 years ago

dzervas commented 3 years ago

Please describe the feature you would like implemented I'd like to be able to expand the GPIOs available on ESP32 with MCP23017/MCP23S17. It adds 16 GPIOs with internal pullups and pulldowns and has an interrupt lane to avoid pinging it periodically

Why do you think this would improve FluidNC? It would add a ton of GPIOs, very cheaply in terms of cost, traces (SPI or I2C) and computing power (has interrupts)

What do you need the feature for? I'm designing a board that it's meant for an MPCNC and its main concern is support for SPI/UART drivers and simplicity of the circuit so it can mostly be milled on a CNC

Do you know of other users who need this feature? Probably? I think your other boards use a shift register to drive the step/dir pins but to my little mind is better to drive these with direct GPIOs and just use an expander (be it GPIO expander or shift register) for control/limit switches

atlaste commented 3 years ago

We are very aware of pin extenders. I have a few of these at home.

I made a board with a PCA pin extender recently, and implemented the necessary pin functionality for it. It just isn't as simple as you might think it is... The time delay that's induced with extenders is very real, which makes it impractical for most users (and they will ruin things that they didn't expect). For example, hard probing will probably be an issue, as well as limit repeatability, etc. In my use cases these things aren't really an issue - but I also use I2SO and GPIO ports on that same board for a reason. I wouldn't even consider driving motors with pin extenders.

The main issue is that while pin extenders tell you via an ISR that a pin has hit, you don't know which pin has hit. Figuring this out takes time. You can't take action during this time - because you don't know if it's an endstop, a probe, a 'pause' or a 'play' button. The behavior of the firmware for each of these is completely different.

For most users, I'd just use the I2SO shift registers. They are also much cheaper and they have proven to work with very high step rates. That should free up plenty of GPIO space for just about anything on most DIY machines. If I wasn't doing experimental things that required lots of input pins, I wouldn't have considered these extenders.

dzervas commented 3 years ago

ooooh you've clearly seen much more "war" than I have. That clears it, I'm gonna go with I2SO shift registers

I'm closing the ticket as adding support for something that by definition is unstable is a very bad idea.

Thank you! Keep rocking, finally a reasonable CNC firmware! :heart:

dzervas commented 3 years ago

hmmm, after a google search it seems that I misunderstood the term I2SO. At first I thought that they communicate over I2S (which I know on ESP32 is really fast). Care to give me a pointer or two? In the 6 pack you use a regular serial-in parallel-out shift register (which is very close to SPI which 1-2 shenanigans on CS) "74AHCT595".

Also why that part specifically? I can't source it locally. Does it cover some special requirement versus let's say "74HC194E" or "74HC595D".

I know I'm getting a tad off-topic but I'd greatly appreciate some info.

atlaste commented 3 years ago

I2SO stands for 'I2S out'. There's also I2SI, hence the 'i' and 'o' that we added. It's really fast, we've tested well over 250 kHz on it already, that is: if you get the pcb layout correct. The 6-pack is designed and reviewed by the best electrical engineers I know; high speed communication is not trivial... AFAIK That's one of the reasons the designs were made open source...

The 'T' in the 74AHCT595D stands for TTL. the 'D' stands for the packaging, I sometimes use the PWR variants. I can't remember what the 'A' stands for, it's probably somewhere in the data sheets.

MitchBradley commented 3 years ago

As the person behind that part of the design, I chose AHCT595 for the following reasons:

If you use HC at 3V3 supply:

If you use HC at 5V supply

Electrical engineering is not as simple as the various hobbyist sites would lead you believe.

dzervas commented 3 years ago

woah, well THAT's an answer. I'm a complete hobbyist electrical... "engineer" hence the questions. Thing is, I unfortunately can't afford to buy the 6 pack and some additions that I need so I'll get away by building something on my own and in the process learn and compromise on some corner cases

Thank you very very much.

unixbigot commented 2 years ago

I'm working on a machine that needs some more io pins (but not for motor stepping), so I'm going to have stab at implementing a generic i2c_bus module for pcf8574, mcp23017 and pca9685.

MitchBradley commented 2 years ago

I suggest that you wait for the I2C expander code that Stefan is working on, and extend that if needed. If your approach does not dovetail well with Stefan's, it will be hard to merge.

unixbigot commented 2 years ago

Thanks, @MitchBradley, I'd done a search on discord and github and hadn't yet found anything outside this issue that indicated someone was already working on it. I'll see if I can pitch in with Stefan (or at least help test). Is there a flashing red beacon or other sign (issue wiki, etc) that I should look at with respect to what's planned?

MitchBradley commented 2 years ago

@atlaste Stefan please contact him

spsspssps commented 2 years ago

Related to the IO extenders:

I am currently designing the electronics for my CNC, and I am open sourcing them. I was about to send my card for production when I questioned my choice of not using IO extenders.

I am considering adding one or more 74AHC595, but I could not find details on how to configure the number of bits to send over i2so. I assume I can cascade the devices, and looking into some of the example yaml files, I would suspect two devices can be cascaded. So, my question is how many bits are we sending out over i2s? Are there several configurations possible? Can I place 4 devices and expect some success with 32 bits? Should I just place 2 devices?

The card as is now (with a lot of optional stuff that will go away) is placed under the main branch of: https://github.com/spsspssps/spscnc

I am integrating the TMC2160 which should be 99% compatible with the 5160 and are readily available. The main reason for making my own design is getting more power out of the drivers, and having proper layout for power dissipation.

Pin count limitations made me consider the ESP32-S2, but I see support is not there yet, and probably most of the extra pins are just inputs.

Thanks in advance,

MitchBradley commented 2 years ago

The code and hardware can handle either 16 bits or 32 bits, so 2 or 4 shift registers. With 2 shift registers the step rate could in principle be boosted from 125K to 250K, although there is usually little need for stepping that fast.

The 6-pack controller uses 32 bits and the FluidNC releases are compiled for that configuration. If you use 2 shift registers the 32-bit code will still work; the extra bits will just go off into nowhere.

spsspssps commented 2 years ago

Thank you very much. That was a very quick answer!

atlaste commented 2 years ago

Since this appears to be a frequently asked question, I'll attempt to answer it briefly without re-opening the ticket. It might answer some of the questions that @unixbigot and others have.

I have already implemented and tested input extenders using I2C, specifically using the PCA input extender. Using SPI for input extenders is very similar, but not implemented. I read over a dozen datasheets, and found that they all work more or less the same (save some details). But be careful: input extenders might not give you what you're looking for! I'm also exploring other options as we speak, which might be much more useful in the long term. FWIW: I also looked at I2S input extenders and some other options.

Long story short. Output is not supported, only input. Well, we do support the I2S 74AHCT595 IC's (see Wiki -> Controller design), but input extenders are simply not suitable for proper PWM signals that steppers need. Keep in mind that I2S are high speed signals, so you must handle high speed signals properly with placements if you make a PCB. The 6-pack is open source and does that properly.

That being the case, input extenders could be useful for certain inputs. Specifically, for non time-critical inputs it works fine. Think about buttons. Endstops is a different story, and [hard] probing is probably never going to work with input extenders. Timing is the crucial element here; even though I use the ISR pin, I know that an interrupt occurred, but not which event it was. To figure that out, you need an I2C roundtrip (which resets the PCA) and then take one or multiple actions.

This is not ideal, which is why I haven't finished this branch even though I already made boards and have them here. If you want to toy around with it, my PinExt2 branch of FluidNC, which I'm probably going to re-write from scratch, currently has some support for them, is tested and works. Just don't expect it to last; I'm not happy with it as-is, and I'm thinking about giving input extenders some very specific functions.

The currently best way to get a lot of I/O is to use the I2S pin extenders that i mentioned earlier, which frees up a bunch of GPIO's for other purposes.

spsspssps commented 2 years ago

Thanks for the extensive documentation. I will stick to I2S output only. I was considering input extenders for things such as the door_open switch, and other low speed gpio, but not time critical stuff. Currently I am not doing much with the Trinamic status outputs on my board, but I would have liked to look into lost steps and stuff like that and pause the process if steps are lost. Still, that's another lengthy discussion.

I think a much simpler approach for extending the number of GPIO would be to use the ESP32-S2 which has more GPIO. An alternative would be to replace all motor drivers with something like a MAX10 FPGA which has a multichannel ADC, and emulate the behavior of several trinamic drivers on a single device. But that's another kind of project.

Regarding the signal integrity of i2s, I will add series resistors, keep the traces short, and use a scope to characterize. But I am more concerned about distributing SPI to several drivers over a long board, with noisy power electronics nearby, a lot of PWM signals, and the step pulses nearby.

Aikhjarto commented 2 years ago

@atlaste Thank you for your work on atlaste/PinExt3 It would work quite fine for me too, but your branch can no longer be merged with recent versions of FluidNC. Do you have plans to update PinExt3 to be compatible with bdring/main again?