MarlinFirmware / Marlin

Marlin is an optimized firmware for RepRap 3D printers based on the Arduino platform. Many commercial 3D printers come with Marlin installed. Check with your vendor if you need source code for your specific machine.
https://marlinfw.org
GNU General Public License v3.0
16.16k stars 19.21k forks source link

ESP32 32-bit HAL #6524

Closed simon-jouet closed 6 years ago

simon-jouet commented 7 years ago

Hi everyone,

So I've forked @thinkyhead 32-bit branch and started to work on an ESP32 implementation. The code isn't functional yet, I got the very basic code working to get it compiled + uploaded to the ESP as well as basic code to handle timers. The fork is available here: https://github.com/simon-jouet/Marlin/tree/HAL_ESP32/Marlin If some people find the idea of running Marlin (or more generally a 3d printer ...) with an ESP32 feel free to contribute. I've little free time to spend on this project so it's likely to be a bit slow for now.

Why the ESP32?: It's a very very nice chip with a lot of horse power (dual core up to 240MHz), it has built-in WiFi and Bluetooth plus a bunch of peripherals and it's very cheap ~$5. I think it can be a very nice chip to use for a 3d printer and with some love that might happen... The main downside is the fairly limited number of GPIO ports but that can mostly be dealt with.

I also started drafting the circuit in KiCad to make a ramps like board with a built-in ESP32. The design isn't on github yet, I will push that a bit later. Anyway for the moment I've been trying things on protoboard it's dodgy but it looks to be working okay (the hot glue is to keep the deadbug-style wires in place):

img_20170501_131220

img_20170501_131142

Going back to the limited availability of the GPIO, could users give some details about what they are using? I would like to figure out what the minimum required to fit most users (pretty much should I include an IO expander by default or we can do without). For instance I've got a clone of a prusa i3 mk2 (thanks @tom3d for the build series)

As a side note: On the ESP32 arduino implementation ENABLED is defined for a pinMode, so I had to change all references to ENABLED(config) to OPTION_ENABLED(). Make sense to have the #define slightly less broad than what it is currently, but in the long term not sure how this should be dealt with.

JustAnother1 commented 7 years ago

Did you see the "32bit-RCBugFix-new" branch? Would it make sense to merge this into that branch? If yo could you create a pull request?

The reason for my questions is that there have been a few forks with implementations for 32bit based cpus. They all have been abounded. And Marlin tries to channel the 32bit effort into that branch so that we all together can maintain that single branch and won't have to deal with too many different branches.

simon-jouet commented 7 years ago

hi @JustAnother1, thanks, yes actually this fork is from 32bit-RCBugFix-new :), I should have been more specific in my post. I won't create a pull request for now, the code is too fiddly at the moment once it's okay enough to run on my own printer and if people show interest then I will.

I think maintaining Marlin for 32bit code might not be too bad, the HAL in the current branch is quite straightforward and actually getting Marlin compiled for the ESP32 wasn't that bad. (okay it's far from done but still)

JustAnother1 commented 7 years ago

My impression is that the 32bit branch is currently more of a "work in progress" type branch. So IMHO unfinished code should be ok if it helps move the HAL interface forward. If you don't want the pull now then that is ok, but don't forget to send the pull request once your satisfied with your code.

Do you use arduino IDE to compile your code? Or do you have a build environment that is independent of Arduino?

simon-jouet commented 7 years ago

Do you use arduino IDE to compile your code? Or do you have a build environment that is independent of Arduino?

The code is compatible with the arduino IDE, the ESP32 guys have done a great job in getting this working. However for the dev I use platformIO (in arduino mode) as it's much more practical to dev. with Atom than the terrible IDE of Arduino

teemuatlut commented 7 years ago

I think it would be very interesting to see Marlin on an ESP. I've got one coming as well.

On the ESP32 arduino implementation ENABLED is defined for a pinMode, so I had to change all references to ENABLED(config) to OPTION_ENABLED()

Possible usecase for #undef?

timonsku commented 7 years ago

The ESP32 actually has quite a few GPIO pins. 48 to be exact, the limitation only comes from the Wroom module. If a board would be created using the IC itself, not the breakout board the GPIO shortness might not be an issue. Though FCC certification etc. might be an issue in that case. https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf

The IC is only really getting into larger production right now so there might be more breakout boards in the future with more pins available.

