DIY and Entry-Level 3D-Scanner Forum

www.diy3dscan.com
It is currently Tue Apr 08, 2025 2:30 am

All times are UTC




Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Wed May 08, 2013 6:17 pm 
Offline
Site Admin
User avatar

Joined: Fri Mar 22, 2013 3:30 pm
Posts: 349
Location: Ausria
The Lidar Scanner will be controlled via a Python script that controls both the Stepper motors (Arduino) and the Laser Range finder (LR4).

I will use this tutorial from Jkm3141 to develop the software:

http://arduino.cc/forum/index.php/topic,8332.0.html


Tutorial on Python programming:

http://zetcode.com/lang/python/


Tutorial on Python Gui programming:

http://zetcode.com/tutorials/pyqt4/

_________________
Bernhard
www.virtumake.com


Top
 Profile Send private message  
 
PostPosted: Wed May 08, 2013 7:04 pm 
Offline
Site Admin
User avatar

Joined: Fri Mar 22, 2013 3:30 pm
Posts: 349
Location: Ausria
If you are interested in the Python part of the project please drop me a line. I am no coder and could use some help :)

_________________
Bernhard
www.virtumake.com


Top
 Profile Send private message  
 
PostPosted: Fri May 17, 2013 6:10 pm 
Offline
Site Admin
User avatar

Joined: Fri Mar 22, 2013 3:30 pm
Posts: 349
Location: Ausria
I managed to code an interface in Python that tells the Arduino to move the steppers:

Attachment:
VirtuRange_Gui_V00.JPG
VirtuRange_Gui_V00.JPG [ 19.66 KiB | Viewed 20934 times ]


The upper part defines the COM boards. Enter the COM of the Arduino and hit "init" to set up the connection.

The lower part defines, how many steps the LIDAR should move (5 in this example) to the next measurement point. "MaxSteps" are the total amount of steps in Y- and Z-Axis. 1.600 steps would be a full rotation, 800 half, 400 a quarter aso.

This is the Python code:

Code:
#Source: http://www.tkdocs.com/tutorial/install.html#helloworld
#  // String "mx10100"
#  //         m ... "move"
#  //         s ... "start"
#  //         x ... "stop" 
#  //          x ... x-Axis
#  //          y ... y-Axis
#  //           1 ... turn cw
#  //           0 ... turn ccw
#  //            0100 ... make 100 Microsteps

from tkinter import *
from tkinter import ttk
import serial
import time
import sys

class MyGui:
   
    def __init__(self, master):
       
        mainframe = ttk.Frame(master, padding="3 3 12 12")
        mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
        mainframe.columnconfigure(0, weight=1)
        mainframe.rowconfigure(0, weight=1)
       
        ySteps = StringVar()
        zSteps = StringVar()
        yStepsMax = StringVar()
        zStepsMax = StringVar()
        yPosition = StringVar()
        zPosition = StringVar()
        arduinoCom = StringVar()
        flukeCom = StringVar()
       
        ttk.Label(mainframe, text="Arduino COM").grid(column=1, row=1, sticky=N)
        ttk.Label(mainframe, text="Fluke COM").grid(column=1, row=2, sticky=N)
       
        ttk.Label(mainframe, text="Y-Axis").grid(column=1, row=4, sticky=N)
        ttk.Label(mainframe, text="Z-Axis").grid(column=1, row=5, sticky=N)
       
        ttk.Label(mainframe, text="Steps").grid(column=2, row=3, sticky=E)
        ttk.Label(mainframe, text="Max Steps").grid(column=3, row=3, sticky=E)
        ttk.Label(mainframe, text="Position").grid(column=4, row=3, sticky=E)
       
        self.arduinoCom = ttk.Entry(mainframe, width=2, textvariable=arduinoCom)
        self.arduinoCom.grid(column=2, row=1, sticky=(W, E))
        self.arduinoCom.insert(0, "COM4")
       
        self.flukeCom = ttk.Entry(mainframe, width=2, textvariable=flukeCom)
        self.flukeCom.grid(column=2, row=2, sticky=(W, E))
       
        self.ySteps = ttk.Entry(mainframe, width=7, textvariable=ySteps)
        self.ySteps.grid(column=2, row=4, sticky=(W, E))
        self.ySteps.insert(0,"1")
       
        self.zSteps = ttk.Entry(mainframe, width=7, textvariable=zSteps)
        self.zSteps.grid(column=2, row=5, sticky=(W, E))
       
        self.yStepsMax = ttk.Entry(mainframe, width=7, textvariable=yStepsMax)
        self.yStepsMax.grid(column=3, row=4, sticky=(W, E))
       
        self.zStepsMax = ttk.Entry(mainframe, width=7, textvariable=zStepsMax)
        self.zStepsMax.grid(column=3, row=5, sticky=(W, E))
       
        self.yPosition = ttk.Label(mainframe, width=7, textvariable=yPosition)
        self.yPosition.grid(column=4, row=4, sticky=(W, E))
       
        self.zPosition = ttk.Label(mainframe, width=7, textvariable=zPosition)
        self.zPosition.grid(column=4, row=5, sticky=(W, E))
       
        ttk.Button(mainframe, text="init", command=self.scanInit).grid(column=3, row=2, sticky=W)
        ttk.Button(mainframe, text="Start", command=self.scanStart).grid(column=2, row=6, sticky=W)
        ttk.Button(mainframe, text="Stop", command=self.scanStop).grid(column=3, row=6, sticky=W)
        ttk.Button(mainframe, text="Exit", command=self.scanExit).grid(column=4, row=6, sticky=W)
       
        for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)
       
    def callback(self):
        self.root.quit()

    def scanStart(self):
        self.scanStop()
        global scanState
        scanState = 1
        if (ser.isOpen()):
            ser.write(bytes("s", encoding='ascii'))
        scanSeq = MyScanLoop(self.ySteps.get(),self.yStepsMax.get(),self.zSteps.get(),self.zStepsMax.get())
        scanSeq.run()

    def scanStop(self):
        global scanState
        scanState = 0
        if (ser.isOpen()):
            ser.write(bytes("x", encoding='ascii'))
       
    def scanExit(self):
        ser.close()
        sys.exit()
       
    def scanInit(self):
        ser.setPort(self.arduinoCom.get())
        ser.baudrate = 9600
        ser.open()
       
