smartin015 / peerprint

A distributed system allowing for sharing and running of 3D printing jobs
Apache License 2.0
2 stars 0 forks source link

Lower cost per printer for network printing #13

Open smartin015 opened 1 year ago

smartin015 commented 1 year ago

Raspberry pi's are expensive, and greatly increase the cost of a print farm if required per printer.

What if there was a low-cost esp32-based controller that could sub in for the raspi+CPQ plugin, that hooked up to the printer via USB and:

  1. Fetches IPFS files and streams them to the microSD embedded in the printer
  2. Starts the print and monitors its state
  3. Runs event scripts (perhaps pulled from a local website, or stored in EEPROM)

If it cost $4 instead of $150 per printer, that'd greatly lower the barrier to entry for prospective print farmers.

smartin015 commented 1 year ago

Fleshing this out a bit more...

Hardware

Software

Note that gRPC is currently not supported on ESP32. Furthermore, logic for selecting useful work is currently in Python and runs via the CPQ plugin repository.

Next Steps:

  1. Try out the IPFS client library and the VCP USB host library - if it can't fetch a file, write to SD, and then start the print, then the core idea is flawed.
  2. Buy a few ESP32 boards with ethernet and try to replicate (1)
  3. Convert "the driver" object in CPQ into a dictionary of drivers, keyed by the ID of the printer. Dynamically create/destroy these drivers as printers come online/offline.
  4. Separate out the on_update code in a way that allows OctoPrint or the ESP32s to trigger state transitions.
  5. Hack together some form of basic MDNS rendezvous that provisions the ESP32 peers with the URL of the IPFS server(s), the CPQ host(s), and any other relevant network details on boot.
smartin015 commented 1 year ago

As an alternative, there's this proof of concept of USB/IP via ESP32-S2: https://github.com/chegewara/esp32-usbip-poc

This is basically hooking up all the printers via "ethernet USB" to a single PC however, which doesn't sound super great for reliability. I'd rather the core "host" logic be on the controllers themselves, and not on the OctoPrint server. Otherwise a restart of the OctoPrint server could take down all the active printers.

smartin015 commented 1 year ago

Another direction to take this idea would be integration with an existing open source IOT project/framework. I'm a fan of Tasmota - however, there isn't a convenient guide for peripherals and it may add more initial complexity than is necessary for a proof of concept.

smartin015 commented 1 year ago

I managed to get the USB virtual com port example working, including redirecting console output to a different set of pins so at least printf debugging is possible. Attempts to use a higher-level (arduino framework) library failed, so it looks like we're going to be using the base esp-idf framework for this.

I also added a basic TCP server that allows opening a socket and sending data packets that are then repeated over USB serial, then write a simple script to connect and send some example GCODE commands.

smartin015 commented 1 year ago

Also discovered the new XIAO ESP32S3 Sense modules from seeed studio that incorporate an OV2640 camera. Definitely more expensive to install, but this could be really useful for spaghetti detection / initial QA of parts. All that's needed would be an additional HTTP endpoint for fetching a snapshot from the microcontroller.

smartin015 commented 1 year ago

Thinking about behavior a bit, I imagine a setup like the following:

Config and connection flow

If not configured, self-host AP and allow configuration via simple HTTP interface. Configurable settings:

It may be useful to implement an auto-provision script that finds and connects to these self-hosted APs and provides specific configuration.

When configured, the device will connect to the wifi and broadcast its IP address on the given port for the PeerPrint server to discover. Broadcasting will cease when it receives a command. If it doesn't receive a command for a while, it'll begin broadcasting again.

Command flow

The PeerPrint server can send the following commands to an HTTP endpoint (followed by example responses):

{"command": "download", "cid": "<ipfs CID>", "src": "<ipfs server address>"} --> {"written": N, "status": "ok", "printer": "idle"}
{"command": "run_script", "script": "<gcode commands>"} --> {"status": "ok", "printer": "busy"}
{"command": "get_state"} --> {"status": "ok", "printer": "paused"}

download should use a modified version of https://github.com/exmgr/ipfs-client-esp32 to fetch the file from src and write it via GCODE to the SD on the printer.

run_script should execute the gcode directly on the printer. get_state should return current state of the printer.

probonopd commented 1 year ago

Check out https://github.com/probonopd/WirelessPrinting

It emulates enough of the OctoPrint API to let e.g., PrusaSlicer discover it via Zeroconf and print to it like if it was an OctoPrint instance. I've been using it for years to do all my 3D printing.

fetch the file from src and write it via GCODE to the SD on the printer.

I have never found a way to do this (fast). Instead, WirelessPrinting uses a microSD card connected to the ESP and stores the GCODE there.

What we didn't have so far is USB host mode, but it seems like you have figured that part out: https://github.com/probonopd/WirelessPrinting/issues/123

smartin015 commented 1 year ago

Check out https://github.com/probonopd/WirelessPrinting

It emulates enough of the OctoPrint API to let e.g., PrusaSlicer discover it via Zeroconf and print to it like if it was an OctoPrint instance. I've been using it for years to do all my 3D printing.

Very cool - using a "standard" API certainly opens up a lot of possibilities.

fetch the file from src and write it via GCODE to the SD on the printer.

I have never found a way to do this (fast). Instead, WirelessPrinting uses a microSD card connected to the ESP and stores the GCODE there.

Gotcha. I was hoping to not require a microSD slot on the board as that bumps up the price. Did you try GCODE based SD writing by any chance? What was the performance like for that?

What we didn't have so far is USB host mode, but it seems like you have figured that part out: probonopd/WirelessPrinting#123

Yup - I mostly just mashed together the existing esp-idf examples into something barely functional. I see your project uses the Arduino framework... AFAIK there's not a decent port to an arduino lib yet from the IDF examples. I tried a couple, none of them really seemed well supported.

In any case, I see some collaboration potential here :)

probonopd commented 1 year ago

Did you try GCODE based SD writing by any chance? What was the performance like for that?

I didn't really try it as I was told it would be slooow. Maybe worth a try nevertheless.

In any case, I see some collaboration potential here :)

Cool :+1: