The purpose of the experiment is to identify an object by detecting it's thickness. This is done with the help of an implemented touch sensor round the arm gripper opening which is connected to the parallel port of the computer. The thickness of each object is obtained by the different degree of turns of the servo controlling the gripper open/close. This is a number that varies from 0-254. This is not possible without an understanding of how the parallel and the serial port communicate with the hardware and also with the program.
In our study for the ports, we have faced two kinds of ports that are commonly used in all computers PCs
CPU Data Serial [bps] [baud] Phone
Bus ------ bytes ----> Port ------ bits --> Modem -- tones --> line--
CPU Data Serial
Bus <----- bytes----- Port <---- bits ------ Modem <---- tones ---------
The serial port connector has two specific shapes:
PCs have 9 pin/25 pin male SUB-D connectors.
Moreover, the serial port always has low speed in communication because the bits are sent one at a time. That is why we usually use the serial port to connect partly slow devices such as the modem (Note: the modem is a slow device because the data received at slow rates from the Network).
As for the transmission signal, this takes the form of high and low or 1 and 0. The following drawn signal represents a model for a signal send via the serial port.
The signal:
High = 1 Low = 0
Parallel Port
: 0-9 Output lines for the parallel port i.e Computer write
: 10-14 Input lines for the parallel port i.e Read
: 18-25 GND lines.
The robot's action is controlled by a series of 6 servos
0- Base rotation servo
1- Shoulder servo 1
2- Shoulder servo 2
3- Gripper open/close servo
4- Arm servo
5- Gripper up/down movement servo
The servos are controlled using a mini servo controller (SSC) connected to the serial port at COM 2.
Thus the servo position and the particular servo can be set into action by software means using any programming language which in our particular case is Qbasic.
The implemented touch sensor which we used due to the fact that ready made touch sensors were not available was composed of two wires . One of the wires was connected to the ground of both the parallel port (pin 25 was used) and the voltage/current regulator. The other wire was connected to pin 10 (input line) of the parallel port. One of these two wires is connected to the right hand grip of the gripper while the other one is connected to the left side. We used the port carrying the address number of 379H to be used for reading the input from the parallel port. The touch sensor functionality was fulfilled by continuously reading the value of bit #10 on the parallel port. As long as it was reading a "one", this indicated that no object was touched and as soon as it turns to read a "zero", this will indicate that the gripper has taken hold of an object. The object that is targeted to be carried should be covered with a conducting material like paper foil. When both the left and right grips have touched the object, this will cause a conduction of current resulting in reading the zero.
After remotely checking that the touch sensor could actually detect the object by reading it's value from the port (If it touched an object this value changed from 1 to 0) and checking that the servos operated optimally it was now left to integrate this aspect in Qbasic so as to coordinate the action of the robot . This was done using sub-routines coordinated by a label Main. The subroutines we came up with came about by placing ourselves in the place of the robot and imagining what we would do. The subroutines we used are:
Main is the governing subprocedure. It is in charge of coordinating the other subprocedures. This is especially necessary as we wanted the program to be structured and thus easier to understand and modify. The various subprocedures are entered into until the last object has been verified or the object was found at any of the predefined points.If the object was not found in any of the positions then the boolean variable Found will be false and this will prompt the program to say the object is not part of the items it had to detect.
This initializes the servos to their base positions which is 150 (the range is 0-254). It is also in charge of moving the base to a defined position. This is coordinated by initbasedisp and currbasedisp. Initially initbasedisp is zero, so is currbasedisp since it depends on objectnum and objectnum is zero.Then initbasedisp is assigned to currbasedisp. This is done after the base has rotated so that initbasedisp will always lag behind currbasedisp.This portion of the code will be entered into until the last predetermined position is reached.
This opens the mouth of the gripper using the servo.
This gets the command from the user such as to which object he wants the robot to pick. This is only entered into once when you run the program. After that the robot acts on its own.
This places the robot in the "object detect position". This is the position the robot assumes each time it is about to detect an object amongst those available.It compares this object thickness with that of the object expected by the user. If the values are comparable then access is given to subroutine successful else access is given to subroutine unsuccessful .
This subroutine is the heart of the detection mechanism. It has access to another subroutine called port. What Detect does is to decrement the gripper mouth while checking subroutine port to see if the value at the port is zero. If it is zero then the loop is terminated and the value of the degree turn in the servo is retained.
Decide compares the value detected within a range with the value of the object chosen by the user. If the values are comparable then access is given to subroutine successful else access is given to subroutine unsuccessful
If the object was found in one of the defined position that is if the port value is zero in one of the positions then this subprocedure is entered into. It raises the object and also sets the value of found to true.Then it ends the program.
If the object was not found in any of the defined positions then this subprocedure is entered into.It's main function is to increment objectnum as this is used by subprocedure initialization to move the base to the next position.
DEFINT A-Z sync.byte = 255 OPEN "com2:9600,n,8,1,cd0,cs0,ds0,op0" FOR OUTPUT AS #1 CLS PRINT PRINT : PRINT PRINT " press- break to end." objectnum = 0 ' object number initbasedisp = 0 ' initial base displacement found = false ' boolean variable MAIN: DO GOSUB GRIPPEROPEN GOSUB INITIALIZATION IF objectnum = 0 THEN GOSUB GETCOMMAND END IF GOSUB SERVOACTION GOSUB DELAYGRIPPER GOSUB DETECT GOSUB DECIDE LOOP UNTIL (objectnum = 6) OR (found) IF NOT found THEN PRINT object$, " Is not part of the items here"; GOSUB INITIALIZATION END IF END SYSTEM INITIALIZATION: FOR I% = 0 TO 5 STEP 1 'initialization of robot servos PRINT #1, CHR$(sync.byte); CHR$(I); CHR$(150); NEXT I% IF objectnum < 6 THEN currbasedisp = 50 * objectnum FOR J% = initbasedisp TO currbasedisp STEP 1 FOR K% = 1 TO 5 PRINT #1, CHR$(sync.byte); CHR$(0); CHR$(J%); 'Slow base action NEXT K% NEXT J% initbasedisp = currbasedisp END IF RETURN GRIPPEROPEN: PRINT #1, CHR$(sync.byte); CHR$(3); CHR$(253); RETURN GETCOMMAND: PRINT "Give the name of the object to pick : " INPUT object$ object$ = UCASE$(object$) RETURN SERVOACTION: FOR I% = 150 TO 100 STEP -1 'To smoothen motion PRINT #1, CHR$(sync.byte); CHR$(1); CHR$(I); NEXT I% FOR J% = 150 TO 50 STEP -1 'To smoothen motion PRINT #1, CHR$(sync.byte); CHR$(5); CHR$(J); NEXT J% RETURN DELAYGRIPPER: FOR W% = 1 TO 3000 STEP 1 FOR F% = 1 TO 800 STEP 1 NEXT F% NEXT W% RETURN DETECT: thickness% = 253 DO PRINT #1, CHR$(sync.byte); CHR$(3); CHR$(thickness%); thickness% = thickness% - 1 PRINT : PRINT GOSUB PORT PRINT y%; widthobj; thickness% 'used for beta testing LOOP UNTIL ((y% = 0) OR (thickness% = 1)) PRINT y%; widthobj; thickness% 'used for beta testing RETURN PORT: x% = INP(&H379) 'Read Parallel Port. y% = ((x% AND 64) / 64) 'Change Data Terminal Ready bit. RETURN DECIDE: SELECT CASE thickness% CASE 56 TO 86 IF object$ = "RUBBER" THEN GOSUB SUCCESS ELSE GOSUB UNSUCCESSFUL END IF CASE 24 TO 55 IF object$ = "CHOCOLATE" THEN GOSUB SUCCESS ELSE GOSUB UNSUCCESSFUL END IF CASE 2 TO 23 IF object$ = "STICK" THEN GOSUB SUCCESS ELSE GOSUB UNSUCCESSFUL END IF CASE 0 TO 1 GOSUB UNSUCCESSFUL END SELECT RETURN SUCCESS: PRINT #1, CHR$(sync.byte); CHR$(3); CHR$(0); ' strong hold FOR I% = 100 TO 150 STEP 1 FOR J% = 1 TO 3 PRINT #1, CHR$(sync.byte); CHR$(1); CHR$(I%); ' raise object NEXT J% NEXT I% 'PRINT #1, CHR$(sync.byte); CHR$(5); CHR$(150); ' relax position 'PRINT #1, CHR$(sync.byte); CHR$(1); CHR$(150); ' relax position PRINT "Yeah, This is the", object$; found = true END SYSTEM UNSUCCESSFUL: PRINT "WHOOPS, Thats a miss" objectnum = objectnum + 1 RETURN