probonopd / WirelessPrinting

Print wirelessly from Cura, PrusaSlicer or Slic3r to your 3D printer connected to an ESP8266 or ESP32 module
352 stars 65 forks source link

Work with printers without serial interface (USB Host Mode) #123

Open TheAssassin opened 5 years ago

TheAssassin commented 5 years ago

Some printers' boards, such as for instance the Creality Ender 2, don't have RX/TX GPIOs for serial communication, which means this project cannot be used with them. As these are mostly inexpensive printers, using OctoPrint with more expensive hardware is annoying due to the price.

The printers however mostly have USB sockets which can be used for serial communication. Therefore the question is: can an ESP board communicate via USB with those?

My hope is there's a USB-to-serial sort of adapter that provides a USB host and translates the USB stuff into raw serial again. The cheap UART adapters you can find online are functionally equivalent to the stuff in the printer board, they lack the host feature and cannot be used.

I know some Mega2560 based Arduino boards can provide a USB host feature and might do the translation, however they're quite bulky and also expensive. It might be cheaper to get something like an Orange Pi or so and try to run OctoPrint on there (UI won't run very well, I hope there will be a completely headless version in the future).

Perhaps there's a kind of USB host chip to do the translation which doesn't require a complex circuit that needs to be soldered on a PCB, as most people don't have access to the tools to realize that.

probonopd commented 5 years ago

Never say never... https://github.com/cnlohr/espusb/issues/45

In the meantime, this is where you can solder to the Creality mainboard: https://github.com/luc-github/ESP3D/wiki/Creality-CR-10-Ender-3

GMagician commented 5 years ago

I tried to connect my esp8266 usb to mega usb (my printer). On mega side I know it works because I usually use it with repetier esp8266 TX and RX are connected to ch340 (or similar) and I thought, why not to use it and avoid soldering? I failed...

TheAssassin commented 5 years ago

@probonopd thanks, I might try later with those pins.

just-jason commented 5 years ago

https://github.com/gdsports/esp8266-usb-host-demos

probonopd commented 5 years ago

Actually there will be a new ESP32 chip version with USB host mode soon: ESP32-S2. I think I am gonna support this one if possible, once boards for it are cheaply available.

Throwing in a USB host to serial chip is always an option of course, so this brings our options (at least) to:

TheAssassin commented 5 years ago

Ever tried either of these chips? I'm a bit sceptical, I couldn't find any quick examples for most of the chips that'd be equivalent to what shall be accomplished here.

probonopd commented 5 years ago

Ever tried either of these chips?

No. But any chip that can convert serial-over-USB to serial should do, at least in theory. In practice, most of this won't make sense from a cost perspective, compared to a Raspberry Pi Zero.

TheAssassin commented 5 years ago

A Raspberry Pi Zero however doesn't run OctoPrint sufficiently smoothly...

probonopd commented 5 years ago

Who said OctoPrint? ;-)

I wonder if we can get this to compile on https://github.com/epsilonrt/piduino. Probably the WLAN stuff would need to be ifdef'd away... since you know C++ quite well, would you like to give it a try?

TheAssassin commented 5 years ago

Who said OctoPrint? ;-)

Well...

It might be cheaper to get something like an Orange Pi or so and try to run OctoPrint on there (UI won't run very well, I hope there will be a completely headless version in the future).

https://github.com/probonopd/WirelessPrinting/issues/123#issue-454434678

Did I mention one of these cheap RasPi clones melted an SD card and it took me an hour to figure out what was wrong?

OctoPrint is great, if you have the right hardware to make use of all the features. However, if you can't, a small, energy-saving solution like WirelessPrinting is preferable.

probonopd commented 5 years ago

a small, energy-saving solution like WirelessPrinting is preferable

Agree! I was just wondering whether we can make it run on the 5 EUR Raspberry Pi Zero which has USB host mode...

TheAssassin commented 5 years ago

Maybe by making this app into a proper C++ library and then building two frontends, one for Arduino, one for Linux hosts. That's the easiest and most manageable way.

TheAssassin commented 5 years ago

A USB host solution by the way is also great for debugging, you don't have to solder to demonstrate this on arbitrary printers -> great for conferences.

probonopd commented 5 years ago

In September or so we will have ESP32-S2 :+1:

https://hackaday.com/2019/05/21/new-part-day-espressif-announces-esp32-s2-with-usb/

probonopd commented 5 years ago

I wonder if we can get this to compile on https://github.com/epsilonrt/piduino. Probably the WLAN stuff would need to be ifdef'd away...

Blocked by https://github.com/epsilonrt/piduino/issues/11 as it currently does not seem to support networking at all.

probonopd commented 4 years ago

Looks like the Geeetech 3D WiFi Module can do it.

Looking at http://www.geeetech.com/firmware/Upgrade3DWF/config.txt the hardware is based on ESP8266 but the firmware is proprietary.

I wonder what chip/electronics they are using for the USB host.

probonopd commented 4 years ago

Digging though their firmware gives Cannot Find the interface for Communication Interface Class. which is a string that appears in https://github.com/stm32duino/Arduino_Core_STM32/blob/9b6938fdc50f6d48b8f6f48eff4b1e96092fe666/system/Middlewares/ST/STM32_USB_Host_Library/Class/CDC/Src/usbh_cdc.c#L163 so I would not be surprised if they had a STM32F105xx or STM32F107xx with USB host mode attached to the ESP8266.

https://www.st.com/en/embedded-software/stsw-stm32046.html

For more details about all the components of a USB OTG host and device library, including examples for different types of devices, refer to STM32F105xx, STM32F107xx, STM32F2xx and STM32F4xx USB On-The-Go host and device library User manual (UM1021).

Intelligent guessing when digging through the firmware is fun:

me@host:~$ strings Downloads/*.bin | grep STM32F Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers.The OTG_FS is a dual-role device (DRD) controller that supports both device and host functions and is fully compliant with the On-The-Go Supplement to the USB 2.0 Specification. It can also be configured as a host-only or device-only controller, fully compliant with the USB 2.0 Specification.
USB host The STM32 Connectivity Line allows developers to take advantage of industry-standard 32-bit processing in designs requiring simultaneous Ethernet, USB, CAN and audio-class I2S capabilities. Two variants are available, including the STM32F105 series combining a Full-Speed USB 2.0 Host/Device/OTG peripheral and two CAN2.0B controllers with advanced filtering capabilities. The STM32F107 family adds a complete 10/100 Ethernet MAC with hardware support for the IEEE1588 Precise Time Protocol, enabling Ethernet connectivity for real-time applications. Dedicated buffers allow the USB OTG, the two CAN controllers and the Ethernet interfaces to operate simultaneously to satisfy communication-gateway applications, as well as a host of challenges requiring flexible, industry-standard connectivity.

So at this point I'd say that's the hardware they are using. Are they flashing the STM32F105xx from the ESP8266, or why does the STM32F105xx stuff show up in the ESP8266 firmware?

Actually, the manual says under "Specs": CPU: STM32F107 + ESP8266

The available STM32F107 boards/modules are more expensive than the Geeetech 3D WiFi Module, so if you need a solution now, then Geeetech 3D WiFi Module may be it.

probonopd commented 4 years ago

ESP32-S2 seems still not to be available yet on eBay.

TheAssassin commented 4 years ago

ESP32-S2

Has this board ever been released? I don't see any of those in the respective shops.

Regarding the combination of an STM32 and ESP8266, it's also a pretty cheap and very universal solution. Ideally, we could simply combine a bluepill board with a NodeMCU or WeMos D1 Mini. I think that such a solution would work out of the box, provided that the STM32 just bridges between the USB serial interface and its own UART pins. Using an STM32 might even allow for utilizing Marlin's "SD card reader" feature without having to use the serial interface, which can be painfully slow for larger G-Codes.

Edit: the vendor publishes a library which claims to support USB host mode for USB-CDC devices. This class is also used by the USB-to-RS232 bridges, which internally use chips from e.g., FTDI or (especially cheaper ones) Prolific. See https://www.st.com/resource/en/data_brief/stsw-stm32046.pdf for more information.

Edit 2: hosting CDC devices is not available on cheaper boards like the bluepill, you need a specific chip which contains a USB host.

probonopd commented 4 years ago

Yes, unfortunately the Blue Pill is lacking the needed USB OTG/host functionality.

The ESP32-S2 had been announced some time ago, but as far as I know there are no board with it on the market for sale yet. And also no code for the Arduino framework to use it as a USB OTG/host device yet.

TheAssassin commented 4 years ago

I've found some USB host shields for ~8USD, that still exceeds a RasPi Zero's price.

Perhaps this repository should be split up and modularized so that it's easier to build frontends for e.g., embedded devices, but also native ones? Some hardware abstraction wouldn't be too hard to implement, C++ makes it really easy (adding an abstract class which defines the serial communication interface as well as two or more implementations for the ESP8266/ESP32, Linux (for the RasPi Zero but also development machine), and in the future perhaps even a simple Arduino Nano (should work for LAN, see #125)). Another advantage is that you can develop on your computer to debug non-hardware-related problems, e.g., the communication protocols. Unit testing also becomes a lot easier.

probonopd commented 4 years ago

...or we just wait a bit more, then we will get Linux capable modules for the price of an ESP8266. It's only a question of time :-)

TheAssassin commented 4 years ago

Linux is not a real-time system. But I guess that doesn't really matter here, since we just forward commands to an actual real-time system.

probonopd commented 4 years ago

Yes. Actually, we can send a few lines "in advance" to what is being printed; hence the exact timing should not matter too much.

TheAssassin commented 4 years ago

I ordered an STM32F4 for evaluation, which could be combined with a WirelessPrinting device, serving as a bridge between a USB CDC device and UART.

probonopd commented 4 years ago

Which one did you order? Seems like STM32F401CCU6 boards are becoming cheaply available, but with that dreaded USB Type C plug (despite the chipset having USB 2.0 OTG FS).

Also note that not all printer boards implement USB CDC; some have chip-proprietary implementations like FTDI, Silabs, Prolific, WCH-IC CH340, etc., all of which you need host drivers for. Does STM32CubeMX contain all of those or "just" CDC?

probonopd commented 4 years ago

ESP32-S2 support is beginning to trickle into the libraries... https://github.com/hathach/tinyusb/commit/2ff3f765db7e62201d0491093111b0d649446046. Unfortunately,

The Host stack is under rework and largely untested.

And is likely missing the CDC/other serial modes.

TheAssassin commented 4 years ago

Someone mentioned the ESP32-S2? http://invidio.us/watch?v=L6IoSVdKwNM Looks like a nice device, let's hope for the best. The thing has just one core, but it's fine for WirelessPrinting, nothing time critical running really. What's a bit annoying is the need for an external SPI MicroSD interface. Maybe it's even a bit cheaper than the ESP32, that would be nice, too.

dlyckelid commented 2 years ago

I am interested in developing a pcb with either ESP32-S2 or maybe a USB-Hostcontroller chip like MAX3421 and make it especially for this library with onboard sd-card reader or larger onboard volatile memory if that is better.

Has any tests been made with ESP32-S2 as USB-Host?

Looking at this example makes me think that doing this with an ESP32-S2 will actually work. Atleast there is examplecode for arduino here but should also work in PlatformIO.

https://github.com/espressif/arduino-esp32/blob/master/libraries/USB/examples/USBSerial/USBSerial.ino

Does not take much time or money to get a develop-pcb up and running so I think I will give it a shoot

dlyckelid commented 2 years ago

image There you go! Should be a good first prototype and if it works I can spend more time making sure it is more solid EMC and probably a bit better placing of the parts. But for test purposes this should work just fine :)

The only way this makes sence is to buy a larger batch of them because otherwise they will be more expensive than a Raspberry Pi Zero 2 W that can run Octopie.

If I ordered 50 of them fully assembled the cost/piece is $7.4 + shipping and taxes

just-jason commented 2 years ago

image There you go! Should be a good first prototype and if it works I can spend more time making sure it is more solid EMC and probably a bit better placing of the parts. But for test purposes this should work just fine :)

The only way this makes sence is to buy a larger batch of them because otherwise they will be more expensive than a Raspberry Pi Zero 2 W that can run Octopie.

If I ordered 50 of them fully assembled the cost/piece is $7.4 + shipping and taxes Do you have a schematic to look at?

dlyckelid commented 2 years ago

Schematic_ESP32 3D-Printer controller_2022-02-02.pdf

Sure here is the schematics. I do need to look everything over again, Its basicly a collection of things Ive done in other projects copied and paste together so everything should work but I would put some more esd-protection, probably a cleaner powersupply and also a way to separate the 5v from the printer. Also I need to check if there is any levelshifting needed for D+ and D-

But this was what I needed to get an estimate of size, and price

probonopd commented 2 years ago

I have not attempted to do this with the ESP32-S2.

As for the MAX342, the code needed to support it would need to be written first...

dlyckelid commented 2 years ago

Ok. I will do a little more tinkering with it and perhaps order some samples together with my next order of prototypes for other projects. I have a number of creality-printers and well Raspberry Pi is to expensive (And I´ve also had stability issues with octoprint) and Pi zero 2 w seems impossible to buy

dlyckelid commented 2 years ago

Would 16MB onboard memory be sufficent to skip the sd-card altogether? The ESP32-S2 is available with 16MB onboard flash or you could use an external memorychip (Because the onboard flash is only safe for 10000rewrites). I am using a W25Q128JVSIQ chip in another project and that is a pretty cheap useful chip. It is also non-volatile and 16MB and safe to 1000000 rewrites.

TheAssassin commented 2 years ago

I don't think it's going to be sufficient. Complex shapes can generate a lot of G-Code. Limiting oneself to 16 MB of storage space is not a good idea therefore. And non-volatile flash memory will be cheaper than those Winbond chips. Talking to microSD cards shouldn't be too hard, there's plenty of libraries for the Arduino platform.

I think that after all, writing a minimal, OctoPrint-compatible server which runs on some Linux host will be easier and cheaper (a RasPi Zero W 1st gen is less than 12 EUR in Germany, even with a microSD and a PSU you'll be under 20 EUR) than manufacturing a custom board just for this purpose.

probonopd commented 2 years ago

Would 16MB onboard memory be sufficent to skip the sd-card altogether?

I would say it highly depends on what models one wants to print. As for me, most of my G-Code files are actually much smaller than that. But there are notable exceptions.

TheAssassin commented 2 years ago

https://www.winbond.com/hq/product/code-storage-flash-memory/qspinand-flash/?__locale=en might be a better choice, each chip contains 1 Gb of NAND flash (128 MB). Perhaps one could add as many chips as needed?

dlyckelid commented 2 years ago

Just for starting to think about it I created this miniboard with onboard memory. I will look into the NAND Flash if that is possible to include in this. The board could be done both in micro and mini usb (Because I have printers with both)

But I am quite pleased with this. Would be really easy for anyone wanting their printer to be wireless :) But ofcourse limited to 16Mb with this solution

image image

Price for this one is completely different. Again if you just order 5 of them it will be about $10 for each depending on what price you get on the ESP32-S2. But if you order in larger quantities like 50 you could get as low as $6/piece. Fitting it with an SD-Card reader would be cheaper to produce ofcourse but then you need a SD-Card. That is most of the time provided with the printer so maybe that is the way to go anyway just to have a very cheap alternative to octopi?

The reason I am looking at this is that I run a small electronics business and look for projects and be a little like adafruit that provide everything opensource for them who like to do it themselves but also provide finished boards for the bigger crowd. Its just a small scale side hustle right now :)

TheAssassin commented 2 years ago

For the record, I'd include the option to add some control buttons (e.g., by including pin headers). Most important button IMO is "abort print", that should trigger some "move print head away and turn off heaters" G-Code.

dlyckelid commented 2 years ago

That is a good idea. The first step is to ofcourse just see if it is possible at all to do it with the ESP32-S2. Should be easy enough just to test if I can get the printouts from a printer to the esp.

I do have a small board with the USB-port connected to a ESP32-S2 somewhere so think I will start there just to test. The construction exercise was just to see if it is viable at all for me to spend my time on (More seriously) and because it was fun to attempt to do something as little as possible :)

But what I see could be possible when compared to other options is:

TheAssassin commented 2 years ago

I just thought about your second proposal. I think you shouldn't add a specific connector (or do different boards for different types of USB connectors). The Ender-2, the printer I mentioned in the original post, wouldn't allow fitting a board right on the USB connector, which is exposed to the front through a little cutout in the acrylic cover. I always wanted to use a cable and mount the wireless interface in some place it fits into. Some printers might not even have space for such a board, so you'd have to mount it on the outside anyway. Your first prototype with the female USB type A looks most promising therefore. Just add a suitable (maybe even angled) USB A-to-[printer connector] cable and you're set.

Re. SD card vs. onboard flash: in the long term, SD cards will be the better option. You can just swap it for another one on failures, for example. Also, there's virtually no size limitation. The cards are really cheap, and I think many people have some old ones for such a purpose (I do have some 2-8 GiB ones I don't use, for instance, which could perfectly work as a cache for such a board). Also, with an SD card, some old g-code could even be kept for quick reprints (I'd like to have such a feature, also has some use in print farms for instance; of course that'd likely require a little display to be hooked up to the ESP).

I think the board should be discussed in a new repository. This issue is about adding support to @probonopd's firmware. Hardware questions are out of scope.

dlyckelid commented 2 years ago

I just thought about your second proposal. I think you shouldn't add a specific connector (or do different boards for different types of USB connectors). The Ender-2, the printer I mentioned in the original post, wouldn't allow fitting a board right on the USB connector, which is exposed to the front through a little cutout in the acrylic cover. I always wanted to use a cable and mount the wireless interface in some place it fits into. Some printers might not even have space for such a board, so you'd have to mount it on the outside anyway. Your first prototype with the female USB type A looks most promising therefore. Just add a suitable (maybe even angled) USB A-to-[printer connector] cable and you're set.

Re. SD card vs. onboard flash: in the long term, SD cards will be the better option. You can just swap it for another one on failures, for example. Also, there's virtually no size limitation. The cards are really cheap, and I think many people have some old ones for such a purpose (I do have some 2-8 GiB ones I don't use, for instance, which could perfectly work as a cache for such a board). Also, with an SD card, some old g-code could even be kept for quick reprints (I'd like to have such a feature, also has some use in print farms for instance; of course that'd likely require a little display to be hooked up to the ESP).

I think the board should be discussed in a new repository. This issue is about adding support to @probonopd's firmware. Hardware questions are out of scope.

I agree totally with this. I think I was focusing to much on my own printers (Creality Ender 3 v2 and Creality CR-10s pro) Where the minimialistic design would work really well. But there is other issues with this approach like manufacturing gets more complicated for hobbeist becuase of the small size and dual side components and so on. I just ordered a pick and place machine and this will probably be one of the first projects I´ll do on it to test it out. I wil most likely go for something like the first design I made.

I will also create another repository for it when I get into that project more.

probonopd commented 1 year ago

There are now very inexpensive ESP32-S2 based boards called the S2 Mini.

image

Photo credits: @smartin015

They have a USB-C port which a 3D printer can be plugged in using a USB-A to USB-C adapter.

And Espressif seems to have a USB host mode driver for serial bridges and for CDC class compliant devices.

So possibly it could be done now.

Actually, someone has done almost exactly what we have in mind: https://www.youtube.com/watch?v=zkpkUem1ZGw

But that code doesn't use a microSD card to store the GCode; instead it opens a socket over the network. But it should be possible to port it over... Code: https://github.com/smartin015/esp32-tcp-serial

Volunteers?

Cross-reference: https://github.com/smartin015/peerprint/issues/13#issuecomment-1510416104

smartin015 commented 1 year ago

Heya! That was a quick demo, more just to prove the concept than to be used in a "production" setup. I'm glad it caught your attention though, I'd be happy to help contribute here as this project is way further along.

The examples I pull from all use the ESP-IDF framework. I expect building compatibility between the IDF stuff and your Arduino framework code would be step 0 here. WDYT?

probonopd commented 1 year ago

Indeed, porting what you have to the Arduino framework would be tremendous. :+1:

smartin015 commented 1 year ago

Just a heads up that I started the port work today - successfully builds with VCP idf components included and imported into ESP8266WirelessPrintAsync.ino. I haven't yet tried using the VCP components or even running the firmware, but things are looking good so far.

WIP is in https://github.com/smartin015/WirelessPrinting/tree/esp32s2_usb_host.

Note on what it took to combine ESP-IDF and Arduino: it appears there are two recommended ways of combining them.

  1. Use framework = espidf, arduino which builds Arduino as an ESP-IDF component (this seems better supported, but adds a couple extra config files to the repo that are ignored when framework = arduino)
  2. Compile any ESP-IDF dependencies into static libs (.a files) and reference them from the arduino framework. This adds pre-build opaque dependencies into the project, but supposedly still allows just framework = arduino style operation.

I'm much more in favor of (1) and have used that approach when building as it's easier to debug compile-time errors and add more cross-platform stuff later on.

Additionally, I had to exclude the OTA library as I was running into the 1MB FLASH memory limit. Unsure if there's something less impactful I can cut down on, but I'm proceeding with that for now out of convenience.

probonopd commented 1 year ago

Just a heads up that I started the port work today - successfully builds with VCP idf components included and imported into ESP8266WirelessPrintAsync.ino.

Wow, that is awesome news! Very exciting. :+1

I had to exclude the OTA library as I was running into the 1MB FLASH memory limit

Don't we have 4 MB flash on those lolin_s2_mini boards that we want to use for USB host mode?

We can do without the ElegantOTA library (in fact I wanted to remove it anyway), but we do need a way to update via the web interface (I have no physical access to the ESPs built into my 3D printers). Have a look at https://github.com/probonopd/WirelessPrinting/issues/175. We had web based updates working before we added the ElegantOTA library. The ElegantOTA library is purely cosmetical. Before the PR that added the ElegantOTA library, we had a simple (not so graphically nice but leaner) way of updating via the web interface, which hopefully doesn't need as much memory. Maybe you can add the original update mechanism back in, essentially reversing #118?

I hope we can keep SD card functionality for the lolin_s2_mini.

What is very important to me is that CI builds work. Can you enable https://github.com/smartin015/WirelessPrinting/actions?

smartin015 commented 1 year ago

Don't we have 4 MB flash on those lolin_s2_mini boards that we want to use for USB host mode?

Good catch, indeed we do - apparently the default partition config for the S2 mini reserves ~1M for the app, 1.5M for SPIFFS and the rest for OTA. I was able to minimize the SPIFFS and fit it all without disabling OTA.

I hope we can keep SD card functionality for the lolin_s2_mini.

Shouldn't be a problem now :)

What is very important to me is that CI builds work. Can you enable https://github.com/smartin015/WirelessPrinting/actions?

I'm still splicing things together - will enable CI once I'm ready to submit a PR. FWIW I've progressed to sending/receiving some USB serial data while the embedded server/telnet are up, but I'm hitting a snag with command interpretation (apparently my printer doesn't send an ok after handling an M115 command). Dev work continues :)

EDIT: I seem to be running into problems with corruption in the Arduino String library. This is apparently semi-common with more complex firmware. Using char* buffers seems to work just fine though. I might refactor to using those just to get a working result.

dlyckelid commented 1 year ago

Great that you ae working on this!

I have made a prototype hardware that I have at home now available for testing. I did do some mistakes in it but with some modifications it works so I can do testing when you have something that is being able to run.

I did go with the S2_mini cpu but a completely custom pcb around it just to keep cost down and make it easy to just plugin. Unfortunately it does seem like atleast creality printers that I use does not provide a 5V source thru USB as standard as my original idea was to just use the board and have a microusb male contact on it and just mount it on the printer directly on the usb-port. Would be really elegant but sadly I needed to provide my own +5V and powerbrick...