simon-jouet commented 7 years ago

The ESP32 actually has quite a few GPIO pins. 48 to be exact, the limitation only comes from the Wroom module. If a board would be created using the IC itself, not the breakout board the GPIO shortness might not be an issue. Though FCC certification etc. might be an issue in that case. https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf

Hi thanks for the comment, actually the WROOM32 exposes most of the pins on the chip, if you look at the datasheet you sent page 15--17 you can see that quite a few pins are power related, one for RF antenna, enable pin and analog stuff. So at the end by having a dedicated module you might gain a very few pins (6, 7, might be one or two more that I missed). The main issue is that 6 pins are used for the quad-IO flash which the datasheet recommend not to use them for anything else (but they are still exposed on the module).

Anyway like you say, going through the troubles of dedicated FCC certification is probably not worth it when some pins can be easily freed. I'm thinking of getting one of the TI 16 pins I2C GPIO extender for the end-stops, probe, LED anything that's not super timing critical.

Thanks for the different comments, if I have some time I will try to get a bit more working tonight, at the moment it crashes in the temperature ISR after a few ticks, need to investigate.

Cyper77 commented 7 years ago

if you implement a web upload page with nice gui, you are the man.! nice work... but dont do that here, make it and send a post hackaday or eg.. here is the bug page eventually.

Cyper77 commented 7 years ago

look at that : this is an regular 3D printer fw with nice gui for old esp chip. https://github.com/openhardwarecoza/ESP8266

timonsku commented 7 years ago

Thats not a 3D printer firmware, it just acts as a wifi bridge that includes a web UI. Totally different beast.

a0s commented 7 years ago

Hi @simon-jouet , what do you think about aprinter firmware ?

Xandrios commented 7 years ago

I think using the ESP would be a great idea. The chip has enough power, and has the potential to run circles around the Arduino Due for example.

The one downside is the low number of IO's - if that can be worked around this has the potential to be a worthy replacement for the Arduino 2560 / RAMPS1.4.

JustAnother1 commented 7 years ago

Regrading low number of pins: The Step and Dir Signals for XYZ and E should definitely be directly connected pins. There are some more pins that could benefit from direct connection, but basically everything else can be connected to an GPIO Expander. But you have to do it right! GPIO Expanders have Interrupt Lines. So all End Stops at an GPIO Expander and the Interrupt line of the expander directly connected to the ESP would be a better solution that what many board do right now. The other thing is that IO Expanders can also do PWM. Therefore no need to switch the Heater on and of and on and off again. Just set the PWM value in the Expander. That also helps with RGB LED ;-)

Also there are temperature sensor Chips that have I2C or SPI.

All this will probably cause bigger changes in Marlin though,....

brewmanchu commented 7 years ago

Just $0.02 but you could also put the display on an I2C expander too. It doesn't need to be updated frequently. In fact I removed my display from RAMPS since I have no use for a built in UI. An rPi3 running a print server works for UI and it even gives a camera interface.

Nickduino commented 7 years ago

Adding an interface like octoprint would be fantastic. The all-in-one board.

About the end stops, you might get away with only one pin: if th pin goes low while your moving the Y, then it's the Y's 0. Then, move the Y 1 mm forward until it "unclick" the microswitch and move tha X to get the X's home. Etc.

alexxy commented 7 years ago

Do you have any progress with ramps like esp32 board?

Roxy-3D commented 7 years ago

Re-ARM with a RAMPS v1.4 board is limping along. But right now it needs to have a Graphical LCD panel on it. When the Folder & File layout is updated this weekend... It is very possible it will work with a 20x4 LCD Panel also.

But if it doesn't.... I'll get that fixed fairly quickly.... The first thing to get added to the Re-ARM HAL is a simulation of the EEPROM by using a file on the SD-Memory card. That will be done in a way other HAL's can also just use it.

The Re-ARM board uses a LPC1768. But I expect all of the ARM flavors to start making faster progress.

simon-jouet commented 7 years ago

I do have, got quite a bit working with a ramps 1.4 and an ESP32, I will push the code at some point soon, there is still quite a few things to debug. Once the first iteration of Marlin 2.0 code is release I will bring the ESP32 changes and push it to my branch.

The ESP still has some issues that won't make the merge with master very simple, I have some ideas on how to tackle them but didn't had much time to look at it. Anyway if the new code refactor is release over the weekend I might work on it next week.

alexxy commented 7 years ago

Btw another possibility to free up some pins is to use i2c for communicating with steppers and endstops

Roxy-3D commented 7 years ago

Btw another possibility to free up some pins is to use i2c for communicating with steppers and endstops

Yes. But that is so slow... It kind of begs the question: Why move to a 32-Bit platform if you are just going to slow everything down with bit-banging?

timonsku commented 7 years ago

Using I2C based devices =/= bit-banging but I agree that timing intensive tasks like stepper control should run directly on the MCU. But no problem imo to use I2C port expander for "slower" io like aux in/outputs, temp sensors etc.

Roxy-3D commented 7 years ago

Also... There was talk about putting a RTOS underneath the 32-bit processors. With an RTOS there, it is easy to side step the concern because the I^2C task would be lower priority than the really important stuff. It doesn't matter if it uses a lot of CPU to talk to things on that I^2C bus.

teemuatlut commented 7 years ago

This can in part already be accomplished by prioritizing the interrupts on ARM chips. I could also see Marlin making use of semaphores at some point in the future.

3d-gussner commented 7 years ago

Using Trinamic stepper drivers with SPI like TMC2130, TMC260 or even the TRAMS board (TMC5130) would safe a lot of pins and it is fast, quiet and just great. TMC stepper drivers are just the best at this moment for me. DuetWifi/Ethernet uses TMC260, Ultimachine is busy with Einsy board, Smoothieboard V2 comes with TMC2660 and TMC262...

davidelang commented 7 years ago

The ESP32 also has multiple cores, so if you dedicate one core to running the steppers, and the other to doing the communications/planning you may not need more prioritization.

teemuatlut commented 7 years ago

Using TMC2130 in XDIRECT mode or TMC26xx in SPI mode would need a very significant change in Marlin's design. It's only 3 pins that are needed to drive a traditional driver, so 12 for a basic machine.

Marlin will be getting support for TRAMS after the 2.0 release and after I get to do some proper testing first. But I see no reason for it not to work on any 32bit MCU with an SPI interface.

I was under the impression that one of the ESP32 cores handles the wifi communication and you can't program it.

alexxy commented 7 years ago

BTW there already L6470 drivers that supported by marlin that only has SPI interface.

teemuatlut commented 7 years ago

In stepper_indirection.h

 // L6470 has STEP on normal pins, but DIR/ENABLE via SPI

The current Marlin support is very basic for them.

3d-gussner commented 7 years ago

@teemuatlut You are right. With a RAMPS board you will use 3 pins per stepper. But you have to adjust the voltage manually. I am not a developer but checking the 'pins.h' file i can see that RAMBO board use -STEP-PIN, -DIR_PIN, -ENABLE-PIN, -MS1-PIN, -MS2-PIN which are 5 pins per stepper driver ==> 4 stepper drivers x 5 pins = 20 pins in total. Guess these two pins are for software voltage adjustment?

The TRAMS board uses XYZE-ENABLE-PIN, CS-XYZE, XYZEAXIS each plus SPI pins for all of them and the endstops are also read by SPI ==> 4 stepper drivers x 3 pins + 3 SPI pins = 15 pins with software voltage adjustment AND you safe 6 additional endstop pins.

RAMPS vs TRAMS/TMC SPI drivers 12 stepper pins + 6 endstop pins =18 total VS. 12 stepper pins + 3 SPI pins = 15 total with software voltage adjustment

RAMBO vs TRAMSTMC SPI drivers 20 stepper pins + 6 endstop pins = 26 VS. 12 stepper pins + 3 SPI pins = 15 total

As I see it you safe PINs using TRAMS/TMC SPI stepper drivers and it should be worth to get into it. Here the link to TRAMS github https://github.com/trinamic/TRAMS

Update to 3 SPI pins and not just 2 :-)

teemuatlut commented 7 years ago

Yeah I don't know why Trinamic used an EN pin at all as this could be done in software too. But I don't think they were trying to save on pins per se. Not sure what you mean with "AXIS pin"? I think there's only the EN and CS pins for each stepper and then the shared SPI pins (MOSI, MISO, SCK). That would make 11. Drop the EN pins and use software enable, you get down to 7 pins. Hardware wise would be really easy to add 5th and 6th stepper too...

