Hi, I'm not sure if this is the right place to post this, but I'm currently working on a project that includes both the TI-84 and my arduino.

So the entire premise of my project was to be able to hit any button that I assign on my TI-84 to send MIDI messages. I already completely understand the MIDI part, but what I'm missing is knowledge on how I'd be able to make my TI-84 trigger my code to send the MIDI messages for me.
For example, in a more rudimentary way, if we ignore the MIDI messages for now, if I wanted to turn an LED on and off by pressing "1" on my calculator, the code would look something like this

if( //[1 is triggered in TI-84] )
{
digitalWrite(ledPin, HIGH)
}

and with this, I could just replace this with sending my MIDI messages.
how would I be able to do this?

To try to accomplish this project, I've read quite a bit on this forum but I'm still kind of confused.

What I know currently:
I should probably be using an arduino library called ArTICL
https://www.cemetech.net/forum/viewtopic.php?t=10809
I need an 2.5mm I/O cable to connect with my arduino

What I don't know:
Which pins do I connect my 2.5mm cable to? I know which cable is ground, but is there any tutorial out there that would be able to help me figure out which of the other two cables is which?

Will my 2.5mm cable work for this project? I'm using an old cheap white Xbox 360 headset jack.

What kind of software would I need to load to my TI-84?

How do I make it so I don't have to use the command "Send()" on the Ti-84, rather, I'd just simply have to press a single button to trigger the code to send MIDI data.

Is there anything out there that's more condensed than the Example code on "ControlLED" that only controls 1 LED? I'd like the code to be a little less complicated as I'm relatively new to all of this.

I'm really new to tinkering with my TI-84 so if there's any other advice or help you guys have too I'd be really grateful for it.
jacobharris wrote:
Hi, I'm not sure if this is the right place to post this, but I'm currently working on a project that includes both the TI-84 and my arduino.
This is both the correct website and the correct area of the forum.

Quote:
To try to accomplish this project, I've read quite a bit on this forum but I'm still kind of confused.

What I know currently:
I should probably be using an arduino library called ArTICL
https://www.cemetech.net/forum/viewtopic.php?t=10809
I need an 2.5mm I/O cable to connect with my arduino
That's a good start! I agree with both of those points.
Quote:
What I don't know:
Which pins do I connect my 2.5mm cable to? I know which cable is ground, but is there any tutorial out there that would be able to help me figure out which of the other two cables is which?
The ArTICL readme (see https://github.com/KermMartian/ArTICL/blob/master/README.md ) explains the other two wires. If you're not using a TI cable with white and red conductors, just try them one way around, and if that doesn't work, swap what might be tip and ring. You won't break your Arduino or your calculator by having this backwards. Just make sure you have the ground wire correct.
Quote:
Will my 2.5mm cable work for this project? I'm using an old cheap white Xbox 360 headset jack.
Does it have three conductors, like a stereo headphone plug? If so, it will probably work. Does it go all the way into your calculator's I/O socket? Most right-angle plugs don't fit.

Quote:
What kind of software would I need to load to my TI-84?
Nothing.

Quote:
How do I make it so I don't have to use the command "Send()" on the Ti-84, rather, I'd just simply have to press a single button to trigger the code to send MIDI data.
You could write a simple TI-BASIC program, like this:
Code:
PROGRAM:QUIKSEND
:Repeat K=45   // Repeat this loop until [CLEAR] is pressed
:getKey->K    // get the current keypress
:If K=105    // if [ENTER] was pressed...
:Then
:{1->L1   // Send the calculator a 1-element list containing 1.
:Send(L1
:End    // End the If/Then
:End    // End the Repeat loop
:// the program automatically terminates at the end.


Quote:
Is there anything out there that's more condensed than the Example code on "ControlLED" that only controls 1 LED? I'd like the code to be a little less complicated as I'm relatively new to all of this.
The ControlLED demo is already practically a minimal demo. The only thing you could change to simplify it for one LED would be to remove the bitshifting and loop at lines 98-100 (in the current revision).

Quote:
I'm really new to tinkering with my TI-84 so if there's any other advice or help you guys have too I'd be really grateful for it.
Just hang out and ask the questions you have, and we'll be happy to help. You should also Introduce Yourself if you have a chance.
wow this was very insightful thank you so much. Since then I've been able to get my IO cable working so that's a good start.

Also your example TI BASIC program was very helpful as well, however I still have a few questions regarding it because I don't have much experience with TI BASIC. I understand now that the getKey command gives some value that is specific to a keypress on the calculator, and you've given me now that the value specific to the enter key is 105, but what are the other values on the computer? What are these numbers called? Is there some type of page that you could redirect me to in order to find all of these numbers? I also viewed the typeLetter example on ArTICL where we seem to be sending the calculator a letter "M" by the value 0xA6. Is this related to the 105 keypress you mentioned earlier?

edit: I researched a little more and found this page with useful data: http://www.ticalc.org/cgi-bin/zipview?text/calcinfo/tixx_guide.zip;tixx_guide/linkguide/ti83/keys.txt
this seems to show the values of the keys ArTICL side rather than TI BASIC side. Still stuck on where to find the TI-BASIC key values though.

I'm also slightly confused on how the arduino can accept these lists that we are sending. Are we supposed to be using the get command in ArTICL to receive this list?

More specifically for example, if I wanted to type out "1" on my calculator and have my serial output print something like "you pressed 1", I would need to use a variation of this quicksend TI BASIC program that replaces the If statement condition to see if it equals 1 and then send a list of something if it is a 1, but what do you suppose would accept that on the arduino side to be able to recognize that list?
jacobharris wrote:
wow this was very insightful thank you so much. Since then I've been able to get my IO cable working so that's a good start.
Great, that's definitely a good start.

Quote:
Also your example TI BASIC program was very helpful as well, however I still have a few questions regarding it because I don't have much experience with TI BASIC. I understand now that the getKey command gives some value that is specific to a keypress on the calculator, and you've given me now that the value specific to the enter key is 105, but what are the other values on the computer? What are these numbers called? Is there some type of page that you could redirect me to in order to find all of these numbers? I also viewed the typeLetter example on ArTICL where we seem to be sending the calculator a letter "M" by the value 0xA6. Is this related to the 105 keypress you mentioned earlier?

edit: I researched a little more and found this page with useful data: http://www.ticalc.org/cgi-bin/zipview?text/calcinfo/tixx_guide.zip;tixx_guide/linkguide/ti83/keys.txt
this seems to show the values of the keys ArTICL side rather than TI BASIC side. Still stuck on where to find the TI-BASIC key values though.
The File Format and Link Protocol Guide page that you found is indeed the correct source for the ArTICL-side key equates. For the TI-BASIC equates, do you have my book Programming the TI-83 Plus/TI-84 Plus? If so, Figure 6.5 on page 144 has all of the keycodes overlaid on the keys. If not, the basic rule of thumb is that the top row (the Y= etc keys) is 10, the next row is 20, so on down to 100 for the ON to ENTER row. Then, you add the column: Y= is 10 + 1 = 11, DEL is 20 + 3 = 23, and ENTER is 100 + 5 = 105. The exceptions are the arrow keys (24 = left, 25 = up, 26 = right, 34 = down) and ON (which has no code).

Quote:
I'm also slightly confused on how the arduino can accept these lists that we are sending. Are we supposed to be using the get command in ArTICL to receive this list?
The easiest thing to do would be to use the CBL2 class, which already handles listening for and receiving lists from the calculator when it does Send(), and letting your Arduino program know when the calculator has requested a list via Get(). The ControlLED demo uses the CBL2 class in just such a fashion (and now includes more comments than it did originally).

Quote:
More specifically for example, if I wanted to type out "1" on my calculator and have my serial output print something like "you pressed 1", I would need to use a variation of this quicksend TI BASIC program that replaces the If statement condition to see if it equals 1 and then send a list of something if it is a 1, but what do you suppose would accept that on the arduino side to be able to recognize that list?
You could modify the ControlLED demo to try that: in the current version of the file, starting on line 94, the program has determined that the calculator has sent a 1-element list, and figures out what the value of the single element in that one element list is. You could do something like Prompt X:{X}->L1:Send(L1) in TI-BASIC to send a one-element list containing a number from the user, then have your modified ControlLED check the value of that list element and Serial.print() if the element is 1.
Thank you so much. You've been really helpful to me this entire journey and I'm basically already done with everything. The hardware/software side of my project is essentially done now because of your assistance and I only have minor bug issues left to address along with finding a good demo to showcase what I've made.

I still have one last question before I start finalizing though:

With the TI BASIC knowledge that I currently have, I was able to write the code to turn most of the white and grey keys on the TI 84 into MIDI keys by sending lists like suggested. I went through the process of checking if the key equaled a certain value by using a large chain of If Else Statements however that proved to make a relatively slow operating program when pressing the keys closer to the end of that chain (because you've got to check the other elements that appear before it first).
I tried to make this faster by making nested If loops that divide the sections of keys into 5 sectors so if the key doesn't appear in one of the sectors, it can skip over checking an entire section of If loops, making the entire program faster.

the code looks something like this:

Code:

ClrHome
Repeat Q=45
getKey->Q

If Q(>=)102 //first sector is 102 to infinity
Then

If Q=102
Then
Send({1})
Else
If Q=103
Then
Send({2})
Else
If Q=104
Then
Send({3})
Else
If Q=105
Then
Send({4})
End
End
End
End

Else
If Q(>=)92 //second sector is 92 to 101
Then

If Q=92
Then
Send({5})
Else
If Q=93
Then
Send({6})
Else
If Q=94
Then
Send({7})
Else
If Q=95
Then
Send({8})
End
End
End
End

Else
If Q(>=)82 //third sector is 82 to 91
Then

If Q=82
Then
Send({9})
Else
If Q=83
Then
Send({10})
Else
If Q=84
Then
Send({11})
Else
If Q=85
Then
Send({12})
End
End
End
End

Else
If Q(>=)72 //fourth sector is 72 to 81
Then

If Q=72
Then
Send({13})
Else
If Q=73
Then
Send({14})
Else
If Q=74
Then
Send({15})
Else
If Q=75
Then
Send({16})
End
End
End
End
End

If Q(>=)21 //fifth sector isn't included in the Else If's because I was getting an exception
Then          //that I didn't know how to debug but regardless still cuts down on program lag

If Q=26
Then
Send({26})
Else
If Q=24
Then
Send({24})
Else
If Q=25
Then
Send({25})
Else
If Q=34
Then
Send({34})
Else
If Q=21
Then
Send({21})
Else
If Q=31
Then
Send({31})
Else
If Q=41
Then
Send({41})
End                    //I had no idea if I was doing End correctly so I just continued to put them here
End                    //until I stopped having exceptions
End
End
End
End
End
End
End
End
End
End


Although my code already works as desired, how do you think i could improve on this code? Why do you think I was getting an exception when I was trying to make the fifth sector a part of the Else's? Are there any things I could do to the code to make it even faster and just in general optimize it?
I'm more than happy to help, and I hope that you'll post a topic about the project when it's done. If you have some photos (or even a video) and your code for the calculator- and Arduino-side components, I think it would make a great showcase of ArTICL in action as used by someone who wasn't familiar with it when they started. To answer your question, I'd recommend using some math tricks to turn the keycodes into those indexes (1, 2, etc) that you have in your program. A first pass could be something like this:
Code:
If Q>=102 //first sector is 102 to infinity
Send({Q-101}) // 102-101 is 1, 103-101 is 2, etc
If Q>=92 and Q<=95 //second sector is 92 to 101 (or 95, if you prefer)
Send({4+Q-91  // simplify to Q-87 if you desire; it can't hurt.
...etc...
For a second pass, you could even try to combine those into one big mathematical expression. I'd probably consider something like:
1) To get the "offset" (each row of the keyboard starts with a number like 0 or 4 or 8 and then adds the offsets {1,2,3,4}, I'd do Q-10iPart(Q/10)-1, which yields 1 for 102, 1 for 92, 1 for 82, 2 for 103 and 93 and 83, and so on.
2) To get the starting number for the row, we'd need its high digit(s) first, say, iPart(Q/10). This yields 10 for 102 through 105, 9 for 92 through 95, and so on. We want to turn {10, 9, 8, 7...} into {0, 4, 8, 12...}, so we can do 4(10-iPart(Q/10)) or 40-4iPart(Q/10).
3) Put it all together, and we get 40-4iPart(Q/10)+Q-10iPart(Q/10)-1.

Code:
ClrHome
Repeat Q=45
getKey->Q
Send({40-4iPart(Q/10)+Q-10iPart(Q/10)-1
End

Hope this helps! Please ask questions if that simplification doesn't make sense. Wink
Oh yeah! I was thinking about doing something like this when you mentioned the rule of thumb for the key press keys. I just didn't really know how to go at it.

And now that you've brought up this really really short way of how to simplify the code, I kind of felt dumb. Dumb not because I didn't know the math behind all of it, but I felt dumb because I just now realized that I could've been sending the raw number received from getKey to the arduino and simply have my arduino code handle the raw data itself.

so the only thing that the TI BASIC code would have is

Code:

ClrHome
Repeat Q=45
getKey->Q
Send({Q})
End


and because I'm much more familiar with coding with the arduino language, I would be able to code much more efficiently with the added bonus that the code would possibly execute faster. I feel so silly now. I coded so much In a foreign language when I could've been coding much faster. It was an interesting learning experience I suppose.
The math you wrote in the first pass helps me out a lot too, although I'm probably going to write a variation of this in the arduino IDE instead. I don't really understand the second pass though. Why is this second pass necessary? I think the first code block you wrote was pretty sufficient. Oh well, I probably don't understand too well at this time of day anyway.

And yeah of course, I'll most certainly make a post here with code photos and a video. You won't be able to see how totally cool it is without hearing the audio. Although, we should probably keep in mind that most of my understanding of ArTICL came from guessing, testing, and extrapolating. I'm still missing understanding on some ideas that I think are pretty crucial. Regardless, I'll try my best to polish some of the code to hopefully make it worthy to share.
I have one last question before all of this is relatively unambiguous.
For most of my calculator key presses, all of the presses are as they should be. For example, pressing the "window" key returns a 12. However, if I press the "zoom" button I get another 12. This is a pretty recurring theme with the keys on my calculator. The key that should be a different value are returning a values from a button adjacent to it. This happens 3 other times where pressing 26 returns a 26 instead, 52 returns a 51, 64 returns a 65, and 104 returns a 103. For clarification, all of my buttons work as expected in the regular calculator mode when not using getKey. It's only when I use getKey does it return the wrong key value. Do you suppose that this could be from me using a TI-84 Plus rather than a TI-83?
Yeah, this is an unfortunate side effect of the realToFloat8x routine. I wrote a realToLong8x routine for CalcDCC that I'll push into the ArTICL repository now. I recommend using that instead; those errors should vanish.

jacobharris wrote:
and because I'm much more familiar with coding with the arduino language, I would be able to code much more efficiently with the added bonus that the code would possibly execute faster. I feel so silly now. I coded so much In a foreign language when I could've been coding much faster. It was an interesting learning experience I suppose.
My experience is that learning to write something in one language can help you write better in every language, so it certainly can't hurt to try something like this in TI-BASIC, even if you ended up not using it.

Quote:
Why is this second pass necessary? I think the first code block you wrote was pretty sufficient. Oh well, I probably don't understand too well at this time of day anyway.
Because more optimization, if it doesn't make the code too obscure, slims it down, and doesn't slow it down, rarely goes amiss. It's a good challenge to try to optimize code. Smile

Quote:
And yeah of course, I'll most certainly make a post here with code photos and a video. You won't be able to see how totally cool it is without hearing the audio. Although, we should probably keep in mind that most of my understanding of ArTICL came from guessing, testing, and extrapolating. I'm still missing understanding on some ideas that I think are pretty crucial. Regardless, I'll try my best to polish some of the code to hopefully make it worthy to share.
Please ask those questions! I'd be happy to answer them.
I ended up only changing that single part to "Long" but now my serial output is no longer returning any type of value at all. Is there something else that needs to be changed?

Code:
int value = (int)TIVar::realToLong8x(&data[2], model);
Serial.println(value);

I updated the library just in case but that didn't seem to do much.

edit: actually I think I updated to a version of the library that didn't include the Long edits yet. I'll try again.
edit edit: it's still not working out for me. Debug statements written in the onGetAsCBL2 do not even go through whenever I replace Float with Long but when i put float back in everything works as expected, Uh oh nevermind I seemed to have messed something up Float isn't working anymore either. Well I messed up really bad somewhere.
edit edit edit: I got it working on controlLED perfectly. I'm going to see how I can fix what happened in my project code.

KermMartian wrote:
My experience is that learning to write something in one language can help you write better in every language, so it certainly can't hurt to try something like this in TI-BASIC, even if you ended up not using it.
I totally agree. It was an interesting learning experience for me and helped me put programming in a different perspective as well.[/code]
I'm sorry that you were encountering such confusing problems with the new code, but I'm glad you were able to straighten them out. I look forward to the results of testing realToLong8x() in your own code.
I replaced all the "->" in my code with a period and now everything works as expected! All the values are as they should be as well Very Happy This is great. There are no more inconsistencies in the calculator and I can start being more flexible with the button layout of everything now.
However, there are a few final thoughts before this truly becomes final:
1. on a true midi controller, you can press more than one button at a time if you so please and sounds will play simultaneously. Am I right to think that this is impossible to do on the calculator due to the way that the hardware is? I know you can press two keys after another very quickly but you can't really press them at the same time. Is there any way to get around this in TI BASIC?
2. There is also typically a hold and release feature that recognizes whenever you both press and release the button on midi controllers. I know the calculator has something similar to this where the arrow keys can be held down. Is there any way to get a similar effect with the rest of the keys?
3. If I wanted to add in a second calculator to connect to the same arduino, do you think I would be able to send different messages with it if I simply just created a different instance of CBL2 with it's own different versions of onGetAsCBL2 and onSendAsCBL2?

Sorry if these questions are a little basic, I haven't done much research and testing on these questions because I'm mostly just speculating right now.
jacobharris wrote:
1. on a true midi controller, you can press more than one button at a time if you so please and sounds will play simultaneously. Am I right to think that this is impossible to do on the calculator due to the way that the hardware is? I know you can press two keys after another very quickly but you can't really press them at the same time. Is there any way to get around this in TI BASIC?
2. There is also typically a hold and release feature that recognizes whenever you both press and release the button on midi controllers. I know the calculator has something similar to this where the arrow keys can be held down. Is there any way to get a similar effect with the rest of the keys?
Both of these things could be done with an assembly program, but are impossible in pure TI-BASIC.
Quote:
3. If I wanted to add in a second calculator to connect to the same arduino, do you think I would be able to send different messages with it if I simply just created a different instance of CBL2 with it's own different versions of onGetAsCBL2 and onSendAsCBL2?
It could even use the same callbacks, but would indeed be a different instance of CBL2.
*bump* I have taken the liberty of splitting your ASM questions into a new thread in the z80/ez80 ASM subforum to keep this one on-topic about your ArTICL experiences.
Hi..i am a new user here. As per my knowledge if you're not using a TI cable with white and red conductors, just try them one way around, and if that doesn't work, swap what might be tip and ring. You won't break your Arduino or your calculator by having this backwards. Just make sure you have the ground wire correct.
  
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 1
» 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