Jump to content





X-Y Plotter Table For The TI 99/4A Computer - Updated 8/2/18

Posted by Vorticon, 25 May 2018 · 308 views

So I've been mulling the idea of creating an X-Y table for my TI computer, which could be used to draw a bitmap image or perhaps do some laser engraving. I searched the web for inspiration and found this ingenious video by HomoFaciens where he uses the stepper platform that moves the laser head in optical drives to create a very effective but small X-Y plotter.
 

 
So I went ahead an found a couple of used DVD-ROM drives on Ebay and ripped them apart, only to find that only one of them had a stepper motor assembly. According to HomoFaciens, only about 50% of the optical drives actually use stepper motors. Nonetheless, I figured I could start by experimenting in controlling the stepper platform with the TI's parallel (PIO) port. Below is the actual stepper motor assembly from one of the drives:
 
Attached Image
 
The stepper motor in this assembly is a 4 wire stepper motor, which means it has 2 coils with each pair of wires going to one coil. It's easy to identify each pair by simply doing a continuity test on the wires using a multimeter. To move the motor in one direction, one of the coil has to cycle it's polarity repeatedly between positive and negative while the other coil is idle. To reverse the motion, simply repeat the process using the second coil.
In order to be able to control the polarity on the coil, one could use relay circuits like the one on my robotic arm controller, or more commonly use an H-bridge circuit as below:
 
Attached Image
 
Based on the input to the 4 input points on the circuit marked A, B, C and D, the polarity can be switched at will. The table below shows how to do this. 
 
Attached Image
 
Given that we have 2 coils in the stepper motor, we obviously will need 2 H-bridges to control it, one for each coil. While you can purchase ready made stepper motor controllers on most hobbyist sites, it's really pretty simple to build for just pennies, so I went ahead and breadboarded a couple of H-bridges for test purposes.
 
Attached Image
 
As for the connection to the TI, I decided to allocate one data pin on the PIO port to each input port on the H-bridges, which means that all the data pins will be used (Eight). This is problematic because the X-Y table will need 2 stepper motors at a minimum, one for the X axis and one for the Y axis, and I obviously will not have enough data pins for that. The solution is going to involve some kind of multiplexing, but we'll come back to that. For now let's make sure this thing actually works!
 
Here's the connection layout:
 
Coil 1: 
A --> D7
B --> D6
C --> D5
D --> D4
 
Coil 2:
A --> D3
B --> D2
C --> D1
D --> D0
 
So in order to control the coils, I just need to send the appropriate byte pattern to the PIO port. For example, in order to run the stepper motor forward, coil 1 needs to have a bit pattern of 1100 corresponding to the DCAB H-bridge inputs, and coil 2 needs to be inactive, which translates to a bit pattern of 1010 (refer to the table above). Putting it all together we get:
 

   Coil 2           Coil 1
D   C   B   A    D   C   B   A
D0  D1  D2  D3   D4  D5  D6  D7
1   0   1   0    1   1   0   0
 
Converting this 8-bit binary number to decimal we get 172, which we can send to the PIO port via the CALL LOAD command in Rich Extended Basic. Then we reverse the polarity of coil 1 while keeping coil 2 inactive to keep the stepper motor moving forward and so on and so forth.
Here's the control program on the TI. I opted to use Rich Extended Basic for its ease of use and unique ability to allow low-level access to hardware. Below is the test program listing:
10 CALL CLEAR
20 CRU=2432 ! RS232 CARD CRU ADDRESS IS >1300 (4864). RXB USES CRU/2
30 CALL IO(3,1,CRU,1) ! ACTIVATE THE RS232 CARD
40 CALL IO(3,1,CRU+7,1) ! TURN ON THE LED ON THE CARD
50 CALL IO(3,1,CRU+1,0) ! SET THE PIO PORT TO OUTPUT
60 FOR I=1 TO 30 ! 30 FORWARD STEPS
70 CALL LOAD(20480,172) ! COIL 1 POSITIVE POLARITY - COIL 2 INACTIVE -- PIO ADDRESS IS 20480
80 GOSUB 500 ! DELAY TO SLOW DOWN THE MOVEMENT
90 CALL LOAD(20480,163) ! COIL 1 NEGATIVE POLARITY - COIL 2 INACTIVE
100 GOSUB 500
110 NEXT I 
120 FOR I=1 TO 30 ! 30 REVERSE STEPS
130 CALL LOAD(20480,202) ! COIL 1 INACTIVE - COIL 2 POSITIVE POLARITY
140 GOSUB 500
150 CALL LOAD(20480,58) ! COIL 1 INACTIVE - COIL 2 NEGATIVE POLARITY
160 GOSUB 500
170 NEXT I
180 GOTO 60 ! REPEAT THE ENTIRE PROCESS
500 FOR D=1 TO 200::NEXT D::RETURN
And here's what it looks like in action:
 

 
So while it works in principle, as I mentioned in the video there are several issues to contend with if we are to use the DVD-ROM assemblies:
 
  • The quality of the worm gear assembly is highly variable. Mine was pretty bad...
  • The weight that could be supported by the carrier is tiny on my drive assembly, so it will not be able to hold a second assembly on top for the Y axis.
  • The usable draw area is very small, 40x40 steps on my drive assembly, so not very practical.
