Alright, I took a few days to look at the code and it’s really complicated. As it’s a deep rabbit hole to go through, I’ll bring some context on the Palette 3 and what I’ve found so far.
Warning: I am not responsible for anything that happens to your Palette 3 if you try this. Try at your own risk.
Part 1: Palette 3 is just a CM3
So it turns out that if you go through the guide linked below from Mosaic’s guide on flashing the firmware, it turns out it is simply a CM3 module with a secondary MCU that it communicates with:
Also, you can find that there are some ports that are open on the Palette 3 if you connect it to wifi, which are 22, 5000, and 8883. Port 5000 gives you the web interface, the same interface as on the Palette 3. Port 8883 interestingly is a websocket port, but won’t be relevant for this information. That leaves us with port 22 which some will surmise allows us to access the OS using SSH.
If you happen to download and decompress any firmware images from the website, one of the files you will find is a docker compose file, which indicates that the user is mosaic
. However, we don’t get a password… so we’ll have to overwrite the password somehow. I used the chroot method using another raspberry pi. It might be possible another way but using the guide linked above and this method allowed me to access the root files and change the mosaic
password.
If you get here, you should backup the data on the CM3 in case something goes wrong… Happened to me once already O.o
Part 2: How Palette 3 works
As hinted earlier, Palette 3 operates on docker images, of which there are 6 of them. Here is a description of what they generally do (of what limited educated guess I could make out of it):
- Apollo: Backend of the Palette 3
- Cashmere: Frontend of the Palette 3, sending MQTT requests that will be parsed by Simcoe.
- Galaxy: Handles database management. Logs information such as number of splices and other data.
- Liberty: Handles communication to the secondary MCU that controls the hardware of the Palette 3.
- Meridian: Broadcasts information regarding touchscreen input.
- Simcoe: Communicates between Palette 3 and Canvas / Mosaic on print status and details of the current status. This is the central hub for parsing MQTT events and logging things to the backend database.
- Vojvodina: Manages webcam streaming.
Quite a lot… let’s just cut to the chase and say that in reality, only “Liberty
” and “Apollo
” are required to get the functionality of the Palette 3. If you change the network ports to allow port access to 1883, you can simply send MQTT commands outside of the other containers and it will operate the same way, just without the nice interface that Mosaic gives us. For example, to jog the filament, the MQTT topic is palette/request/drives/jog
and the corresponding data parameters can be sent as the following:
{
"header":
{
"originID":"simcoe",
"msgID":75
},
"payload":
{
"method":"job",
"query":
{
"drive":"out",
"withOut":true,
"speed":1
}
}
}
Intentionally, I have changed the speed to 1 but by default it is 40. The drive parameter can be from 1-4 or 1-8 (depending on if you have the pro version or not). Great! Shouldn’t be too hard I think if everything allows us to splice at will?
Part 3: “Liberty”
Well… not quite… Turns out that you can’t just set it in a continuous state of printing and splice at will. Typically for the Palette 3, you would need to set it in something called “accessory mode”, which tracks the progress of splicing using “pings” and “pongs”. However, liberty
requires a file that is a compressed file containing the splice lengths and the expected pongs so that the Palette 3 machine knows where to splice. Bummer.
Underneath liberty
, it actually communicates with a serial port that is linked with the MCU. Luckily, the parameters to communicate with the MCU are there named something else:
- Amarillo: The actual manager of the MQTT events and utilizes “
Citra
” to communicate with the secondary MCU. Also is the one that forwards the flags and commands to the secondary MCU
- Citra: A Nodejs plugin made to communicate with the secondary MCU at a baudrate of 38400 and a port of
/dev/serial0
… Interestingly the default is 115200 but it’s not the case here. Also this plugin indicates STM32 communication.
This then leads to the hard part… While most of the functionality is there, there needs to be a way to allow for “splice at will” during a print, as well as protections if something goes wrong. The todos are thus the following:
- Create a python program (or something similar) to communicate with the secondary MCU as it did with
liberty
- Develop
"splice at will"
filament changing instead of relying on whether there is a .mafx
file to print
- Connect this to Klipper using macros placed in gcode (problem: will require splicing to be done at an earlier point in time, I’m hoping that Klipper can parse the file beforehand to order
"splice at will"
but unsure if it is possible)
I’ll be continuing to look into this but again if anyone is interested, let me know!