Home
About me
Assignments
Final Project

Week 11: Presentation of MTM

1. Production of syringe adapter
Based on the idea sketch, I made a syringe adapter.

Firstly, I made it with the data on the site I referred to.
-VasterLabs, published Nov 9, 2014,Reprap Syringe Extruder
http://www.thingiverse.com/thing:536373
A 20 ml syringe made of polyethylene was used. By correcting the size, it was confirmed that the syringe could be pushed out.


Next, I changed the size by adding a base below so that I can control it on X axis. Fusion 360 was used for designing. A 3 mm thick acrylic plate was used for the base. It was assembled after outputting with a 3D printer. I confirmed that extrusion and movement are possible.



2. Production of main body
Considering the strength, the main body was made using an acrylic plate with a thickness of 5 mm. For the stage part, an acrylic plate with a thickness of 3 mm was used. Designed using Corel Draw X8. It was cut with a laser cutter and assembled. Corner parts were reinforced with acrylic corner to increase strength. M3 screws were used for joining the control part and the main body.








Next, a mounting adapter for a Y-axis rotating stepping motor was manufactured. The picture shows the completion of assembly of the main body. I confirmed that each part works smoothly.



3. Operation test
After the operation test, members of the FabLab Hamamats and Nagano supported them.
Since the main body was completed, the control program was tested. We used magic instead of syringe so I draw on paper cylinder. We modified the parameters of the test program we worked on last week. Coordinate values and moving speed were adjusted while operating. By repeating the adjustment, We could draw a rectangle like a video.



>G-code setting sheet(Google Spreadsheet)



4. Drawn on banana
In the final stage We actually drew in chocolate to the banana. The banana to buy also selected a straight shape banana. We measured the size and adjusted the position of the syringe.Chocolate mixed two kinds of syrups with different softness to prepare chocolate of appropriate softness. Because the banana is soft, We frozen on the previous night.



We did a test, but chocolate was not discharged as We wanted and We failed ourself repeatedly.

Adjustment of chocolate syrup blending ratio and program parameters continued. Judging that it is difficult to draw letters, we switched to a simpler figure drawing. As a result, We succeeded in drawing like a photo. Also, half-size bananas could be drawn with only one side support.




Parameter(FAB.nc)

X0.0000 Y0.0000 Z0.0000
X0.0000 Y0.0000 Z0.2000
X50.0000 Y15.0000 Z2.5000
X100.0000 Y0.0000 Z5.0000
X0.0000 Y0.0000 Z0.0000

We cheered and shared joy. After drawing, we also tasted bananas. It is a video recording the state of drawing.







5. Group members and roles

-FabLab Hamamatsu
Guru.Takemura: Programming, Mr.Kato: Recording and test support
-FabLab Nagano
Muramatsu: Hardware production and assembly ,Mr.Asanuma: Recording and test support



I appreciate the cooperation of the members.

-Group presentation page

Archive
-Syringe_adapter (Fusion360,STL,CorelDRAW X8)
-Banana bot (CorelDRAW X8)
-Moter adapter (Fusion360,STL)
-Moter adapter (Fusion360,STL)
-Control program(all) (Python)
-Control program(FAB.py,Fab.nc) (Python)
*Quote: FabLabTecsupwo,http://archive.fabacademy.org/archives/2016/fablabtecsup/students/machinedesign/

# Control program(FAB.py)
# Two stage example Virtual Machine file
# moves get set in Main
# usb port needs to be set in initInterfaces
# Nadya Peek Dec 2014

#------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
import time
import io
import math

#------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/tty.usbserial-FTZ2C0Z3'))
		
	def initControllers(self):
		self.xAxisNode = nodes.networkedGestaltNode('X Axis', self.fabnet, filename = '086-005a.py', persistence = self.persistence)
		self.yAxisNode = nodes.networkedGestaltNode('Y Axis', self.fabnet, filename = '086-005a.py', persistence = self.persistence)
		self.zAxisNode = nodes.networkedGestaltNode('Z Axis', self.fabnet, filename = '086-005a.py', persistence = self.persistence)

		self.xyzNode = nodes.compoundNode(self.xAxisNode, self.yAxisNode, self.zAxisNode)

	def initCoordinates(self):
		self.position = state.coordinate(['mm', 'mm', 'mm'])
	
	def initKinematics(self):
		self.xAxis = elements.elementChain.forward([elements.microstep.forward(1), elements.stepper.forward(1.8), elements.leadscrew.forward(2), elements.invert.forward(False)])
		self.yAxis = elements.elementChain.forward([elements.microstep.forward(1), elements.stepper.forward(1.8), elements.leadscrew.forward(18), elements.invert.forward(True)])		
		self.zAxis = elements.elementChain.forward([elements.microstep.forward(1), elements.stepper.forward(1.8), elements.leadscrew.forward(2), elements.invert.forward(False)])
		self.stageKinematics = kinematics.direct(3)	#direct drive on all axes
	
	def initFunctions(self):
		self.move = functions.move(virtualMachine = self, virtualNode = self.xyzNode, axes = [self.xAxis, self.yAxis, self.zAxis], 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.xyzNode.setVelocityRequest(8)	#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

#------IF RUN DIRECTLY FROM TERMINAL------
if __name__ == '__main__':
	# The persistence file remembers the node you set. It'll generate the first time you run the
	# file. If you are hooking up a new node, delete the previous persistence file.
	stages = virtualMachine(persistenceFile = "test.vmp")

	# You can load a new program onto the nodes if you are so inclined. This is currently set to 
	# the path to the 086-005 repository on Nadya's machine. 
	#stages.xyNode.loadProgram('../../../086-005/086-005a.hex')
	
	# This is a widget for setting the potentiometer to set the motor current limit on the nodes.
	# The A4982 has max 2A of current, running the widget will interactively help you set. 
	#stages.xyNode.setMotorCurrent(0.7)

	# This is for how fast the 
	stages.xyzNode.setVelocityRequest(3)	
	
	tempdatoX=0
	tempdatoY=0
	tempdatoZ=0
	datoX=0
	datoY=0
	datoZ=0
	listaTemp=[]
	listaG =[]

	codeG = open("FAB.nc", "r")
	linesG = codeG.read().splitlines()
	nroLinesG=len(linesG)

	for x in xrange(0,nroLinesG):
		tempdata = linesG[x].split()
		tempLen = len(tempdata)
		for y in xrange(0,tempLen):
		
			identifier=tempdata[y][0:1]
			if identifier=="X":
				tempdatoX = tempdata[y][1:tempdata[y].find(".")+3]
			if identifier=="Y":
				tempdatoY = tempdata[y][1:tempdata[y].find(".")+3]
			if identifier=="Z":
				tempdatoZ = tempdata[y][1:tempdata[y].find(".")+3]
			
			#tempdatoZ = math.pow(tempdatoX,2) + math.pow(tempdatoY,2)	
				
			datoX = float(tempdatoX)*1
			datoY = float(tempdatoY)*1
			datoZ = float(tempdatoZ)*1
			
			listaTemp=[datoX, datoY, datoZ]
		listaG.append(listaTemp);


	print listaG
	# Some random moves to test with
	moves = listaG


	# Move!
	for move in moves:
                stages.move(move, 0)
		status = stages.xAxisNode.spinStatusRequest()
		# This checks to see if the move is done.
		while status['stepsRemaining'] > 0:
			time.sleep(1)
			status = stages.xAxisNode.spinStatusRequest()


This week's assignment is over.