In this tutorial we will be using Tobor to create some light paintings
OverviewThis tutorial is separated into 3 parts.
- Part 1: Creating the Spiral Generator
- Part 2: Program Tobor and the NeoBoard
- Part 3: Create more fun paintings
- Part 4: Take the Picture!
The first thing we've created was a small program that let's us create robot code that will draw a spiral
The program comes fitted with a 3D viewer that shows 3 states of the program.
- Purple Spiral: The original spiral created by the codeblock
- Green Spiral: The spiral that will actually be drawn by Tobor and is translated by the CNCTranslator Parameter
- Yellow Spiral: This is the final output of the program and is the robot code that will draw the actual spiral. This code has the scara kinematics already applied by the ScaraKinematics Parameter
The code above was created in the Floe IDE and will create a spiral and there are 3 basic sections.
The first section that contains 3 GuiSliders (slider elements that will show up in the running program. The labels for each slider will be the same name as they have in Floe. These sliders control the height, width and number of revolutions of the spiral.
This section also contains a codeblock that creates the actual spiral. This codeblock returns a string in the form of json lines. Json lines is the format Tobor and the GuiCodeEditors accept.
def function(event: int, height, width, revs): # This line is auto-generated. Do Not Change.
# add your code here
import math, json
def generate_spiral_cone(height, width, revolutions):
"""
Generate (x, y, z) points forming a spiral on a cone.
Args:
height (float): Height of the cone in mm.
width (float): Diameter of the base of the cone in mm.
revolutions (int): Number of spiral revolutions up the cone.
Returns:
generator: List of machine code strings representing the spiral curve.
"""
# Radius of the cone's base
radius = width / 2
# Calculate the total curve length
slant_height = math.sqrt(height**2 + radius**2)
curve_length = slant_height * revolutions
num_points = int(curve_length) # 1mm spacing
# Calculate angle step and vertical step per point
theta_step = 2 * math.pi * revolutions / num_points
z_step = height / num_points
# Generate points
for i in range(num_points):
theta = i * theta_step
z = i * z_step
r = (1 - z / height) * radius # Radius decreases linearly with height
x = r * math.cos(theta)
y = r * math.sin(theta)
cmd = dict(cmd='move.linear', feed=1200, x=x, y=y, z=z)
yield json.dumps(cmd)
# create generator
spiral_points = generate_spiral_cone(height=height.state,
width=width.state,
revolutions=revs.state)
output = '\n'.join(spiral_points)
return output
The next two sections move the spiral to where we would actually like it to be drawn with relation to Tobor. Finally we transform the robot code to scara kinematics. We no longer have x, y coordinates we have the angles of Tobor's joints.
Generate the SpiralWe choose the location and the dimensions of the spiral and export the code.
Part 2: Programming Tobor and the NeoBoardWe want to have a programmable RGB Led (WS2812) to be our light source. This led will blink random colors for the ornaments and then return to a green color for the remainder of the time to be the tree.
A single pixel was attached to the front of the 4th axis stepper motor as it was an easy place to affix it. We then used the NeoBoard edge board to control the led.
For Tobor's program we started with everything we already have for the standard Pick and Place setup with the addition of a few elements that can be used to control the led.
The parameters used here are:
- color: This parameter is just used to send some bytes. In this case it'll be used to send something like b'\x00\x03\x01' (0, 3, 1) to send a light green blue color.
- tree_anim: This parameter is used to send a string, which can be used to start the ornaments animation
- tree_delay: This parameter renders a graphic slider in Tobor's web gui so we could easily try different values to see what we liked.
For the NeoBoard program we need to create a few functions to drive the led.
The section to create the ornament animation
- tree_anim: This parameter is used to accept a string sent by Tobor.
- delay: This parameter is used to an int sent by Tobor to set how fast the animation plays.
- do_tree: internal flag used to a see if we wish to continue with the animation.
- set_animation: CodeBlock parameter that contains the animation code.Note this code_block has all three of the above parameters as arguments when it's called
def function(event: string, neo, do_tree, delay):
import uasyncio as asyncio
from random import randint
colors = ((22,0,0), (11,11,0), (0,0,22), (11,0,11))
green = (0,2,0)
def get_rand():
return colors[randint(0,3)]
async def tree_animation():
while True:
color = get_rand()
print(color)
neo(color)
await asyncio.sleep(delay.state/100)
neo(green)
await asyncio.sleep(2)
if not do_tree.state:
break
async def topper():
neo((2,2,2))
await asyncio.sleep(2)
neo.off()
if event == 'tree':
do_tree(True)
asyncio.get_event_loop().create_task(tree_animation())
elif event == 'topper':
do_tree(True)
asyncio.get_event_loop().create_task(topper())
else:
do_tree(False)
The next two sections create the Neopixel object and has a parameter called color that will accept a bytearray for color.
Bringing these programs together with cluster canvasesWith cluster canvases we can drop both Tobor and the NeoBoard together and network them. See this canvas here https://floe.evezor.com/ide/673f3f1bc7480dcdcanv
By dragging lines between the two we create connections. When Tobor sends a string on it's own tree_anim parameter NeoBoard recieves that message on it's own parameter that is also named tree_anim
Now on Tobor, all you must to is type tree_anim('some string') or color(color) and NeoBoard will recieve that message on the appropriate channel.
Networking devices has never been simpler!
Part 3: Create more fun paintingsTo begin we need to create a path for Tobor to take as we're drawing this picture.
See how to export gcode from inkscape in this video tutorial. (Larger text based tutorial coming soon to Hackster)
Once we've created a.gcode file from inkscape we will import it into another program created in Floe tree_light_inkhttps://floe.evezor.com/pyscript/673f94ae8d0b4162canv?core=mpy
This program is pretty much the same as the program from the video except we want to move where this will be drawn from the x, y plane to the y, z plane. That is taken care of in the transform codeblock
def function(event: any): # This line is auto-generated. Do Not Change.
import json
def trans(line):
line = json.loads(line)
if line['cmd'] in ['move.linear', 'move.rapid']:
return json.dumps(dict(cmd=line['cmd'], y=line['x'], z=line['y'], feed=500))
else:
return json.dumps(line)
lines = event.split('\n')
return '\n'.join(trans(line) for line in lines)
Next up we want our tool (the led) to turn on with some color and off on tool_up and tool_down So we are calling the color object we created in Tobor's program, which sends a message to NeoBoard's color parameter, which in turn changes the color of the led.
And when we run the this program and stick the.gcode file we exported from inkscape into the ink_sender gui parameter and hit submit.
To get the desired effect you're going to want to keep the shutter of your camera on the whole time Tobor is drawing and you'll get amazing pictures.
Some of the ones I didn't care for too much
We've got a lot more tutorials and information coming!
Find out more about Tobor and more on Crowd Supply
Comments