Week16Week 16::mechanical design, machine design

Assignments:

- make a machine, including the end effector build the passive parts and operate it manually, document the group project and your individual contribution

- automate your machine, document the group project and your individual contribution


1. Group assignment

This week assignment consists of creating a machine, document the group project and your individual contribution

Team (FabLab León):


Fabricio Santos

Description, design and module cutting

Read More

Szilárd Kados

Machine description and assembly

Read More

Raúl Diosdado

Electronic control

Read More

Carlos Cano

Programming

Read More

This assignment was a group assignment and we had to use 4 modules since we were 4 of us. Firstly we had a brainstorming to know exactly what we’ll build and how we’ll implement everything together. We knew it from the start that we would try to build a full 3 axis machine, but our 4th module was a little bit out of the line and didn’t really knew how to implement it in our machine. Apart from the 4th module we had to take in consideration the actual machine and be sure to build a functional and stable prototype. Following this idea and taking in consideration only 3 modules we couldn’t find a functional, nor stable way to build our machine. Naturally, we reviewed again the available information from the mtm website and we started to play with the presented ideas: 2 integrated modules for the base of our machine. This idea resulted useful since it presented stability and horizontal movement by moving those 2 modules at the same time. From this point forward we almost had our final idea defined: the 2 modules conferred our y axis movement, one transversal module conferred our x axis movement and finally a vertical module conferred our z axis movement. We had the full 3 axis movements defined and all the 4 modules integrated. Onwards, we had to define the purpose of our machine and we have choose to design and build a machine that can draws shapes on paper. Great, we had everything defined and ready to build our drawing machine.

Presentation Slider:

Presentation: Machines


2. Description of the modules and design of the structure (Fabricio Santos)

We need to build 4 modules so we prepare the model in order to be cut in the laser cutting machine. But our machin e was smaller than the unroll pieces we need to cut; so we had to split the model to be cut by using a kind of press-fit zipper made by Nadya and then we join it and stuck with cellotape.

Preparing cut:

Preparing cut

Laser Cut:

Laser Cut

For the material we chose a 3 mm thickness cardboard and we cut it in an Epilog Mini Laser 40w. So we use this cutting parameters: (speed/power/dpi)
blue: 60/50/1000 (cutting)
red: 100/15/500 (engraving)

assembly 1:

assembly 1

assembly 2:

assembly 2

Then we design a cardboard tool to hold the pen in the Z axis. So we design it the unroll surface of the model, we cut it and then we stuck its flaps in order to give it enough stiffness to bear the pressure of the vertical axis at the tip of the pen.

Pen Support
Pen Support

3. Machine description and assembly (Szilárd Kados)

This assignment was a group assignment and we had to use 4 modules since we were 4 of us. Firstly we had a brainstorming to know exactly what we’ll build and how we’ll implement everything together. We knew it from the start that we would try to build a full 3 axis machine, but our 4th module was a little bit out of the line and didn’t really knew how to implement it in our machine. Apart from the 4th module we had to take in consideration the actual machine and be sure to build a functional and stable prototype. Following this idea and taking in consideration only 3 modules we couldn’t find a functional, nor stable way to build our machine. Naturally, we reviewed again the available information from the mtm website and we started to play with the presented ideas: 2 integrated modules for the base of our machine. This idea resulted useful since it presented stability and horizontal movement by moving those 2 modules at the same time. From this point forward we almost had our final idea defined: the 2 modules conferred our y axis movement, one transversal module conferred our x axis movement and finally a vertical module conferred our z axis movement. We had the full 3 axis movements defined and all the 4 modules integrated. Onwards, we had to define the purpose of our machine and we have choose to design and build a machine that can draws shapes on paper. Great, we had everything defined and ready to build our drawing machine. Fabricio already was cutting out the cardboard for the modules, Raul was preparing the electronics, Carlos was familiarizing with Gestalt and I started to fold, glue and prepare the modules for the machine. Folding the modules were tricky since it needed special care because of the material (cardboard) and even so it wasn’t as consistent as we would expected. For every module I made I have tried to improve folding or make it better, stronger as the last one. With this learning by doing technique the first folded module came out the worst and the last one the “best”. These modules needed to be strong enough and to present consistent / smooth internal movements. Since we are talking about cardboard these modules were ok, but far from perfect.

assembly 1:

assembly 1:

assembly 2:

assembly 2:

After the 4 modules were prepared we have started to build our machine, to fit together these modules. We used an MDF sheet as of the base of the machine and glued 2 modules horizontally, taking special care to glue them parallel to each other. Glue another module transversally to the moving pieces of the first two modules. And glue the last module vertically to the moving piece of the 3d module. With this we had the base structure of our drawing machine, but still we were missing one important part: the marker holder. This holder we made it from cardboard and on the fly, simply cutting cardboard with a cutter and taping it together. In the end everything came out quite nicely and it was ready for the electronics and program executing.

assembly 3:

assembly 3:

assembly 4:

assembly 4:

4. Electronic control (Raúl Diosdado)