Here's my updated TRAMS branch and I've got a TMC5130 Arduino library also that I've yet to push online. So if anyone wants to make a ARM + TMC5130 based board, the software would already be there.

3d-gussner commented 7 years ago

@teemuatlut Very nice explanation!!! Even more pins to safe 👍 And thanks for sharing your effort 🥇

3d-gussner commented 7 years ago

With SENSORLESS_HOMING we could save additional 6 pins for the end stops @simon-jouet What happend to your ESP32 HAL? @teemuatlut How is the status of the TRAMS board? Anyone started with Marlin 2.0?

teemuatlut commented 7 years ago

TRAMS is seeing communication errors when printing. So very much WIP.

simon-jouet commented 7 years ago

@3d-gussner The version that was on github was quite behind my local version and then I paused for a while waiting for Marlin 2.x branch to be out. Anyway now that 2.x is started I will get back to it, I already have a much better devboard than what is displayed above and managed to get the GPIO port expander to work properly.

@Roxy-3D Slow reply sorry. The ESP32 uses FreeRTOS and the arduino library are actually just a wrapper on top of FreeRTOS so all the goodness of FreeRTOS is still available if necessary. Though that's very specific to this micro and implementation so probably not very useful for Marlin in general.

More as a discussion point than anything, but is there any discussion going on to more seamlessly support GPIO port expanders? In my current branch I modified the IO functions to talk to the I2C expander if the IO port MSB is set, allowing default pins definition to be used with or without an IO expander. However, that's not a particularly clean approach, but the advantage is that it's limited to modifying the HAL for a specific platform.

3d-gussner commented 7 years ago

@teemuatlut Hope it will get better and Trinamic will help. Think it is one of the best hardware you can get for the money, just get it running is a challenge. @simon-jouet Thanks for the update...did you read the comments above? With Trinamic stepper drivers you could use much less pins for the motors and with SENSORLESS_HOMING even more for the end stops. So maybe no need for a GPIO port expander. With a nice web interface on the ESP32, like https://github.com/luc-github/ESP3D, i don't need a LCD screen. Just buy a cheap tablet under 80$ if you need kind of interface on the printer.

vido89 commented 6 years ago

Im looking forward to see this in action, what is current status of development ?

simon-jouet commented 6 years ago

Okay I went back to it after quite a while, got much easier with all the changes in the Marlin 2 branch!

Anyway I've pushed a fork https://github.com/simon-jouet/Marlin in the esp32 branch with working stepper movements.

If people want to try it out (and possibly contribute) the requirements are very minimal, I use a devkit-c-like module (cheap version from aliexpress) and a MCP23017 as a GPIO expander on top of a RAMPS board (I would guess about £10 total (ESP32: $5.65, devkit: $3.14, RAMPS £3.15)).

Anyway here are some of the todos:

sanchosk commented 6 years ago

I have a small suggestion. Replace the MCP23017 with 8-bit shift registers. Look at what CNLohr did with ESP8266 - you can add 32GPO for next to nothing and blazingly fast (192kHz PWM no problem). It also uses DMA, so almost no utilization of the CPU. For cheap inputs, use ADS1X15 for fast and precise ADC - if 12bit is enough, use ASD1015, if you want 16 bits, use ADS1115 (4 inputs, $2.20 on Aliexpress).

paulbearne commented 6 years ago

Just came across simon's branch for the esp32 , i've just sent a pcb layout off to made and wondered if it may be of use to anyone i primarily built it for my D-bot based roughly on my existing rumba i've compromised a little due to the lack of pins and tried to avoid io expanders on heaters and steppers due to a bad experience on hvac system. i was going to to do a second board to take on of the cheap rpi touch screens and have hooked into the controller via wifi. the gerbers and schematics are on my site http://esp32robots.co.uk and i'll have tinker with esp32 code of simons when the boards arrive.

simon-jouet commented 6 years ago

@paulbearne sounds good, I will have a look at your board. I also avoided expanders on heaters and steppers, at the moment the GPIO expander is used only for the stepper enable and the endstops and I got the thermisors, step/dir and mosfets on the ESP32's GPIO. In this board I kept HSPI pins available so I might connect an ILI9341 screen to it, but I think I might just in the long term use my phone over wifi/bluetooth (well that's a bit long term to say).

