TI-83 (and probably others too)

I've spent the better part of the last two days working on interfacing my Arduino with my (brother's, actually) TI-83 (plus, actually). I started by Googling to see if anyone else had done it and couldn't find anything (I can't imagine I'm the first, but hey, someone's got to be).

Using schematics for the home made serial cable I was able to figure out what the pins were supposed to do. When one gets pulled down it's a zero bit, when the other gets pulled down it's a one bit and I have to pull the opposite down to acknowledge receipt.

I wrote a short TI-Basic program to continuously send simple but changing data:

:While getKey=0
:Disp A

There's probably a better way to do it but it's just a test program...

And lo, I was able to get data out.

82 - C9 - B - 0 - 9 - 0 - 0 - 41 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 4A - 0 - 82 - C9 - ...

After noticing how often it repeated I was able to separate them into packets. I then realized that, even though the calculator was displaying an increasing number, the packets I was receiving weren't changing. I had to do more research.

After a long time of researching and fiddling I found a site with an incredibly complete description of the link protocol (had to realize I needed to be searching for "ti link protocol" and not "ti serial protocol").

Aha! So the reason it's not changing is because the calculator is asking if it can send stuff. (the second bit is the command). So I next had to figure out how to send it the ACK command, in addition to the CTS (clear to send) command. This was far more difficult than it turned out to be, I had the lines backwards.

Once I'd figured out how to send commands back I started receiving the actual data:

82 - C9 - B - 0 - 9 - 0 - 0 - 41 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 4A - 0 - 
Machine: 82, Command: C9, Data Size: 11 Bytes
82 - 56 - 0 - 0 - 
Machine: 82, Command: 56, Data Size: 0 Bytes
82 - 15 - 9 - 0 - 0 - 80 - 20 - 0 - 0 - 0 - 0 - 0 - 0 - A0 - 0 - 
Machine: 82, Command: 15, Data Size: 9 Bytes
Digits: 2.0000000000000E0
82 - 92 - 9 - 0 - 
Machine: 82, Command: 92, Data Size: 9 Bytes
82 - C9 - B - 0 - 9 - 0 - 0 - 41 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 4A - 0 - 
Machine: 82, Command: C9, Data Size: 11 Bytes
82 - 56 - 0 - 0 - 
Machine: 82, Command: 56, Data Size: 0 Bytes
82 - 15 - 9 - 0 - 0 - 80 - 30 - 0 - 0 - 0 - 0 - 0 - 0 - B0 - 0 - 
Machine: 82, Command: 15, Data Size: 9 Bytes
Digits: 3.0000000000000E0

I'm simplifying matters a little, I had to figure out how to decode the data portion of the packet, for example.

One odd thing I've come across is that the machine ID given by the calculator depends on how and what you're sending. Using TI-Basic's send() command gives it as 82 (in hex), presumably so it can communicate with the CBL (calculator based laboratory) things that were created for the TI-82. Using the link menu gives it as 83 and also uses different commands (sends Check ready (RDY) first). If you try and send a program it gives the ID as 7 and the command as D1 (which appears to be undocumented). Choosing "SendID" or "SendOS" gives it as 73 (TI-83 plus).

One problem that came up is that the data portion of the packet is of variable size and the Arduino language can't handle creating arrays on the fly. I tried putting in the "new" operators that were suggested in another topic somewhere but that only seemed to work once (the operators must not have been implemented correctly). I've left those in, though commented out, for when I (or someone else) figures out how to do it. Meanwhile I've created a hard coded array that handles a data size of up to 11 bytes (the size of the "variable header").

I will provide my code as soon as I can figure out the best way to do that. (I don't want to just paste it here as that'd be rather ugly)

[edit]Oh dang, I just realized this may not be the correct forum category for this. Though I'm not really sure, maybe it should go into software interfacing?[/edit]

And here's my code. Keep in mind this is VERY rough and could probably be done much better. This is just what evolved out of my original program which consisted of something along the lines of "if(red==0) display 0, else if(white == 0) display 1"

It would be really cool to create a graph writer, something you can use to "print" out the graphs that the calculator displays. I know these exist already, but they're expensive and only print on little strips. It should be relatively simple to have the calculator send over the information and have the Arduino control two motors to move a pen or pencil along a piece of paper. Maybe even with a way to lift the writing utensil off the paper and move it elsewhere. Essentially creating a miniature home made plotter controlled by a calculator.

The TI-Graphic calc make interesting projects. I spent allot of time back in the late 90's messing around with my TI-85. Don't know about the newer models but the old TI-82 and TI-85 used Z80 based controllers. Is was back then that people figured out how to hack them and program them in ASM. I recall seeing an ad dons that used the TI_Link port to expand the memory of the unit. There was also a program for the calcs and the PC. The PC side of it would convert a small audio file so that it could be uploaded to the calc and played back threw headphones on the TI-Link port. Always meant to learn ASM for the TI's but never did. This is renewing my enthusiasm for it. It could be rather interesting to see what you could pull together linking the TI with the arduino. I think using the arduino to add various inputs that can be controlled and displayed by the cal would be a great project.

I love your idea, but I’m having a hard time figuring out how to wire things up to match your configuration. I have a TI Graph Link cable (gray) and it has a 25 pin connector, but I also have the 9 pin converter. I also have a spare TI connector cable that I could cut up if needed.

You say that you used the home made serial cable schematic, but you didn’t say whether you made the cable or used an existing TI Graph Link cable. Please clarify.

Also, in your code you explain how the connections are made, but it’s difficult to understand which pins from the cable get connected to which pins on the Arduino.

Are you using the TI Graph Link and just connecting pin 2 on the Graph Link to pin 2 on the Arduino and the same for pin 3, 4 and 5?

If you are using the homemade serial link cable, did you include the diodes (because you only mentioned the use of the 10k pull-up resistors, not any diodes)?

There is the mention of 10k pull-up resistors, but the home made serial cable doesn’t use 10k resistors and I would suspect that the TI Graph Link cable already has all the required circuitry (unless you mean that the Arduino has open collector outputs and the pull-up resistors are needed for that reason).

The way your write up reads, it sounds like you made your own cable and just connected the tip (red) directly to pin 2 and 4 and then the middle (white) directly to pins 3 and 5 and then the ground from the TI to the ground of the power supply on the Arduino.

If you could help me out with some clarifying info, I might have a few people who could help to refine the code a bit.

Ok, my associate and I have been experimenting and we think we have the wiring down. It would be nice if someone could confirm or deny. We used all the reference docs in the posts above. We used the home made serial link (not the parallel one) schematic to try to figure out how to wire the TI Graph Link (gray) cable to the Arduino to work with the code provided above.

We are using the 9 pin adapter on the Graph Link. Here is our mapping of the Graph Link to Arduino wires:

Arduino -> Graph Link (9 pin connector)

3 -> 6 5 -> 4 G -> 5 (G = Ground) 2 -> 8 4 -> 7

These assumptions are made because the code says that 3 is the white input and 6 on home made serial link is the white output (hoping that the home made serial link has similar wiring to the Graph Link). We are also assuming that 4 on the home made serial link is the input to white, so we're assuming that because 5 is the white output on the Arduino code, we attached 5 from the Arduino to 4 on the 9 pin adapter.

Unfortunately, this wiring is not giving us the expected output on the terminal from the Arduino. Also, we did check to ensure that our 25 pin to 9 pin adapter is wired in the standard way for an RS-232 connector (http://www.lammertbies.nl/comm/cable/RS-232.html#pins).

If anyone has any thoughts, we would appreciate reading them. Thanks.

Well, the previous post couldn't have worked because it was based on the assumption that the TI Graph Link cable was electrically equivalent to the home made serial cable, but it's not. In the home made serial cable, the white (middle of 3 way plug) is connected directly to pin 6 of the serial cable 9 pin connector. In the TI Graph Link, there is no connection between the white and pin 6 (or any other pin). I did break open the Graph Link and there is circuitry in there to convert the TI signals into RS-232.

Unfortunately, I'm still not sure how to get the RS-232 from the Graph Link cable to be recognized by the Arduino. You would think that if you just connected pins 2 and 3 (and ground) to the Arduino using something like NewSoftSerial, you would be able to at least receive data from the TI-83, but we were getting nothing. We did try to drive some of the other Graph Link pins high and that caused the TI-83 output to speed up, but still nothing from the Arduino on the terminal (with NewSoftSerial, you can still output to the terminal even when performing serial communications using pins other than TX and RX).

When we hooked up the Graph Link cable to the computer serial port, we did get the from the TI-83 using RealTerm. It looks like you have to set RTS and DTR high in order for the data to flow. Then, it looks like data comes to the computer via pin 2 (RX) on the Graph Link DB-9 connector. RealTerm shows which pins are active during communication. RealTerm also let's you set RTS and DTR. It would be nice to be able to duplicate what RealTerm is doing with the Arduino. We'll keep working. Would love to be able to reliably communicate with the TI-83.

I know there is one manufacturer of a TI calculator robot - ah, here it is:


I think they use a small PIC to control everything, but as far as I know you may indeed be the first using the Arduino.

Heres a project using an ATTiny to implement a touchscreen interface:



I didn't use a serial cable at all. I used the standard calc-to-calc link cable, I used the schematic of the home made serial cable (which uses the calc-to-calc cable) to determine what the three conductors were supposed to do.

I plugged one end into the calculator and used alligator clips on the other end (eventually I went and bought a jack that allowed for easier alligator clip interfacing). The idea was to use a direct connection to the calculator without bothering with any other interface. There wasn't actually any serial cable involved (though, of course, the calc-to-calc cable is technically a form of serial cable).

The calculator doesn't actually use the RS-232 protocol, it uses its own weird protocol, which is what I described in my original post.

Thank you for your response, StarkRG. So, if you did not use a fancy cable, how are all the wires connected? Are wires 2 and 4 and red all tied together directly? The same for 3 and 5 and white? If so, I'm not sure why you mention the 10k pullup resistors or where they should go. Any additional info would be helpful. Thanks.

The calculator doesn't actually use the RS-232 protocol, it uses its own weird protocol, which is what I described in my original post.

I was more meaning the "interface to a microcontroller", rather than "figuring out the raw comms protocol", which I am sure has also been done before. The TI graphing calculators have been, historically, one of the most hacked calculator series on the planet, I think. Your research and information, though, will definitely help, so I don't consider it a waste of time or anything, in fact, I find it pretty cool and useful (I wonder if I could get my TI92 set up to use this?)...


Ok, one of my students, Andrew, finally figured out the secret recipe. You can use the code provided at the beginning of this thread. But you cannot just attach the TI-83 cable wires to the Arduino (as is implied in the thread above). Instead, you need to use the circuit displayed at http://zastava.student.utwente.nl/linkguide/hardware.html. You actually need to construct this circuit twice. Once for the red wire on the TI-83 and once for the white wire. Where it says input, that is the Arduino read line, where it says output, that is the Arduino write line. So, you will need to use four pins on the Arduino and if you look at the code above, it is obvious which pins you should use.

Also, the recommended circuit does invert the Arduino write signal, so the code must be changed to reflect that (ie. if the code says to set the write line high, set it low instead and if the code says to set the write line low, set it to high instead).

Alright, I know I could have provided more details, but I wanted to share some lessons learned while my mind was on this. Hope it helps others and please share if you come up with something cool.