class MyScanLoop:
 
    def __init__(self, ySteps, yStepsMax, zSteps, zStepsMax):
        self.ySteps = int(ySteps)
        self.yStepsMax = int(yStepsMax)
        self.zSteps = int(zSteps)
        self.zStepsMax = int(zStepsMax)
 
    def run(self):
        z = 1
        dirY = "0"
        while z <= self.zStepsMax:
            y = 1
            while y <= self.yStepsMax:
                if (ser.isOpen()):
                    stpY = str(self.ySteps)
                    command = "my" + dirY + stpY.zfill(4)
                    ser.write(bytes(command, encoding='ascii'))
                y = y + self.ySteps
                root.update()
                time.sleep(0.5)
                if scanState == 0:
                    return
               
            if dirY == "1":
                dirY = "0"
            else:
                dirY = "1"
               
            if (ser.isOpen()):
                stpZ = str(self.zSteps)
                command = "mz0" + stpZ.zfill(4)
                ser.write(bytes(command, encoding='ascii'))
            z = z + self.zSteps
            root.update()
            time.sleep(0.5)
           
        if (ser.isOpen()):
            ser.write(bytes("x", encoding='ascii'))
                                   
ser = serial.Serial()                   
global scanState
root = Tk()
app = MyGui(root)
root.mainloop()


and this is the Firmware of the Arduino:

Code:
/* VirtuRange Firmware V11 by VirtuMake
** Follow it at www.diy3dscan.com
** Homebase www.virtumake.com
** This is Open Source. Do whatever you want with the code :)

** low/low Full Step (2 phase)
** high/low Half Step
** low/high Quarter Step
** high/high Eight Step

** Step Full = 1,8° = 200 steps * 8 = 1600 steps

*********************************************************/

int dirPinY = 4;
int stepperPinY = 5;
int dirPinZ = 2;
int stepperPinZ = 3;
int sleepPin = 7;
int MS1 = 10;
int MS2 = 11;
char command;
char doit[2];
char dost[4];
int stepperPin;
int dirPin;
char dir;
int steps;

void setup() {
  pinMode(dirPinY, OUTPUT);
  pinMode(stepperPinY, OUTPUT);
  pinMode(dirPinZ, OUTPUT);
  pinMode(stepperPinZ, OUTPUT);
  pinMode(sleepPin, OUTPUT);
  pinMode(MS1, OUTPUT);   // set pin 13 to output
  pinMode(MS2, OUTPUT);   // set pin 9 to output
  Serial.begin(9600);
 
  digitalWrite(sleepPin, LOW);
 
  digitalWrite(MS1, 1);  // step mode 1/2 // Set state of MS1 based on the returned value from the MS1_MODE() switch statement.
  digitalWrite(MS2, 1);
}

