Lego Scanner

Post your NXJ projects, project ideas, etc here!

Moderators: imaqine, 99jonathan, roger

cmk20
New User
Posts: 3
Joined: Sun Jul 03, 2016 5:12 pm

Lego Scanner

Postby cmk20 » Sun Jul 03, 2016 5:52 pm

I've been working on a lego mindstorms nxt scanner heres a picture of the setup

Image

Here is a picture that it scanned (This is not the same as the set up shown above only the red/blue/white paper, the yellow strip and the purple pokadot thing are in it.)

Image

Here is the nxt code

Code: Select all

import java.io.DataOutputStream;
import java.io.IOException;

import lejos.nxt.ColorSensor;
import lejos.nxt.ColorSensor.Color;
import lejos.nxt.LCD;
import lejos.nxt.Motor;
import lejos.nxt.SensorPort;
import lejos.nxt.TouchSensor;
import lejos.nxt.comm.Bluetooth;
import lejos.nxt.comm.NXTConnection;

public class Scanner extends Thread {
   static TouchSensor mreset = new TouchSensor(SensorPort.S1);
   static ColorSensor color = new ColorSensor(SensorPort.S3);
   static int HightLimit = 870;
   static int LengthLimit = 500;
   static int MovementDiffrence = 0;
   static int CurrentMovement = 0;
   static int OldMovement = 0;
   static String OutString = "";
   static boolean start = false;
   static boolean exit = false;
   public static NXTConnection connection;
   public static DataOutputStream dataOut;
   public void run() {
      String temp = "";
      LCD.drawString("waiting for BT", 0,1 );
       connection = Bluetooth.waitForConnection();
       DataOutputStream dataOut = connection.openDataOutputStream();
       LCD.clear();
       start = true;
      while(!exit) {
         while(!OutString.isEmpty()) {
            temp = OutString;
            OutString = "";
            try {
               dataOut.writeUTF(temp);
               dataOut.flush();
            } catch (IOException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
            }
         }
      }
   }
   public static void main(String[] args) throws InterruptedException {
      Motor.C.setSpeed(75);
      //Motor.A.rotate(HightLimit,true);
      //Motor.B.rotate(HightLimit);
      Reset();
      //Motor.C.rotate(LengthLimit);
      (new Scanner()).start();
      while(start != true) {
         //Wait For Bt
      }
      for(int y=1; y<HightLimit + 1; y+=2) {
         Motor.C.resetTachoCount();
         for(int x=1; x<LengthLimit + 1; x+=2) {
            Motor.C.forward();
            CurrentMovement = Motor.C.getTachoCount();
            while(CurrentMovement - OldMovement <= 1) {
               CurrentMovement = Motor.C.getTachoCount();
            }
            OldMovement = CurrentMovement;
            Color c = color.getColor();
            OutString = OutString + Integer.toString(x) + "," + Integer.toString(y) + "," + Integer.toString(c.getRed()) + "," + Integer.toString(c.getGreen()) + "," + Integer.toString(c.getBlue()) + "\r\n";
         }
         OldMovement = 0;
         Motor.C.flt();
         Motor.A.rotate(2,true);
         Motor.B.rotate(2,true);
         Reset();
         }
      OutString = OutString + "f";
      Motor.A.rotate(-HightLimit,true);
      Motor.B.rotate(-HightLimit);
      exit = true;
   }
   public static void Reset() throws InterruptedException {
      Motor.C.setSpeed(600);
      Motor.C.backward();
      while(!mreset.isPressed()) {
         //Wait
      }
      Motor.C.stop();
      Motor.C.setSpeed(75);
   }

}


Then here is the pc code that receives the data then writes it to a file

Code: Select all

import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileWriter;
import java.io.IOException;

import lejos.pc.comm.NXTCommLogListener;
import lejos.pc.comm.NXTConnector;

public class ScannerReceive {
   public static BufferedWriter out;
   public static FileWriter fstream;
   public static void main(String[] args) {
      String fname = System.currentTimeMillis() + " Pic.csv";
      String s = "";
      try {
         fstream = new FileWriter(fname);
      } catch (IOException e1) {
         // TODO Auto-generated catch block
         e1.printStackTrace();
      }
      BufferedWriter out = new BufferedWriter(fstream);
      NXTConnector conn = new NXTConnector();
      
      conn.addLogListener(new NXTCommLogListener(){

         public void logEvent(String message) {
            System.out.println("BTSend Log.listener: "+message);
            
         }

         public void logEvent(Throwable throwable) {
            System.out.println("BTSend Log.listener - stack trace: ");
             throwable.printStackTrace();
            
         }
         
      }
      );
      // Connect to any NXT over Bluetooth
      boolean connected = conn.connectTo("btspp://");
   
      
      if (!connected) {
         System.err.println("Failed to connect to any NXT");
         System.exit(1);
      }
      DataInputStream dis = new DataInputStream(conn.getInputStream());
      try {
         while(true) {
            while(dis.available() == 0) {
               
               try {
               s = dis.readUTF();
               if (s.contains("f")) {
                  s = s.replaceAll("f", "");
                  out.write(s);
                  out.close();
                  System.out.println(fname);
                  System.exit(0);
               }
               else {
                  out.write(s);
                  System.out.print(s);
               }
               } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
               }
               out.flush();
            }
            
         }
      } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }
}


Lastly there it some python 3.5 code that turns the csv file into a picture using the pillow image library

Code: Select all

from PIL import Image, ImageDraw
import csv

out = Image.new("RGB",(250,435))
dout = ImageDraw.Draw(out)
import csv
with open('pic.csv', 'r') as f:
    reader = csv.reader(f)
    for row in reader:
        dout.point((int(row[0]) / 2,int(row[1]) / 2),fill=(int(row[2]),int(row[3]),int(row[4])))
        #print(row[0] + " " + row[1] + " " + row[2])
out.show()


The scanner works however I have a few questions

1: The scanner is very slow it takes 1 hour to scan... how can I make it faster without sacrificing quality? (The main bottleneck for this is reading the color sensor)
2: I'm trying to read the raw rgb data from the color sensor am I doing this correctly?
3: The pictures are quite fuzzy i'm assuming this is a limitation on the color sensor itself
4: Would buying the Hitechnic color sensor v2 be a good idea for this project and would it solve any of the above problems?

If you have any questions about the project please ask :)

-Cmk20

User avatar
gloomyandy
leJOS Team Member
Posts: 5914
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Lego Scanner

Postby gloomyandy » Sun Jul 03, 2016 6:23 pm

The basic resolution is probably limited by the area scanned by the sensor. One option that might improve that would be to repeat the scan with a small offset (1 degree) and combine the two scans. You might also be able to sample the colour sensor more often and average the results? But I suspect you might be pushing the mechanical setup a little. A further option would be to use two (or more) colour sensors one offset a little and combine the readings.

It may also be limited by the mechanical accuracy which could perhaps be limiting things is the mechanical accuracy. One way to improve this would be to create a "track" and use a cog wheel to run on it (basically a rack and pinion system). You may need a lot of the "rack" parts though. If you do this you may be able to run things at a faster speed but still retain the accuracy. Another possibility to improve the speed could be to scan in both directions of the sensor movement (rather than resetting each time), that way you might save the reset time. the rack and pinion track might make this option more feasible.

I don't think that using a Hitechnic color sensor would really help, that uses an i2c interface and I think the rate that you can read it will be slower than using the LEGO sensor.

Interesting project. Have fun trying to improve it!
leJOS news https://lejosnews.wordpress.com/

cmk20
New User
Posts: 3
Joined: Sun Jul 03, 2016 5:12 pm

Re: Lego Scanner

Postby cmk20 » Sun Jul 03, 2016 6:39 pm

gloomyandy wrote:The basic resolution is probably limited by the area scanned by the sensor. One option that might improve that would be to repeat the scan with a small offset (1 degree) and combine the two scans. You might also be able to sample the colour sensor more often and average the results? But I suspect you might be pushing the mechanical setup a little. A further option would be to use two (or more) colour sensors one offset a little and combine the readings.

It may also be limited by the mechanical accuracy which could perhaps be limiting things is the mechanical accuracy. One way to improve this would be to create a "track" and use a cog wheel to run on it (basically a rack and pinion system). You may need a lot of the "rack" parts though. If you do this you may be able to run things at a faster speed but still retain the accuracy. Another possibility to improve the speed could be to scan in both directions of the sensor movement (rather than resetting each time), that way you might save the reset time. the rack and pinion track might make this option more feasible.

I don't think that using a Hitechnic color sensor would really help, that uses an i2c interface and I think the rate that you can read it will be slower than using the LEGO sensor.

Interesting project. Have fun trying to improve it!


Thanks for the ideas I would try the rack and pinion setup however I don't have any of the rack parts and i'm not sure were to get them... my idea as to why the image is fuzzy is that the color sensor has a large viewing area and is rescanning past areas this is why I was debating the Hitechnic sensor as it may have a smaller viewing area...

cmk20
New User
Posts: 3
Joined: Sun Jul 03, 2016 5:12 pm

Re: Lego Scanner

Postby cmk20 » Thu Jul 07, 2016 5:39 pm

Project Update:

I added a small piece of coffee over the color sensors led light limiting it's spread it increased the sharpness of the pictures dramatically.

GarryDan
New User
Posts: 1
Joined: Sat Nov 25, 2017 10:49 am

Re: Lego Scanner

Postby GarryDan » Mon Dec 04, 2017 3:40 pm

That's quinte clever, Cmk20. Such an interesting project. Do you have any current updates to share?


Return to “NXJ Projects”

Who is online

Users browsing this forum: No registered users and 3 guests