Monoprice Mini Marlin 2.0 Support

Getting Marlin to run on the Monoprice Mini/Malyan M200.

Similar projects worth following
I greatly enjoy my Monoprice Select Mini 3d printer. For an entry-level printer, it's all kinds of fun. The only problem is that as much as I like to tinker with hardware, I *love* to tinker with software. And the mini's firmware wasn't open-source. Thus began the process of getting Marlin 2.0 to run on the mini.

The MPMini/Malyan M200 V1, V2, and Pro (V3, for all purposes) run on an STM32Fxxyy processor using a firmware which is claimed to not be derived from Marlin (hook a serial monitor to the display port and make your own decisions whether or not that's true). These project logs follow my progress making Marlin 2.x run on this board across multiple hardware revisions/Arduino cores.

V1 and V2 work today if built with the Arduino IDE. V3 in theory works (it's the same processor as most V2s) though ABL doesn't work without EEPROM emulation. M300 support would most likely be a different project, but it feels like an extension of this one, so for now, I'm leaving it here.

  • V2 Success

    J.C. Nelson6 days ago 0 comments

    Last night I was able to successfully do a few test prints of the lucky cat and butterfly using the V2 (STM32F070) MCU. This means this project is drawing to a close, of sorts. Marlin main now supports the printer, V1 and V2 both click-compile for the most part. The sample config will work if I update the documented settings on how to compile, or I may update the sample config. 

    V3 (with auto-level) is a matter of defining the probe pin (I believe it's PA3) and configuring ABL, but to do that, I'd need to re-enable EEPROM emulation. It doesn't currently work under ST's core using the unified HAL. It's really one of the last things to be needed, and once it's done, short of adding WIFI printing to Marlin Main, and Malyan's custom GCODE, there's not much left.

    I created a config for the Malyan M300 delta /MPMD and may do a test with it as an extension of this, but the delta more or less just works. We'll see once I draw the V2 work to a close.

    V3 is a possibility, enabling ABL, except I don't have a V3 - I'll need to use my V1 + probe or the bl-touch I wired to a V2. 

    Delta is a possibility.

    Soon I'll get back to the Lerdge project.

  • BL-Touch (on a V2).

    J.C. Nelson05/05/2019 at 01:22 0 comments

    I have been experimenting with a number of different probes, and returned to something I'd only gotten tangentally working - a BL touch sensor on the V2. Why the V2? Because nice, new V2 motherboards have a handy JP socket exposing Serial2. Older boards all the way back to original V1s have solder pads or through board vias you can put a header on, but the V2 came ready. So I built a little adapter to let me test it.

    In short, there's a lead from the 12V input which runs to a buck converter, providing 5v for the BL-touch and powering the 5v side of a 5->3v level shifter. Power and Ground from Serial2 plus PA3 go to the low side of the 5->3v level shifter, and the rest of the wiring is pretty much standard bl-touch. 

    Does it work? It does. It probes just fine, though it's not clear to me why the bl-touch can't be at an agle. There's probably a reason. 

  • Wifi Printing

    J.C. Nelson04/26/2019 at 19:59 0 comments

    The MalyanM200/Monoprice Mini has an interesting feature in that it supports wifi printing - the ability to connect Cura or something similar via wifi and print directly that way. This is accomplished via  combination of features, starting with the ESP8266 which drives the LCD. By default the ESP bridges telnet to serial.

    The Malyan firmware also supports a sort of dual host support, in which bytes with the high bit set from the UI are UI commands, and bytes with the high bit off are channeled commands.

    Marlin 2.x has multihost support in which you can have multiple serial outputs, but what is missing is a simple bit of glue: A ring buffer Serial implementation which can be fed the channel bytes, while the UI code consumes the encoded ones. Fortunately, both the ESP and Linux HALs have a sort of fake Serial, which I quickly adapted to MemorySerial, and plugged into the LCD code.  There's a new feature in configuration.h, WIFI_PRINTING, which enables this. 

    I'll be testing this once I can get my mini joined to the WIFI network. Malyan's firmware supports custom GCODE commands to set the SSID and password. Marlin does not. I'll need to figure out a way to get it set up.

    The last missing chunk only really works on Windows. MalyanLink uses the opensource Com0Com virtual com port driver to link a host and port to a virtual com port. I'm not sure what I'll use, yet, since OSX doesn't let me symlink using netcat to create a virtual modem.

  • The importance of choosing the right libraries

    J.C. Nelson04/26/2019 at 05:34 0 comments

    While I'm glad I spent some time looking at the pulses under an oscilloscope, what I found was that the minimum stepper pulse was working. How did I do this? Well, my DSO scope has only a 10us option for its finest sampling setting, so instead I increased the minimum pulse to 30us...and was able to measure it just fine.  Pulse count, as well, was right down the line.

    But I began considering something different, something I should have considered earlier.

    The display controller communicates movement using float numbers for the GCODE injected. Arduino has the option to have very small runtime libraries, without the ability to print floats or parse them. The homing moves (G28) inject distances directly. After looking for a bit, I realized I hadn't selected a runtime with float support, so I went back and adjusted my settings--and it moved.

  • Oscilloscope, Ahoy

    J.C. Nelson04/24/2019 at 16:38 0 comments

    The USB init Pull Request for Malyan M200 V1 systems is now officially merged into ST's Arduino core, which means USB works reliably now. A few minor changes to define UWMEM addresses and allow the MalyanM200 pins to be used with the ST core, and I can compile using the Arduino IDE every time, reliably. 

    That's great.

    Heaters work, USB, the LCD, fans, SD card, etc. All of that works just fine. There's just one little problem:

    THe motors don't move correctly.

    Now, if you go back through the project logs, you'll see this is a recurring problem I've fought with a number of different reasons. Sometimes it's the min pulse length (needs to be 2 on my Malyan boards, even though the documentation claims 1 is sufficient). Sometimes it's the ISR timer prescalar/frequency. Some advice from the Marlin github issues suggested that it would be a max rate issue, so I adjusted the settings to match the M200's defaults.

    No luck.

    Homing moves successfully raise the Z axis, but the other axises don't even budge, they'll occasionally stutter.

    And I can't lower the Z axis.

    Now, the Z axis is unique in that its step count is ~3x the number of any of the others. This means that missing pulses or incorrect ones have a margin of error. To figure this out, I needed to measure the pulse lenghts and see what's being sent. I do own a scope, a DSO138 hobby scope that I 3d printed a case for. It's a single channel, but I only need to measure one, so I hooked it up to the stepper output after checking to make sure the scope could handle it and ran some tests.

    The stepper output is garbage.

    But it turns out I made a critical mistake. I'm not measuring the actual pulse, I'm getting the output from the stepper driver. I have two approaches I'm going to chase in parallel. First off, on V2 hardware, there's a beautiful JP socket for Serial2 (what I used to hook up the BL-touch). I'm going to cheat and define the TX and RX pins as X and Y step. I can measure those directly.

    Secondly, there's a board definition in Marlin (STM32F1_R) which isn't for a real printer, it's a bluepill. I'm going to get that compiling and load it onto a bluepill. That will let me measure the pulses directly.

    It could be that I have everything configured wrong in the timer. It could be that the no interrupts code is causing some blocking. We'll find out.

  • USB Revisited, plus Timer work

    J.C. Nelson04/16/2019 at 17:12 0 comments

    I've been fighting PlatformIO to get it to build, so for now, I switched back to compiling with the Arduino IDE. I wasn't terribly surprised to see that the V2 board (an STM32F070 board) simply worked with USB CDC. Why? Because the V2 doesn't have a pullup transistor. It has the place for one (and I'm near certain PB9 could be used as an output with a little soldering), but it doesn't have it.

    The V1 board variant turns on PB9 on variant init.

    However, V1 USB doesn't work. The reason why is related to a previous log on USB support. The ST Arduino core signals reenumeration by pulling DP low. However, if DP is being fed by a pullup transistor, pulling it low alone doesn't do the trick.

    To fix this, we need to make the reenumerate function weak, something I've opened a PR to do, and add a reenumerate to our variant, something I've also done.

    Timer wise, we have to deal with the fallout of an earlier log where I noted that timer conflicts with hardware PWM could cause resets. To handle this, I consulted the timer map and the PWM map.

    We use PB3, PB6, PB7, and PB8 in analog write (FAN2, HEATER, HOTEND, and FAN1). This leaves timers 1 and 3 open, which just so happen to also (apparently) be available on the 070. So I've updated the pin map and will test.

  • Board Support is In

    J.C. Nelson01/30/2019 at 06:24 4 comments

    A small log to note that the current master branch for ST's arduino core now supports Malyan's M200 V1 and V2 (and possibly delta/M100). I am extremely limited in hacking time at the moment, but it's in.

    Go forth, build Marlin, and enjoy.

  • V2/STM32F070 Support

    J.C. Nelson11/23/2018 at 21:37 1 comment

    Having successfully gotten a mostly functional firmware on the V1/STM32F103 MCU Mini, I moved on to supporting the STM32F070 processor. That's the one that drives the Monoprice Mini Delta, the later run Malyan M200V2, the Malyan M300/Monoprice Mini Pro (aka V3), and highly likely to be the same chip in the new CR-10 clones from Malyan.

    I do not know about the SLA printers - if anyone owns one, I'd love to know fi the motion controller is a variant wired to galvos or not. 

    In enabling V2 support, I discovered some ugly hacks I'd done to to the build flags and unwound them, and in a few hours, had a working firmware that boots on V2 boards.

    These are, as of yet, untested in printers.

    Why? USB support. I'm waiting for the 1.5 release with its CDC virtual com port emulation, which allows you to hook the printer up via USB.

    Regardless, it's time to begin the work of integrating the boards for a proper PR, and also, figuring out how to support the Malyan M100, which is theoretically a variant, but I have reports that the same firmware doesn't function there.

    One note about V2 support:

    Copying over the vector tables in STM32F070 variant init means that pre-main intializers which use interrupts are in trouble. The vectors aren't in place until variant Init, which is part of the main() function (for arduino folks, that's before setup()).

    I don't know yet what I"m going to do (if anything) about this.

  • Core Woes Unwound

    J.C. Nelson11/22/2018 at 16:04 0 comments

    As noted in the last log, I'd seen some on-again, off-again woes in the ST official core for Arduino. I thought they'd been transient, the result of the mismatch of cores and core-specific hacks in Marlin's code, there's a general rule I should have remembered:

    If you don't know how you fixed it or why it was broken, it isn't fixed, only hiding.

    And sure enough, a few rebuilds later, the behavior manifested again, as though I wasn't feeding the watchdog.

    So I did what any good programmer would do, and put watchdog statements in my code and looked for them.  Look, I'm feeding the watchdog.

    I tested running the temperature ISRs directly from the main() loop.

    Then, I stumbled on a key. The behavior only manifested once Marlin had sampled the temperatures enough to average them.

    This behavior manifested on a bluepill as well as the M200 mainboard, so I stuck with the bluepill, using gdb to debug, and there I began to unravel a call that made no sense. No matter how often I broke in, the core seemed to be answering an interrupt for timer 4.

    No problem, that's the stepper timer, and it runs quite often. 

    But with GDB, I noted that nothing was getting dispatched, as if my ISR had gotten lost. I stepped back and put a breakpoint on timer initialization, hit the reset button.

    Both my ISRs got registered as expected. Perhaps some sort of memory corruption?

    But on a whim, I left it running, and a moment later, I hit an unexpected init.

    It turns out that ST's official core uses hardware PWM for EVERYTHING. STM32GENERIC uses a single timer for all pwmWrite (analogWrite) calls. Maple uses a mix of hardware and software PWM.

    And in ST's official datasheet, the different pins the mini uses for fans and heaters (the two PWM entities) are mapped to timers 2 and 4.


    For now, the answer is to shift timers to 1 and 3. 1's the right value for the stepper timer, because it holds a larger (32 bit) value, which is important when we want to run very slowly. 

    Long term, I'll either need to request (or write and generate a PR) a simpler PWM implementation which doesn't consume every timer on the board.

    But with that change, my M200 mainboard remains running. I can print using the LCD...sort of. 

    We need USB support (coming in 1.5 of ST's official core) before this can be usable by the world, but we're getting there.

  • More Core Weirdness

    J.C. Nelson11/13/2018 at 15:15 0 comments

    After a ton of debugging where nothing made sense, I moved away from using the M200 mainboard and started debugging on a bluepill using...another bluepill. Yes, you can convert a bluepill to a blackmagic probe, and getting that set up was actually key to another project of mine, hacking the obfuscation in Lerdge boards via the PC/SP registers (in essence, while Lerdge has protection set, you can't stop reading the SP/PC registers, so a firmware with the PC counter hacked and SP set to a known value will yield 4 decrypted byte values at a time.

    This gave me the chance to take a breath and step away, and when I came back, I synced up, and lo and behold, the mysterious crashes went away. While I can't use the malyan LCD and the serial definition at the same time, it's now at the point where I need to plug a main board into the printer and begin actually testing...

View all 20 project logs

Enjoy this project?



Károly Kiripolszky wrote 2 days ago point

Just found this project and have ordered a Select Mini V2 yesterday. According to the post from 3 days ago Marlin seems to be working now. Incredible timing! :D The Mini will be my first 3D printer. Thank you for your work, awesome project!

  Are you sure? yes | no

Thomas wrote 04/30/2019 at 17:33 point

I've got a Select Mini V2 I'm willing to help test with. What is the current state like? Will your marlin or stock marlin now print at least as well as the stock firmware? 

  Are you sure? yes | no

J.C. Nelson wrote 05/05/2019 at 01:15 point

I believe it does. You're welcome to download and test. It's a bit of a pain since you need to install using the dev board manager, delete the downloaded core, and then drop the github repo in on top. I'm experimenting with building a portable directory for Arduino. It seems to work, but I"m not sure where I'll host.

  Are you sure? yes | no

Thomas wrote 6 days ago point

I've got the arduino ide setup with the STM32 core, loaded up Marlin and coppied the example config for the M200, and twiddled the build menu settings to things I think make sense (3d printer boards + M200 v2 + CDC/no serial, etc) and it fails to compile with an error about serial port 0 not existing. I've tried playing with the board config menu options but nothing seems to work. 

edit: AAAH, you did say I need to delete the downloaded core. sigh. I'll try that...

  Are you sure? yes | no

J.C. Nelson wrote 6 days ago point

Thomas - every STM32 core has different definitions for Serial. You want to set it to -1 for USB.

  Are you sure? yes | no

Thomas wrote 6 days ago point

ok, trying the two methods for copying things over, I get compiler missing errors. woo. I'll keep trying.

  Are you sure? yes | no

Thomas wrote 6 days ago point

Ok, cool. I got Marlin to compile with only a single warning: 

warning: #warning "No CMSIS startup file defined, custom one should be used" [-Wcpp]
 #warning "No CMSIS startup file defined, custom one should be used"

All I needed to do was setup the board support package in the board manager, installed the STM32 stuff from git in ~/Arduino/hardware", downloaded and installed a newer arm gcc package since the stm32 stuff seems to want it.. then modified the platform.txt file to update a few things (like CMSIS paths etc). I'm hoping it'll work now. 

  Are you sure? yes | no

J.C. Nelson wrote 6 days ago point

The CMSIS warning is expected. A custom one is defined (or else it wouldn't link, since it has my reset handler in it). Sounds like you have a firmware to try updating with.

  Are you sure? yes | no

Thomas wrote 6 days ago point

Ok, I've coppied the .bin file over to the sd card and it appears to have attempted a flash, however it appears to not be responding over usb or sending any version number to the LCD on bootup. so I assume its currently not booting properly.

  Are you sure? yes | no

Thomas wrote 6 days ago point

Tried a different sd card for kicks knowing the board's finickyness, and that appears to have gotten it to change some things and show up over usb. currently though the LCD is having issues doing anything with the printer.

  Are you sure? yes | no

Thomas wrote 6 days ago point

trying to print via octopi and the printer halts when it tries to move one of the axis.. I think a bunch of the axis pins are wrong. is there a known working config for the M200 v2? The one in the example's folder for M200 is incomplete.

  Are you sure? yes | no

J.C. Nelson wrote 6 days ago point

The one in the example folder is exactly complete, however, like any M200 printer, there's a significant chance your axis are reversed. Put the X carriage in the middle of the bed and issue a G1 X10 command. If it moves inward (toward the tower), you need to invert X. Same thing with Y. If it doesn't move forward, invert it. Same thing with X. Marlin 2.x will kill the printer if a homing move doesn't actually succeed in homing. The solution, as always, is to fix the config to match your individual printer.

  Are you sure? yes | no

Thomas wrote 6 days ago point

Maybe I got the wrong thing then, because I needed to change the MOTHERBOARD macro to 

BOARD_MALYAN_M200. ALSO I just did some more testing and I'm wrong, its just that the axis are moving really strange. Z is deff backwards and simple enough to fix, but X and Y don't always respond to commands and If I spam move commands from octoprint it will sometimes move but erratically.

  Are you sure? yes | no

Thomas wrote 5 days ago point

More testing. X and Y will moove in relative mode but they wont always move the same amount between each G1 command. sometimes they go backwards a bit. And they don't move anywhere near as much as they should given the M92 settings.

  Are you sure? yes | no

Thomas wrote 5 days ago point

And more testing. Not sure what change I made fixed things if anything did.. but homing now works properly :D  

  Are you sure? yes | no

Thomas wrote 5 days ago point

I have a feeling it was the options to disable the steppers all the time that may have done it. I told it to keep them active, and thats probably what did it? Now though I'm part way through a print and the printer just decides to cool down and raise the head till it hits the top then eventually gives an error.

  Are you sure? yes | no

Thomas wrote 5 days ago point

Part way through this print I get a bunch of strange behavior and messages. I generally notice when the printer sends the head to the far right, and the bed to the front (so the head is in the back right), and then raises the head a few mm at a time every few seconds... messages like:

Send: N26641 G1 X45.6 Y55.479 E1299.51499*91
Recv: echo: too long extrusion prevented
Recv: echo: too long extrusion prevented

checking the gcode, I think it might be the model. weird...

  Are you sure? yes | no

Thomas wrote 5 days ago point

Different model that I know used to work is now failing the same way. WEIRD. I think its the PREVENT_LENGTHY_EXTRUDE option.. but I've tried 500mm, which you'd think would be enough unless cura is doing something strange? trying 1000mm now.

  Are you sure? yes | no

Thomas wrote 4 days ago point

Latest attempt and it just got to a corner of a test model and spazzed out trying to extrude with too high a feed rate and sent the head to the back right again. so weird.

  Are you sure? yes | no

J.C. Nelson wrote 4 days ago point

Are you printing via USB and octoprint? If not, try raising the SPI speed.

  Are you sure? yes | no

Thomas wrote 4 days ago point

Yes, printing via usb with octoprint.

  Are you sure? yes | no

Thomas wrote 4 days ago point

Interesting, I think the problem occurrs after the following lines i get in the terminal:

Recv: echo:enqueueing "G91"

Recv: echo:enqueueing "M18"

Which means it's switched to relative position mode and disabled the steppers?  Neither commands are found anywhere in the gcode for the model that was printing. The octoprint terminal also doesn't show any "Send" lines containing those commands near by. So its possible its something marlin is doing. For what, or where it's doing it, I don't know. I'll try and dig around a bit, but it doesn't appear to happen every print. I thought printing slower seemed to help, but it probably didn't make too much difference. perhaps delayed it?

  Are you sure? yes | no

Thomas wrote 4 days ago point

Wait.. a quick grep shows it might be the "process_lcd_j_command" function in the lcd/malyanlcd.cpp file which is handling stuff comming from the lcd I think... So the lcd is sending down some commands? :o erm why would it do that if I didn't touch it?

  Are you sure? yes | no

J.C. Nelson wrote 4 days ago point

If you disable the LCD and select/start the print via USB, does it work? If so, I'd guess your LCD dial is flakey. I may look into disabling move processing during a print.

  Are you sure? yes | no

Thomas wrote 4 days ago point

Currently running another test print. I'll try yanking the lcd connector next time. Why would it send down a J: E command to extrude if the menu was last on the home screen, nowhere near the movement menu? I don't touch the dial/lcd much at all in general. That'd be quite the bug in their firmware... 

  Are you sure? yes | no

Thomas wrote 13 hours ago point

So, I stopped getting the random issues after yanking the LCD. But after a few days of testing the board has now just died. won't even initialize the usb or the LCD now. I presume the mcu isn't starting up. I may try to troubleshoot at some point.

  Are you sure? yes | no

dukeneukam wrote 11/29/2018 at 02:59 point

I'm interested in this project.  If you need someone to help with testing, let me know

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates