Huber Girón Nieto
Electronic and Mechatronic Engineer
Contact
e-mail: huber.giron.nieto@iberopuebla.mx
phone: +52 (222) 372 3000 ext.12917
FABLAB Puebla Researcher
WEEK ASSIGNMENT:
Mechanical Design and Machine Design
Make a machine, including the end effector, build the passive parts and operate it manually, automate your machine, document the group project and your individual contribution.
For this week activity we make a machine and automate the machine, so we decide to make a Styrofoam cutting machine.
The machine was design by Aristarco Cortes and Itan Fuentes, and my individual contribution was automate the machine.
The Styrofoam cutting machine have 4 stepper motors: one on "X" and one in a 360° that move the base, and two in "Z" that move the tool: hot wire.
"X" motor and 360° Base motor:
"Z1" and "Z2" motor:
Electronic
To control the Stepper motors we use 4 gestalt nodes, FabNet adapter and a USB adapter
Control Software: Python Aplication
To control the Stepper motors we write a Python application for Ubuntu, based in the Single_Node and XY_Plotter from the gestalt demo codes.
This Python application read a txt file with instructions to place each stepper motor, this code read the instructions for motor x, motorz1, motor z2 and final to 360° motor.
/////////CODE://///////
# FabLab Puebla - Huber Giron Nieto
#------IMPORTS-------
from pygestalt import nodes
from pygestalt import interfaces
from pygestalt import machines
from pygestalt import functions
from pygestalt.machines import elements
from pygestalt.machines import kinematics
from pygestalt.machines import state
from pygestalt.utilities import notice
from pygestalt.publish import rpc #remote procedure call dispatcher
from Tkinter import *
import time
import io
motores = 'Motor1', 'Motor2', 'Motor3', 'Motor4',
r1=0
r2=0
r3=0
r4=0
cha = [0,0,0,0]
outx="En espera...x"
#------VIRTUAL MACHINE------
class virtualMachine(machines.virtualMachine):
def initInterfaces(self):
if self.providedInterface: self.fabnet = self.providedInterface #providedInterface is defined in the virtualMachine class.
else: self.fabnet = interfaces.gestaltInterface('FABNET', interfaces.serialInterface(baudRate = 115200, interfaceType = 'ftdi', portName = '/dev/ttyUSB0'))
def initControllers(self):
self.xAxisNode = nodes.networkedGestaltNode('Motor 1', self.fabnet, filename = '086-005a.py', persistence = self.persistence)
self.yAxisNode = nodes.networkedGestaltNode('Motor 2', self.fabnet, filename = '086-005a.py', persistence = self.persistence)
self.zAxisNode = nodes.networkedGestaltNode('Motor 3', self.fabnet, filename = '086-005a.py', persistence = self.persistence)
self.wAxisNode = nodes.networkedGestaltNode('Motor 4', self.fabnet, filename = '086-005a.py', persistence = self.persistence)
self.hNode = nodes.compoundNode(self.xAxisNode, self.yAxisNode, self.zAxisNode, self.wAxisNode)
def initCoordinates(self):
self.position = state.coordinate(['mm', 'mm', 'mm', 'mm'])
def initKinematics(self):
self.xAxis = elements.elementChain.forward([elements.microstep.forward(4), elements.stepper.forward(1.8), elements.leadscrew.forward(8), elements.invert.forward(False)])
self.yAxis = elements.elementChain.forward([elements.microstep.forward(4), elements.stepper.forward(1.8), elements.leadscrew.forward(8), elements.invert.forward(True)])
self.zAxis = elements.elementChain.forward([elements.microstep.forward(4), elements.stepper.forward(1.8), elements.leadscrew.forward(8), elements.invert.forward(False)])
self.wAxis = elements.elementChain.forward([elements.microstep.forward(4), elements.stepper.forward(1.8), elements.leadscrew.forward(256), elements.invert.forward(False)])
self.stageKinematics = kinematics.direct(4) #direct drive on all axes
def initFunctions(self):
self.move = functions.move(virtualMachine = self, virtualNode = self.hNode, axes = [self.xAxis, self.yAxis, self.zAxis, self.wAxis], kinematics = self.stageKinematics, machinePosition = self.position,planner = 'null')
self.jog = functions.jog(self.move) #an incremental wrapper for the move function
pass
def initLast(self):
# self.machineControl.setMotorCurrents(aCurrent = 0.8, bCurrent = 0.8, cCurrent = 0.8)
# self.hNode.setVelocityRequest(0) #clear velocity on nodes. Eventually this will be put in the motion planner on initialization to match state.
pass
def publish(self):
# self.publisher.addNodes(self.machineControl)
pass
def getPosition(self):
return {'position':self.position.future()}
def setPosition(self, position = [None]):
self.position.future.set(position)
def setSpindleSpeed(self, speedFraction):
# self.machineControl.pwmRequest(speedFraction)
pass
#CODIGO INTERFAZ GRAFICA
def fetch(entries):
aza=1
for entry in entries:
motorx = entry[0]
paxo = int(entry[1].get())
print('%s: "%d"' % (motorx, paxo))
if aza==1:
r1=paxo
elif aza==2:
r2=paxo
elif aza==3:
r3=paxo
elif aza==4:
r4=paxo
aza=aza+1
supercoords = [[r1,r2,r3,r4]]
for coords in supercoords:
stage.move(coords, 0)
status = stage.xAxisNode.spinStatusRequest()
while status['stepsRemaining'] > 0:
time.sleep(0.001)
status = stage.xAxisNode.spinStatusRequest()
def makeform(root, motores):
entries = []
for motorx in motores:
row = Frame(root)
lab = Label(row, width=15, text=motorx, anchor='w')
ent = Entry(row)
row.pack(side=TOP, fill=X, padx=5, pady=5)
lab.pack(side=LEFT)
ent.pack(side=RIGHT, expand=YES, fill=X)
ent.insert (10,0)
entries.append((motorx, ent))
return entries
# CODIGO PARA LEER UN TXT
def decodifica():
numerocuenta=0
to=0
ls=0
ps=0
ry1=0
ry2=0
ry3=0
ry4=0
print ("Decodificando....")
po = caja1.get()
print("%s" % po)
while(not((po[numerocuenta]=='\n') and (po[numerocuenta+1]=='\n'))):
if(po[numerocuenta]!=',' and po[numerocuenta]!='\n'):
cha[ls]=(int(po[numerocuenta]))
ls= ls + 1
elif(po[numerocuenta]==','):
to= (cha[0]*(10**(ls-1)))+(cha[1]*(10**(ls-2)))+(cha[2]*(10**(ls-3)))
print("%d:" % to)
ps=ps+1
if (ps==1):
ry1=to
elif (ps==2):
ry2=to
elif (ps==3):
ry3=to
cha[0]=0
cha[1]=0
cha[2]=0
cha[3]=0
to=0
ls=0
if(po[numerocuenta+1]=='\n'):
to= (cha[0]*(10**(ls-1)))+(cha[1]*(10**(ls-2)))+(cha[2]*(10**(ls-3)))
print("%d:" % to)
ry4=to
muevete(ry1,ry2,ry3,ry4)
cha[0]=0
cha[1]=0
cha[2]=0
cha[3]=0
to=0
ls=0
ps=0
numerocuenta=numerocuenta+1
def muevete(hx1,hx2,hx3,hx4):
r1=hx1
r2=hx2
r3=hx3
r4=hx4
print("Motor1: %d" % r1)
print("Motor2: %d" % r2)
print("Motor3: %d" % r3)
print("Motor4: %d" % r4)
supercoords = [[r1,r2,r3,r4]]
outx= ("%d , %d , %d , % d" %(r1, r2, r3, r4))
var.set(outx)
root.update_idletasks()
for coords in supercoords:
stage.move(coords, 0)
status = stage.xAxisNode.spinStatusRequest()
while status['stepsRemaining'] > 0:
time.sleep(0.001)
status = stage.xAxisNode.spinStatusRequest()
#
# CODIGO PARA ir a CERO
def ZERO():
muevete(0,0,0,0)
#
#------IF RUN DIRECTLY FROM TERMINAL------
if __name__ == '__main__':
stage = virtualMachine(persistenceFile = "test.vmp")
stage.hNode.setVelocityRequest(4)
root = Tk()
root.title('FabLab Puebla - CNC Machine')
root.geometry("700x170+0+0")
var = StringVar()
# nuevo codigo
caja1= Entry(root)
caja1.pack(side=LEFT, padx=5, pady=5)
b2 = Button(root, text='Cortar', bg='red', command=(lambda : decodifica()))
b2.pack(side=LEFT, )
labZX= Label(root, width=15, textvariable=var)
labZX.pack(side=LEFT, padx=5, pady=0)
var.set(outx)
#
ents = makeform(root, motores)
root.bind('<Return>', (lambda event, e=ents: fetch(e)))
b1 = Button(root, text='Avanza', bg='green',
command=(lambda e=ents: fetch(e)))
b1.pack(side=LEFT, padx=55, pady=5)
b2 = Button(root, text='Zero', bg='green',
command=(lambda : ZERO()))
b2.pack(side=LEFT, padx=5, pady=5)
root.mainloop()
Test's
/////////CODE:///////// PIRULI
0,0,0,0
0,180,180,0
0,150,150,0
150,150,150,0
150,180,180,0
0,180,180,0
30,180,180,0
30,150,150,0
30,0,0,64
0,0,0,64
0,150,150,64
30,150,150,64
30,0,0,128
0,0,128
0,150,150,128
30,150,150,128
30,0,0,192
0,0,0,192
0,150,150,192
30,150,150,192
30,0,0,256
0,0,0,256
/////////CODE:///////// COPA
5,0,0,0
5,10,10,0
30,10,10,0
30,40,40,0
0,70,70,0
0,100,100,0
90,100,100,0
90,70,70,0
60,40,40,0
60,10,10,0
90,10,10,0
90,0,0,0
110,0,0,0
110,0,0,43
90,0,0,43
90,10,10,43
60,10,10,43
60,40,40,43
90,70,70,43
90,100,100,43
0,100,100,43
0,70,70,43
30,40,40,43
30,10,10,43
0,10,10,43
0,0,0,43
0,0,0,86
5,0,0,86
5,10,10,86
30,10,10,86
30,40,40,86
0,70,70,86
0,100,100,86
90,100,100,86
90,70,70,86
60,40,40,86
60,10,10,86
90,10,10,86
90,0,0,86
110,0,0,86
110,0,0,129
90,0,0,129
90,10,10,129
60,10,10,129
60,40,40,129
90,70,70,129
90,100,100,129
0,100,100,129
0,70,70,129
30,40,40,129
30,10,10,129
0,10,10,129
0,0,0,129
0,0,0,172
5,0,0,172
5,10,10,172
30,10,10,172
30,40,40,172
0,70,70,172
0,100,100,172
90,100,100,172
90,70,70,172
60,40,40,172
60,10,10,172
90,10,10,172
90,0,0,172
110,0,0,172
110,0,0,215
/////////CODE:///////// Waffle
0,0,0,0
0,32,32,0
16,55,55,0
33,42,42,0
49,55,55,0
66,42,42,0
82,55,55,0
100,42,42,0
130,42,42,0
130,22,22,0
130,22,22,64
100,22,22,64
82,45,45,64
66,22,22,64
49,45,45,64
33,22,22,64
16,45,45,64
0,22,22,64