At Formnext 2023 I spent some unexpected time to discover a new class of procedural structure called “Spherene” (“sphere” + “graphene”), it’s a name as introduced by a company with the same name.
It’s main feature is isotropic (“all directions”) distribution of forces. Their service provides the creation of this structure based on:
density (ratio of material vs empty space), hence their term of Adaptive Density Minimal Surface (ADMS)
form
wall thickness
where all of them are freely definable in 3D space contained within an overall boundary. Their service “renders” a mesh which complies with such, like defining at some point a lower or higher density, and transits in 3D space from one to another.
Patent
My immediate impulse was to code the Spherene aside of the existing TPMS’s, but I realized their business core is the service of creating meshes based on their procedure as described in a patent:
at its core it describes 6 steps (abbreviations added for clarity)
creating envelope
creating density field
adaptive Voronoi tesselation (AVT),
1st skeleton graph (SG) associated to AVT (SG-AVT1)
generated from the edges of the Voronoi cells
2nd skeleton graph associated to SG-AVT1 (SG-AVT2)
generated using Delaunay tetrahedralization
minimal surface from SG-AVT1 and SG-AVT2, using equidistant from both skeleton graphs, with minimal wall thickness requirements
Abstract: A method of additively manufacturing a minimal surface structure of a three-dimensional article includes a computer executing the steps of recording, in the computer,
an envelope of the three-dimensional article; generating a density field across a volume enclosed by the envelope with densities of the density field corresponding to local requirement values of at least one physical parameter at respective positions of the three-dimensional article;
generating an adaptive Voronoi tessellation of the volume using the density field;
generating a first skeleton graph associated with the adaptive Voronoi tessellation;
generating a second skeleton graph associated with the first skeleton graph; and
generating a digital minimal surface model from the first and second skeleton graphs.
The method may further include a 3D printer additively manufacturing the minimal surface structure according to the digital minimal surface model.
I think if Spherene is truly as significant for Additive Manufacturing, and an essential invention, it has to move beyond the grip of a single company and its patents – time will tell.
Samples
Daniel Bachmann from Spherene Inc. kindly shared with me a few samples, 20x20x20mm cubes, and 20mm diameter spheres with Spherene infills, illustrating their properties:
Spherene 20mm, 15mm and 10mm sampleSpherene 40mm in white & grey resin (top row) and white, grey and black PLA/PLA+Spherene resin samplesSpherene resin samplesSpherene resin samples
A few support structures were required for the spherical samples, the cubic samples did not require such:
Lychee Slicer: spherical spherenes required support structure due overhangs
Additionally I printed a few cubic samples with FDM on my CoreXY Ashtar C without supports at 40x40x40mm scale.
Subtractive Manufacturing & Molding Usage
The structure cannot very well machined with subtractive manufacturing processes – or only if the piece is sub-divided so all indentations can be milled, and sequentially fused or welded again.
Another approach comes to my mind is to form dedicated bricks, e.g. for large scale application like a building, and have a limited kinds of bricks depending on their position and use case, and have molds to form those limited kinds in larger quantities.
In order to produce a mold one would inverse the original model, the negative volume, that would be produced using additive manufacturing and then produce lost-form casting molds, or highly simplify the form so one can remove the positive without destroying the mold.
2024/01/22: published without much reflection & conclusion as research is ongoing
2023/12/02: adding more examples and refining details
2023/10/22: start writeup
Introduction
While studying continuous fiber 3D printing and its main nature is to find ways to lay fiber without interruption. In order to refresh my memory I revisited the Lissajous forms, which until recently only knew in their 2D form, the swirling strings or lines – and now extending it into 3D as well.
The main idea is to realize how a line, string or fiber can be used to fill non-planar and circumvent a 3D structure and how angular shifting in Lissajous context affects such form.
3D Lissajous
angle: 0 .. 2pi or 0 .. 360°
p, n, m: 0 .. 1000, the amount of loops
phi0, phi1, phi2: the angular offsets 0 … 2pi or 0 .. 360°
X = sin(angle*p+phi0)*r
Y = sin(angle*n+phi1)*r
Z = sin(angle*m+phi2)*r
I did a lot of experimenting – I could post hundreds of forms – but let me focus on one a bit closer, which got my attention:
While playing with 3D Lissajous, I thought to adapt the cyclic nature, but apply it to a circle laying in the XY plane and then rotate in X axis, and Y axis as well, and optionally cyclic translation as well:
d: diameter
angle: 0 .. 2pi or 0 .. 360°
p: amount of loops as in X=sin(angle*p)*d/2, Y=cos(angle*p)*d/2
q: amount of X rotations: rotateX(angle*q)
r: amount of Y rotations: rotateY(angle*r)
Spherical Lissajous 12.23 with spreading struts
The model was printed with MSLA white resin at XYZ 50um resolution with 120mm diameter, with a few support structures near the bottom:
Spherical Lissajous 12.23 with spreading struts MSLA printed at 120mm diameterSpherical Lissajous 12.23 with spreading strutsSpherical Lissajous 12.23 with spreading struts closeup 1Spherical Lissajous 12.23 with spreading struts closeup 2Spherical Lissajous 12.23 with spreading struts closeup 3Various spherical Lissajous
Spherical Lissajous with Translations
Using the Spherical Lissajous and extend it slightly:
After using Anycubic Photon Mono X2, and not that happy with it, I saw Anycubic released another resin printer:
build volume: 195.8 x 122.4 x 200 mm (WxDxH), same size as Mono X2:
reuse all its third party parts also compatible with X2: vat, FEP films etc
resolution: XY 34μm, Z 10-50μm
9.1″ display with 6K resolution (5760×3600) display
monochromatic LCD (hence “Mono”), faster printer due shorter exposure
affordable with EUR 250-280 (2023/11)
no network, only USB drive printing
The Photon Mono X2 with XY 48μm has not so well performed for me in regards of precise parts, as 100μm precision was not really delivered, either it was underexposing and fail on 1mm walls, or solid walls but thicker – somehow I could not find a good balance. The Photon Mono 4K performed more reliable for me and was able to print geometrically more reliable and correct with XY 35μm; so my hope is that the X 6Ks delivers with 34μm pixel size.
I ordered the Photon Mono X 6Ks in 2023/11 for EUR ~230 incl. shipment, and it arrived a few days later from a warehouse in Germany to Switzerland.
Anycubic’s Naming Convention & Communication
The X 6Ks is kind of successor of the X2 with the same body shape and build volume, but who cares of good naming? It could have been X2 6K simply. Aside, Anycubic seems the care little to provide customers the XY resolution anymore on info material or their web-site (2023/11) but only state XY build area and XY resolution, and announces 4K, 6K or whatever – you need to calculate the XY pixel size yourself . . .
Print Settings
retrieved from Anycubic 2023/11/11 as screenshot:
For Lychee Slicer (2023/11) I recommend following settings:
enable Two Stage Motion Control (TSMC)
Bottom Layer: 1-6 (1 for small pieces, 6 for larger pieces)
Transition Layers: 10 (for flat pieces reduce to 1)
Lift Distances: [1] 4mm, [2] 8mm
Lift Speeds: [1] 1mm/s, [2] 3mm/s or 60mm/min, 180mm/min
Here my settings:
Mono X 6Ks machine defaultsMono X 6Ks resin defaults (two stage lifting enabled)
Flex Build Plate
I’ve got a spring steel plate 202×128 mm from Aliexpress, and as I ordered two of them for X2 but I can reuse one for the X 6Ks as well:
magnetic base: 2.2mm thick, slightly extends, 203x129mm
steel plate: 0.5mm thick, exact 202x128mm, I roughed up the exposed surface with sandpaper to increase adhesion
so one has to compensate 2.5 – 3mm in Z height and adjust, speak extend, the Z-level probe. I just glued a black strip of paper, and then of course re-level the bed again afterwards.
Glued a piece of paper extending it ~2.5mm (I used black marker to darken the paper afterwards)
cost-effective for 196x122mm build area and 34μm pixel size
good third party market (X K6s parts are mostly compatible with X2, except UV LCD & mainboard)
Cons:
Mechanical Quality Control (QC):
build-plate has too much horizontal play (2+mm), the Mono X2 build-plate which has the same size fits tighter (see below for detailed photos)
grey/clear upper case is/was warped, doesn’t fit seamless off by 3-4mm bent inside on left & right; likely package long stored in wrong position or bad clear plastic deforming over time (remedy below “Cover Wedges”)
no WiFi
very basic firmware
poor quality SD stick, it usually won’t last a couple of weeks before it becomes unwritable or unreadable, but this time I couldn’t even backup the data, the stick failed right away; visit anycubic.com and download the slicer, handbook and test files to calibrate UV exposure times
Anycubic is known to invest very little into the firmware which is provided by Chitubox, given they are one of the biggest resin printer sellers, it affects 100,000s of customers.
Mono X2 build plate mount (likely extruded): solid, little playMono X 6Ks build platemount: simple metal sheet bent + plastic distance where screws enterMono X 6Ks build plate mount: horizontal playMono X 6Ks build plate mount: horizontal play
The build plate also has new a black plastic connector to the mount, an attempt to reduce cost perhaps. The Mono X2 build plate mount is much better in my opinion, more solid; the Mono X 6Ks build plate has more wiggle/play horizontally, therefore pieces printed you want definitely in the center of the UV LCD/vat, not on the side to avoid any wiggle or play while printing introducing imprecisions.
Cover Wedges
As the X K6s came with a warped cover, and with the X2 with the same case geometry it was wiggly everytime I put the cover over, I printed a few “wedges” which align the cover easily:
white wedges (I removed to replace with black wedges)10x black cover wedgescover slides over properly
Formlabs 3’s & EMake SLA printers use a laser beam which has 100μm in diameter, but it can be positioned 25μm exact, the latter was used to calculate the value
The UV pixels are non-square, the longer side was used to calculate the value
The XY area in SLA scales not as good as with MSLA, as the laser beam takes longer the more XY area (e.g. more pieces) need to be rendered per layer – so, MSLA is recommended for aiming fast parallel printing. Interestingly Formlabs 4 is now a MSLA as well (2024/04), they seem to have abandoned the SLA laser-based approach.
Anycubic Mono X 6Ks, X2 and 2x 4K
One of the main reason I choose Anycubic MSLA is the third party market for add-on’s, like flex build plate, vats, LCD replacement etc, and I also like the build plate mount with 4 screws for alignment; and I hoped to replace the firmware of the Mono 4K which did not happen as the Open Source variant is still incomplete (2023/11).
Another year, another November in Frankfurt (Germany) and Formnext – this is the main event of the year professionally for me. As I reside in Switzerland the travel is fairly easy and short and the 770 exhibitors in two halls (11 & 12) with two floors each is so overwhelming that even 4 days attending is not sufficient.
Day 1 (Tue, Nov 7): I spent an entire day to explore hall 12.1 alone, which turns out a good choice as it was a dense populated hall with many smaller companies
Day 2 (Wed, Nov 8): visiting with a client half of the day to review some of their possible competition, and then explore 12.0
Day 3 (Thu, Nov 9): some schedules meetings and then explore 11.0 and 11.1
Day 4 (Fri, Nov 10): revisiting 12.1 and 11.1 briefly, visiting with another client some selected booths to check products on display
I surely missed a few booths in 11.1 and 12.1 still; whereas 12.0 and 11.0 were more large scale industrial AM solutions, mixed with university and regional focused booths which I didn’t have time to explore in detail.
Personal Selection
I feature some companies according my personal professional interests:
Spherene (Math)
I made contact with Spherene before via LinkedIn but I realized I missed the point of what Spherene actually “invented”, at their booth Daniel Bachmann took the time to show me the features of their new class of minimal surface model and it was challenging for me to follow him despite of my own experience with Triply Periodic Minimal Surfaces (TPMS) – after apprx. 20 mins I realized the scope and some of their depth of their “invention”.
Spherene: sphere sample with variable porousitySpherene: resin printed rabbit with spherene infillSpherene: FFF/FDM printed bone replace with spherene infillSpherene: print samples (MSLA, FFF/FDM, SLM)
In essence, the sphere is used as a base form, and density, wall thickness and other features are processed in a localized manner, filling the space. The main result doing is optimizing a form to distribute inner/outer forces, e.g. the ends of the spheres are perpendicular to the surface providing ideal way to distribute them into a network of thin walled interconnected spheres providing isotropic (“all directions”) property.
The samples on display were printed with MSLA, SLA, FFF/FDM or SLM were indeed very strong in relation to the printed volume, e.g. the hallow rabbit printed with resin barely gave in when pushing on the thin outer perimeter – impressive.
Their approach is available as cloud-based GUI or as Grasshopper/Rhino plugin. The actual details of their procedure isn’t easily found but a patent (WO2020229692A1) by CEO Christian Waldvogel gives some idea.
Genera (DLP Resin)
There are many MSLA/SLA/DLP printer manufacturers, yet, I wasn’t aware of Genera and I was shown their system, an integrated workflow:
all resin vatshave a lid (only applies for G1/F1 combo but not their bigger machines), which are opened only within the machine
the finished prints (still on the plate) are moved in a box into the washing machine (without any person touching resin or the resin coated prints)
once automatically cleaned and post-cured, the prints are removed from the build plate manually
In essence one does not interact with resin directly, it’s all contained within the workflow – which I like a lot. They also provide wide selection of resins: hard, soft, rubbery, opaque, transparent/clear.
My idea has been to adapt some of their approach to make my own resin printing with Photon series (4K, X2 and X 6Ks); right now I also have multiple vats, and flex-plate, but moving the printed parts and washing them are still messy.
Quantica (Resin Jetting)
Last year I already visited the booth of Quantica, and so this year again. I asked earlier for printed samples, but they declined, and again this time . . . it is bizarre to see a machine actually able to print, and they don’t hand out samples, but I was told by January 2024 I might get some. This tells me a few things, the printed pieces are very sparse or not yet at the quality they want others to experience – some samples were on display, but sealed behind a glass box unable to have in my hand. So I guess now, they are expecting or already have better and more reliable printing results where the printed pieces match other similar printing processes.
QuanticaQuantica: NovoJet OpenQuantica: multi material samplesQuantica: multi material samplesQuantica: multi material samplesQuantica: multi material samples
I follow their development closely since ~2 years as I consider it very innovative to print with 7 different resin-based materials at the same time and able to fine-tune material properties on the voxel-level.
Duet3D (Open Source Hardware & Community Building)
UK-based Duet3D with its Duet boards and RepRapFirmware (RRF) is, as I wrote before, a beacon within the Open Source Hardware community – it isn’t just an example for other companies, and but also a great synergy provider, aiming to bring different individuals, groups and companies together.
Duet3D: with David’s backDuet3D: Voron 0 with Brandon Build’s variant of Open5X Duet3D 5-axis Open5X with tool changerThe many companies using Duet boardsDuet3D booth: Josef Prusa & Tony Lock – legends of 3D printing community
Brandon Builds’ Open 5X version was featured on a Voron 0, and a second machine also 5-axis setup with a tool changer.
Rapid Liquid Printing / RLP (Flexible Structures)
While roaming around a small booth of RLP caught also my attention, where a video was featured of a nozzle moving in a bed filled with silicon printing rubber, and other flexible material:
Rapid Liquid Print (RLP)RLP: multi color samplesRLP: white “finger” sampleRLP: area with flexible “fingers” and color gradientRLP: Flexible seat print with inflatable cushions
Reinforce 3D (Enhancement)
Another truly innovative approach combining and enhancing existing additive manufacturing processes was shown by Reinforce 3D:
using existing AM methods such as SLM, SLA, MSLA and even FFF/FDM to make models with thin walled tunnels and then
filling or rather pushing them with strains of carbon fibres along with resin into the tunnels
and thereby reinforcing free forms by keeping the result lightweight but incredible strong due the embedded carbon fibres
Reinforce 3D boothReinforce 3D: SLM and resin (MSLA) printed pieces carbon fiber reinforcedReinforce 3D: FDM printed and carbon fiber reinforcedReinforce 3D: FDM printed and carbon fiber reinforced
A very small but significant detail is, that you can print multiple parts on a smaller printer, but once you start to insert the bundles of carbon fiber those segments of pieces get combined in a strong assembly, as the aluminium skeleton shown above.
INo Trident – inductive hotend by Plasmics: fast heatup and cooldown / 3s from 20C to 220C, 10s from 220C to 150C
At the booth of Plasmics I looked at the inductive hotend and saw the heating up in a few seconds from 20C to 220C and cool-off in a small demo first hand.
The hot part of the nozzle looks like a needle, with little thermal mass, hence the fast heat and cooling-off time, and then surrounded by ceramics with the inductive coil on it.
The hotend incl. the controller board priced at EUR 400 is high for DIY enthusiasts but low for an industrial setup.
And UltiMaker (after Ultimaker & MakerBot merger) wasn’t present again; the consensus has been that BambuLab‘s printers have taken the higher quality consumer FFF/FDM printers market segment, and the air getting thinner for UltiMaker – at the same time they are doing a great service with the Open Source Cura slicer.
Random Impressions
Metafold: samplesStratasys: samplesPhotocentricPhotocentric: samplesPhotocentric: samplesPhotocentric: large scale statueHP: samplesPrusa ResearchPrusa Research Pro seriesSnapmakerSnapmaker with CNC drillSnapmakerSnapmaker: IDEXFormlabsAnisoprintAnisoprintAnisoprintAnisoprintE3DE3D: non-planar / belt printer nozzlesApexMakerApexMaker & PangJi resin printer LCDsSintratec: SLS printersSintratecSintratecNexa3D: SLA & SLS machinesNexa3DAiBuild: multi-axis slicingElegoo: printers, filaments, resinsFormFuturaBambu LabBambu LabDyze Design: water cooled large hotends
running Klipper on it, likely requires expansion board with additional USB ports, not yet tested; ArchLinux repo provides it though
any kind of quick experimental setup when Linux is a requirement, and Raspberry Pi perhaps overkill already, and ESP32 not powerful enough to run Linux*)
*) as of 2023/09 a few people working on Linux for ESP32-S3
A couple of years ago I used ESP8266 with Lua, and ESP32 with Lua and MicroPython, but the functionality was very limited, although it had WiFi built-in, but barely ran anything more complex or serious – the Milk-V Duo changes this, at the same pricing of USD 5.00-9.00; and I really looking forward to have just a small device running Linux, and competing with Raspberry Pi’s which either hardly were available or sold at 2-3x the announced price.
Milk-V Duo 64MB RAM (bare)Milk-V Duo 64MB RAM with USB-C connected and SD cardMilk-V Duo 64MB RAM (backside)Milk-V Duo 64MB RAM, CPI ID: “CVITEK CV1800B AA202500 T6N605 2303A”
and the newer 256MB RAM variant (released 2023/12):
Milk-V Duo 256MB RAM (frontside)Milk-V Duo 256MB RAM (backside)Milk-V Duo 256MB RAM, CPU ID: “SG2002 AA202300 TM5M48 2357A”
Specification & Features have been partially copied from Milkv.io (2023/09 & 2024/02):
– boots, but then fails with systemd (coredump) – no login possible
Linux BuildRoot Disk Image
The BuildRoot is a minimal custom Linux release which is meant for IoT developers who know what they want and need and select the features at building time and then get a disk image which contains then a set of features and applications. It’s not very user friendly, e.g. there is no package manager which allows to add new packages afterwards once the system is running.
Attach a SD card to your host, find out which device it became (Linux):
% lsblk
CAUTION: make sure /dev/sdX (replace X with proper letter) is the SD card and not your other disk(s) as copying the disk image will erase and replace the content of the device you choose with the following command:
then remove SD card from the host*), and insert it to the MilkV-Duo board, and power it on via USB-C.
*) in case you have the wrong /dev/sdX, or write to it if it’s not plugged in, you might struggle to write there again, simply do sudo rm /dev/sdX and then pull out and plugin the SD card again, and you should be able to write again to it.
Ubuntu 22.04 LTS Network: automatically starts it USB EthernetThe client sets the network: 192.168.42.0 and the “host” chooses 192.168.42.100 its own IP.
After ~15 seconds you should be able to login with ssh root@192.168.42.1 into your MilkV-Duo with passwd: milkv or you attach a UART to USB bridge like that:
Pin 16/TX: RX/white UART-USB
Pin 17/RX: TX/green UART-USB
Pin 18/GND: GND/black UART-USB
don’t connect 5V/red UART-USB
and use tio /dev/ttyUSB0 (or another number) under Linux to connect via serial port; also useful in case bootup is stuck after doing changes, and ssh isn’t possible anymore.
Note: you won’t need to solder the male connectors, I usually just insert them loosely and the cable bending gives sufficient connectivity for a brief login to fix things and then remove UART-USB cable again.
[root@milkv-duo]~# ls /bin
arch dmesg linux64 nuke sleep
ash dnsdomainname ln pidof stty
base32 dumpkmap login ping su
base64 echo ls pipe_progress sync
busybox egrep lsattr printenv tar
cat false mk_cmds ps touch
chattr fdflush mkdir pwd true
chgrp fgrep mknod resume umount
chmod getopt mktemp rm uname
chown grep more rmdir usleep
compile_et gunzip mount run-parts vi
cp gzip mountpoint sed watch
cpio hostname mt setarch zcat
date kill mv setpriv
dd link netstat setserial
df linux32 nice sh
/usr/bin
[root@milkv-duo]~# ls /usr/bin/
[ fold od tee
[[ free openvt telnet
ar fuser passwd test
ascii gcore paste tftp
awk gdb patch time
basename gdb-add-index pip top
bc head pip3 tr
bunzip2 hexdump pip3.9 traceroute
bzcat hexedit printf truncate
chrt hostid pyserial-miniterm ts
chvt htop pyserial-ports tty
cksum id python uniq
clear install python3 unix2dos
cmp ipcrm python3.9 unlink
crc32 ipcs readlink unlzma
crontab killall realpath unlzop
cut last renice unxz
cvi_pinmux less reset unzip
dbclient logger resize uptime
dc logname scp uudecode
deallocvt lsof seq uuencode
diff lspci setfattr vlock
dirname lsscsi setkeycodes w
dos2unix lsusb setsid wc
dropbearconvert lzcat sha1sum wget
dropbearkey lzma sha256sum which
du lzopcat sha3sum who
easy_install md5sum sha512sum whoami
easy_install-3.9 mesg shred xargs
eject microcom smtpd.py.9 xmlcatalog
env mkfifo sort xmllint
event_rpcgen.py mkpasswd ssh xmlwf
evtest nl strace xsltproc
expr nohup strace-log-merge xxd
factor nproc strings xz
fallocate nslookup svc xzcat
find ntpdate svok yes
flock ntptime tail
[root@milkv-duo]~# ls -1 /usr/bin/ | wc -l
151
Multiple Milk-V Duos / Alternative IPs
In order to support multiple Milk-V Duos on the same host via USB-C, you assign for each board its own network:
board 1: 192.168.51.0
board 2: 192.168.52.0
board 3: 192.168.53.0
Edit on each board two files:
/mnt/system/usb-rndis.sh (buildroot-based) or /etc/usb-rndis.sh (other systems):
ifconfig usb0 192.168.51.1
/etc/dnsmasq.conf:
dhcp-range=192.168.51.2,192.168.51.242,1h
In order to add a new board, you login into 192.168.42.1 as usual, and change it to the 192.168.52.1 and so on.
Resizing Disk
By default the entire available space of the SD card is only 1GB (or 2GB in case you use another distro), but you can make the rest of the SD card available to /data for example – part of the guide was taken from a post in the forum but updated it:
% mkdir /data
% fdisk /dev/mmcblk0
n (new partition)
p (primary partition)
4
<RETURN> (confirm start selection)
<RETURN> (confirm end selection)
w
q
% reboot
I followed this guide to get ArchLinux working – thanks to Judehahh doing the main work – and added RNDIS support (Virtual Ethernet over USB) and made a disk image to use, the date e.g. “2023-10-09” references the riscv64 rootfs date which was unpacked as a base, the “x.xgb” describes the size of disk or rootfs and “vX.X.X” the actual release version. Unzip downloaded image first before writing on the SD card.
– 240MB RAM (no camera support) – 250MB swap enabled – RNDIS (connect via usb virtual ether) – minimum 8GB SD card – 5.7GBfree in rootfs – persistent MAC addresses for RNDIS (internet routing ready)
For the 256m-version disk image I downloaded the kernel from this thread and just copied boot.sd and fip.bin into the first partition, otherwise no changes toward the milkv-duo disk-image (below) was made
– 55MB RAM (no camera support) – 250MB swap enabled – RNDIS (connect via usb virtual ether) – minimum 8GB SD card – 5.7GBfree in rootfs – persistent MAC addresses for RNDIS (internet routing ready)
– 55MB RAM (no camera support) – 250MB swap enabled – RNDIS (connect via usb virtual ether) – minimum 2GB SD card – 960 apps in /usr/bin/ – only 40MB free in rootfs (!!)
– package management (apk) – rndis / usb network (but random MAC addresses) – rootfs 1GB, 150MB used
– dropbear v2022.83
– use apk [add|update] –no-check-certificate
For the 256m-version disk image I downloaded the kernel from this thread and just copied boot.sd and fip.bin into the first partition, otherwise no changes toward the milkv-duo disk-image (below) was made.
– package management (apk) – rndis / usb network (but random MAC addresses) – rootfs 1GB, 150MB used
– dropbear v2022.83
– use apk [add|update] –no-check-certificate
Notes:
use apk [add|update] --no-check-certificate to install new packages, otherwise installs or update fail
Ubuntu Disk Image
I followed this guide (see discussion thread as well) – thanks to Bassusteur – and added RNDIS related services so you can login with ssh root@192.168.42.1 (passwd milkv) via virtual Ethernet over USB; unzip disk image before you write on the SD card.
Notes:
apt / apt-get are awfully slow on Milk-V Duo at step “Building dependency tree...“, takes 4+mins for each apt install call as apt requires 50+MB RAM to build that dependency tree, which goes hard on all available RAM + swap
these are very experimental disk images
Note: milkv-duo (64MB RAM) vs milkv-duo-256m (256MB RAM)
– 240MB RAM (no camera support) – RNDIS (connect via usb virtual ether) – persistent MAC addresses for RNDIS (internet routing ready) – apt works now smoothly – minimum 8GB SD card – 6.0GBfree in rootfs
– dropbear (v2020.81) – python 3.10.12
For the 256m-version disk image I downloaded the kernel from this thread and just copied boot.sd and fip.bin into the first partition, otherwise no changes toward the milkv-duo disk-image (below) was made.
– 55MB RAM (no camera support) – 250MB swap enabled – RNDIS (connect via usb virtual ether) – persistent MAC addresses for RNDIS (internet routing ready) – minimum 8GB SD card – 6.0GBfree in rootfs
– dropbear (v2020.81) – python 3.10.12 – zram enabled in kernel, and works now, but apt still very slow
– 55MB RAM (no camera support) – 250MB swap enabled – RNDIS (connect via usb virtual ether) – persistent MAC addresses for RNDIS (internet routing ready) – minimum 8GB SD card – 6.0GBfree in rootfs
– dropbear (v2020.81) – python 3.10.12 – zram not enabled in kernel yet
– 55MB RAM (no camera support) – 250MB swap enabled – RNDIS (connect via usb virtual ether) – persistent MAC addresses for RNDIS (internet routing ready) – minimum 8GB SD card – 6.0GBfree in rootfs
disabled systemd-resolved service due clash with dnsmasq
added /etc/resolv.conf.tail with default DNS servers
installed dropbear (lightweight sshd), removed the auto generated keys, added in /etc/default/dropbear the -R switch so new keys are generated at first boot
Tips & Examples
Most of the examples relate to the Duo BuildRoot SDK setup, but should be easily adaptable to ArchLinux or other distros.
blink.py with sysfs GPIO
There is a way to control GPIO via sysfs with Python:
import time
import gpio as GPIO
pin = 440
GPIO.setup(pin, GPIO.OUT)
while True:
GPIO.output(pin, GPIO.HIGH)
time.sleep(1.0)
GPIO.output(pin, GPIO.LOW)
time.sleep(1.0)
and run it:
% python blink.py
See this table for GPIO names, pins and numbers, a copy (2023/10/10):
GPIO NAME
GPIO PIN
GPIO Number
Notes
GPIOA14
19
494
GPIOA15
20
495
GPIOA16
16
496
GPIOA17
17
497
GPIOA22
24
502
GPIOA23
21
503
GPIOA24
22
504
GPIOA25
25
505
GPIOA26
27
506
GPIOA27
26
507
GPIOA28
1
508
GPIOA29
2
509
GPIOC9
14
425
1.8V
GPIOC10
15
426
1.8V
PWR_GPIO4
29
356
1.8V
PWR_GPIO18
12
370
PWR_GPIO19
6
371
PWR_GPIO20
7
372
PWR_GPIO21
11
373
PWR_GPIO22
10
374
PWR_GPIO23
9
375
PWR_GPIO25
5
377
PWR_GPIO26
4
378
Pinpong
Follow the guide to install pinpong.zip (my mirror), only for V1.0.4 system image, and then:
blink2.py
import time
from pinpong.board import Board,Pin
Board("MILKV-DUO").begin()
led = Pin(Pin.D0, Pin.OUT)
while True:
led.value(1)
time.sleep(1)
led.value(0)
time.sleep(1)
The pinpong library covers quite a lot of functionality, and useful examples:
According this post, tinycc has been ported as well – C compiler and C interpreter in one – download the .zip (my mirror) and run its install.sh, and then fix missing executable bit:
lua (5.4.6): segmentation fault, luac (5.4.6): seems to work (both compiled with tinycc)
lua & luac (5.3.6) works
lua & luac (5.4.6) works
extras
quickjs/qjs, micropython, nano, screen, git, make (no gcc/cc, use tinycc), thttpd, nginx, lighttpd, php-cgi, file, which, sudo
pacman (package mgr), lighttpd, file, which, sudo, make
Internet Access for Milk-V Duo
RNDIS (Virtual Ethernet over USB)
The host has to run Ethernet over USB and also operate as transparent router and let the connected board(s) reach the internet, see this guide (use google translate to english), here the brief description:
On The Host
The outgoing_if is the outgoing interface, either eth0 or wpl0s0 or something, check with ifconfig of the proper name, and then as root perform:
Also, find out which IP your host got (ip_of_host) from the connected board, e.g. 192.168.42.120, also check with ifconfig.
On The Board
% ip r add default viaip_of_host
% echo "nameserver 8.8.8.8" >> /etc/resolv.conf
Static IP for Host with RNDIS
What may look simple actually isn’t that easy as RNDIS itself is the culprit:
one can limit the IP range in dnsmasq.conf to from/to be the same IP, but
as RNDIS assigns random MAC addresses to the RNDIS host (the board) and the RNDIS client (the host the board is connected to) treat it as new device at every boot – if you force it to have the same IP again, the host will not get a new IP via DHCP as it has the IP remembered for another MAC address . . .
it’s a mess
So, a working solution is:
/etc/rndis-macs.sh which generates two random MAC addresses but keeps them persistent then:
#!/bin/bash
RNDIS_USB="/tmp/usb/usb_gadget/cvitek/functions/rndis.usb0"
MAC_FILE="/etc/rndis-macs.conf"
generate_random_mac() {
printf "02:%02x:%02x:%02x:%02x:%02x\n" $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256))
}
# check if the MAC address file exists and has exactly two lines
if [[ -f "$MAC_FILE" ]] && [[ $(wc -l < "$MAC_FILE") -eq 2 ]]; then
# read the two MAC addresses from the file
IFS=$'\n' read -d '' -r -a macs < "$MAC_FILE"
dev="${macs[0]}"
host="${macs[1]}"
echo "using existing MAC addresses:"
else
# generate two new MAC addresses and store them in the file
echo "generating new MAC addresses:"
dev=$(generate_random_mac)
host=$(generate_random_mac)
echo "$dev" > "$MAC_FILE"
echo "$host" >> "$MAC_FILE"
fi
echo "dev_addr: $dev"
echo "host_addr: $host"
echo "$dev" > "$RNDIS_USB"/dev_addr
echo "$host" > "$RNDIS_USB"/host_addr
/etc/usb-rndis.sh:
/etc/uhubon.sh device >> /tmp/rndis.log 2>&1
/etc/run_usb.sh probe rndis >> /tmp/rndis.log 2>&1
/etc/rndis-macs.sh >> /tmp/rndis.log 2>&1
/etc/run_usb.sh start rndis >> /tmp/rndis.log 2>&1
sleep 0.5
ip link set dev usb0 up
ip a add 192.168.42.1/24 dev usb0
ip r add default via 192.168.42.2
sleep 0.5
systemctl start dnsmasq
Note: if you had 192.168.42.2 once assigned to the host, choose another “static” IP in your range, as your host has remembered the IP to a particular MAC address and won’t accept it again, e.g. 192.168.42.200 or so.
Here my brief guide – see also this guide (use google translate) – how to customize packages included in the base distribution of the image for the SD card:
% cd duo-buildroot-sdk/buildroot-2021.05% make menuconfig
then go into the “Target packages”, and then walk through:
Audio and video applications
Compressors and decompressors
Debugging, profiling and benchmark
Development tools
Filesystem and flash utilities
Fonts, cursors, icons, sounds and themes
Games
Graphic libraries and applications (graphic/text)
Hardware handling
Interpreter languages and scripting
Libraries
Mail
Miscellaneous
Networking applications
Package managers
Real-Time
Security
Shell and utilities
System tools
Text editors and viewers
once you selected the packages you like to have included, choose “Save” and confirm as ‘.config’ and then “Exit”.
% cp .configconfigs/milkv_duo_musl_riscv64_defconfig
% cd ..
% ./build_milkv.sh
and after while, depending on how many packages you selected, you find in out/ folder your new disk image you can copy on the SD card.
Note: buildroot is quite a quirky package, e.g. when you select a package and make a build, later deselect a package, it will still be included – worse, if you commit a clean slate in output/, some packages might not fully build anymore – you have to go back to an earlier state of fewer packages, remake the build, and restart re-selecting new packages.
Postfixing missing .so file
As of 2023/10 v1.0.4 buildroot-2021.05 environment, there seems a problem regarding a missing shared library for some of the compiled apps (like qjs), you can fix this:
% cd /lib
% ln -s ld-musl-riscv64v0p7_xthead.so.1 ld-musl-riscv64.so.1
– lua, quickjs/qjs, micropython, nano, screen, git, make (no gcc/cc, use tinycc), thttpd2), nginx, lighttpd, php-cgi – 55MB RAM1) available – “fixed” image has .so lib-fix included
– lua, quickjs/qjs, micropython, nano, screen, git, make (no gcc/cc, use tinycc), lighttpd (doesn’t work yet out of the box) – 55MB RAM1) available
apprx. 55MB actual available RAM, no camera support, INO_SIZE=0
thttpd, nginx and lighttpd are all http-server, only use one, see /etc/init.d/ where those are started.
Ethernet Add-On
The easier way is to get proper networking is to add a real ethernet port and properly wire it to the ethernet router. There are several options & sources (2023/09):
I did a small case for the bare board without Ethernet or Extension board to be 3D printed:
Milk-V Duo (bare): bottom case & lidMilk-V Duo (bare): bottom caseMilk-V Duo case closedPrinted in white & black PLAwhite vs black case blue & red LEDs see-throughwhite PLA cases allow LEDs see throughwhite PLA (FFF/FDM), white & clear resin (MSLA)MilkV Duo’s running BuildRoot & ArchLinux
As the Milk-V Duo has the same width and depth (X/Y) as the Raspberry Pico but it’s a bit thicker so the some of the existing cases work only partially:
Raspberry Pi Pico Case by Botvinnik works perfectly, recommended, bottom/lid with 2 options: closed or with holes
Raspberry Pi Pico Case w Slider 3D Print Model by AndysTechGarage bottom part works, but lid doesn’t fit due the camera connector; you need to disconnect board from power in order to put in or out from the case
Raspberry Pi Pico Case by Kuma0055: has pins for holes which Milk-V Duo PCB doesn’t have, not recommended
As soon my Ethernet connectors and Extension boards arrived I will provide case variants (2023/10/05).
2023/10/04: finally published, added CircuitPython which should work better than MicroPython
2023/09/25: retesting WiFi, still fails with latest firmware
2023/02/03: starting writeup
Introduction
Wemos S2-Mini is a ESP32-S2FN4R2 chip on a small module, supporting to run MicroPython and connecting to existing WiFi or operating as WiFi Access Point – it’s ideal as IoT device, or easy add-on to 3D printing infrastructure to probe sensors and make them WiFi compatible.
Compatible with MicroPython, Arduino, CircuitPython and ESP-IDF
At the price of barely EUR 2.00 on Aliexpress (2023/02) this is a very affordable IoT device.
Note: MicroPython on ESP32-S2 seem not able to connect to an WiFi AP, and also not operate as WiFi AP itself. Before you follow any steps below, read it first through entirely and decide whether MicroPython or CircuitPython is more suitable – for me both approaches fail to provide WiFi connectivity.
Installing MicroPython (no WiFi)
My modules came without MicroPython unlike advertised, I had to upload the latest MicroPython firmware myself:
attach module with USB-C cable to the computer (e.g. running Linux as in my case)
press Button “0” and hold down, press Button “RST” briefly, wait 2 secs, release Button “0”
use ./esptool.py --port /dev/ttyACM0 --baud 1000000 write_flash -z 0x1000 firmware-LOLIN_S2_MINI-v1.19.1-669-gd4b9df176.bin
Adadfruit ampy
In order to use the modules, one requires ampy which is installed via
% pip3 install adafruit-ampy
and provides ampy command line interface:
Usage: ampy [OPTIONS] COMMAND [ARGS]...
ampy - Adafruit MicroPython Tool
Ampy is a tool to control MicroPython boards over a serial connection.
Using ampy you can manipulate files on the board's internal filesystem and
even run scripts.
Options:
-p, --port PORT Name of serial port for connected board. Can optionally
specify with AMPY_PORT environment variable. [required]
-b, --baud BAUD Baud rate for the serial connection (default 115200).
Can optionally specify with AMPY_BAUD environment
variable.
-d, --delay DELAY Delay in seconds before entering RAW MODE (default 0).
Can optionally specify with AMPY_DELAY environment
variable.
--version Show the version and exit.
--help Show this message and exit.
Commands:
get Retrieve a file from the board.
ls List contents of a directory on the board.
mkdir Create a directory on the board.
put Put a file or folder and its contents on the board.
reset Perform soft reset/reboot of the board.
rm Remove a file from the board.
rmdir Forcefully remove a folder and all its children from the board.
run Run a script and print its output.
so you can put (upload), run, delete files – essentially you have a small filesystem where files reside, to run/execute or read from or write to.
Booting Module
By default /boot.py is executed, where some default behavior can be defined.
No WiFi (Yet)
As first I uploaded wifimgr.py and webserver.py (see main.py), along with default wifi.dat:
myssid;password
which contains the SSID / Password of the WiFi AP I wanted the module to connect to. All 3 files I uploaded ampy -p /dev/ttyACM0 put wifimgr.py and so on, one can only upload one file at a time with ampy.
Finally one can ampy -p /dev/ttyACM0 run webserver.py
As of 2023/09 with MicroPython V1.20.0 I was not able connect the module to an existing WiFi neither have it operate as Access Point (AP) itself – both cases failed; quite disappointing.
Firmware
Boot
REPL
WiFi Client
AP
LOLIN_S2_MINI-v1.19.1-669
ok
ok
failed
failed
LOLIN_S2_MINI-20230228-unstable-v1.19.1-910
ok
ok
failed
failed
LOLIN_S2_MINI-20230426-v1.20.0
ok
ok
failed
failed
LOLIN_S2_MINI-20230914-unstable-v1.20.0-475
ok
ok
failed
failed
Installing CircuitPython (no WiFi)
Alternatively you can install CircuitPython, for such you
then press button “RST” again, after few seconds the board appears like a USB disk, and then you copy the adafruit-circuitpython-....bin into the USB disk – once done, it does reboot itself again (or press button “RST” again).
It will again appear as USB disk named “CIRCUITPY”, that means CircuitPython has been successfully installed and is active running.
Running Code on CircuitPython
Well, you create on that USB disk a new file called code.py which is executed as default when its content changes – so you can edit it directly. Any other files which that code.py needs resides in the same root folder.
The lib/ folder contains all libraries, which you can copy from CircuitPython Libraries, you download a .zip file with all libraries and unzip it and then individually copy libraries you need into the lib/ which become then active right away.
The console is viewable if you start
% tio /dev/ttyACM0
I tried to run a web-server example, but it failed with ConnectionError: Unknown failure 2 – so neither MicroPython or CircuitPython are providing working WiFi connectivity.
No WiFi Yet
I’m quite surprised to see my Wemis S2-Mini fail to connect to my WiFi network, regardless of MicroPython or CircuitPython – it seems to me the libraries involved as faulty for both approaches, I cannot believe that this is a hardware problem, but is a software problem.
Orange Pi Zero: I use a couple of them as Print3r/Prynt3r printhub: I connect multiple USB-based printers, and used Print3r/Prynt3r network-based remote printing capabilities
Embedded Single Board Computer (eSBC)
Milk-V Duo (EUR 5.00-9.50) Ethernet over USB, Linux, Python
2024/11/04: update with long(ish)-term usage of flex-plate
2023/07/25: published
2023/06/13: adding my print settings to increase reliability
2023/03/31: first prints performed
2023/03/29: adding Formlabs 3/3L and Prusa SL1S as comparison
2023/03/23: starting write-up
Introduction
After my first steps with Anycubic Photon Mono 4K, an entry-level MSLA I also got a slightly larger Anycubic Photon Mono X2:
build volume: 196 x 122 x 200 mm (WxDxH)
resolution: XY 48μm, Z 50μm
9.1″ display with 4K+ resolution (4096×2560) display
monochromatic LCD (hence “Mono”), faster printer due shorter exposure
affordable with EUR 300-350 (2023/03)
no network, only USB drive printing
I ordered at Anycubic.com directly (EUR 350) 2023/03/24, and got it a week later.
Default Settings
Defaults Firmware V0.2.3
My Settings 2023/07
My Settings 2023/11
Bottom Layers
6
5
1 .. 62)
Exposure Off [s]
1.0
Bottom Exposure [s]
30.0
25.0
25.0
Normal Exposure [s]
2.0
2.5
2.5
Transition Layers
4
10
10
Bottom Region
Bottom Layer [0] Rising Height [mm]
3.0
4.0
Bottom Layer [0] Rising Speed [mm/s]
1.0
Bottom Layer [0] Retract Speed [mm/s]
1.0
Bottom Layer [1] Rising Height [mm]
4.0
4.0 1)
Bottom Layer [1] Rising Speed [mm/s]
3.0
1.5
1.5
Bottom Layer [1] Retract Speed [mm/s]
3.0
Normal Region
Normal Layer [0] Rising Height [mm]
3.0
4.0
Normal Layer [0] Rising Speed [mm/s]
1.0
Normal Layer [0] Retract Speed [mm/s]
1.0
Normal Layer [1] Rising Height [mm]
4.0
4.0 1)
Normal Layer [1] Rising Speed [mm/s]
3.0
1.5
1.5
Normal Layer [1] Retract Speed [mm/s]
3.0
UV Light (not available)
in Lychee Slicer the 2nd lift distance is the sum of [0] Rising Height 4.0mm + [1] Rising Height 4mm = “4.0mm > 8.0mm”:
depending on the size of the pieces, if they are small (e.g. 20x20mm foot print) then I use 1 bottom layer, for larger pieces I increase up to 6 bottom layers
After some prints I realized the 3mm/s or 180mm/min 2nd rising speed really decreased the reliability of prints I did, usually after bottom layers some models, especially fine structures, deliminated and I realized the transitioning needed to be longer and also reduce the 2nd rising speed, the retraction speed could stay as is. The slowed down the overall print time, but reliability is getting near to Mono 4K.
Various Resins
from Anycubic Web-Site (2023/04/02)
Mono 4K vs Mono X2 vs Mono M3 Max
The print area Mono 4K doubles nearly with Mono X2, and the Mono M3 Max (EUR 1000) additionally doubles the print area:
As pointed out previously, the print area with MSLA directly affects the print speed, the larger the build plate, the faster the print: more parts can be printed at the same time.
The Mono X2 is relatively new as of writing this blog-post, just released in late 2022, so the third party market has not yet taken off regarding spare vats, spring steel magnetic build plate, protective films and alike.
Update 2023/07: The Mono X2 already discontinued as M5 and M5S has been released.
Photon Mono X2 vs Creality LD-006: Details Matter
The main reason I prefered the Photon Mono X2 (EUR 350) over the Creality LD-006 (EUR 250) with the nearly same build-volume is that the LD-006 has a bad build-plate mount where resin is trapped near the screws – which makes cleaning and switching resins much harder:
Anycubic Photon Mono X2 build plate: all resins flows away from the build plate, good designCreality LD-006 build plate: mounting screws trap resin, bad designCreality LD-006 build plate: mounting screws trap resin, bad design
Eventually either cured, dried or semi liquid resin trapped in there will contaminate your next prints – so a bad build plate design can ruin your prints eventually.
Slicer Support
Lychee Slicer 5.x and upward also supports the Mono X2 out of the box, whereas Prusa Slicer SLA slicer, as of 2.x series, does not slice to any but .sl1, and so requires a custom setting to add support for it indirectly then requires a tool like UVtools to convert to .pmx2 (Note: as of 2023/03 the output format is not working properly).
The native Photon Workshop slicer coming with the printer has no Linux support and only works via Wine “Windows” emulator, and is barely usable.
Lychee Slicer, positioning 40x cubes, left column requires support, all others directly on the bedLychee Slicer slicing 40x cubes
Printing 40x Triply Periodic Minimal Surfaces 20mm cubes samples at once, and it took 1h45m (with default settings) with apprx. 30mm height, as some required support.
Mono X2 printing 40x Triply Periodic Minimal Surface 20mm cubesdisplay shows current layer exposureafter 1h45m the print was finished, using drip hook to tilt platform
The pieces were overexposed, the bottom layers were significantly overexposed, the clear resin as well the white resin which came as 2nd batch – the defaults as recommended by Anycubic and consequently by Lychee Slicer 5.1.8 were not as good as Photon Mono 4K.
The default settings with 3mm/s or 180mm/min for 2nd lift speed caused multiple failed prints for me such as delimination, and I reduced it to 1.5mm/s or 90mm/min and increased transitioning layers from 4 to 10 – after that fine structures like those 40mm cube lattice prints came out quite well.
Photon Mono X2 Drip Hook
I highly recommend a drip hook, you want uncured resin easily drip over a period of 5-10min back into the vat, before you wash it off in water (when using water wash resin) or isopropyl alcohol (IPA).
263 x 169 x 30 mm (outside max) 238 x 162 mm (inside)
steel build plate
Elegoo Saturn S (same LCD size)
202 x 129 mm (min. 196 x 122mm)
Spring Steel Plate
I made two prints with the original build plate, and it was difficult to remove the prints without flexing and scratched the plate right away – the adhesion is good, too good actually. So it became clear, I also want a spring steel plate for it.
Magnetic spring steel plate: 202x128mm for Photon Mono X2Photon Mono X2 202x128mm spring steel plate
magnetic base: 2.2mm thick, slightly extends, 203x129mm
steel plate: 0.5mm thick, exact 202x128mm
so one has to compensate 2.5 – 3mm in Z height and adjust, speak extend, the Z-level probe. I just glued a black strip of paper, and then of course re-level the bed again afterwards.
Mono X2 Z probeZ probe removedZ probe extended with strip of black paper (or any opaque tape), apprx. 3mm to the bottomZ probe with extension mounted back
Update 2024/11: well, let me add here after 20 months usage, where the built-plate rested for apprx. 5 months without use, the steel plate fused with the magnetic rubber counter part, and while trying to separate, the rubber base tore a hole, but as it turned out, also the adhesive of the rubber base detaching from the actual build-plate:
While detaching steel from rubber base, the rubber base tore multiple tears and even a holeAdditionally rubber base detached from the actual build plate as wellManually detached rubber base, revealing adhesive no longer attaching, and also thin transparent layer also detaching
This is bad . . . I’m not sure if it came to be of the long stand-still / resting without detaching the steel plate, or a rather short lifetime of the flex-plate, I suspect a combination of both. I clean(ed) the steel plate and rubber counter part after every print session (one or multiple consecutive prints), but still some resin residue could have remained, sufficient to fuse the flex steel plate with the rubber counter part.
Either way, I gonna replace it and keep using the flex steel plate as it makes it easier to detach smaller or delicate pieces. I can conclude this flex steel plate likely will last 15-20 months only, and if I won’t use the printer for longer then I detach the flex steel plate from the rubber magnetic base.
Motherboard
The motherboard has two main chips:
ARM GD32F407
driving Z stepper motor with endstop (Z=0)
driving USB port
driving both LCDs via ASIC
EF2L 45L G1444B (ASIC)
driving monochrome LCD via MIPI DSI (not sure where the image buffer resides)
driving UI color LCD with touchscreen
Mono X2 motherboard
Preliminary Review Mono X2
Pros:
good value for build size, but not features
mid-size build volume with 196 x 122 x 200 mm (WxDxH)
no cover sensor (can be on or off and still prints)
available replacement of parts (LCD, vat, build-plate)
Cons:
no Wi-Fi (only USB Stick)
surprisingly noisy with fans while printing
firmware doesn’t allow to change UV light intensity
default settings are not giving reliable prints1)
very simple firmware & UI
no flex build plate
no upper endstop (you can ramm the build-plate into the plate on top)
no sensor for running plate against cured remains in vat2), that would require more advanced firmware
cheap USB memory stick (breaks after a few days, data corruption)
using original Anycubic Water Washable Resin +
newer printers (2023) have load cell to measure counter force, and prevent build-plate to run with force against vat and LCD underneath. Update 2023/05: Anycubic released Mono M5S (2023/05) which has a load-cell sensor, but reviews are mixed.
Photon #4 (Mono X2) & Photon #1 & #2 (Mono 4K): additional handle on top, and labels on cover and body
Addendum
Printing Procedure
Let me take the chance to describe my MSLA resin printing procedure – if you are newcomer you might like to read it in a concise way.
resin printing (as in 2023) is still a messyprocedure at the consumer and prosumer level as well
the moment the print is finished, you need to remove the build-plate or flex steel plate, no matter which, the piece(s) still have resin on it, which likely will drip on the printer and especially around the vat is the most critical area:
by any means prevent any resin to come under the vat
don’t touch the underside of the vat with hands or gloves, unless you have a fresh piece of sheet of paper towel or equivalent
if you must clean the underside of the vat – and if you do you already screwed up when this happens – clean it first thoroughly, and after that the side of the vat and other part of the printer
prevent any resin to get on the LCD or protective layers on the LCD, wipe it away right away
cured resin is difficult to remove, especially from softer surfaces like plastic – so I have the habit to remove all resin outside of the vat right away
clean your gloves with pieces of paper towel, to prevent to further spoil your equipment you grab as next:
clean gloves when handling the build plate
I keep the same gloves for multiply prints or a 1-2 weeks as I clean them with paper towels right away (2-3 times per print: whenever I touch the 3d printer, the gloves are clean)
when removing the pieces from the build plate, things will become messy, no matter what
washing the piece(s) off in a water container as I use only water wash resin
1st wash container: I dip the pieces with the build plate into the container, my gloves don’t get wet or touch resin
2nd wash container: I remove the flex build plate, and dip it with the pieces still on the plate into the 2nd container – dipping in and out several times
then I remove the pieces from the flex build plate, by flexing the build plate or use a metal scrapper, and they drop into a small container with layers of paper towels where they dry a bit (10-30min) – I don’t touch the pieces with my gloves, I only touch the build plate
cleaning the build plate with paper towels dry, mount it back on the printer
cleaning the flex build plate with paper towels and attach it to the build plate
no cured remains in vat: using the plastic scrapper to push on the vat’s bottom softly, and move through the vat slowly to see if there are remains attached to the vat bottom, those needs to be removed otherwise at next print the build plate will push it unto the LCD and potentially damage it – high risk to damage the MSLA printer severely, such as puncture FEP of the vat and leak resin all over
if there are cured remains on the bottom FEP which I can’t remove with the plastic scrapper (large enough to pick out), then
either I expose the entire plate for 10-20s, and remove then a full cured layer of the entire area, this removes all small remains
if there are small floating pieces, then I empty the vat off the resin by pouring through a metal or paper filter (keeps back remove all cured remains) back into the bottle – this is time consuming and messy as you need to clean funnel and metal filter again
if I have printed pieces with small holes where water might still be captured, I take a piece of paper towel and wrap it and shake it fast in my hands – I have seen people blowing compressed air on the cured pieces, this makes sense if you produce many pieces in series frequently
2nd stage curing of the pieces in UV chamber:
white/black/grey resin 1-3 mins
clear resin 2 mins max
further resting the piece(s) for 1-2 hours to dry further
And I leave the resin in the vat, and let the vat stay on the printer for weeks and even months – no refilling back and forth to and from bottles, unless I know I have cured fragments in the vat, then I empty the vat with metal or paper filter back into the bottle and clean it with paper towels thoroughly as mentioned above already.
Keep everything around resin printer as clean as possible.
Consumer MSLA vs Professional SLA/MSLA
When trying to compare consumer MSLA and professional SLA & MSLA like from Formlabs, notable they switched from SLA 2024/04 to MSLA with their Form 4 series as well, one might just look at the print size or build volume (state 2024/11):
★★☆☆☆ depends on layer cross section & print height
★★★★☆ depends only on print height
Hardware Maintainability
★★★☆☆
★★★☆☆
★★★★☆
★★★☆☆
★★★☆☆
Original Online Resources
★☆☆☆☆
★☆☆☆☆
★★★★★
★★★★★
★★★★☆
Community Resources
★★★★☆
★★★☆☆
★★★★☆
★★★☆☆
★★★☆☆
After Sales Support
★★☆☆☆
★★☆☆☆
★★★★☆
★★★★☆
★★★★☆
Third Party Market
★★★☆☆
★★☆☆☆
★★☆☆☆
★☆☆☆☆
★☆☆☆☆
Reliability
★★☆☆☆1)
★★★★☆
★★★☆☆
Value
★★★☆☆2)
★★★★☆2)
★★★☆☆2)
★★★☆☆2)
★★★☆☆2)
based on overall build and firmware, which can’t even properly calculate remaining print time while printing, I have a low expectation
value for most are nearly the same, because the low price for Anycubic Photon Mono series also give you moderately good solution, whereas Formlabs printers are very pricey but also giving you good value, and Prusa SL1S rather high priced for the gaining reliability and print speed, Elegoo Mars & Saturn Ultra value is higher due lower price
Form Wash station for Form 3, Form Wash L for Form 3L, you move the build plate direct into the washing station, and before curing remove them from the build plate
Prusa SL1S & Elegoo Mars/Saturn Ultra prints a layer in 2 seconds in total, whereas traditional MSLA takes 7-10s (exposure time + lifting/retraction)
Impressive selection of resins, incl. bio compatible, strong and durable options
As a follow-up, while reviewing another resin printer, I realized the “value” for me I could actually determined by the XY area which translate into parallel printing capability, which is more relevant than the height (Z), combined with the precision or voxel size – as of 2023 Anycubic doesn’t even mention the XY resolution anymore – a bad marketing move.
(M)SLA Value Comparison
A numeric value summarization for features I care about, the rough & simple formula:
XY Area [mm2] / Price [EUR] / XY Resolution [μm]
The bigger the XY area, the smaller the price and the smaller the resolution, the higher the value:
Formlabs 3’s & EMake SLA printers use a laser beam which has 100μm in diameter, but it can be positioned 25μm exact, the latter was used to calculate the value
The UV pixels are non-square, the longer side was used to calculate the value
The XY area in SLA scales not as good as with MSLA, as the laser beam takes longer the more XY area (e.g. more pieces) need to be rendered per layer – so, MSLA is recommended for aiming fast parallel printing. Interestingly Formlabs 4 is now a MSLA as well (2024/04), they seem to have abandoned the SLA laser-based approach.
2023/07/25: moved content from blog into regular pages
2023/03/15: adding more Settings for different resins, different default for different firmware version, added preliminary Review
2023/03/09: finally published
2023/03/05: first prints made, more info on Lychee Slicer, Prusa Slicer SLA, more on magnetic steel plate use, prints with or without support, closeup photos added
2022/11/29: added Drip Hook, still preparing the utilities to make first print
2022/11/26: Mono 4K arrived, preparing software pipeline (slicer, converters) and working place
2022/11/07: starting write-up
Introduction
The past years I focused on Filament Deposition Manufacturing (FDM) / extrusion based 3D printing, and the time came to focus on MSLA resin based process as well.
My main use case a small pieces, like custom pulleys and idlers – precise parts, such as:
Custom pulley ID8 20T: MSLA @35μm XY, 50μm Z vs FFF @400μm nozzle, 100μm ZCustom pulley ID8 20T: MSLA @35μm XY, 50μm Z vs FFF @400μm nozzle, 100μm Z
Anycubic Photon Mono 4K
The Anycubic Photon Mono 4K seemed like a good choice to start with:
build volume: 132 x 80 x 165 mm (WxDxH)
resolution: XY 35μm, Z 50μm
6.1″ display with 4K resolution (3840×2400) display
monochromatic LCD (hence “Mono”), faster printer due shorter exposure
affordable with EUR 170-220 (2022/11)
no network, only USB drive printing
SLA Stereolithography Apparatus – one beam/point light source
MSLA Mask Stereolithography Apparatus – one light source, masking what does not need to be printed
DLP Digital Light Processing – one image, each pixel controlled by micro mirror
I ordered 2022/11/22 for EUR 170 and received it 4 days later via Anycubic Store within Amazon, along with a few utilities like water wash resins, gloves, etc – ready to MSLA print.
Update 2023/05: the Mono 4K has been discontinued, and replaced with Mono 2 with slightly larger print volume of 143 (+11mm) x 89 (+9mm) x 165 (+33mm).
FDM/FFF vs Resin
FDM/FFF
Resin MSLA
X, Y precision: 100μm Z precision: 50μm minimal structure: 200-600μm1) minimal post-processing minimal toxicity of filament print duration based on printed volume large scale prints affordable 1kg filament EUR 15-30 mixed materials2)
X, Y precision: 35-75μm Z precision: 30-50μm minimal structure: 30-50μm extensive post-processing severe toxicity of resin print duration based on print Z height only large scale prints require expensive printers 1kg resin EUR 30-803) single material
depends on nozzle diameter
multiple printheads/hotends required, e.g. IDEX, tool changer, material changer
Anycubic sold water wash resins at 22-27 EUR/kg 2023/03 (black, white, clear, grey and waterblue)
Print Settings
layer height: 0.05mm / 50μm
exposure time: 2s
light-off time: 0.5s
bottom layer count: 6
bottom exposure time: 40s
lifting distance: 6mm
lifting speed: 4mm/s
retract speed: 6mm/s
anti-aliasing level: 1
file formats: pwma (proprietary)
Photon Workshop on Linux
My development environment is Linux, and as of 2022/11 there is no Linux Photon Workshop, the name of the slicer needed to slice for Mono 4K; but you can run it via Wine (a Windows compatibility wrapper):
I tried my xyzHollowCalibrationCubeV2 and used auto hollow feature which defaults to 2mm thickness:
This seems to work but is not ideal. The Photon Workshop reveals that Photon Mono 4K supports only .pmwa format, which as it turns out, is PWS format just with the extension .pmwa to avoid mixing up different PWS files for different machines, as the pixel-based slices are hardware dependent now as resolution of the display is set.
Chitubox for Linux
Chitubox Slicer is available for Linux natively and supports a variety of SLA printers, also the Mono 4K:
I also used the auto hollow feature, which defaulted to 1.2mm wall thickness.
Lychee Slicer for Linux
I ended up with the Lychee Slicer which is available for Linux as well, which contains some annoying advertising to wait for when slicing or exporting various formats, but functionality-wise it it is more intuitive than Chitubox Slicer.
Lychee Slicer 4.1.0 for Linux (AppImage)
Prusa SLA Slicer
Prusa Slicer 2.4.0 using SLA subsystem and custom build-volumeRedefining Printer Settings to fit Anycubic Photon Mono 4K: 132x80mm / 3840×2400 px
As mentioned, the Photon Mono 4K has its own proprietary file-format PWS file to print with, with a particular file extension to indicate which Anycubic MSLA device it is sliced for:
Machine
File Extension
Layer Image Encoding
Mono
PWNO
PWS
Mono SE
PWMS
PWS
Mono X
PWMX
PWS
Mono X2
PMX2
PWS
Mono 4K
PWMA
PWS
S
PWS
PWS
Zero
PW0
PW0
X
PWX
PWS
Ultra
DLP
PWS
D2
DLP2
PWS
Prusa Slicer slices also for MSLA, it’s own .sl1 format, just a ZIP file with a list of PNG files per slice, in order to convert .sl1 to PWS/.pwma another tool is required:
UVtools, it can read and write many SLA image formats, incl. PhotonWorkshop (.pw*) file-formats
another approach could be (as of 2022/12 not yet) to just convert sl1 to .photon with SL1toPhoton command line tool, and extend functionality to support PWS/.pwma as well
alternatively uv3dp supports pw0 and pws files, but struggles with new(er) PWS files like .pwma
.photon/ctb/cbddlp vs .pw*
.photon (and ctb/cbddlp) is an older file format, whereas newer Photon Workshop (PW) has PWS and PW0 encoded images as layers – so far the format seems reverse engineered and somewhat documented via UVTools: PhotonWorkshopFormat.cs
does not report layer counts, but be determined from the amount of enclosed .png files
does not support multi-exposure printing
PWS
SL1
x_resolution [px]
display_pixels_x [px]
y_resolution [px]
display_pixels_y [px]
xy_pixel [μm]
display_pixels_x / bedshape[x] * 1000 [μm]
layers_count
len(<*.png>)
Replacing Firmware
MSLA resin printers are quite closed systems without much information of the hardware, firmware, and additional having their own proprietary file formats which contain the layer images.
For the Anycubic Photon Mono 4K is an open source firmware available, Turbo Resin – which gave me a good reason to get this 3D printer (2023/07: the firmware isn’t complete yet). Along with it, the hardware has been pretty much reversed engineered.
Anycubic Firmware
Turbo Resin (2022/12)
– PW0/PWMA format
– PW0/PWMA & CTB format
Custom MSLA Slicer
Pondering on a custom MSLA slicer:
automatic hollowing of solids at certain wall thickness
automatic support generation, outside and inside (after hollowing)
drain hole generation
command line interface (CLI)
external preview of sliced part
supporting sl1 and pws/pw0 as a start
Feature
Prusa Slicer
Lychee Slicer
ChituBox Slicer
command line interface (CLI)
Y
–
–
automatic hollowing
Y
Y
Y
drain holes
Y
Y
Y
automatic support
Y
Y
Y
Linux support
Y
–
–
PWS support
–
Y
Y
Open MSLA Format
Unfortunately there is no open (M)SLA format, each manufacturer kind of does its own, whereas G-code .gcode has some conformity, although G-code in general is also machine specific has it has absolute positioning, which differ from machine to machine, but at least G-code is easy to compose unlike proprietary (M)SLA file formats.
SL1 format by Prusa Engineering is a simple ZIP file which contains:
config.ini: irrelevant info
prusaslicer.ini: info about printer (bed size), pixel density, and many slicer settings
*.png: enumerated image files per slice in PNG format
and thereby is open enough for my taste.
Requirements of Open MSLA Format
simple format for controller to decode
simple pixel data1)
simple preview image format1)
this is why PWS/PW0 or CTB fileformat use some simple RLE algorithm to compress pixel data
First Print
After many weeks postponing, as I wasn’t eager deal with the inherent messiness of resin printing, I gave it a shot with some of the Triply Periodic Minimal Surfaces (TPMS) (2023/03/05):
Lychee Slicer: 8 TPMSScene exported as STL with supportAnycubic Mono 4K: starting print 2h 15mAnycubic Mono 4K: mid print
The Lychee Slicer gave 1h 15m print time, the printer itself showed 2h 15m; I used Anycubic White Water Wash Resin. I used automatic supports, and it printed 5 pieces successful, 3 pieces failed and only apprx. 4mm Z height were printed, interestingly all 3 failed pieces failed at the same Z height and broke off and stuck at the print plate.
Batch 1: 5 pieces printed successful, 3 failedWashed & cured: 5 TPMS 20mm: (front) Schwarz P, FRD, (background): Schwarz D, Gyroid, Gyroid Skeletal Washed & cured: 5 TPMS 20mm: (front) Schwarz P, FRD, (background): Schwarz D, Gyroid, Gyroid SkeletalBatch 2: reprinting previously 3 failed prints again, this time successful at the same position, same settings
I reprinted the 3 failed pieces at the same place, and this time they succeeded – which is strange as I suspected perhaps uneven light or some other positional inconsistency, but obviously the position did not matter, which is bad as I don’t know what caused the first failed print.
The curved bottoms (not directly printed but with diverse support pipes) already showing severe distortion while printing.
Update: It seems my office rooms aren’t warm enough, so the bed adhesion isn’t optimal as I read up in some forum posts. I tried to print a few other pieces, all failed the next day in the room with 15-19C° – the prints detached after 2-3mm height from the build plate. I moved it to another warmer room, warmed the resin on the radiator which helped.
The overall quality of the pieces is astonishing, no visible voxels or layers are seen, incredible quality for those prints which didn’t fail.
Yet the failure rate is still significant for my taste, so I need to pay close attention to room temperature, and other aspects:
Variable frequency of Schwarz P & D TPMS (40mm cube): with support and withoutSchwarz D variable frequency TPMS: with and without support (both successful prints)Schwarz P variable frequency TPMS: with and without support (mixed success)Schwarz P variable frequency TPMS with support (successful print)Schwarz P variable frequency TPMS without support: deliminated near bottom (failed print)Schwarz P variable frequency TPMS without support: deliminated near bottom (failed print)Schwarz D: 35μm XY, 50μm Z, seeing the voxels in the closeup
The cause of the “delimination” isn’t clear yet to me, it seems the prints with proper support and elevated bottom printed better, but I need to confirm with more prints.
As a start I assembled a simple DIY curing station with a 5m UV LED strip and placed it inside a plastic cup, with some aluminium foil at the bottom and top lid:
I only cure for 4-5mins, longer exposure changes the white resin into yellowish tint, and indicates over curing.
Keeping Resin in the Vat
After a print, the resins needs to be filtered for impurities, such as partial cured pieces not attached to the part, with a funnel and filter into a cup or bottle, and then it can be poured back into the vat ready to print again.
One can leave the resin in the vat for weeks, if you stir the resin short before you print again – stirring the resin within the vat is not ideal, as one has to avoid to scratch or FEP film; yet there is no need to pour resin back into the bottle unless one changes the resin, like the brand or color.
Drip Hook
I remixed an existing drip hook for Photon Mono to fit Photon Mono 4K, and make it easier to slide the bed on and off.
Additionally I’ve got a spring steel build plate 135x80mm with a magnetic base for EUR 10 (2022/12).
This turned out to be a good choice, the removal of the pieces is easy without additional tool.
Caution:
the thickness of the adhesive magnet holding the plate required the optical Z endswitch to recalibrate, instead to move the sensor, I extended the light breaking piece with just a small piece of paper with a drop of glue – it was easier than 3d printing an extender for the entire sensor.
in my case the small handle of the plate scratches on the original vat at the last 3-4mm height, therefore the entire plate needs to be slightly misaligned (just pushing one side while fastening the build plate) so the handle doesn’t touch the vat.
third party Anycubic Mono 4K vat like from Mega/Kingroon have a larger space, and don’t need any fiddling around therefore
the spring steel is sharp, it happened several times the single-use gloves being torn/cut while handling the plate
(One of) My Use Case
After a few days I aimed for the main use case of mine: printing custom pulleys.
MSLA @ 35μm XY, 50μm Z vs FFF @ 400μm nozzle, 100μm Z
As I printed them with Anycubic Water Wash White Resin without support, the “elephant foot” comes from the first 6 layers being cured for 40s as in my case, and the UV light refracting and curing more than meant to be, but I can neglect this.
16 custom pulleys ID8 20T printed with Anycubic Photon Mono 4K in 1h 30m or 5m30s per piece
MSLA
FDM/FFF
geometrical accuracy
★★★★☆1)
★★★☆☆
surface quality
★★★★☆
★★☆☆☆
mechanical sturdiness
(not yet tested)
★★★☆☆ (PLA)
print time per piece
5m 30s2)
15m
print time for 1 piece
1h 30m
15m
print time for 16 pieces
1h 30m
4h
due the “elephant foot” the Z accuracy was off by 0.8mm, instead of 15.0mm it’s 14.2mm
when printing 16 pieces, it took 1h 30m for printing 15mm in Z, I could have printed ~28 pulleys on 132 x 80mm build plate, bringing print time for a piece down to 3m 10s
Settings
from Anycubic Web-Site (2023/03/12)
My own experience with different resins (to be extended):
Defaults V0.0.11 Firmware V0.11
Defaults V2.0.2 Firmware V0.16
White WATER WASH RESIN (Anycubic)
Clear Water Wash Resin (Resione)
Layer Thickness [μm]
50
50
50
50
Exposure Time [s]
3
2.5
3
2 .. 3
Exposure Off Time [s]
2.5
1
0.5
0.5
Bottom Exposure [s]
50
30
40
40
Bottom Layers
6
6
6
6
Anti-alias
1
1
1
1
Z Lift Distance [mm]
3.0
4.0
6.0
6.0
Z Lift Speed [mm/s]
1.0
1.0
2.0
1.0
Z Retract Speed [mm/s]
1.0
1.0
4.0
1.0
UV Power [%]
100
100
100
50 .. 100
Notes
Distance, Speed & Retract Speed for – [BL] Bottom Layers – [NL] Normal Layers individually definable
– geometrical precise
– soft with 3s exposure – stiffer & brittle with 5s exposure – geometrical not precise (+0.2 .. 0.8mm in XYZ)
Preliminary Review
Pros:
good prints for the price
cost effective
power loss recovery actually works
lot’s of third party replacements (vat, FEP, etc)1)
alternatively Open Source firmware
nearly full reverse engineered hardware
this actually is quite important: popular machine raise a secondary market for replacements: future replacement of parts even when Anycubic ends support
Cons:
newly bought machine had outdated firmware
updated firmware calculates wrong total print time, this is just sloppy
touchscreen unreliable (wrong position) ‘print’ vs ‘delete’, use a soft pencil
slow prints with default settings (1mm/s Z motion), not nearly at 50mm/h height as advertised
Confusing:
slicer print settings are ignored, only settings on the machine matter
advantage: once sliced the .pwma can be printed with different resins and settings changed on the machine only
disadvantage: one has to memorize or document settings for different resins, as it not stored in the .pwma file
Verdict
It’s a low-cost entry level MSLA machine, Anycubic seems to care little about the software (2023/03) as the slicer as well the firmware are Minimal Viable Product (MVP) level, but aren’t mature or reliable at all. Given they sell 500K+ machines per year at least, investing to improve in the firmware would help 500,000 users.
Small anecdote: I bought a pre-owned Mono 4K, becoming “Photon 2”, from official Anycubic store at Ebay directly – the listing said the machine likely would miss some parts – but I felt to get some more in-depth experience, and I’ve got what I asked for: the machine came dirty with resin all over, no power-supply, no build-plate, no vat, and cured resin between LCD and underlying (acryl-)glass, spent EUR 120+ for replacement parts, and 10+ hrs cleaning it to get it in working condition again. From a cost saving point of view not worth it, but experience wise it was good to get to know the machine more thoroughly.
(M)SLA Value Comparison
A numeric value summarization for features I care about, the rough & simple formula:
XY Area [mm2] / Price [EUR] / XY Resolution [μm]
The bigger the XY area, the smaller the price and the smaller the resolution, the higher the value:
Formlabs 3’s & EMake SLA printers use a laser beam which has 100μm in diameter, but it can be positioned 25μm exact, the latter was used to calculate the value
The UV pixels are non-square, the longer side was used to calculate the value
The XY area in SLA scales not as good as with MSLA, as the laser beam takes longer the more XY area (e.g. more pieces) need to be rendered per layer – so, MSLA is recommended for aiming fast parallel printing. Interestingly Formlabs 4 is now a MSLA as well (2024/04), they seem to have abandoned the SLA laser-based approach.