How to Make a Very Small Rubik Cube Solver Robot 20220406 (1)
How to Make a Very Small Rubik Cube Solver Robot 20220406 (1)
2. Project scope:
Based on the introduction you probably can guess the project scope
This second Rubik’s cube solver robot project wants to be affordable, to attract more people and especially students
into robotics and programming.
The overall idea is to build a scalable robot, based on a minimalist base version.
3. Robot name:
I’ve started this project with the idea to write and share the instructions, and along the way I thought a robot name
would make the project more complete.
By combining CUBE, ROBOT and -INO, the Italian suffix for diminutives (to remark the small robot size), the chosen
name is CUBOTino
By considering the Top cover, combined with the Lifter, has a "C" profile shape, then CUBOTino become:
4. Conclusions:
Only the Base version is finished so far, therefore the conclusions are based on this version:
Pro:
1. The robot and the GUI are working fine
2. Costs are relatively low (about 30 to 40 euro of material, on early 2022)
3. Robot dimensions are very small
4. Rather easy to set the robot parameters via the GUI
Cons:
1. Solving time is from 60 to 90 seconds.
2. Micropython documentation is somehow limited.
3. Micropython documentation does not always correspond to real cases, for instance the PWM (on latest two
official release) have much lower resolution than reported on the docs.
5. Next steps:
Work out the other two robot versions
6. Commitment:
If you read these instructions, there are chances you are interested on making this project, or to get some ideas on a
sub part of it, or you’re a curious person…
In any case, I hope the information provided will help you! If that’s the case please consider to leave a message or a
feedback or thumbs up on Youtube (https://youtu.be/ZVbVmCKwYnQ), or at the Instructable site.
In case you cannot find the solution by yourself (part that makes projects fun ), please drop a detailed question at
the instructables site (https://www.instructables.com/CUBOTino-a-Small-Simple-3D-Printed-Inexpensive-Rub/).
I can’t promise I’ll be able to answer your questions, as well as I cannot commit to be fast in replying….
Please feel free to provide your tips and feedback, on all areas: This will help me
7. Safety:
Energize the robot only via USB ports having a class 2 insulation from the power supply net (laptops and PC normally
have this safety feature).
Despite the robot mechanical force is limited, it has to be operated only under adults’ supervision.
If you build and use a robot, based on this information, you are accepting it is on your own risk.
8. Models:
This project considers the robot to be scalable.
The idea is to develop three robot levels, by re-using the same mechanical part to manoeuvre the cube.
Notes:
The cube status detection method I’m trying for the Medium version, is via 9 colours sensors (LDR+WS2812B leds),
as explained at: https://fourboards.co.uk/rubix-cube-solving-robot
I’ve spent some time on this method, but the quality of my soldering is not successful yet; I’m even doubting if it
really fits the overall project scope, as this method involves too many skills.
Anyhow I’ve some other ideas for this Medium model….
Construction principles:
1. The inclined cube-holder is inspired to Hans construction Tilted Twister 2.0 - LEGO Mindstorms Rubik's Cube
solver - YouTube;
This is a clever concept, as it allows to flip the cube around one of the horizontal axes by forcing a relatively small
angle change (about 30 degrees, over the 20 degrees of the starting cube holder angle); Once the cube center of
gravity is moved beyond the foothold, the cube falls on the following face thanks to the gravity force.
Overall, it allows to flip the cube via a relatively small and inexpensive movement.
2. The Top-cover, combined with the cube Lifter, is the logical simplification step from my previous robot:
• The Top-cover provides a constrainer for cube layer rotation, further than suspending sensors for the cube
status detection, while keeping a compact robot construction.
• The cube Lifter flips the cube around one of the horizontal axes.
• Top-cover with integrated lifter is directly actuated by a servo, therefore controlled via angle.
Overall, it allows to combine multiple functions in a relatively small space, parts quantity, and costs.
There are many different examples of Rubik’s cube solver robot, based on two servos; I think most of them are
variations from the one made by Matt’s on 2014: https://hackaday.com/2014/06/28/rubiks-cube-solver-made-out-
of-popsicle-sticks-and-an-arduino/
In these executions, the solution used to flip the cube on one of the horizontal axes, requires the main pivot (servo)
to be placed rather far from the cube; This obviously increases a lot the overall dimensions.
11. 3D printed parts:
See notes below for filament quantity, and printing time …
Filament Printing
Ref Part
meters grams time
1 Structure 49 145 14h33m
2 Top_cover 39,5 117 12h26m
3 Hinge 17,2 51 5h37m
4 Baseplate front 12,2 36 3h33m
5 Baseplate back 12,6 37,3 3h36m
6 Cube_holder 11,6 34,4 3h36m
7 Cube_lifter 5,5 16,2 1h48m
8 PCB_cover 5,1 15 1h23m
Servo_axis_sup
9 2,4 7,2 0h55m
(or its alternative)
Servo_axis_inf
10 2,4 7 0h52m
(or its alternative)
TOTAL 158m 466g 48h20m
Notes:
1. The biggest part is the Structure, and it easily fits on printers with plate size of 200x200mm.
2. Filament length is based on Ø1.75mm.
3. Filament weight is based on PETG density (1.23g/mm³), and printing settings I’ve use on my Ender 3 printer, for
accurate result:
• 0.2mm layers
• Low speed (between 25 to 40mm/s for the external parts and 1st layer)
• 4 layers on vertical walls
• 5 layers on horizontal walls
• 30% filling
• 8mm brim
4. The filament quantity, and printing time, in the table should be considered as an upper limit. After printing, the
parts total weight is closer to 400grams than 466grams estimated by the slicer SW.
5. All parts have been designed to be printed printing without supporting the overhangs.
6. Some parts have been split, for easier and better 3D printing.
7. The suggested part orientation for the 3D print is showed on below Table.
8. The stl files are available on below websites:
• https://www.instructables.com/CUBOTino-a-Small-Simple-3D-Printed-Inexpensive-Rub/
• https://www.thingiverse.com/thing:5342368
Part name image 3D print orientation
Structure
Top_cover
Hinge
Baseplate front
Baseplate rear
Cube_holder
Cube_lifter
PCB_cover
Servo_axis_sup (or
Symmetrical
its alternative)
Servo_axis_inf
Alternative
Servo_axis_inf
12. Bought parts:
Cost
Q.ty Part link to the shop I used Notes
(euro)
https://www.aliexpress.com/i
tem/32864722159.html?gate
ESP32 30 pins wayAdapt=glo2ita&gatewayA
1 4.5
development board dapt=glo2ita&gatewayAdapt=
glo2ita&spm=a2g0o.9042311.
0.0.27424c4dBteSIp
https://www.aliexpress.co
Servo TD-8325MG m/item/32298149426.html 25
2 (180deg 25Kg metal) ?gatewayAdapt=glo2ita&sp (2 servos
and metal arm “25T” m=a2g0o.9042311.0.0.5d1 + 2 arms)
e4c4d14Qjaz
Screws:
Quantity Dimension Head type
1 M4x20 Cylindrical
~ 20 M3x12 Cylindrical
~30 M3x12 Conical
4 M2.5x10 Cylindrical
Touch pad:
Q.ty Part Notes
Piece of metal sheet
Aluminium is easy to work with.
1 (16x75mm, 1.5 to
Alternatively, bare wire in between the two screws will also do the job
2mm thickness)
Off course some other common materials are needed (USB-Microusb cable having with data lines, wires, solder and
solder device, tire wraps, self-adhesive rubber feet, etc).
13. ESP32 dev. board (30 pin) pinout:
Used pins:
Pin Purpose
D22 Cube Holder servo
D23 Top cover servo
D32 Touch plate for robot stop
Notes:
Added two capacitors (16V 220uF) at Vin and 3V3 vs GND
14. Connections board:
Top view:
Bottom view:
15. Setting up the ESP-32 microcontroller:
Step1: Before starting, do check if you’ve the driver for USB to UART communication installed:
To communicate with ESP32 board, via USB, a CP210X driver for the USB to UART communication is needed
Drivers are likely already available in your computer OS, if not:
1) Connect the ESP32 board via a USB cable
2) Go to https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers and download the driver for
you OS
3) For Windows OS, open Device manager and in case the driver is missed it should look like:
4) Right click on CP2102 device, select Update Driver Software…, navigate to the folder with unzipped
driver files, confirm
5) With installed/updated drivers, the connection should look like:
6) The COM number might be different, at it depends from the system you have
Step2: Download Micropython firmare for the ESP32;
At https://micropython.org/download/, select generic ESP32 dev board
If the firmware installation went well, on the REPL should appear: “MicroPython v1.17 on 2021-09-02; ESP32
module with ESP32”
Type esp.flash_size() to check the flash memory, that should be around: 4194304
Step5: Save the (below listed) files on the microcontroller.
When Micropython is installed, and the board energized, by launching Thonny the below window appears:
A the File Open request below window appears, meaning Thonny can open files from both the PC and the
ESP32 microntroller:
Choose This computer, and one by one open the below files:
• main.py
• Cubotino_moves.py
• Cubotino_servos.py
• Cubotino_settings.txt (select all files (*.*) option to be able to see the .txt file)
Save the above files, by using the Save as command, and by selecting the MicroPython device.
Note that files names should not be changed, as these are the reference for module import.
16. Files needed at PC
Python is needed for the below applications (it is suggested to make a virtual environment in Python):
Below the required libraries, that aren’t part of normal Python distributions:
Other files to be copied, into the folder where the Kociemba solver is located:
When the serial communication is established, the “Settings windows” button is activated, and via such button the
Settings window can be reached:
Each window is somehow divided in areas:
Notes:
Some buttons are activated only when some pre-conditions are fulfilled; For instance the Settings window button
requires to have the serial communication up and running with the robot.
2 4
1
5
3
Area 1 and 3:
• To fill the cube sketch, a color can be picked on the palette, with the left mouse button, and applied on the
facelets by pressing again the left mouse button; Colors can also be entered, or adjusted, via the mouse
scroll wheel when the pointer is over a facelet.
• It is possible to change the faces center colours as well (not when the pointer is not over the face letter).
It’s possible to select the cube status source, webcam or screen sketch.
The Read & solve button sends to the Kociemba solver the cube status depicted
on the sketch; in case the cube status is coherent, on the Text window will be
printed:
• Cube status
• Cube solution string, and number of manoeuvres
• Robot solution string
The Random button generates random cube status on the screen sketch; By Read & solve them we have countless
amount of cube solution to test/tune the robot movements
The CUBOTino sketch updates the center facelets colours, as guidance to drop the
cube on the robot according to the orientation used while detecting the status
The progress bar is updated in real time, according to the progress feedback sent by
the robot at each move
The Settings window button gets activated when the communication with ESP32 is
established
The Refresh COM button updates the connected COM ports, that will populate the drop-down menu; The COM ports
list will be displayed by pressing the little rectangle, see picture below
1
2
3 4 5
When a COM port has been selected, the drop-down menu closes and the Connect button becomes active
When the Connect button is pressed, in case the communication with ESP32 goes well the Settings window button
gets activated
The Settings window button activates the GUI dedicated window for the robot and webcam settings
On the Settings window there are the below areas:
Notes:
1. The changes eventually made on the servo related sliders, will be effective at the robot only after pressing Send
new settings to CUBOTino button.
2. By pressing the servo related buttons (FLIP, OPEN, CLOSE, CCW, HOME, CW) it’s possible to test the PWM and
servos positions.
3. Not all the timers can be tested via test buttons associated functions, yet most of them 😊
3 To move back to
the Main window
4
Area1, Receive and sending robot setting:
Get current CUBOTino settings button, to receive the servo settings stored in the ESP32 microcontroller.
Send new settings to CUBOTino button, to send the sliders servo settings to the ESP32 microcontroller.
Get AF settings button, to receive the servo settings of my CUBOTino, just as reference (hard coded settings).
Area2, Top cover – servo settings:
Notes:
1. For the PWM smaller values means the Top cover rotating closer to the cube
2. Servo motors don’t provide feedback of their positions: Timers are used to wait the needed rotation time before
moving to the next action
Notes:
18. The smaller the frame dimension, the faster the facelets detection time is.
Notes:
1. The folder data_log_folder is made from the folder where Cubotino_GUI.py is running.
2. The logged data is saved in the Cubotino_log.txt file.
3. Text file uses tab as separator.
Purpose for the data logging is mainly fun, yet it might be useful for debug or statistics
20. Assembly steps:
Before assembling the robot:
• Make the ESP32 support board
• Setup the ESP32 microcontroller
• Install all the files and libraries
• Position the two servos output gear to their middle position (see Tuning chapter)
Assembly order (for the details see Assembly details, toward the document end):
1. Screw the bottom servo to the structure
2. Prepare the sandwich Servo_axis_inf / servo lever / Servo_axis_inf
3. Assemble the Cube_holder to the Servo_axis assembly
4. Assemble the Cube_holder assembly to the bottom servo
5. Assemble the Hinge to the Structure
6. Assemble the “T25” servo arm to the upper servo.
7. Insert the Top_servo assembly into the Top_cover slot
8. Assemble the Top_cover assembly to the Hinge
9. Complete the top servo assembly to the Hinge
10. Assemble the Lifter to the Top_cover
11. Assemble the “STOP” touch plate, and related cable, to the Structure
12. Position the cables, and assemble the Baseplate_rear
13. Fix the ESP32 connection board to the Structure
14. Connect the servos and the touch plate to the ESP connection boards
15. Insert the ESP32 dev board to the ESP connection board
16. Assemble the Baseplate_front to the Structure
17. Stick self-adhesive rubber feet to the baseplates
18. Assemble the PCB cover
Tools necessary:
Allen keys 3mm, 2.5mm and 2mm
21. How to operate the robot:
1. GUI , Robot → Launch the GUI and connect the robot to an USB port of your PC (no obliged order on energizing
the robot / launching the GUI).
2. Robot → When the robot gets energized:
1. The red LED on ESP32 dev board will light up
2. The ESP32 boots, in few seconds
3. Servos settings are loaded, and servos are “initialized”:
a. Top cover is moved to the open position
b. Cube holder is moved to the home position
7. GUI → Start the cube solving process, via Send data to robot button:
• The blue LED at ESP32 dev board will flash during the cube solving period.
• CUBOTino starts solving the cube.
• Progress is feedback to the GUI, that keeps updated the Cube sketch and the progress bar.
• When the robot completes all the moves, the solving time is displayed on the Text message window.
9. Robot → The robot can be unplugged at any moment (no shut down procedure needed).
10. GUI → The GUI can be closed at any moment; The cube status on screen sketch is never saved.
22. Tuning:
1. Reference angles for servos:
The servos I bought, have 180-degrees of rotation, that is more than sufficient for the (lifter and Upper-cover) angles
of this robot; I don’t suggest buying 270-degrees servo as this will further affect the angle resolution.
The point is that the connection between the servo arms, and the servo’s outlet gear, have many possible positions
(believe there are 25 teeth).
This means the reference angles set on Cubotino_settings.txt file, are working fine on my robot, are not necessarily
the best choice on other systems.
These parameters must be tuned on your system, and the Settings windows GUI is the convenient
Before assembling the robot, the servos rotation range must be checked:
1. In case only one servo rotates 180° or slightly more, use this servo for the cube holder.
2. Search the min and max PWM values that makes the servos gear moving (connect an arm to better
check).
3. Set both the servos on their mid range position (mid PWM value), prior to the robot assembly.
4. The Settings windows at GUI can be used for these tests.
Note: In case your servo makes too much less than 180° rotation, to get the robot working properly, there are
tutorials in internet on how to increase the rotation angle, by adding some resistors in series with the servo
potentiometer (servo must be opened for this eventual change).
5. The Top_cover isn’t intended to keep pushing the cube when it’s in the close position; In case the cube layers
don’t align nicely, by playing with the cube_Holder settings, it’s possible to use the Top_cover to level the cube.
By lower the Top_cover close position to have a little interference with the cube, will improve the cube layer
alignment in particular after flipping the cube. In this case it will be convenient to set one or few units on PWM
release from close setting. Via this setting is possible to release the tension between the Top_cover and the cube,
after pressing it, to allow the cube_Holder to rotate with less effort.
6. Webcam app reads twice the same cube face: After one face has been detected, there are 3 seconds time in
which the facelets are ignored, to give the time to move the cube to another face. A solution is to move the cube
apart as soon as a face has been detected, and presented it again to the webcam once rotated to the next face.
7. Webcam app is slow: Speed is largely affected by the number of pixels under analysis. On the Settings window at
GUI, it’s possible to reduce the frame size (width, height, crop) to gain speed.
8. Webcam app ends with incoherent cube status statement: There are few reasons:
1. The cube orientation isn’t correct; The cube faces order should be URFDLB, and oriented to correctly
read the numbers 0 to 53 as per the sketch at “High level info” chapter.
2. The cube interpretation counts the same colour more than 9 times; This happens when the light
reflection changes between faces. To solve this issue, it’s recommended to have light coming from the
side or to use a cube with less glossy facelets.
Cube with in-moulded coloured facelet, that Cube with glossy stickers (after taking this
I’ve made matt with sandpaper (grit 1000) picture I made matt these facelets too)
24. Robot solver algorithm:
On this chapter it’s explain the approach used to convert the cube solution manoeuvres into robot moves; This part
is embedded in the Cubotino_moves.py file.
It is clear this robot has very limited degrees of freedom, as it can only rotate the bottom face (from -90° to +90°),
farther than flipping the cube around the L-R horizontal axis; This obviously requires an algorithm that prevents
additional cube movements to those (many) that are strictly necessary.
The Kociemba solver provides a string with the rotations to be applied on the 6 faces, like U2 F1 R3 etc (I will refer to
these three moves as example on the below explanation).
The precondition for the cube solution is that the cube orientation doesn't change, meaning the U (upper) side
remains up oriented and the F (front) side remains front oriented during the solving process; This pre-condition is
clearly not fulfilled by the robot.
1. All the 18 possible cube moves (U1, U2, U3, ….. , B1, B2, B3) the solver can return, are used as keys in a
dictionary; There are 18 sets of robot movements (hard coded) associated to these keys. These robot
movements consider the cube as ideally positioned: U side facing up and F side facing front.
2. When the robot moves the cube, its orientation is tracked per each applied movement (i.e. after the first U2
move, to follow above example).
3. When the next move must be applied, F1 in our example, the robot solver simply swaps the requested move (F1)
to an adapted move; The adapted move reflects the real F side location at that moment in time. Based on the
above example, the F1 move will be done by using the servo sequence associated to B1, simply because the F
side is located at B side at that moment in time.
4. Above points are considered when the cube solution string is parsed, to generate a string with all the servo
movements.
25. Colour’s detection strategy (when using the webcam):
1. The vision system is used to detect the cube’s facelets edges (contours), more or less as explained at
https://medium.com/swlh/how-i-made-a-rubiks-cube-color-extractor-in-c-551cceba80f0
2. Average BGR is calculated for the areas defined by the contours, for the 54 facelets, and stored in a dictionary;
Average HSV (of a small area at each contour’s centers) is also calculated and stored on a second dictionary.
Note: On a 3x3x3 Rubik cube, the 6 center’s facelets have useful properties:
a. These facelets don’t move (fix facelets number)
b. These facelets have (obviously) 6 different colours
c. Opposite faces have known colours couples, white-yellow, red-orange, green-blue (Western colour code).
This means we can make use of these 6 facelets as colour reference
3. The average HSV, detected on the 6 centers, is used to determine which colour is located on the 6 centers:
a. White facelet is the one having the largest V-S delta (difference between Value, or Brightness, and
Saturation), while the yellow one is located at opposite face.
b. Remaining 4 centers are evaluated according to their Hue, and the Hue at opposite face.
c. Orange has very low Hue, and red should be very high (almost 180); Depending on light condition, the
red’s Hue could be very low (few units) and lower than the orange, in that case both Orange and red are
very low, yet orange is always higher than red.
d. Out of the two remaining centers, blue is the one with highest Hue, and consequently the green is also
known.
4. Based on previous step, the 6 cube colours (at least their centers) have a known average HVS and therefore an
average BGR colour; This also informs on the cube orientation (colours) as placed on the cube-holder.
5. Facelets colour interpretation is made, by using two methods, with a tentative approach:
a. The first method compares the average RGB colour of each facelet, in comparison with the one at the 6
centers, and the colour decision is based on the smallest colour distance.
b. In the second method the Hue value of each coloured (non-white) facelet are compared to the Hue of the 5
reference centers; White facelets are retrieved according to 3 parameters (Hue, Saturation, Value), in
comparison to the white center HSV.
First method is in general better than the second one, yet the second one “wins” when there is lot of light; The
second method is only used (called) when the first one fails.
As result both methods are used, to get reliable cube status detection under different light situations.
26. Credits:
• to Mr. Kociemba, that further than developing the two-phase-algorithm solver, he also wrote a python
version of it; Credits to him also for the simple GUI he made available, from which I’ve further build the one
for this robot.
• Hans Andersson, with his Tilted Twister (Tilted Twister 2.0) Lego robot, so inspiring: Very simple yet effective
mechanic concept.
• to Jacques, who triggered me on the colours sensors direction.
• all the people who provided feedbacks on my first robot.
27. Assembly details:
Couple of notes:
• Before tightening the four screws, checks if the servo output gear is well centred to the Structure hole.
• To limit the protrusion of the below two screws, add a couple of washers to these screws; This to prevent
eventual interference with the servo_axis_inf part.
Step5 (sandwich Servo_axis_inf / servo arm / Servo_axis_inf):
4x M3x12mm conical head
Check if the supplied X arm fits with the indentation of Servo_axis_inf part:
If you don’t have a X arm to make it fit, please print the alternative parts (Servo_axis_inf and Servo_axis_sup)
designed to fit the aluminium “T25” arm (arm has to be reduced in length).
✓
1x M3x12mm cylindrical head
Note: three screws will slightly protrude underneath the Structure; If screws of 12mm then this won’t be a problem.
Note: The screw should not protrude from the Structure plane; Add some washers under the screw head if needed
Do not fully tighten the two M3x12mm, until also the third screw is positioned
Step12 (Complete the top servo assembly to the Hinge):
Rotate the Top_cover to have the hole facing the third screw accessible
1x M3x12mm cylindrical head (add washers if the screws doesn’t push on the “T25”Arm)
Step13 (Assemble the Lifter to the Top_cover):
4x M3x12mm cylindrical head
Picture 1
Picture 2
Picture 3