I don't know how many optical drives HomoFaciens had to go through before he got the high quality ones he demonstrated, but I'm not terribly inclined to go that route. This of course means that I will have to build my own table. 
 
UPDATE 6/10/18
 
Pack007 suggested using a 74HC595 8-bit serial shift register chip for multiplexing to PIO data lines, and it worked extremely well. That chip basically takes in an 8 bit number serially one bit at a time starting with the LSB and outputs that number in parallel using 8 output lines. In addition it has an Output Enable pin which places the parallel output pins in a high impedance state when high, effectively inactivating the chip. The control sequence will go like this:
  • Make the LATCH pin (12) low to isolate the serial input from the output
  • Activate the chip by making the OE pin (13) low
  • Present 1 bit to the DATA pin (14) and cycle the CLOCK pin (11)
  • Go back to 3 until all 8 bits are in
  • Cycle the LATCH pin (12) to present the number to the output pins
  • Go back to 1 for the next number
The output 8-bit number will be coded per the coil sequence discussed earlier and connected to the H-bridges accordingly for the stepper motor. Here's the circuit diagram for a single motor:
 
 Attached Image
PIO Connections:

D7 (2) --> DATA
D6 (3) --> OE for motor 1
D5 (4) --> OE for motor 2
D4 (5) --> OE for motor 3
HSKOUT (1) --> CLOCK
SPROUT (14) --> LATCH

 
Now we will need 3 stepper motors for the plotter: X, Y and Pen. The way this will work is that each motor will have 2 H-bridges connected to a separate 74HC595 chip. These 3 chips will share the LATCH, CLOCK and DATA pins connections but will each have their own OE pin connections. That way, the computer will be able to select the desired motor by simply making the corresponding OE line low and the other 2 OE lines high. All in all, only 6 output lines from the PIO port will be needed instead of the 24 lines required without multiplexing. Problem solved! This leaves me with several lines that could be used to detect axis end of travel through the use of micro-switches.
 
And here's the RXB test code. It's definitely a slower process than the previous direct parallel method, but it's the price to pay for multiplexing. This is fine for testing, but I might have to switch to assembly for the final control program in order to speed things up. We'll see...
10 CALL CLEAR
11 OE1=12 ! BIT PATTERN TO ISOLATE MOTOR 1
14 DIM FWD(16),REV(16),OFF(8)
15 CRU=2432 ! CRU BASE OF RS232 CARD DIVIDED BY 2
20 CALL IO(3,1,CRU,1) ! ACTIVATE RS232 CARD
30 CALL IO(3,1 CRU+7,1) ! TURN LED ON
40 CALL IO(3,1,CRU+1,0) ! SET PIO TO OUTPUT
50 FOR I=0 TO 15::READ FWD(I)::NEXT I ! READ FORWARD CONTROL SEQUENCE
60 FOR I=0 TO 15::READ REV(I)::NEXT I ! READ REVERSE CONTROL SEQUENCE
70 FOR I=0 TO 8::READ OFF(I)::NEXT I ! READ IDLE CONTROL SEQUENCE
80 REM MOTOR 1 MOVE FORWARD
90 CALL IO(3,1,CRU+3,0) ! MAKE LATCH PIN LOW
100 CALL LOAD(20480,OE1) ! ISOLATE MOTOR 1
110 FOR I=1 TO 30 ! 30 FORWARD STEPS
120 FOR N=0 TO 15 ! FORWARD BIT SEQUENCE IS 2 8-BIT NUMBERS LONG (16 BITS)
121 REM THE LINE BELOW SENDS A SINGLE BIT OUT THE PIO LSB (D7) PIN 
122 REM IF THE BIT IS 1, IT IS ADDED TO THE OE1 BIT PATTERN (D6-D4)
123 REM OTHERWISE ONLY OE1 IS SENT AND D7 REMAINS 0
130 IF FWD(N)=1 THEN CALL LOAD(20480,OE1+1) ELSE CALL LOAD(20480,OE1) 
140 CALL IO(3,1,CRU+2,1)::CALL IO(3,1,CRU+2,0) ! CYCLE THE CLOCK PIN
141 REM THE LINE BELOW PRESENTS THE 8-BIT NUMBER TO OUTPUT
150 IF N=7 OR N=15 THEN CALL IO(3,1,CRU+3,1)::CALL IO(3,1,CRU+3,0) ! CYCLE THE LATCH PIN
160 NEXT N
170 NEXT I 
180 REM MOTOR 1 REVERSE MOVE
190 FOR I=1 TO 30 ! 30 REVERSE STEPS
200 FOR N=0 TO 15 ! REVERSE BIT SEQUENCE IS 2 8-BIT NUMBERS LONG (16 BITS)
201 REM THE LINE BELOW SENDS A SINGLE BIT OUT THE PIO LSB (D7) PIN 
202 REM IF THE BIT IS 1, IT IS ADDED TO THE OE1 BIT PATTERN (D6-D4)
203 REM OTHERWISE ONLY OE1 IS SENT AND D7 REMAINS 0
210 IF REV(N)=1 THEN CALL LOAD(20480,OE1+1) ELSE CALL LOAD(20480,OE1) 
220 CALL IO(3,1,CRU+2,1)::CALL IO(3,1,CRU+2,0) ! CYCLE THE CLOCK PIN
221 REM THE LINE BELOW PRESENTS THE 8-BIT NUMBER TO OUTPUT
230 IF N=7 OR N=15 THEN CALL IO(3,1,CRU+3,1)::CALL IO(3,1,CRU+3,0) ! CYCLE THE LATCH PIN
240 NEXT N
250 NEXT I
260 GOTO 110 ! REPEAT THE PROCESS
500 REM MOTOR ACTIVATION SEQUENCES
510 REM FORWARD
520 DATA 0,0,1,1,0,1,0,1,1,1,0,0,0,1,0,1
530 REM REVERSE
540 DATA 0,1,0,1,0,0,1,1,0,1,0,1,1,1,0,0
550 REM IDLE
560 DATA 0,1,0,1,0,1,0,1
It is likely I will need to use more beefy transistors for the H-bridges because the current needed by the stepper motors in the final design will be hefty. However, the basic circuit design will remain the same.
 
Next I'm going to focus on the mechanical assembly.
 
Update 6/14/18
 
Soooo, to be perfectly honest I have not been too happy with the performance of the stepper motor extracted from the optical drive. The torque was way too low and the steps were far too large and I had the nagging suspicion I was doing something wrong, and indeed I was!
After further research, it turned out that my step control sequence was incomplete, and I was essentially skipping every other step. The correct sequence for a bipolar 4-wire stepper motor like the one I have turned to be as below:
 
Attached Image
 
A and B represent the 2 coils in the motor. To reverse the rotation, simply swap the sequences of A and B. And sure enough when I applied that sequence the torque increased dramatically because both coils were always energized at any one time and the steps were much smaller and smoother. Live and learn :)
 
Furthermore, after taking a closer look at the H-bridge circuit I had used and comparing it to other circuits out there, I realized that there was no need to use a mix of NPN and PNP transistors, and that just NPN ones will do the trick, as well as only require 2 input pins for control instead of 4 per H-bridge! And that meant that now I could control 2 stepper motors using only one 74HC595 chip instead of 2 chips! Here's the updated circuit for a single motor:
 
Attached Image
 
The new PIO connections become:
PIO Connections:

D7 (2) --> DATA
D6 (3) --> OE for motor 1 & 2
D5 (4) --> OE for motor 3
HSKOUT (1) --> CLOCK
SPROUT (14) --> LATCH 
 And the control sequence for the steps will be as below, with A and B this time representing each H-bridge input:
   COIL 2        COIL 1
  A      B      A      B
  ----------------------

  1      0      1      0  FORWARD
  0      1      1      0
  0      1      0      1
  1      0      0      1


  1      0      1      0  REVERSE
  1      0      0      1
  0      1      0      1
  0      1      1      0
Amended RXB control test program. Notice that the trailing 4 zero bits of each byte in the control sequences are reserved for the future control of the seconds stepper motor.
10 CALL CLEAR
20 OE1=4 ! ISOLATE MOTORS 1 & 2
30 OE2=2 ! ISOLATE MOTOR 3
40 DIM FWD(32),REV(32)
50 CRU=2432 ! BASE RS232 / 2
60 CALL IO(3,1,CRU,1) ! ACTIVATE RS232 CARD
70 CALL IO(3,1,CRU+7,1) ! TURN LED ON
80 CALL IO(3,1,CRU+1,0) ! SET PIO TO OUTPUT
90 FOR I=1 TO 31::READ FWD(I)::NEXT I
100 FOR I=1 TO 31::READ REV(I)::NEXT I
110 REM FORWARD STEPS
120 CALL IO(3,1,CRU+3,1) ! MAKE LATCH LOW
130 CALL LOAD(20480,OE1) ! ISOLATE MOTORS 1 & 2
140 FOR I=1 TO 5 
150 FOR N=0 TO 31
155 REM LINE BELOW SENDS DATA BIT BY BIT VIA D7 PIN ON PIO PORT
160 IF FWD(I)=1 THEN CALL LOAD(20480,OE1+1) ELSE CALL LOAD(20480,OE1)
170 CALL IO(3,1,CRU+2,1)::CALL IO(3,1,CRU+2,0) ! PULSE CLOCK
180 IF N=7 OR N=15 OR N=23 OR N=31 THEN CALL IO(3,1,CRU+3,1)::CALL IO(3,1,CRU+3,0) ! CYCLE LATCH
190 NEXT N
200 NEXT I
210 REM REVERSE STEPS
220 FOR I=1 TO 5
230 FOR N=0 TO 31
240 IF REV(N)=1 THEN CALL LOAD(20480,OE1+1) ELSE CALL LOAD(20480,OE1)
250 CALL IO(3,1,CRU+2,1)::CALL IO(3,1,CRU+2,0) ! PULSE CLOCK
260 IF N=7 OR N=15 OR N=23 OR N=31 THEN CALL IO(3,1,CRU+3,1)::CALL IO(3,1,CRU+3,0) ! CYCLE LATCH
270 NEXT N
280 NEXT I
290 GOTO 140
500 REM MOTOR ACTIVATION SEQUENCES
510 REM FORWARD
520 DATA 1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0
530 REM BACKWARD
540 DATA 1,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,1,0,0,0,0,0
And here's the whole thing in action:
 

 
OK now I can focus on the mechanical assembly :)
 
Update 6/17/18
 
Quick update here: I re-wrote the stepper motor control program in assembly (quick and dirty draft) and the speed difference was remarkable as seen in the video below. I actually could drive the motor much faster than this, but it would likely damage it... And here's where the usefulness of RXB really comes through: it's super efficient to use for rapid prototyping and validation of design ideas because of the ease of editing and running, and once everything is working properly then porting to assembly, if needed for speed, can be done in a fairly straightforward manner.
 

 
Update 6/30/18
 
The mechanical assembly of the X-Y Plotter is now completed. I eventually settled down on an overlapping table design because I felt it would be a bit more compact.
I started by getting my hands on a couple of cheap rod sets on Amazon along with 2 of the ubiquitous Nema 17 4-wire bipolar stepper motors.
 
Attached Image
 
Attached Image
 
Unfortunately, I suppose you get what you pay for, and the rod sets were not well matched at all, with the threaded rod supports being shorter than the sliding rod ones, and thus required a bunch of risers in order to even things out. Furthermore, the threaded rods came with an odd circular nut rather than a flat sided one, making the attachment of a platform to the nut much more of a pain than it had to be. Essentially I had to carve out slots under each platform into which the nut was inserted and glued. The platforms were cut from 5mm thick birch plywood which is pretty stiff.
 
Attached Image
 
One issue I noted was that the second level platform tended to sag a little bit when the pen holder platform was all the way to the end, and the whole assembly tended to tip as well. The solution was a simple free coasting wheel on the edge of the second platform for support. For the pen up/down function, I chose to use the stepper motor assembly I had pulled out from the old DVD-ROM drive which I have shown earlier since little torque was going to be needed for that function. I created a simple pen bracket with a set screw which I glued to the lens assembly along with a couple of support brackets.
Time to put the 3D printer to good use!
 
Attached Image
 
Attached Image
 
And here's the final product. 
 
Attached Image
 
Attached Image
 
Attached Image
 
Attached Image
 
Finally I added limit switches to the X and Y axes as well as the pen control assembly so that I could initialize the plotter to the origin before each print.
 