void step(int dirPin,int stepperPin,boolean dir,int steps){
  digitalWrite(dirPin,dir);
  delay(50);
  for(int i=0;i<steps;i++){
    digitalWrite(stepperPin, HIGH);
    delayMicroseconds(1500);
    digitalWrite(stepperPin, LOW);
    delayMicroseconds(1500);
  }
}

void loop(){
 
  // String "mx10100"
  //         m ... "move"
  //         s ... "start"
  //         x ... "stop" 
  //          x ... x-Axis
  //          y ... y-Axis
  //           1 ... turn cw
  //           0 ... turn ccw
  //            0100 ... make 100 Microsteps
 
  if(Serial.available() > 0){
    command = char(Serial.read());
   
    if( command == 's') {
      digitalWrite(sleepPin, HIGH);
    }
   
    if( command == 'x') {
      digitalWrite(sleepPin, LOW);
    }
   
    if(command == 'm'){
      for (int i = 0; i < 2; i++)  {
        command = char(Serial.read());
        doit[i] = command;     
      }
      for (int i = 0; i < 4; i++)  {
        command = char(Serial.read());
        dost[i] = command;     
      }
     
      if (doit[0] == 'y') {
        stepperPin = stepperPinY;
        dirPin = dirPinY;
      }
      else {
        stepperPin = stepperPinZ;
        dirPin = dirPinZ;
      }
     
      if (doit[1] == '1') {
        dir = true;
      }
      else {
        dir = false;
      }
     
      steps = atoi(dost);
     
      step(dirPin,stepperPin,dir,steps);
    }
 
  }

}


Unfortunately if have no idea how to talk to the Range Finder. Any ideas?

_________________
Bernhard
www.virtumake.com


Top
 Profile Send private message  
 
PostPosted: Sun May 19, 2013 6:38 pm 
Offline
Site Admin
User avatar

Joined: Fri Mar 22, 2013 3:30 pm
Posts: 349
Location: Ausria
Little demo of the software so far:



The only missing part is the connection to the LR4 board from Procupine electronics. Please help me, if you know something about Python and talking to an USB device :)

_________________
Bernhard
www.virtumake.com


Top
 Profile Send private message  
 
PostPosted: Sun May 19, 2013 8:17 pm 
Offline

Joined: Mon May 06, 2013 12:28 pm
Posts: 22
You are very productive Bernhard ! It's incredible !


Top
 Profile Send private message  
 
PostPosted: Sun May 19, 2013 8:25 pm 
Offline
Site Admin
User avatar

Joined: Fri Mar 22, 2013 3:30 pm
Posts: 349
Location: Ausria
Next milestone: vacation with my family ;)

_________________
Bernhard
www.virtumake.com


Top
 Profile Send private message  
 
PostPosted: Thu Oct 31, 2013 8:30 pm 
Offline

Joined: Tue Oct 15, 2013 5:49 pm
Posts: 1
virtumake,

I am doing DIY LIDAR 3D scanner for my school project.
We are gonna get 3D image from DIY LIDAR 3D scanner and display in Oculus Rift.
How did you get the data from LR4 board?
could you give me some tips? :)


Top
 Profile Send private message  
 
PostPosted: Sun Nov 03, 2013 5:51 am 
Offline
Site Admin
User avatar

Joined: Fri Mar 22, 2013 3:30 pm
Posts: 349
Location: Ausria
Hi! The LR4 software has the option to copy and paste the last measuremet to any application. I tested it with the notepad.
Then the values from the notepad are imported to Meshlab to show the pointcloud.

_________________
Bernhard
www.virtumake.com


Top
 Profile Send private message  
 
PostPosted: Thu Mar 27, 2014 6:33 am 
Offline

Joined: Mon Mar 10, 2014 6:42 am
Posts: 2
kyungjae wrote:
virtumake,

I am doing DIY LIDAR
3D scanner for my school project.
We are gonna get 3D
image from DIY LIDAR 3D scanner and display in Oculus Rift.
How did you get the data from LR4 board?
could you give me some tips?
:)



3D scanner can be used to analyze a real-world object or environment to collect data on its shape and possibly its appearance.


Top
 Profile Send private message  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group