The electronic controller of the machine consists of nodes "Gestalt", the machine will have many nodes as motors have to control.
This is one of the Gestalt nodes:

Gestalt node
Gestalt node

The communication between the computer and the nodes is done in series, so that all nodes are interconnected, can be added as many nodes as you want, you only need to add at the end of the last node. The resulting configuration looks like this:

Schema
Schema

As shown in the picture above, you need to create a board that bridges between the computer and the first node.
This board is used for transmitting nodes both information and power to the engines.

Bridge
Bridge

In the "Source files" you can find the file to make this board. In the next picture you can see the mounted machine with each of its nodes numbered

Machine
Machine

Problems with electronic
When performing tests with the machine we detect a slight problem with electronics, the driver power that feeds the engine overheats, we realized that some projects had already made heat sinks to solve this problem, but we we did not have heat sinks in the FabLab at that time, so we regulate the power that is given to the engine regulating it in the potentiometer.

Potentiometer
Potentiometer

We have set the current around 150mA, more than enough power to move the motors


5. Programming the modules(J. Carlos Cano)

In the task group, at the beginning we have had many problems and questions with the mcm, gradually were solved thanks to the documentation available on the Internet from other projects and feedback through the mailing list of the Fab Academy.I Have paid attention to all parts of this project in which my colleagues worked, but my mission within the Group has been learn to communicate various kits and investigate about the programming of these devices.

Drivers needed for comunications:

Drivers needed for comunications

Connections:

Connections

We have lost enough time trying to load the bootloader on the supplied boards, we finally got it, then realised that it was not necessary, as the board come with the firmware already installed.To load the boot loader is necessary to install the USB-RS485 cable drivers and drivers of the programmer (AVRISP mkII), in my case, both were installed automatically with windows 7. I did the same actions in Kubuntu 14.10, to install the FTDI cable drivers downloaded drivers from http://www.ftdichip.com/Drivers/VCP.htm and the AVRISP programmer mkII didn't install anything. We can find the bootloader source code at the following address: https://github.com/imoyer/086-005. Once downloaded and uncompressed we accede to the newly created folder and in command line to load the bootloader I wrote the following:

cd 086-005-master
Nano Makefile

look at some options that has this file, at the end we can read:

program-avrisp2
# uncomment to bootloader program
#avrdude - e - c avrisp2 - P usb - p m328p - U flash:w: 086-005a_boot.hex
# uncomment to program application
avrdude - e - c avrisp2 - P usb - p m328p - U flash:w: 086-005a.hex

This Defaults configuration did not work for me, once loaded the bootloader can't could communicate with the board via the supplied python scripts. I modified the code in the following way to reprogramme the bootloader:

program-avrisp2:
# uncomment to bootloader program
avrdude - e - c avrisp2 - P usb - p m328p - U flash:w: 086-005a_boot.hex
# uncomment to program application
# avrdude - e - c avrisp2 - P usb - p m328p - U flash:w: 086-005a.hex

Now communication is correct.

sudo make program-avrisp2-fuses
sudo make program-avrisp2

As I said above, is not necessary (usually) load the bootloader on the boards, from this point I started to investigate the way to communicate with the board from the PC. First we must install Python 2.7, pip (for linux install of pyserial) and pyserial. Since Python 2.7.9 + (released December 2014) ship with Pip.To install pyserial:
- Windows: download and run the installer from the following link: https://pypi.python.org/pypi/pyserial
- Linux: Run on a terminal:

sudo pip install pyserial

