Commits

Elias Bakken committed aa4e44f

A lot of work on porting the code to kernel 3.8. Working fine now and just about ready for first print on HipsterBot.

Comments (0)

Files changed (11)

  - Add lables to the SMD outputs (A1, A2, B1, B2)
  + Switch channels for ADC on Ext1 and Ext2?
  + Switched +5V and SYS_5V.
+
+
+Todo list going from Rev 1 to Rev A2:
+ - Uninvert the PWM channels for the Mosfets
+ - Add pin for GND for the thermistors
+ - Add connector for temperature sensing via Dallas 1-wire. 
+ + Widen the tracks for the MOSFETs
+ - Add OSHW logo 
+ - Add some kind of speaker support :)
+ - Add support for LEDs 
+ - LED to show when the plate is warm. 
+
 
 #RPATH=/home/root/replicape
 #REMOTE=root@10.24.2.124
-RPATH=/root/replicape
-REMOTE=root@10.24.2.85
+RPATH=/home/ubuntu/replicape
+REMOTE=root@10.24.2.64
 
 .PHONY : software firmware eeprom
 
 	scp software/*.py $(REMOTE):$(RPATH)/software
 
 gui: 
-	scp -r software/gui/ $(REMOTE):$(RPATH)/software
+	scp -r software/GUI/ $(REMOTE):$(RPATH)/software
 
 minicom:
 	minicom -o -b 115200 -D /dev/ttyUSB1

images/3.8.6-bone12/3.8.6-bone12-dtbs.tar.gz

Binary file added.

images/3.8.6-bone12/3.8.6-bone12-modules.tar.gz

Binary file added.

images/3.8.6-bone12/3.8.6-bone12.zImage

Binary file added.

software/GUI/arrows.py

+#!/usr/bin/env python
+'''
+A GUI for Hipsterbot
+
+Author: Oyvind Nydal Dahl
+email: oyvdahl@online.no
+Website: http://www.build-electronic-circuits.com
+License: BSD
+
+You can use and change this, but keep this heading :)
+'''
+
 import random
 import wx
- 
+import os, stat
+
+
+#Named pipes for communicating with main 3d-printer controller
+wfPath = "/var/tmp/rcape_in"
+rfPath = "/var/tmp/rcape_out"
+
+
+
 ########################################################################
 class TabPanel(wx.Panel):
     #----------------------------------------------------------------------
     def __init__(self, parent):
         """"""
         wx.Panel.__init__(self, parent=parent)
- 
-        #colors = ["red", "blue", "gray", "yellow", "green"]
-        #self.SetBackgroundColour(random.choice(colors))
-        
+        dirname = "/home/ubuntu/replicape/software/GUI"
         
-        imageLeft = wx.Image("arrow-left.jpg", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
-        imageRight = wx.Image("arrow-right.jpg", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
-        imageUp = wx.Image("arrow-up.jpg", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
-        imageDown = wx.Image("arrow-down.jpg", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
+        imageLeft   = wx.Image(dirname+"/arrow-left.jpg",  wx.BITMAP_TYPE_ANY).ConvertToBitmap()
+        imageRight  = wx.Image(dirname+"/arrow-right.jpg", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
+        imageUp     = wx.Image(dirname+"/arrow-up.jpg", 	  wx.BITMAP_TYPE_ANY).ConvertToBitmap()
+        imageDown   = wx.Image(dirname+"/arrow-down.jpg",  wx.BITMAP_TYPE_ANY).ConvertToBitmap()
         
         btnLeft = wx.BitmapButton(self, id=-1, bitmap=imageLeft, pos=(10, 20), size = (imageLeft.GetWidth()+5, imageLeft.GetHeight()+5))
         btnRight = wx.BitmapButton(self, id=-1, bitmap=imageRight, pos=(10, 20), size = (imageRight.GetWidth()+5, imageRight.GetHeight()+5))
 
     #Button click events
     def btnLeftClick(self,event):
-        print "G91"
-        print "G1 X-100 F4000"
-        print "G90"
+        write_to_pipe("G91")
+        print "RX: " + read_from_pipe()
+        write_to_pipe("G1 X-100 F4000")
+        print "RX: " + read_from_pipe()
+        write_to_pipe("G90")
+        print "RX: " + read_from_pipe()
 
     def btnRightClick(self,event):
-        print "G91"
-        print "G1 X100 F4000"
-        print "G90"
+        write_to_pipe("G91")
+        print "RX: " + read_from_pipe()
+        write_to_pipe("G1 X100 F4000")
+        print "RX: " + read_from_pipe()
+        write_to_pipe("G90")
+        print "RX: " + read_from_pipe()
 
     def btnForwClick(self,event):
-        print "G91"
-        print "G1 Y100 F4000"
-        print "G90"
+        write_to_pipe("G91")
+        print "RX: " + read_from_pipe()
+        write_to_pipe("G1 Y100 F4000")
+        print "RX: " + read_from_pipe()
+        write_to_pipe("G90")
+        print "RX: " + read_from_pipe()
 
     def btnBackClick(self,event):
-        print "G91"
-        print "G1 Y-100 F4000"
-        print "G90"
+        write_to_pipe("G91")
+        print "RX: " + read_from_pipe()
+        write_to_pipe("G1 Y-100 F4000")
+        print "RX: " + read_from_pipe()
+        write_to_pipe("G90")
+        print "RX: " + read_from_pipe()
     
     def btnUpClick(self,event):
-        print "G91"
-        print "G1 Z10 F4000"
-        print "G90"
+        write_to_pipe("G91")
+        print "RX: " + read_from_pipe()
+        write_to_pipe("G1 Z10 F4000")
+        print "RX: " + read_from_pipe()
+        write_to_pipe("G90")
+        print "RX: " + read_from_pipe()
 
     def btnDownClick(self,event):
-        print "G91"
-        print "G1 Z-10 F4000"
-        print "G90"      
+        write_to_pipe("G91")
+        print "RX: " + read_from_pipe()
+        write_to_pipe("G1 Z-10 F4000")
+        print "RX: " + read_from_pipe()
+        write_to_pipe("G90")
+        print "RX: " + read_from_pipe()
 
  
 ########################################################################
  
         self.Show()
  
-#----------------------------------------------------------------------
+    #----------------------------------------------------------------------
+
+
+
+###########################################################################
+def check_com():
+    #Check if named pipes exist, exit if not
+    try:
+        if not stat.S_ISFIFO(os.stat(wfPath).st_mode):
+            print "Communication error with " + wfPath
+            exit(1)
+
+        if not stat.S_ISFIFO(os.stat(rfPath).st_mode):
+            print "Communication error with " + rfPath
+            exit(1)
+
+    except OSError:
+        print "Communication error"
+        exit(1)
+
+###########################################################################
+def write_to_pipe(msg):
+    wp = open(wfPath, 'w')
+    wp.write(msg + "\n")		
+    wp.close()
+    print "TX: " + msg
+
+
+###########################################################################
+def read_from_pipe():
+    rp = open(rfPath, 'r')
+    message = ""
+    messages = rp.readlines()
+    for msg in messages:
+        message = message + msg
+    rp.close()
+    
+    return message
+
+###########################################################################    
 if __name__ == "__main__":
+    check_com()
     app = wx.App(False)
     frame = DemoFrame()
     frame.ShowFullScreen(True, style=wx.FULLSCREEN_ALL)
         if hasattr(self, 'next'):
             a = self.global_pos
             b = self.vector
-            # Do not continue the update beyond the bnext segment
+            # Do not continue the update beyond the next segment
             self.next.set_global_pos(dict( (n, a.get(n, 0)+b.get(n, 0)) for n in set(a)|set(b) ), False)
     
     ''' Get the length of this path segment '''
                 return np.pi
         return angle
         
+    def stepper_to_axis(self, pos, axis):
+        ''' Give a steppers position, return the position along the axis '''
+        if self.axis_config == "H-belt":
+            A = np.matrix('-0.5 0.5; -0.5 -0.5')
+            if axis == "X":
+                X = np.array([pos, 0])
+                b = np.dot(A, X)
+                return tuple(np.array(b)[0])
+
+            if axis == "Y":
+                X = np.array([0, pos])
+                b = np.dot(A, X)
+                return tuple(np.array(b)[0])
+
+        # For all other axes, return the same value
+        return pos
+            
         
 if __name__ == '__main__':
     a = Path({"X": 10, "Y": 0}, 3000, "RELATIVE")

software/Path_planner.py

         td          = num_steps/steps_pr_meter                          # Calculate the actual travelled distance        
         if vec < 0:                                                     # If the vector is negative, negate it.      
             td     *= -1.0
-        self.current_pos[axis] += td                                    # Update the global position vector
+
+        # If the axes are X or Y, we need to transform back in case of 
+        # H-belt or some other transform. 
+        if axis == "X" or axis == "Y":
+            (td_x, td_y) = path.stepper_to_axis(td, axis)
+            self.current_pos["X"] += td_x 
+            self.current_pos["Y"] += td_y 
+        else:                        
+            self.current_pos[axis] += td                                    # Update the global position vector
 
         return (pins, delays)                                           # return the pin states and the data
 
         self.ddr_mem_used   = 0  
         self.clear_events   = []       
         self.ddr_lock       = Lock() 
-        self.debug = 2
+        self.debug = 0
     
         self.i = 0
         pypruss.modprobe(0x40000)    			        # This only has to be called once pr boot
             self.ddr_mem = mmap.mmap(f.fileno(), ddr_filelen, offset=ddr_offset) # mmap the right area            
             self.ddr_mem[self.ddr_start:self.ddr_start+4] = struct.pack('L', 0)  # Add a zero to the first reg to make it wait
        
+        dirname = os.path.dirname(os.path.realpath(__file__))
         pypruss.init()						            # Init the PRU
         pypruss.open(0)						            # Open PRU event 0 which is PRU0_ARM_INTERRUPT
         pypruss.pruintc_init()					        # Init the interrupt controller
         pypruss.pru_write_memory(0, 0, [self.ddr_addr, self.ddr_nr_events])		# Put the ddr address in the first region 
-        pypruss.exec_program(0, "../firmware/firmware_pru_0.bin")	# Load firmware "ddr_write.bin" on PRU 0
+        pypruss.exec_program(0, dirname+"/../firmware/firmware_pru_0.bin")	# Load firmware "ddr_write.bin" on PRU 0
         self.t = Thread(target=self._wait_for_events)         # Make the thread
         self.running = True
         self.t.start()		        

software/Replicape.py

 from Thermistor import Thermistor
 from Fan import Fan
 from USB import USB
+from Pipe import Pipe
 from Ethernet import Ethernet
 from Gcode import Gcode
 import sys
     
 logging.basicConfig(level=logging.INFO)
 
-#import signal
-#import sys
-#def signal_handler(signal, frame):
-#        print 'You pressed Ctrl+C!'
-#        sys.exit(0)
-#signal.signal(signal.SIGINT, signal_handler)
-
 DEVICE_TREE = True
+LCD = False
+
+
 
 class Replicape:
     ''' Init '''
     def __init__(self):
         print "Replicape initializing"
+        if LCD: 
+            print "LCD screen present"
+        if DEVICE_TREE:
+            print "Kernel has support for device tree"
+
         # Init the IO library 
-        io.bbio_init()
+        if not DEVICE_TREE:
+	        io.bbio_init()
 
         # Make a list of steppers
         self.steppers = {}
 
         # Init the 5 Stepper motors
-        self.steppers["X"] = SMD(io.GPIO1_12, io.GPIO1_13, io.GPIO2_4,  0, "X") 
+        self.steppers["X"] = SMD(io.GPIO1_12, io.GPIO1_13, io.GPIO2_4,  5, "X") 
         self.steppers["Y"] = SMD(io.GPIO1_31, io.GPIO1_30, io.GPIO1_15, 1, "Y")  
         self.steppers["Z"] = SMD(io.GPIO1_1,  io.GPIO1_2,  io.GPIO0_27, 2, "Z")  
-        self.steppers["E"] = SMD(io.GPIO3_21, io.GPIO1_7, io.GPIO2_1,  3, "Ext1")
-        self.steppers["G"] = SMD(io.GPIO1_14, io.GPIO1_6, io.GPIO2_3,  4, "Ext2")
+        self.steppers["H"] = SMD(io.GPIO3_21, io.GPIO1_7, io.GPIO2_1,  3, "Ext1")
+        self.steppers["E"] = SMD(io.GPIO1_14, io.GPIO1_6, io.GPIO2_3,  4, "Ext2")
 
         # Enable the steppers and set the current, steps pr mm and microstepping  
         self.steppers["X"].setCurrentValue(1.0) # 2A
         self.steppers["X"].setEnabled() 
-        self.steppers["X"].set_steps_pr_mm(6.105)         
+        self.steppers["X"].set_steps_pr_mm(4.3)         
         self.steppers["X"].set_microstepping(2) 
 
         self.steppers["Y"].setCurrentValue(1.0) # 2A
         self.steppers["Y"].setEnabled() 
-        self.steppers["Y"].set_steps_pr_mm(5.95)
+        self.steppers["Y"].set_steps_pr_mm(4.3)
         self.steppers["Y"].set_microstepping(2) 
 
-        self.steppers["Z"].setCurrentValue(1.0) # 2A
+        self.steppers["Z"].setCurrentValue(1.5) # 2A
         self.steppers["Z"].setEnabled() 
-        self.steppers["Z"].set_steps_pr_mm(155)
+        self.steppers["Z"].set_steps_pr_mm(50)
         self.steppers["Z"].set_microstepping(2) 
 
         self.steppers["E"].setCurrentValue(1.5) # 2A        
 
         # init the 3 thermistors
         if DEVICE_TREE:
-            self.therm_ext1 = Thermistor("AIN4", "MOSFET_Ext_1", "B57560G104F") # QU-BD
-            self.therm_hbp  = Thermistor("AIN6", "MOSFET_HBP", "B57560G104F")
+            if LCD: 
+                self.therm_ext1 = Thermistor("/sys/devices/ocp.2/thermistors.15/AIN4", "MOSFET_Ext_1", "B57560G104F") # QU-BD
+                self.therm_hbp  = Thermistor("/sys/devices/ocp.2/thermistors.15/AIN6", "MOSFET_HBP", "B57560G104F")
+            else:
+                self.therm_ext1 = Thermistor("/sys/devices/ocp.2/thermistors.11/AIN4", "MOSFET_Ext_1", "B57560G104F") # QU-BD
+                self.therm_hbp  = Thermistor("/sys/devices/ocp.2/thermistors.11/AIN6", "MOSFET_HBP", "B57560G104F")
         else:
             self.therm_hbp  = Thermistor(io.AIN6, "HBP", chart_name="B57560G104F")
 
         # init the 3 heaters
         if DEVICE_TREE:
-            self.mosfet_ext1 = Mosfet("/sys/bus/platform/devices/mosfet_ext1.12")
-            self.mosfet_hbp  = Mosfet("/sys/bus/platform/devices/mosfet_hbp.14")
-            self.mosfet_ext2 = Mosfet("/sys/bus/platform/devices/mosfet_ext2.13")
+            if LCD: 
+                self.mosfet_ext1 = Mosfet("/sys/devices/ocp.2/mosfet_ext1.12")
+                self.mosfet_ext2 = Mosfet("/sys/devices/ocp.2/mosfet_ext2.13")
+                self.mosfet_hbp  = Mosfet("/sys/devices/ocp.2/mosfet_hbp.14")
+            else:
+                self.mosfet_ext1 = Mosfet("/sys/devices/ocp.2/mosfet_ext1.8")
+                self.mosfet_ext2 = Mosfet("/sys/devices/ocp.2/mosfet_ext2.9")
+                self.mosfet_hbp  = Mosfet("/sys/devices/ocp.2/mosfet_hbp.10")
         else:
             self.mosfet_ext1 = Mosfet(io.PWM2B) # PWM2B on rev1
             self.mosfet_hbp  = Mosfet(io.PWM0C) # PWM0C on rev1 
 
         # Set up USB, this receives messages and pushes them on the queue
         self.usb = USB(self.commands)		
+        self.pipe = Pipe(self.commands)
         self.ethernet = Ethernet(self.commands)
+        
 
         # Get all options 
         self.options = Options()
                 self._execute(gcode)
                 if gcode.prot == "USB":
                     self.usb.send_message(gcode.getAnswer())
+                elif gcode.prot == "PIPE":
+                    self.pipe.send_message(gcode.getAnswer())
                 else:
                     self.ethernet.send_message(gcode.getAnswer())
                 self.commands.task_done()
         except KeyboardInterrupt:
             print "Caught signal, exiting" 
             return
+        except Exception as e:
+            print e
         finally:
             self.ext1.disable()            
-            self.hbp.disable()            
+            #self.hbp.disable()            
             self.usb.close() 
+            self.pipe.close()
             self.path_planner.exit()   
             print "Done"
 		
                 axis = g.tokenLetter(i)                             # Get the axis, X, Y, Z or E
                 smds[axis] = float(g.tokenValue(i))                 # Get tha value, new position or vector             
             path = Path(smds, self.feed_rate, "ABSOLUTE")           # Make a path segment from the axes
+            print "moving to "+str(smds)
             self.path_planner.add_path(path)                        # Add the path. This blocks until the path planner has capacity
+            
         elif g.code() == "G29": 
             print self.current_pos
         elif g.code() == "G90":                                     # Absolute positioning
             self.ext1.setTargetTemperature(float(g.tokenValue(0)))
         elif g.code() == "M105":                                    # Get Temperature
             answer = "ok T:"+str(self.ext1.getTemperature())
-            answer += " B:"+str(int(self.hbp.getTemperature()))
+            if hasattr(self, "hbp"):
+                answer += " B:"+str(int(self.hbp.getTemperature()))
             g.setAnswer(answer)
         elif g.code() == "M106":                                    # Fan on
             if g.hasLetter("P"):
             fan = self.fans[int(g.getValueByLetter("P"))]
             fan.setPWMFrequency(int(g.getValueByLetter("F")))
             fan.setValue(float(g.getValueByLetter("S")))	           
+        elif g.code() == "M142":
+            print "Current pos is "+str(self.current_pos)
         else:
             print "Unknown command: "+g.message	
    

software/Thermistor.py

     ''' Return the temperature in degrees celcius '''
     def getTemperature(self):	
         if DEVICE_TREE:
-            with open("/sys/devices/ocp.2/thermistors.15/"+self.pin, "r") as f:
+            with open(self.pin, "r") as f:
                 try:
                     voltage = 0.001*float(f.read().rstrip())
                 except IOError: