In early 2010, we published a set of rudimentary routines to link graphing calculators to Arduino boards. In the intervening four years, a number of developers have given me feedback on the routines, including features that they'd like to see and improvements that could be made. Those improvements have made their way into a new library called ArTICL (Arduino-TI Calculator Linking). Like any good Arduino library, it contains a set of classes you can use in your own Arduino programs, plus a handful examples made by yours truly and other Cemetech members. We plan to continue to expand the library and eventually create one or more lesson plans that teachers could use to teach rudimentary electronics and programming with TI-83 Plus or TI-84 Plus calculators and Arduinos.

The ArTICL library (pronounced "article") lets Arduino programs send and receive TI link protocol-formatted packets at a low level. In addition, it includes a CBL2 class that lets the calculator emulate either a CBL2 device or a calculator speaking the CBL2 protocol (thanks to Cemetech member CVSoft for helping to make this possible). This means that you can use the Send() and Get() commands on your graphing calculator to control the Arduino, including turning LEDs and motors on and off, reading the state of buttons and switches, and performing measurements with sensors. You could even use the ArTICL library to control a Norland Research robot with an Arduino. The attached topic will be updated as the library progresses. In the meantime, check out the video below demonstrating toggling LEDs on and off with the Send() command on a calculator, and feel free to contribute to ArTICL by sending a pull request on GitHub.

Hmm I do wonder if I can use this to make my SilverLink clone more robust

I think you can, and you should definitely give it a try. At the very least, it should make your code much cleaner than using my original Arduino-TI Calculator linking library.

In other news, I've added a new class that converts between TI and POSIX datatypes. So far it has the single (static) method realToFloat8x, which converts a 9-byte TI-OS floating-point number used on the TI-8x calculators into an IEEE 754 floating-point number, unfortunately with the expected loss of precision. I plan to at least add a method to convert back to TI-OS TI-8x floats, and if there's call for it, add proper TI-9x support to both the TIVar and CBL2 classes.

Edit: I've finished and tested the floatToReal8x routine with g++ and a Linux computer, but I used only floating-point routines that the Arduino documentation claims are available. Sample output:

Should someone need / want to implement it, the layout of TI-68k AMS BCD floats is described in the GCC4TI documentation: https://debrouxl.github.io/gcc4ti/timath.html#bcd .
Tagged floats have a 14-digit mantissa instead of 16-digit, the last byte of the mantissa being 0x23 = FLOAT_TAG.

Should someone need / want to implement it, the layout of TI-68k AMS BCD floats is described in the GCC4TI documentation: https://debrouxl.github.io/gcc4ti/timath.html#bcd .
Tagged floats have a 14-digit mantissa instead of 16-digit, the last byte of the mantissa being 0x23 = FLOAT_TAG.

Duly noted. I have not yet implemented TI-89/TI-92 support, but the TIVar member functions will recognize when they're supposed to handle such variables, and abort accordingly. If someone wants to implement that, I would still appreciate that.

In other news, I have expanded the TIVar class significantly to understand and work with TI-82/83/84+ Real variables as well as TI-85/86 Real variables, which are one byte longer and have a larger exponent. This also means that using the CBL2 class to respond to a Get() request from a connected calculator now works properly, as demonstrated with the new ReadAnalog example. However, ReadAnalog currently uses floatToReal8x rather than longToReal8x, so there is some unfortunate imprecision leading to values in the sent list like 536.0001. I am debugging the AVR compiler's handling of the following code to understand why g++ does the right thing but the AVR tools do not: Code:

long n2 = (n/10);
uint8_t cdigit = (uint8_t)(n - 10 * n2);

It appears that the AVR compiler incorrectly assumes that 10 * (n / 10) = n for integers, which of course is not true.

Edit: In the end, it turned out that I was trying to cram 14 digits into a long (sizeof(long) = 4 on AVRs), and that wasn't working out well. I switched to long long ints (sizeof(long long) = , and now everything is happy. I have pushed the completed ReadAnalog example.

I was thinking about making a general program for the Arduino that would let the calculator controll the Arduino. It would accept a list of digital pins going to be used, a list of input/output for those pins, and a list of analog pins that would be used. That way you wouldn't have to modify the Arduino code every time you came up with a new project. I'm not sure how you would accept lists with different dimensions though.

Also, kind of unrelated to that, can you use silent linking while running another program?

I was thinking about making a general program for the Arduino that would let the calculator controll the Arduino. It would accept a list of digital pins going to be used, a list of input/output for those pins, and a list of analog pins that would be used. That way you wouldn't have to modify the Arduino code every time you came up with a new project. I'm not sure how you would accept lists with different dimensions though.

Take a look at the ReadAnalog example, which returns the values of the analog pins as a 5-element list, and the ControlLED example, which lets you control some of the digital pins using the bits in the first element of a 1-element list. Expanding this to be more general would be an admirable endeavor. For example, you could use Send({3, 1}) to set digital pin 3 to high, Get({103, 0}) to get the value of analog pin 0, and send({212, 1}) to set digital pin 12 to input (or output).

Quote:

Also, kind of unrelated to that, can you use silent linking while running another program?

It depends. If you're at an Input, Prompt, Menu, or Pause, yes. Otherwise, no.

That was exactly what I was thinking, then you could just plug in whatever you want to the microcontroller, an wouldn't have to worry as much about the code on it. I have already started the code on it. Updates and questions coming later

That's great! If you don't mind me doing a little code review on your work, I'd be very interested in incorporating it as an official ArTICL example, so feel free to submit a pull request to my GitHub repo once you have semi-finalized code.

Ah, okay. So the first element in the buffer specifies the size of the list, and then longToReal8x() is used to convert between the types, which is then stored into the thrid element of the buffer? So to create a list with three elements and set every value to 6, it would be: (Assuming I had the header preset):

Well, if you take a look at the File Format and Link Protocol guide description of lists, you'll see that lists are a two-byte, little-endian field indicating the number of elements in the list, followed by that many real numbers (which could be 9 or 10 bytes, depending on which calculator the Arduino is emulating). Yes, your code would be correct (although if it's responding to an existing message, it should use that model rather than the hard-set CALC83.

Muessigb: Great, you should submit a PR, if you feel the code quality is up to snuff for inclusion in the repository.
Mateo: That's a great idea; I look forward to seeing what you create. That's definitely something that's missing currently.

Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.