While working on an updated version of my Arduino to TI calculator linking routines, currently available as the ArduinoTILP library, I had a chat with CVSoft about the CBL2. He very helpfully transcribed the following TI-83+ <--> CBL2 conversation for me:
Code:
:Send({0
:Send({7
:Get(L1
CBL2 returned {5.0627,0,0,8888,0,0,0,0,0,0,0,0,0,1,0,0,0}


Code:
82 C9 0B 00 0B 00 01 24 00 00 00 00 00 00 00 30

12 56 00 00
12 09 00 00

82 56 00 00
82 15 0B 00 01 00 00 80 00 00 00 00 00 00 00 81 00

12 56 00 00

82 92 0B 00

12 56 00 00

82 C9 0B 00 0B 00 01 24 00 00 00 00 00 00 00 30

12 56 00 00 12 09 00 00

82 56 00 00
82 15 0B 00 01 00 00 80 70 00 00 00 00 00 00 F1

12 56 00 00

82 92 0B 00

12 56 00 00

95 A2 0B 00 0B 00 04 01 41 00 00 00 00 00 00 51

15 56 00 00
15 06 05 00 AC 00 04 01 41 F2 00

95 56 00 00
95 09 05 00

15 56 00 00
15 15 AC 00 [0xAC bytes] 12 13

95 56 00 00
This tells us a variety of interesting things. First, regarding endpoint IDs:
  • A TI-83+ performing a Send() request uses ID 0x82 (TI-82)
  • The CBL2 responds to Send() requests as ID 0x12 (??)
  • A TI-83+ performing a Get() request uses ID 0x95 (??)
  • The CBL2 responds to Get() requests as ID 0x15 (??)


More coming soon.
I've logged the serial port from five different usage scenarios (not checking if CBL2 acts the same) and plopped the data into dropbox. Link is here.

Case 1 is basic send/get into L1.
Case 2 is basic send/get into L2.
Case 3 is basic send/get into ʟABC.
Case 4 is setting up and receiving a 20 character string.
Case 5 is sampling and receiving a picture from the original CBL (Vernier took out the receive as picture functionality in the CBL2/LabPro).
Thanks for sharing those; they're quite interesting. As expected, Case 1 and Case 2 are very similar, and in fact, for the Get(, they both request "0x04 0x01 0x41" (which is not a valid variable name, but would be "Str2A" or so. The conversations go something like this:

:Send({0
Calculator (0x82): Request to send (RTS) list 0x24 (L38), length 0x0B
CBL2 (0x12): ACK RTS
CBL2 (0x12): Clear to send (CTS)
Calculator (0x82): ACK CTS
Calculator (0x82): DATA containing 0x0B bytes of the list data with leading 0x01, 0x00 element size and single element {0}.
CBL2 (0x12): ACK DATA
Calculator (0x82): End of transmission (EOT)
CBL2 (0x12): ACK EOT

:Send({7
Calculator (0x82): Request to send (RTS) list 0x24 (L38), length 0x0B
CBL2 (0x12): ACK RTS
CBL2 (0x12): Clear to send (CTS)
Calculator (0x82): ACK CTS
Calculator (0x82): DATA containing 0x0B bytes of the list data with leading 0x01, 0x00 element size and single element {7}.
CBL2 (0x12): ACK DATA
Calculator (0x82): End of transmission (EOT)
CBL2 (0x12): ACK EOT

:Get(L1
Calculator (0x95): Request for variable (REQ) name 0x04 0x01 0x41 (Invalid variable name Str2A)
CBL2 (0x15): ACK REQ
CBL2 (0x15): Variable header (VAR) of variable 0x04 0x01 0x41 length 0xAC. Not only is this variable name nonsense, the VAR header does not have the name padded out to 8 bytes, as the known spec specifies.
Calculator (0x95): ACK VAR
Calculator (0x95): CTS
CBL2 (0x15): ACK CTS
CBL2 (0x15): DATA packet, length 0xAC
Calculator (0x95): ACK DATA
(!!) No EOT / ACK EOT exchange appears to be performed!

:Get(Str1 (from Case 4)
Calculator (0x82): Request for variable (REQ) name 0x00 0xAA (Real variable I-don't-even-know)
CBL2 (0x12): ACK REQ
CBL2 (0x12): Variable header (VAR) of variable 0x04 0xAA length 0x16. CBL2 returned variable of type "string" (doesn't it always?), and for once it's correct.
Calculator (0x82): ACK VAR
Calculator (0x82): CTS
CBL2 (0x12): ACK CTS
CBL2 (0x12): DATA packet, length 0x16
Calculator (0x82): ACK DATA
(!!) No EOT / ACK EOT exchange appears to be performed!

So, final deductions:
  • When the calculator addresses the CBL2 as device 0x82 (TI-82), the CBL2 responds as device 0x12. When the calculator addresses the CBL2 as device 0x95 (unknown), the CBL2 responds as device 0x15.
  • Variable names used with the CBL2 are nonsense. My working theory is that only the second byte of the variable is used, and the first byte is discarded. Second byte = 0x24 may indicate a list, and = 0xAA may indicate a string. Testing will have to be performed (or documentation found) to confirm this.
  • When the calculator sends to the CBL2, an EOT/ACK EOT ends the conversation. When the CBL2 sends to the calculator, no such courtesy is observed, unless CVSoft ended his traces early.
I was attempting to decipher the transcript in the first post using the TI Link Protocol Guide I found online and I failed at the first line.


Code:
82 C9 0B 00 0B 00 01 24 00 00 00 00 00 00 00 30


It looks a byte too short. The captures linked in the second post seem to confirm my suspicion. Did you omit the checksum MSB?
acspike wrote:
Did you omit the checksum MSB?
Good eye; I did indeed unintentionally omit the checksum.
yay I didn't omit anything Very Happy

I checked again, Case 4 indeed does not send the EOT ACK. I'm now getting some data from sampling and various other commands. Sending a command 80 to the CBL2/LabPro and getting the return list (supposed to be a 6-element list) results in the list in the Get( statement being erased.
Relevant to this project: I have pushed (untested) code to my ArduinoTILP library to perform the necessary message exchange for sending and receiving data as a CBL2, presumably making an Arduino capable of communicating with a calculator via TI-BASIC Get() and Send() commands. I'll be testing this this evening on HCWP.
Some more stuff!
Performing a Get( while the CBL2 is sampling:

Code:
Get(L₁


Code:
Calc: 95 A2 0B 00 4A 00 04 01 41 00 00 00 00 00 00 90 00
CBL2: 15 56 00 00
(wait for sampling to end)
CBL2: 15 06 05 00 66 00 04 01 AC 00
Calc: 95 56 05 00 95 09 05 00
CBL2: 15 56 00 00
CBL2: 15 15 66 00 0A 00 00 00 FC 24 43 79 00 00 00 00 00 00 FC 23 75 37 00 00 00 00 00 00 FC 23 75 37 00 00 00 00 00 00 FC 23 75 37 00 00 00 00 00 00 FC 23 70 48 00 00 00 00 00 00 FC 23 70 48 00 00 00 00 00 00 FC 23 75 37 00 00 00 00 00 00 FC 23 70 48 00 00 00 00 00 00 FC 23 70 48 00 00 00 00 00 00 FC 23 70 48 00 00 00 00 45 12
Calc: 95 56 66 00

Returns list {2.44379, 2.37537, 2.37537, 2.37537, 2.37048, 2.37048, 2.37537, 2.37048, 2.37048, 2.37048}
------

The broken Command 80 (results in L1 being deleted in this case):

Code:
Get(L₁

(Command 80,0 has already been sent, this is the Get exchange):

Code:
Calc: 95 A2 0B 00 14 00 04 01 41 00 00 00 00 00 00 5A 00
CBL2: 15 56 00 00
CBL2: 15 15 02 00 00 00 00 00 FC 00 00 00  00 00 00 00 00 00 FC 00 00 00 00 00 00 00 00 00 FC 00 00 00 00 00 00 00 00 00 FC 00 00 00 00 00 00 00 F0 03 


--------

Testing with an emulated TI-92 Plus:

Code:
// Send {3, -1}

Calc: 89 06 08 00 06 00 00 00 04 01 FF 00 0A 01

CBL2: 19 56 00 00 19 09 00 00 

Calc: 89 56 00 00
Calc: 89 15 0A 00 02 00 00 00 20 33 20 2D 31 00 D3 00

CBL2: 19 56 00 00

Calc: 89 92 00 00

CBL2: 19 56 00 00

// Get x

Calc: 89 A2 06 00 00 00 00 00 04 00 04 00

CBL2: 19 56 00 00
CBL2: 19 06 06 00 1F 00 00 00 04 00 23 00

Calc: 89 56 00 00 89 09 00 00

CBL2: 19 56 00 00
CBL2: 19 15 1F 00 02 00 00 00 20 2B 32 2E 34 34 33 37 39 45 2B 30 30 20 2B 30 2E 30 30 30 30 30 45 2B 30 30 00 F1 04
// Returns {2.44379, 0}

Calc: 89 56 00 00


68k calcs can only Get lists, so no need to worry about other data types.
Things that are dumb and/or weird, discovered while working on a new demo called ReadAnalog (which predictably returns the state of the analog pins in a 6-element list).

1) The CBL2 seems to not send standard TI-OS floats when it is pretending to be endpoint 95: 00 00 FC 24 43 79 00 00 00 00 does not match the standard. Is this a known oddity? Is this a known format? Your Get(L₁) in the previous post confirms this. Edit: specifically, they're 10 instead of 9 bytes, have a leading 00, and seem to have exponents offset from 0xFC instead of 0x80.

2)
Quote:
The broken Command 80 (results in L1 being deleted in this case): [...]
This is because the calculator deletes the list (L₁ in this case) when the Get() begins, but the CBL2 jumps immediately to the DATA message without sending the VAR header. The calculator rejects this premature data, and no new list gets created.

Edit #2: In what should have been obvious to me, the 0x95 lists returned in fact contain TI-85 real numbers. Now it all makes sense.
I was going to ask you what the 0xFC meant, but it seems you got to it before I remembered to posf. I'll throw in an example that has a wide range of numbers.

EDIT: I forget the obvious easily.
As per request, communication between TI-82 and the original CBL.


Code:
//Send({1,1,1})

TI-82: 82 C9 0B 00 1D 00 01 5D 00 00 00 00 00 00 00 7B 00

CBL1: 12 56 00 00
CBL1: 12 09 00 00

TI-82: 82 56 00 00
TI-82: 82 15 1D 00 03 00 00 80 10 00 00 00 00 00 00 00 80 10 00 00 00 00 00 00 00 80 10 00 00 00 00 00 00 B3 01

CBL1: 12 56 00 00

TI-82: 82 92 1D 00

CBL1: 12 56 00 00

//Get(L2) with no data to get

TI-82: 82 A2 0B 00 1D 00 00 5D 01 00 00 00 00 00 00 7B 00

CBL1: 12 5A 00 00



Code:
//Send({7})

TI-82: 82 C9 0B 00 0B 00 01 5D 00 00 00 00 00 00 00 69 00

CBL1: 12 56 00 00
CBL1: 12 09 00 00

TI-82: 82 56 00 00
TI-82: 82 15 0B 00 01 00 00 80 70 00 00 00 00 00 00 F1 00

CBL1: 12 56 00 00

TI-82: 82 92 0B 00

CBL1: 12 56 00 00

TI-82: 82 A2 0B 00 0B 00 00 5D 01 00 00 00 00 00 00 69 00

CBL1: 12 56 00 00
CBL1: 12 06 0B 00 41 00 01 5D 01 00 00 00 00 00 00 A0 00

//Get(L2) returning {1.06,0,999,999,999,999,1}

TI-82: 82 56 0B 00
TI-82: 82 09 0B 00

CBL1: 12 56 00 00
CBL1: 12 15 41 00 07 00 00 80 10 60 00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 82 99 90 00 00 00 00 00 00 82 99 90 00 00 00 00 00 00 82 99 90 00 00 00 00 00 00 82 99 90 00 00 00 00 00 00 80 10 00 00 00 00 00 00 B3 08

TI-82: 82 56 41 00
Is it possible to do a capture where the CBL device doesn't respond to Get() immediately? I'm wondering what an appropriate timeout/retry cycle might look like.
acspike wrote:
Is it possible to do a capture where the CBL device doesn't respond to Get() immediately? I'm wondering what an appropriate timeout/retry cycle might look like.

I already did but I didn't clearly state that was what happened in the data. It's this example:
CVSoft wrote:
Some more stuff!
Performing a Get( while the CBL2 is sampling:

Code:
Get(L₁


Code:
Calc: 95 A2 0B 00 4A 00 04 01 41 00 00 00 00 00 00 90 00
CBL2: 15 56 00 00
(wait for sampling to end)
CBL2: 15 06 05 00 66 00 04 01 AC 00
Calc: 95 56 05 00
Calc: 95 09 05 00
CBL2: 15 56 00 00
CBL2: 15 15 66 00 0A 00 00 00 FC 24 43 79 00 00 00 00 00 00 FC 23 75 37 00 00 00 00 00 00 FC 23 75 37 00 00 00 00 00 00 FC 23 75 37 00 00 00 00 00 00 FC 23 70 48 00 00 00 00 00 00 FC 23 70 48 00 00 00 00 00 00 FC 23 75 37 00 00 00 00 00 00 FC 23 70 48 00 00 00 00 00 00 FC 23 70 48 00 00 00 00 00 00 FC 23 70 48 00 00 00 00 45 12
Calc: 95 56 66 00

Returns list {2.44379, 2.37537, 2.37537, 2.37537, 2.37048, 2.37048, 2.37537, 2.37048, 2.37048, 2.37048}
*bump-ish*
A capture from TI-89 exchanging with a TI CBL (original):

Code:
// Send {0}
89 06 08 00 03 00 00 00 04 01 FF 00 07 01
19 56 00 00
19 09 00 00
89 56 00 00
89 15 07 00 01 00 00 00 20 30 00 51 00
19 56 00 00
89 92 00 00
19 56 00 00

// Send {7}
89 06 08 00 03 00 00 00 04 01 FF 00 07 01
19 56 00 00
19 09 00 00
89 56 00 00
89 15 07 00 01 00 00 00 20 37 00 58 00
19 56 00 00
89 92 00 00
19 56 00 00

// Get x
89 A2 06 00 00 00 00 00 1E 00 1E 00
19 56 00 00
19 06 06 00 52 00 00 00 04 00 56 00
89 56 00 00
89 09 00 00
19 56 00 00
19 15 52 00 06 00 00 00 20 2B 31 2E 30 36 30 30 30 45 2B 30 30 20 2B 30 2E 30 30 30 30 30 45 2B 30 30 20 2B 39 2E 39 39 30 30 30 45 2B 30 32 20 2B 39 2E 39 39 30 30 30 45 2B 30 32 20 2B 39 2E 39 39 30 30 30 45 2B 30 32 20 2B 39 2E 39 39 30 30 30 45 2B 30 32 F7 0E
89 56 00 00

Interestingly (to me, at least) the list contents from the CBL are in the same ASCII format that LabPro sends via RS232.
I've been testing some of my ArTICL programs with the TI-84 Plus C Silver Edition, and I've noticed:
  • Lists sent as Send(L1) are type $5D
  • Lists sent as Send({1}) are type $24 (this is a known variation that I've inexplicably never made ArTICL support)
  • Matrices sent as Send([A]) are type $5C
  • Variables sent as Send(X) are type $58
These are all with device type $82, by the way. A Get(L1) uses device type $95 but the expected data type $01. Have you observed anything like this?
Nope(edit: I might have, but I don't remember any of these off the top of my head); are these new values coming only from the CSE? Maybe we need to do a scan of all the type bytes and see how they're returned.

[edit] [edit] Dammit TI, use more different names.
CVSoft wrote:
Nope; are these new values coming only from the CSE? Maybe we need to do a scan of all the type bytes and see how they're returned.
Good idea. I'm trying to correlate this with our existing list of known variable types, but unfortunately there's no fixed offset.

Quote:
[edit] [edit] Dammit TI, use more different names.
About your previous edit: Yes, device type 0x95 (which I call CALC85b in the ArTICL source) requires that the CBL2 (or Arduino Razz) respond as device type CBL85 (0x15), so that's nothing new, happily.
If you want definitive answers and have a lot of time (lolno), you could look at the CBL2 OS. BrandonW has tools to disassemble TLCS-900 instructions.
Heh, when and if I have time, I'll look into that possibility. Disassembling and annotating the CBL2 OS could be a lot of fun and a good exercise in reverse engineering and forensics. In the meantime, I have added a rudimentary extra enum in ArTICL's CBL2.h enumerating the known TI-84+CSE-style variable types it uses to talk to a CBL2; the diff of the file on GitHub.
Hi, i found the linking protocol in this site:http://merthsoft.com/linkguide/ti83+/silent.html
Using send and get i can get request a variable as in the example but i cant send a variable, im using TI 84+
i send:
73 C9 0D 00 09 00 00 41 00 00 00 00 00 00 00 00 00 4A 00
and i tried with some formats and i always receive only the first 2 bytes of ACK:
73 09

and cant get anything more

can you help me ?

Thank you !
  
Register to Join the Conversation
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.

» Go to Registration page
Page 1 of 2
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement