Omnimaga

Calculator Community => TI Calculators => Axe => Topic started by: Matrefeytontias on January 03, 2012, 09:53:42 am

Title: How to use the link port
Post by: Matrefeytontias on January 03, 2012, 09:53:42 am
Hi guys !

I try to make a little link port test with two balls which are moved with the arrows of the other calc. But when I push a key on each calc, the balls don't move.

Why ?
Title: Re: How to use the link port
Post by: Xeda112358 on January 03, 2012, 09:57:56 am
Could you post a some of your code? I imagine if you are only using arrows, you will only need to send 4 bits, too, if that helps :) We might be able to help out!
Title: Re: How to use the link port
Post by: Matrefeytontias on January 03, 2012, 12:29:33 pm
Now, no bug when I push a key on each calc, but only one white ball moves (on each calc, there is a black balle moved by the calc and a white ball moved by the other calc).

Code: [Select]
.MULTI

ClrHome
ClrDraw
ClrDrawr

0→A→C→D→X→Y
56→B

[3C7EFFFFFFFFFF7E3C→Pic1J1
[3C428181818181423C→Pic1J2

Repeat getkey(15)
 If getkey(2) and (X>0)
  X--
  1→C
 ElseIf getkey(3) and (X<88)
  X++
  2→C
 Else
  0→C
 End

 sub(GET)
 Send(C,500)
 sub(GET)

 DispGraphrClrDraw

End

ClrHome
ClrDraw

Lbl GET
Get→D
If D=1
 A--
ElseIf D=2
 A++
End
Pt-Off(X,Y,Pic1J1
Pt-Off(A,B,Pic1J2
Return
Title: Re: How to use the link port
Post by: saintrunner on January 03, 2012, 01:25:34 pm
Ooooh i love two player games! I hope thats what your going to make! Although good calc gamers are hard to fin at my school :P good luck!
Title: Re: How to use the link port
Post by: Nick on January 03, 2012, 01:27:42 pm
isn't it just because you store the value for both calcs in D ?
when you do that, the sent and gotten value are the same, since it's D for both calcs, get it?
i might be wrong :w00t:
Title: Re: How to use the link port
Post by: Matrefeytontias on January 03, 2012, 02:51:04 pm
@saintrunner yes, that's what I'm trying to do :)

@Nick it's not that, because variables of each calc are undependant, I believe.
Title: Re: How to use the link port
Post by: saintrunner on January 03, 2012, 02:52:56 pm
OOOH! What type of game?
Title: Re: How to use the link port
Post by: Matrefeytontias on January 03, 2012, 04:16:27 pm
I don't know right now ; I'll first practice a bit with the link port, and after that make a big game. Coming soon ;) (if I can resolve the current problem ;D )
Title: Re: How to use the link port
Post by: kindermoumoute on January 06, 2012, 03:10:46 pm
Ok, the fact : I looked around the forum about link command, but I saw nowhere a complete code that used the port link so improved.
So today I worked on it.

My technique is initially to define a calculator server and a calculator client, in Boolean it mean 1 and 0. To specify if the calculator is server or client, I do it more or less randomly, because for the rest of the program I don't mind the order.
Code: [Select]
:.r1 is the number of swap you want to try it work, ussualy 10 is same than 200
:Lbl SYN
:Output(0,,"Synchronisation ...
:0→r2
:Repeat r2>r1 or getKey(15)
:If Get+1
:→r2
:End
:Send(r2,100)
:End
:Returnr2^2
Now we have a server (0) and a client (1), and the first application is to separate server code and client code :
Code: [Select]
!If B
:SRV()
:Else
:CLT()
:End
My first idea was to make a program where the server send and the client get each loop, here a funny example :
Code: [Select]
:.AXE
:[183C7EFFFF7E3C18]→Pic1
:0→X
:ClrHome
:SYN(200)→B
:Repeat getKey(15) or (B>1
:!If B
:SRV()
:Else
:CLT()
:End
:DispGraphClrDraw
:End
:Return

:.Program host
:Lbl SRV
:If X<96
:Pt-On(X,48,Pic1
:End
:X<192?X++,→X
:Send(X,5000)
:Return

:.Program client
:Lbl CLT
:If X>95
:Pt-On(X-96,48,Pic1
:End
:If Get+1:-1→X:End
:Return
(http://data.imagup.com/11/1140453111.gif)
NB : With real calculator there isn't this speed lag, here it's cause of wabbitemu mistake.

Now I thought about a way to send multiple bytes in both directions (for games such as Battleship, Chess, pokemon, and thousands more). My first solution is a system of roundtrip between server and client, after synchronizing calcs.
Code: [Select]
:.r1 ==> number of bytes to send
:Lbl ECH
:SYN(10)
:For(I,0,r1)
:!If B
:Send({L1+I},5000)
:GET()→{L2+I}
:Else
:GET()→{L2+I}
:Send({L1+I},10000)
:End
:End
:Return
:
:Lbl GET
:Repeat Get+1→r2
:If getKey(15)
:Goto ERR
:.ERR routine just leave program
:End
:End
:Returnr2-1
And it work perfectly, but I find this routine not very optimized, so I decided to try another way by sending all at once to the server, then to the client... to be continued.  :thumbsup:

PS : I can't test my code for the moment because of wabbitemu' mistakes...
Title: Re: How to use the link port
Post by: kindermoumoute on February 08, 2012, 04:12:35 pm
I appeal to experts to advise me about the best way to exchange bytes between 2 calcs. Actually the main problem is that link command are bugged : I always loss of bytes with a constant percentage (2~10% according to the calculator). How can we fix and optimize it? :w00t:


I have attached a program that exchange 20 bytes, and then calculates the sum of received values​​: it should display 190. Try it with real calc please.
Title: Re: How to use the link port
Post by: Xeda112358 on February 08, 2012, 04:27:11 pm
Do I send the program to both calcs and then run the program on both?

EDIT: I tried it 10 times on each calculator and they said 190 each time. Also, I even have a bad cord and it worked! +1 :D

EDIT2: If I can figure out how this code works, can I use it in Grammer? (My link protocol does not work for synchronising and whatnot :/)
Title: Re: How to use the link port
Post by: Quigibo on February 08, 2012, 10:15:54 pm
Maybe the problem is that you left Interrupts on?  Interrupts should be off or custom when using the link port otherwise the OS might decide to alter the ports in the middle of the linking.  Try adding an FnOff at the beginning of your program.
Title: Re: How to use the link port
Post by: kindermoumoute on February 09, 2012, 12:37:49 pm
I tried it 10 times on each calculator and they said 190 each time. Also, I even have a bad cord and it worked! +1 :D
Really ? O_o
Ok Quigibo, I'll try it tomorrow.
Title: Re: How to use the link port
Post by: Xeda112358 on February 09, 2012, 02:15:02 pm
Yes and I found that if I pressed clear while it was still synchronizing it returned 20 every time (on either calculator).
Title: Re: How to use the link port
Post by: Happybobjr on February 09, 2012, 04:46:31 pm
wish youwould have told me that months ago Quigibo....
awesome
Title: Re: How to use the link port
Post by: Xeda112358 on February 09, 2012, 05:09:30 pm
O.O I just modified the source a bit and I just now made a program that exchanges Ans with the other calculator if it is a string o.o I used a few spots of assembly, but it works :D I am going to see if there is some way to make it terminate after receiving a certain byte ...

On another note, I tested this twice earlier by sending 255 bytes 100 times and the checksum worked every time :) (this was between TI-84+ and TI-84+SE)
Title: Re: How to use the link port
Post by: kindermoumoute on February 10, 2012, 11:11:08 am
Ok, I identified the problem : when I try between a 83+fr and another 83+fr, it work perfectly. Then when I try with a 83+ and another 83+.. it work perfectly !
The probleme is when I try a 83+ with a 83+fr. :S
After analyzing 25 times, the 83+fr displayed 190 each time, but on the 83+ I have :
So... we have a problem btw 83+ and 83+fr only. FnOff makes no difference, and I wonder if the "port" command could solve the problem? But I really don't understand how it work...  :(

PS : few people have 83+ in France...

EDIT : I though it could help to understand the problem : link1 (http://wikiti.brandonw.net/index.php?title=83Plus:Ports:00), link2 (http://wikiti.brandonw.net/index.php?title=83Plus:Ports:02).
Title: Re: How to use the link port
Post by: Xeda112358 on February 10, 2012, 02:05:58 pm
My friend does not like me at the moment (we got in an argument), so I could not test between the 84+/SE and the 83+ (he has the 83+). Also, I am still trying to work on exchanging two different sized strings.
Title: Re: How to use the link port
Post by: Keoni29 on February 19, 2012, 11:25:50 am
I found these. I dunno if it works like this with axe.
Title: Re: How to use the link port
Post by: Keoni29 on February 19, 2012, 03:53:34 pm
Sorry for the doublepost, but I really need help on getting to know how the AXE protocol works! It's for my TI-nterface schoolproject which has to be finished before the presentations this wednesday!

Please help me out D:
Title: Re: How to use the link port
Post by: Runer112 on February 19, 2012, 05:10:11 pm
Sorry if this is difficult to follow, I didn't really know how to structure the diagram (if you want to call it a diagram). If you have any questions, just ask. Otherwise, I hope this helps!

Code: [Select]
SENDER RECEIVER
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Pull ring low

Repeat up to [ARG 2]*8μs If ring is not low, abort
 | If tip is low, break from loop Pull tip low
If tip is not low, abort

Release tip
Received byte = 0

LOOP 8 TIMES LOOP 8 TIMES
 | Release ring, pull tip low |
 | Wait ~21μs | Wait until tip == ring
 | Rotate byte to send left |
   | If 0 rotated out, pull ring low |
   | If 1 rotated out, release tip |
 | Wait ~12μs | If tip is low, rotate 0 left into byte
 | | If tip is high, rotate 1 left into byte

Release tip and ring
Title: Re: How to use the link port
Post by: calc84maniac on February 19, 2012, 08:16:22 pm
Well that's... different. I had no idea Axe used a delay-based method.
Title: Re: How to use the link port
Post by: Quigibo on February 20, 2012, 07:23:08 pm
Well, one line acts as a "clock" and the other is the data bit being sent.  The receiver never sends confirmation other than telling the sender to start and thus is necessarily delay based rather than confirmation based.  This is because it is the fastest way to link and guarantees that neither calculator can freeze from dead-lock, interruption, or interference.  However, I do want to overhaul the entire routine at some point because there are definitely cross-compatibility issues such as with 83+ to 83+fr.
Title: Re: How to use the link port
Post by: Torio on February 22, 2012, 03:14:28 am
Hello, I don't know if it could be useful for your problem, but I coded this routine a few months ago for a 2-player game.
It works perfectly, and takes 3 parameters :
1) - The adress of the variable to store the byte recieved (°A, for example)
2) - The byte to send
3) - The byte to send after you recieved something

Code: [Select]
Lbl RES
-1 -> {r1}r
Repeat {r1}r != -1 and ({r1}r != 255) or getkey(15)
Send(r2,10)
Get->{r1}r
End
Send(r3,50)
Pause 1
Return

For example if you want to send 1, and recieve something in A and then send 2 :
Code: [Select]
RES(°A, 1, 2)
I separated the byte you send before you recieve, and after you recieve, but it can be the same, though.
If you have any questions, just ask me.
Title: Re: How to use the link port
Post by: kindermoumoute on February 22, 2012, 06:02:46 am
Code: [Select]
{r1}r != -1 and ({r1}r != 255)
Why do you test {r1}r != 255 ???
Title: Re: How to use the link port
Post by: Torio on February 22, 2012, 07:45:15 am
Because you certainly know that when you don't recieve something from Get, it will store -1 in the variable, but sometimes it could store 255 !
That was a major problem that made me lose a lot of time, I don't know why you can have 255 after a unsucessful Get.
Title: Re: How to use the link port
Post by: kindermoumoute on February 22, 2012, 08:11:01 am
I think we get the bug... now quigibo you know what you have to do. ;)

Here a new version, I just add a modulo 256 after all Get+1.
EDIT : don't work... :banghead:
Title: Re: How to use the link port
Post by: Xeda112358 on February 22, 2012, 10:46:56 am
Doesn't Axe return -1 (65535) if it was unsuccessful? (not 255)
Title: Re: How to use the link port
Post by: Torio on February 22, 2012, 10:53:53 am
I'm quite sure, that was the source of all my bugs.
Test my routine, and you will see.
Title: Re: How to use the link port
Post by: Xeda112358 on February 22, 2012, 11:03:09 am
Oh, okay, so you mean sometimes it is supposed to return -1, but instead it returns 255?
Title: Re: How to use the link port
Post by: Torio on February 22, 2012, 11:05:43 am
Exactly. Sometimes 255, sometimes 65535.
Title: Re: How to use the link port
Post by: Xeda112358 on February 22, 2012, 11:16:12 am
I looked at the Axe stuff and in 1.1.1 it seems to only be able to return 255 if it detects that the receiver is ready (and the receiver sends 255). So I am curious, what calculators were you using?
Title: Re: How to use the link port
Post by: Torio on February 22, 2012, 11:22:59 am
Sender and Reciever : TI-83+ (fr).
I can't test right now because I don't have 2 calculators, but when I tested it, I added an Output to see why the byte recieved was wrong, and it was 255.
Title: Re: How to use the link port
Post by: Keoni29 on February 25, 2012, 04:45:12 am
Sorry if this is difficult to follow, I didn't really know how to structure the diagram (if you want to call it a diagram). If you have any questions, just ask. Otherwise, I hope this helps!

Code: [Select]
SENDER RECEIVER
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Pull ring low

Repeat up to [ARG 2]*8μs If ring is not low, abort
 | If tip is low, break from loop Pull tip low
If tip is not low, abort

Release tip
Received byte = 0

LOOP 8 TIMES LOOP 8 TIMES
 | Release ring, pull tip low |
 | Wait ~21μs | Wait until tip == ring
 | Rotate byte to send left |
   | If 0 rotated out, pull ring low |
   | If 1 rotated out, release tip |
 | Wait ~12μs | If tip is low, rotate 0 left into byte
 | | If tip is high, rotate 1 left into byte

Release tip and ring
D: It's not quite clear to me when I have to add delays. This is what I understood:
Code: [Select]
Function get:
If ring is low
 Pull down tip
 Delay
 Release tip
 Set byte to 0 by default
 Loop 8 times
  Wait until tip and ring are equal
   If tip is low
    bit received is 0
  otherwise
    bit received is 1
  Delay 12μs
 End of loop
otherwise
Return -1
End
Return received byte
Added some delays. Otherwise the receiver would just receive a lot of the same (1 or 0)


Code: [Select]
Function send:
Pull ring low
Loop until time runs out
 If tip is low, break from loop
End loop
If time ran out
 Return -1;
Loop 8 times
 Release ring
 pull down tip
 Delay 21μs
 If the bit is 1
  pull ring low
 otherwise
  release tip
 Wait 12μs
End of loop
Release tip and ring

Code: [Select]
void setup(){
 pinMode(2,INPUT);
 pinMode(3,OUTPUT);
 digitalWrite(2,HIGH);//ring release
 digitalWrite(3,HIGH);//tip release
 Serial.begin(9600);
}
int Get(){
 if (digitalRead(2)==LOW) {
  digitalWrite(3,LOW);//pull tip down
  delayMicroseconds(12);
  digitalWrite(3,HIGH);//release tip
  int recvbyte=0;
  for(int i=7; i>=0; i--){
   while (digitalRead(2)!=digital
 Read(3)){}//wait until tip==ring
   if (digitalRead(2)==HIGH){
    bitSet(recvbyte,i);
   }
   while (digitalRead(2)==digitalRead(3)){}
  }
  return recvbyte;
 }
 else {
   
   return 0;
 }
 
}
void loop(){
  Serial.println(Get());
  delay(1000);
}
I ported it to arduino. Lemme tell ya: It doesn't work at all :| Do I have to count cycles???
Title: Re: How to use the link port
Post by: Quigibo on February 25, 2012, 06:59:38 pm
The problem with Torio's code is that its not checking if send was successful.  Also, the wait time is dangerously low as the Get could easily miss it, probably resulting in the byte 255 being received during the next iteration of the loop.  Your pause time should be at least 1000.  I recommend over 5000 to be absolutely safe.  I notice in your code, you receive a byte in between sending.  I'm guessing this is because you want to make sure the first byte sent, but this is definitely the WRONG way to do it.  Here is some example code to send 2 bytes:

:Lbl SEND
:Repeat Send({or1},5000)
:  If getkey(15)
:    Return 0
:  End
:End
:Return Send({or1+1},20000)


This has the same IO as the 1 byte Send command as well as the feature that it will continue to try until it is successful or the clear key is pressed.  The Receive command would be:

:Lbl GET
:!If Get→r1+1
:  Return -1
:End
:Pause 2
:!If Get→r2+1
:  Return -1
:End
:Return r2*256+r1


Again, same IO as regular Get.
Title: Re: How to use the link port
Post by: Keoni29 on March 01, 2012, 03:26:19 pm
I still wonder why my code doesn't work. Do I have to count cycles??
Title: Re: How to use the link port
Post by: Keoni29 on March 04, 2012, 07:33:28 am
Can someone please help me with my code D:
Title: Re: How to use the link port
Post by: Matrefeytontias on February 04, 2013, 10:40:54 am
Heavy bump,

I don't know if you're still on this (I doubt), but since I am (:P), I answer to that.

I think there is a simpler way to receive a byte from the calc with Arduino :

int ring = 2, tip = 3; // let's say that the ring is port 2 and the tip port 3
int gotByte, byteCounter;

void setup(void)
{
  Serial.begin(9600);
}

int getByte(void)
{
  if (digitalRead(ring) == LOW)
  {
    digitalWrite(tip, LOW);
    delayMicroseconds(12);
    digitalWrite(tip, HIGH);
    gotByte = (byteCounter = 0); // yeah, I'm lazy

    while(byteCounter < 8 )
    {
      if(digitalRead(tip) == digitalRead(ring))
      {
        if(digitalRead(tip) == HIGH) gotByte |= 0x80; // sets the 7th bit
        gotByte >>= 1; // shift the whole byte right
        byteCounter++;
      }
    }
  }
  return gotByte;
}

void loop(void)
{
  Serial.println(getByte());
}
Title: Re: How to use the link port
Post by: Keoni29 on February 12, 2013, 09:15:37 am
Oh I already figured out how to pull it off. I just use a two wire interface with one clock and one data line. The clock line should be controlled by the host device. When the host would like to send something it just does that. When the device wants to send something to the host it has to wait for the host to poll the device. It's not the most efficient, but it is stable and reliable.