Omnimaga
Calculator Community => TI Calculators => Axe => Topic started 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 ?
-
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!
-
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).
.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
-
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!
-
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:
-
@saintrunner yes, that's what I'm trying to do :)
@Nick it's not that, because variables of each calc are undependant, I believe.
-
OOOH! What type of game?
-
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 )
-
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.
:.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 :
!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 :
:.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.
:.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...
-
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.
-
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 :/)
-
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.
-
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.
-
Yes and I found that if I pressed clear while it was still synchronizing it returned 20 every time (on either calculator).
-
wish youwould have told me that months ago Quigibo....
awesome
-
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)
-
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 :
- 18 perfect sends (190)
- 181
- 185
- 187
- 189 (twice)
- And twice I needed to force quit because the other calc had finished : 191 O.O
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).
-
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.
-
I found these. I dunno if it works like this with axe.
-
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:
-
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!
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
-
Well that's... different. I had no idea Axe used a delay-based method.
-
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.
-
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
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 :
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.
-
{r1}r != -1 and ({r1}r != 255)
Why do you test {r1}r != 255 ???
-
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.
-
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:
-
Doesn't Axe return -1 (65535) if it was unsuccessful? (not 255)
-
I'm quite sure, that was the source of all my bugs.
Test my routine, and you will see.
-
Oh, okay, so you mean sometimes it is supposed to return -1, but instead it returns 255?
-
Exactly. Sometimes 255, sometimes 65535.
-
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?
-
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.
-
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!
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:
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)
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
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???
-
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.
-
I still wonder why my code doesn't work. Do I have to count cycles??
-
Can someone please help me with my code D:
-
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());
}
-
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.