Anyway I just (finally) pushed the kicad schematic and PCB to github, https://github.com/simon-jouet/ESPRamps

EDIT: @paulbearne just had a look, very nice board, let me know how it goes once you get them

paulbearne commented 6 years ago

will do simon should have them in a couple weeks then a few days putting the parts down. the rpi displays i think its waveshare although they have pi 20 pin connector are ili9341 and actually use spi with onboard sd card ideally could free up the pc connected to it .

tedder commented 6 years ago

Here to see progress. Have a half-dozen ESP32s floating around my desk, not only are they fast and connected but also dual-core, which is perfect for the Marlin printing. Simon, do you have your ramps board yet? Paul, how about yours?

simon-jouet commented 6 years ago

Hi @tedder,

Sorry for the very slow reply. Yes I do have a board and sent one to @luc-github, the current board is far from perfect though, the minimum hardware is working properly but a new iteration will be needed soon :).

At the moment the code allows most of the basic things to work properly, I can start a print over serial but after a few moves the printer crashes (not too sure why and haven't had the time to work more on this since then). Both the marlin code and the board are on my github page, so if you feel adventurous you can build one.

I will try to go back to it in the new year, design a cleaner board and fix some of the issues with the current iteration. I'm considering going directly for a single board instead of a board + RAMPS as the RAMPS is quite basic and most of the pins of the ramps can't be mapped to the ESP32.

@paulbearne Same as @tedder, did you get your board? Curious to see how that's going.

paulbearne commented 6 years ago

Hi simon yes i got the boards back but haven't had time to play with it fully did some preliminary checks. looking to get back on it in the next couple of weeks.

AlmightyFrog commented 6 years ago

Hi @simon-jouet, what is current status on your rework for ESP32 with regards to the board you want to design?

Need a controller for my new printer. Not sure if I want to go the ESP32 way (as had bad experience when it comes to ESP8266 stability) but it is indeed a nice idea. Still on track with using I2C for portexpanding (MCP23017?) or what do you plan? If It wouldn't be for that part i have not around here I'd just give your latest code in repo a try on a breadboard.

AlexStarFL commented 6 years ago

Hi @simon-jouet, IMHO the best expansion board for ESP32 is another ESP32 board.

simon-jouet commented 6 years ago

If anyone is interested, I've spent some time over the last weeks or so to get back to this. If you have a look at https://github.com/simon-jouet/Marlin there is a version that compile and somehow runs with pretty much the latest bugfix-2.0.x.

There is still quite a bit to be done but I'm hoping to have a first print relatively soon. The steppers are stepping (albeit too slowly - probably a timer issue) the endstops, thermistors and PWM are also working. I've also added very basic code to support OTA updates to help with the dev.

The current setup is very straightforward just an ESP32 without any GPIO expander (it's tight pinwise but enough if you don't have bells and whistles) connected to the mosfets/thermistors voltage dividers/stepper drivers. So if you have a spare RAMPS or the like board or don't mind soldering a bit the only thing needed is an ESP32.

AletheianAlex commented 6 years ago

Good to see some movement on the esp32 front. I haven't had time to even look at it yet, but it has been on the to-do list for a while

simon-jouet commented 6 years ago

I've pushed some more changes, I managed to get a print started, got the printer homed properly and issued the first few dozens of commands properly.

I am now running in an issue with the ESP32 rebooting due to interrupt watchdog timeout which is caused by the processor hanging (or taking too long) while in an interrupt. The default timeout is 300ms so even if it's because it's taking too long the stepper interrupt should take far far less than this. I disabled the interrupt watchdog in esp-idf to give it a try but as expected marlin just hangs at some point.

After quite a bit of debugging I think it's something to do with acquiring the semaphores, either for the timer_set_compare or from the enable/disable ISR in the stepper interrupt. I'm not too sure how to go about debugging this, so if someone wants to give it a try or have a look I would be happy to help. There is no need for a full setup, just a running ESP32 with a serial port is enough.

thinkyhead commented 6 years ago

Marlin operates in a single thread and doesn't use semaphores. Is this something you've added?

The stepper interrupt blocks everything else while it runs, except the serial UART. When it exits it resumes the main loop. Same with the Temperature ISR and the Endstop ISR. The stepper ISR tries to ensure that it will give some time to the main loop and not re-enter right away.