Attached Image
 
Attached Image
 
Overall I'm pretty happy with the end result. Next step is finalizing the control circuitry for the Nema 17 motors. These draw a lot of current and cannot be driven by the test circuit I demonstrated earlier. 
 
Update 8/1/18
I did some testing to figure out how to properly power and control the Nema 17 stepper motors as seen below. Several components' leads did not fit in the breadboard holes, so I ended up with a huge wire mess... The good news is that is miraculously worked! I opted to reduce the component count by using the L298 H-bridge controller, one for each of the stepper motors.
 
Attached Image
 
Attached Image
 
From there, I designed a complete control circuit schematic and a double-sided PCB layout. It's not a professional design, but it's the best I could do with my limited skill set:
 
Attached Image
 
Attached Image
 
The 4 pads at the corners are needed for later alignment.
 
Next is the actual PCB build...
 
Update 8/2/18
 
Printed the layout on transparency sheets using my laser printer. Two copies per PCB side in order to maximize the tracings opacity.
Attached Image
 
Exposure of a double-sided pre-sensitized PCB for 8 minutes under a fluorescent light. I cannot stress enough the need to use a high quality PCB here. I have had very good luck with MG Chemicals. The cheap Chinese stuff is terrible as I painfully discovered from past experience. Aligning the top and bottom layers was fussy work. I marked and drilled into the PCB the 4 corner pads and used pins to go through the top transparency, the PCB itself, and the bottom transparency and I got near-perfect alignment that way. Only 2 pins were really needed.
Attached Image
 
And here's the exposed and developed PCB
Attached Image Attached Image
 
Next I etched the board, and I have to say it turned out overall pretty nice. It is super important at this point to test each trace for continuity and bridges as well for the possibility of a short. I found 3 trace breaks and couple of bridges that way. It is so much easier to fix the issues at this stage rather than try to debug the board once it is fully populated.
Attached Image Attached Image
 
Finally I drilled the pads. i start with a very small drill bit and test fit all the components, drilling progressively larger holes as needed. Again this needs to be done before you do any soldering for component!
Attached Image Attached Image  
 
This was probably the largest double-sided PCB I have ever built! In case you are wondering whether it was worth the effort, it's really more of a philosophy than an economic question. I personally enjoy the challenge of designing and building my projects from scratch as much as possible, although I would definitely get far more professional results had I farmed them out to a PCB fabrication house and it would likely have been cheaper too...
 
I'm going to defer the actual soldering and final testing until I get back from vacation at the end of the month. I need a break anyway :)
 
 
 






You may want to look at 3-D printer designs, you may be able to adapt them.  Check out RepRap HELIOS and some other of Nicholas Seward's designs for something more than XYZ boxes.

 

Plotters were a must have for doing color charts until inkjet printers.  I remember using both a flatbed plotter and a giant roller plotter.  Nowdays I have a color laser printer.

  • Report

You may want to look at 3-D printer designs, you may be able to adapt them.  Check out RepRap HELIOS and some other of Nicholas Seward's designs for something more than XYZ boxes.

 

Plotters were a must have for doing color charts until inkjet printers.  I remember using both a flatbed plotter and a giant roller plotter.  Nowdays I have a color laser printer.

 

Very cool design, but likely a bit more involved than what I had in mind for this project. I was able to secure a couple of inexpensive sets of rods and sliders which I should be able to adapt fairly easily for my purposes. Details to come.

  • Report
I played around with a couple of 28BYJ - 5V Stepper Motors on an Arduino and was going to try and hook 2 up to the Atari joystick ports. I found that I ran out of data pins rather quickly. I was able to use a 74HC595 - 8-bit shift register with output latches(A.K.A serial to parallel converter). I could control the coil sequence for two stepper motors with 3 bits; Data, Clock, and Latch. You might be able to use one of the extra bits can be used for pen up and pen down. Just a thought.
  • Report

I played around with a couple of 28BYJ - 5V Stepper Motors on an Arduino and was going to try and hook 2 up to the Atari joystick ports. I found that I ran out of data pins rather quickly. I was able to use a 74HC595 - 8-bit shift register with output latches(A.K.A serial to parallel converter). I could control the coil sequence for two stepper motors with 3 bits; Data, Clock, and Latch. You might be able to use one of the extra bits can be used for pen up and pen down. Just a thought.


Yes running out of data pins is one of the issues I ran into. I'm definitely going to look into the specs of that chip and see what I can do with it. Thanks for the tip!
  • Report