With the steps above have already you need to communicate with the Gestalt boards, download pygestalt from https://github.com/nadya/pygestalt, this package contains, in addition to framework, code example with which to begin to work. In the folder "examples/machines" will find several projects.We have manufactured the FTDI cable for serial communication, we can follow the steps in http://fabacademy.org/archives/2015/doc/MachineMakingNotes.html Manufactured cable connect to the gestalt board, engine and feed the board with 12v and a maximum of 2A (we use :1, 5A) and we tried everything to be correct, accessing from console or terminal to the folder "/examples/machines/htmaa" and run the command python single_node.py (if you are using linux, remember to put before sudo to work properly). If all goes well the violet led of gestalt board flashes, and on screen you will see instructions indicating that we must press the button that you want to link to the program. Click the button and observe the motor connected to the board begins to rotate.
OK... it's time to try two Gestalt, repeat the previous step interconnecting two boards as described in the diagrams provided:
Schema
Schema
Before you run a new program, it must be said that within the source code you will find the following command/funtion: virtualMachine(persistenceFile = "test.vmp"), with the line managed to save the address of the Gestalt linked in other executions of the program, thus it is not necessary to press the buttons on the board every time you run the script. If you want to start over and the gestalt boards linking different axes (e.g. define as "y axis" a board that acted as "x axis" or simply replace them with others) we must delete this file, is a common mistake to have linked a board and trying to run with another different board get errors because the device is not. Once clarified this, you can run another script in the same folder, which in this case will move two axes of our machine. At this point was a problem with the cable that joins the two boards, one of the connections was not welded well and producing errors not found a second device to link, after a while we discovered the bug, we soldered the cable and everything worked correctly, when running in console python xy_plotter.py blinked violet leds of the two boards and on-screen gave us instructions to press the button on the board that would be the "x axis ", once you press another message asked us repeat the same action for the "y axis ". After this the script continued its runtime and both engines were its rotational movement. Our team has decided to assemble a machine to draw on a flat surface, so we will need 4 Gestalt boards, two of them made their movement as the “X axis ", another will execute the movements of "Y axis" and the last will be the axis that raise and lower a pen to draw “Z axis". By examining several of the examples provided I find in the folder /examples/wallbuilder a file that contains commands to control 4 axes/engines, it is ideal for recycling code and use it for our machine. While my coworkers are Assembly machine and the rest of necessary wires, I dedicate myself to modify the code to try to link the four boards gestalt and try different moves with them, in one of the lines of the source code for the example, (self.pAxis = elements.elementChain.forward ([elements.microstep.forward (4), elements.stepper.forward (1.8) elements.leadscrew.forward (6.096), elements.invert.forward (True)])) I can modify the parameters to get different speeds of rotation , which I have modified to increase the speed of the machine and get a motion in approximate inches.
I'm going to define an array called moves with the movement needed to draw a square:
moves = [[40,40,40,0],[40,40,40,7],[-40,-40,40,7],[-40,-40,-40,7],[40,40,-40,7], [40,40,40,7],[40,40,40,0],[0,0,0,0]]
Each position of the array corresponds to [x1, x2, y, z]
x1 and x2: are the x-axis and should move with the same value, otherwise we could warp or damage the machine.
y:” y axis”
Z: axis that rises or falls a marker pen.
This array of values is read by a "for” loop that executes sequentially each defined movements. When the machine is made, we all connections, we define the different axes and focuses them, creating a kind of "home" x and y focused on a sheet of paper and z "raised".
The following video shows the result when you run our program: leonidas.py:

Machine: Leonidas from FabLab León on Vimeo.

Source code (leonidas.py):

# Forked from wallbuilder july 2014
# set portname
# set location of hex file for bootloader
#
#------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

#------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 = 'COM7'))

      def initControllers(self):
           self.pAxisNode = nodes.networkedGestaltNode('X1 Axis', self.fabnet, filename = '086-005a.py', persistence = self.persistence)
           self.qAxisNode = nodes.networkedGestaltNode('X2 Axis', self.fabnet, filename = '086-005a.py', persistence = self.persistence)
           self.rAxisNode = nodes.networkedGestaltNode('Y Axis', self.fabnet, filename = '086-005a.py', persistence = self.persistence)
           self.sAxisNode = nodes.networkedGestaltNode('Z Axis', self.fabnet, filename = '086-005a.py', persistence = self.persistence)

           self.pqNode = nodes.compoundNode(self.pAxisNode, self.qAxisNode)
           self.rsNode = nodes.compoundNode(self.rAxisNode, self.sAxisNode)

           self.pqrsNode = nodes.compoundNode(self.pAxisNode, self.qAxisNode, self.rAxisNode, self.sAxisNode)
      def initCoordinates(self):
           self.position = state.coordinate(['mm','mm','mm', 'mm'])

      def initKinematics(self):
           self.pAxis = elements.elementChain.forward([elements.microstep.forward(4), elements.stepper.forward(1.8), elements.leadscrew.forward(6.096), elements.invert.forward(True)])
           self.qAxis = elements.elementChain.forward([elements.microstep.forward(4), elements.stepper.forward(1.8), elements.leadscrew.forward(6.096), elements.invert.forward(True)])
           self.rAxis = elements.elementChain.forward([elements.microstep.forward(4), elements.stepper.forward(1.8), elements.leadscrew.forward(6.096), elements.invert.forward(True)])
           self.sAxis = elements.elementChain.forward([elements.microstep.forward(4), elements.stepper.forward(1.8), elements.leadscrew.forward(6.096), elements.invert.forward(True)])

           self.stageKinematics = kinematics.direct(4) #direct drive on all axes
      def initFunctions(self):            self.move = functions.move(virtualMachine = self, virtualNode = self.pqrsNode, axes = [self.pAxis, self.qAxis, self.rAxis, self.sAxis], 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(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, None, 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 = "leon.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.pqNode.setVelocityRequest(4)
           stages.rsNode.setVelocityRequest(4)
# Some random moves to test with
#moves = [[40,40,40,0],[40,40,40,7],[-40,-40,40,7],[-40,-40,-40,7],[40,40,-40,7],[40,40,40,7],[40,40,40,0],[0,0,0,0]]
           moves = [[0,0,0,-40]]
# Move!
      for move in moves:
           stages.move(move, 0)
           status = stages.pAxisNode.spinStatusRequest()
# This checks to see if the move is done.
      while status['stepsRemaining'] > 0:
           time.sleep(0.001)
           status = stages.pAxisNode.spinStatusRequest()

Files: