i am developing a 3D printer that uses 88 valves/nozzles as output. In the RepRap G-code list there is the M670 command, where you can define IO pins that will have a certain state when sending a G1 command, using the P parameter.
I can’t find if this is supported by Klipper or not. If not, is there another way to control up to 88 digital outputs during a G1 move, so I can control my 88 valves?
There is currently no simple mechanism to set arbitrary io pins during movement in Klipper today.
You may be able to define pins using [output_pin] config sections and use the SET_PIN command just prior to and after the requested movement. I’m not sure if that is feasible for your application. Note that the SET_PIN command is currently limited in the number of times per second it can update a pin (see the “Klipper laser support” threads on this Discourse for further information).
If this is fast enough, this might be an option. I have full control over the generated G-code (custom slicer) so inserting the valve commands like SET PIN in between G1 commands is no problem.
Is there anything known about how fast this mechanism is? I need maximum several milliseconds response time.
By the looks of it, that branch only adds support for a single ‘high throughput’ pin, while I need a lot of them…
I guess it is not so easy to reduce this minimum time for SET_PIN, as it probably requires to go to some higher throughput channel, seeing how @Cirromulus implemented it.
Also, if I need to set a lot of pins, that will be a lot of SET_PIN commands, as it can only set one pin at a time.
Are there ways to send a string or something to a remote device, that I can then use as a remote IO device? Which I can update every x milliseconds? Then I encode the 88 values into a few characters, and then do the actual pin-setting at the remote IO device.
While reading through the docs, I see it supports generic SPI command sending, which could very well fulfill my needs (MCU commands - Klipper documentation). Then i just have to match it to a few SPI based port expanders, and Bob’s your uncle.
If it doesn’t work, you would probably have to add your own queue-able ‘topic’ where every valve is represented by one bit in a 11 byte array. This would require a bit firmware-coding, but could ultimately use my high_troughput mode, just with 11 bytes instead of one.
I was now thinking along the lines of making a CAN based port extender board to control my valves. I see that Klipper support CAN bus, but as far as I can tell, not necessarily in a generic way, i.e.: send a CAN message through a G-code. That would be ideal: i just send the required valve configuarion (ON/OFF) for all 88 valves as a CAN message (or perhaps two, as only 8 bytes data length is supported).
If I look at this information, only specific MCU’s are supported as CAN devices. However, I planned on creating a custom CAN device, which uses simple CAN port expanders (MCP25050). Is this possible? Or do I need to create a board using one of the supported MCUs, and use that basically as a port expander?
(I’m looking into CAN, as the valves will sit several meters away from the controller board, for which SPI/I2C is not really suited)
Now that I think a bit more about it, I have connected a CAN-board with a SPI interface. Does that mean I might be able to use the send SPI command to send messages over CAN? I haven’t delved too deep into the workings of SPI/CAN with klipper yet, maybe somebody can help me understand?