I own an FX7700 Power Graphic Calculator. I was astonished at the cost of the 'official' Casio interface (about double the calculator cost !!) and so began an investigation with a college.
Connection to the calculator is via a 2.5 mm stereo jack plug.
The connections are:
/\ .... Tip : Transmit data from calc.
== .... Middle : Receive data into calc.
== .... Bottom : 0V or Ground.
[ ]
[__]
I made a cable up (about 1/2m length) where tip and middle are reversed (tip of A to middle of B etc.).
In the rear of my PC I have COM2, a 25w 'D' type connector. This was wired as per the instruction manual for the calculator.
Two problems existed.
To power the Maxim ic I used the RTS/CTS lines which are tied together. These generate around +12V. If memory serves I used a series diode and small electrolytic capacitor to ensure the supply didn't drop out. This raw +12V was passed through a 5V regulator. Whilst this would not be recommended normally, the power drawn by this circuit is negligible, even when communicating.
The below cicuit was built onto a tiny proto-board and fitted inside the 'D' type back shell, with just a 2.5mm stereo jack socket protruding from the rear.
NPN (BC549)
c e
------o-----o-------\ /-------o-------------o----------
13 o | | | --- | | |
o |+ | | | | |+ | |
12 o === | | | 1k |b === | ---
o --- | |_| | --- | ===
11 o | | | | | | +|
o | | o--------o | | |
10 o ___ | | | ___ ------------ |
o /// | | | | /// ---|1 16 | |
9 o | ------- ---100n |+ | | |
o | | / \ 5.6V --- === | | |
8 o-----------o /___\ | --- | 2|-----
o---------o | | | | |
PC 7 o----\ | | | ---|3 6|-----
o \-----|-----o---o----- ---|4 | |
'D' 6 o___________| | |+ | | ---
type o ___ === | MAX232 | ===
5 o____ /// --- | | +|
o | | | | ___
4 o____| ---|5 | ///
o | |
3 o___________________________________________|7 10|___ Middle
o <- Rx | |
2 o___________________________________________|8 9|___ Tip 2.5mm
o Tx -> | | jack
1 o | 15 | _ Base socket
------------ |
| |
___ ___
/// ///
Note:
Unless otherwise stated, all caps are 22uF 16V electrolytic.
NPN transistor is TO92 general purpose. (What I had available).
Connections to pins 6 and 2 of the ic are deliberately reversed, these
being the +10V and -10V charge pump generated supplies.
___ is 0V.
///
There are two protocols for data transfer, single programmes or block mode (all programmes stored within the calculator). I only implemented the first.
In the following, Tx is the calculator and Rx the PC. All data is hexadecimal.
When you press the send key on the calculator the following happens in the single programme transfer mode.
Note: When sending from PC to calculator if the slot in the calculator is full then it responds to the header block with 21h instead of the usual 06h or 2Bh. In this situation the PC must ask the user to continue or not. If not the PC sends 15h otherwise 06h.
Byte No. Data
1 3Ah
2 50h
3 31h + slot number (programme memory no.)
4 00h
5 High byte of prog length
6 Low byte of prog length
7 00h
8 00h
9-39 FFh
40 Checksum byte
Bytes 4,7 and 8 are not known, but are believed to relate to the calculator mode the programme is operating in. (eg Matrix, Regression etc.)For simply storing and retrieving programmes on a computer this information is not required.
However. The calculator only allows upper case characters to be typed. The character set contains ALL ASCII characters, so a programme could be written/modified on your PC and then downloaded to the calculator with lower case characters (or indeed other ASCIIs) for a 'different' look. This would require the checksum to be recalculated for the programme, and if the programme length changed the header would also need modification.
The Microsoft Quick Basic programme I wrote now follows. The software performs its function but is a little fragile. Situations can occur where 'finger' trouble can cause the programme to hang in a loop waiting for the calculator to send data, if the data has already been sent before the pc was ready. I began to incorporate timeout delays but other projects have taken a higher priority.
Credits to Pete Lawrence who helped with the protocol used by the calculator.
GOSUB initialise
DO
DO
GOSUB display
IF select$ = "R" THEN GOSUB rdprg
IF select$ = "T" THEN GOSUB wriprg
IF select$ = "V" THEN GOSUB show
IF select$ = "E" THEN GOSUB edit
IF select$ = "L" THEN GOSUB lprog
IF select$ = "S" THEN GOSUB sprog
IF select$ = "C" THEN GOSUB catalogue
IF select$ = "D" THEN GOSUB delete
LOOP WHILE select$ <> "Q"
PRINT
PRINT
PRINT TAB(10); "Really Quit....Data Backed up ? Quit..(Y)es/(N)o ";
GOSUB yorn
LOOP WHILE question$ <> "Y"
CHDIR "c:\"
CLS
END
initialise:
CHDIR "c:\qbasic\calculat"
file$ = ""
timeout = 100000
num = 7
max = 4095
DIM header(39), cast$(255), valid(num), prglen(num), prgname$(num)
DIM prog(max, num) AS INTEGER
FOR lp = 0 TO num
valid(lp) = -1
NEXT
FOR lp = 0 TO 255
IF lp < 127 AND lp > 31 THEN
cast$(lp) = CHR$(lp)
IF lp = 92 THEN cast$(lp) = CHR$(157)
ELSE
READ cast$(lp)
IF cast$(lp) = "x2" THEN cast$(lp) = CHR$(253)
IF cast$(lp) = "x3" THEN cast$(lp) = CHR$(254)
IF cast$(lp) = "^0.5" THEN cast$(lp) = CHR$(251)
IF cast$(lp) = "^1/3" THEN cast$(lp) = CHR$(254) + CHR$(251)
IF cast$(lp) = "Sigma x" THEN cast$(lp) = CHR$(228) + "x"
IF cast$(lp) = "Sigma x2" THEN cast$(lp) = CHR$(228) + "x" + CHR$(253)
IF cast$(lp) = "Sigma y" THEN cast$(lp) = CHR$(228) + "y"
IF cast$(lp) = "Sigma y2" THEN cast$(lp) = CHR$(228) + "y" + CHR$(253)
IF cast$(lp) = " divide" THEN cast$(lp) = CHR$(246)
IF cast$(lp) = "theta" THEN cast$(lp) = CHR$(233)
IF cast$(lp) = "pi" THEN cast$(lp) = CHR$(227)
IF cast$(lp) = "=<" THEN cast$(lp) = CHR$(243)
IF cast$(lp) = ">=" THEN cast$(lp) = CHR$(242)
IF cast$(lp) = "=>" THEN cast$(lp) = CHR$(175)
IF cast$(lp) = " degrees" THEN cast$(lp) = CHR$(248)
END IF
NEXT lp
RETURN
display:
CLS
PRINT TAB(25); "Fx7700 Interface Software"
PRINT TAB(25); "-------------------------"
PRINT
PRINT TAB(5); "(R)x a programme from the Calculator"; TAB(45); "(L)oad a programme from disk"
PRINT TAB(5); "(T)x a programme to the Calculator"; TAB(45); "(S)ave a programme to disk"
PRINT TAB(5); "(D)elete a programme"; TAB(45); "(E)dit/create a programme"
PRINT TAB(5); "(V)iew a programme"; TAB(45); "(Q)uit the programme"
PRINT TAB(25); "(C)atalogue files"
PRINT
FOR row = 0 TO 1
FOR col = 0 TO 3
PRINT TAB(col * 17 + 5); row * 4 + col; ": ";
PRINT prgname$(row * 4 + col);
NEXT
PRINT
NEXT
PRINT
PRINT TAB(30); "Select: ";
DO
select$ = INKEY$
LOOP WHILE select$ = ""
select$ = UCASE$(select$)
RETURN
catalogue:
PRINT
FILES "*.fxp"
GOSUB continue
RETURN
rdprg:
PRINT TAB(15); "Receive a programme from the Fx7700"
GOSUB whereto
IF question$ = "N" THEN RETURN
PRINT TAB(16); "Awaiting data"
OPEN "COM2:9600,N,8,2" FOR RANDOM AS #1 LEN = 256
DO
LOOP WHILE EOF(1)
IF count = timeout THEN RETURN
DO
'Put timeout counter here
in$ = INPUT$(LOC(1), #1)
LOOP WHILE ASC(in$) <> 22
PRINT #1, CHR$(19);
PRINT TAB(16); "Waiting for header ";
FOR lp = 0 TO 39
DO
LOOP WHILE EOF(1)
in$ = INPUT$(LOC(1), #1)
header(lp) = ASC(in$)
NEXT
chksum = 0
FOR lp = 0 TO 39
chksum = (chksum + header(lp)) MOD 256
NEXT
length = header(4) * 256 + header(5)
IF chksum <> 58 THEN
GOSUB chksum
RETURN
ELSE
PRINT ".....Checked"
PRINT #1, CHR$(6);
END IF
PRINT TAB(16); "Waiting for programme"
prglen(slot) = length
FOR lp = 0 TO length - 1
DO
LOOP WHILE EOF(1)
in$ = INPUT$(LOC(1), #1)
prog(lp, slot) = ASC(in$)
NEXT
IF chksum MOD 256 <> 58 THEN
GOSUB chksum
ELSE
PRINT #1, CHR$(6);
valid(slot) = 0
DO
PRINT
PRINT TAB(16); "Transmission finished "
PRINT TAB(16); "Call file ";
INPUT file$
LOOP WHILE LEN(file$) > 8
prgname$(slot) = file$
END IF
CLOSE #1
RETURN
wriprg:
PRINT TAB(15); "Transmit a programme to the Fx7700"
GOSUB wherefrom
OPEN "COM2:9600,N,8,2" FOR RANDOM AS #1 LEN = 256
IF valid(slot) = -1 THEN RETURN
chksum = 0
FOR lp = 0 TO prglen(slot)
chksum = chksum + prog(lp, slot)
NEXT
header(0) = 58
header(1) = 80
header(2) = 49 + slot
header(3) = 0
header(4) = INT(prglen(slot) / 256)
header(5) = prglen(slot) MOD 256
header(6) = 0
header(7) = 0
FOR lp = 8 TO 38
header(lp) = 255
NEXT
chksum = 0
FOR lp = 0 TO 38
chksum = chksum + header(lp)
NEXT
header(39) = 58 - chksum MOD 256
IF header(39) < 0 THEN
header(39) = header(39) + 256
END IF
PRINT #1, CHR$(22);
GOSUB find
IF response <> 19 THEN
BEEP
PRINT TAB(16); "CHECKSUM ERROR!! "
GOSUB continue
RETURN
END IF
PRINT TAB(16); "Sending Header.....";
FOR lp = 0 TO 39
PRINT #1, CHR$(header(lp));
NEXT
GOSUB find
IF response = 43 THEN
BEEP
PRINT TAB(16); "CHECKSUM ERROR!! "
GOSUB continue
RETURN
END IF
PRINT ".....Checked"
IF response = 33 THEN
con$ = "Y"
BEEP
PRINT TAB(16); "Programme area is full."
PRINT TAB(17); "CONTINUE (Y)es/(N)o ";
GOSUB yorn
IF question$ = "N" THEN
PRINT #1, CHR$(21);
RETURN
ELSE
PRINT #1, CHR$(6);
GOSUB find
END IF
END IF
PRINT TAB(16); "Sending programme"
FOR lp = 0 TO prglen(slot) - 1
PRINT #1, CHR$(prog(lp, slot));
NEXT
GOSUB find
IF response <> 6 THEN
BEEP
PRINT TAB(16); "CHECKSUM ERROR !! "
ELSE
PRINT TAB(16); "Transmission finished "
PRINT TAB(17);
END IF
GOSUB continue
CLOSE #1
RETURN
find:
DO
LOOP WHILE EOF(1)
in$ = INPUT$(LOC(1), #1)
response = ASC(in$)
RETURN
edit:
PRINT TAB(15); "Edit a programme"
RETURN
lprog:
PRINT TAB(15); "Load a programme from disk"
GOSUB whereto
IF question$ <> "N" THEN
FILES "*.fxp"
PRINT TAB(17);
INPUT "Filename to Load"; prgname$(slot)
file$ = prgname$(slot) + ".fxp"
OPEN file$ FOR INPUT AS #1
INPUT #1, prglen(slot)
FOR c = 0 TO prglen(slot)
INPUT #1, prog(c, slot)
NEXT
CLOSE #1
valid(slot) = 0
END IF
RETURN
sprog:
PRINT TAB(15); "Save a programme to disk"
GOSUB wherefrom
IF question$ <> "N" THEN
file$ = prgname$(slot) + ".fxp"
OPEN file$ FOR OUTPUT AS #1
PRINT #1, prglen(slot)
FOR c = 0 TO prglen(slot)
PRINT #1, prog(c, slot)
NEXT
CLOSE #1
END IF
RETURN
whereto:
DO
PRINT TAB(16); "Into which memory slot 0 -"; num; " : ";
DO
slot$ = INKEY$
LOOP WHILE slot$ = ""
slot = ASC(slot$) - 48
LOOP WHILE slot < 0 OR slot > num
PRINT slot
question$ = "Y"
IF valid(slot) = 0 THEN
BEEP
PRINT TAB(17); "That slot is already full ";
PRINT "Overwrite (Y)es/(N)o ";
GOSUB yorn
END IF
RETURN
wherefrom:
DO
PRINT TAB(16); "From which memory slot 0 -"; num; " : ";
DO
slot$ = INKEY$
LOOP WHILE slot$ = ""
slot = ASC(slot$) - 48
LOOP WHILE slot < 0 OR slot > num
PRINT slot
IF valid(slot) = -1 THEN
BEEP
PRINT
question$ = "N"
PRINT TAB(16); "That slot is empty to Continue ";
INPUT q$
END IF
RETURN
chksum:
PRINT #1, CHR$(43);
BEEP
PRINT TAB(17); "CHECKSUM ERROR !!"
GOSUB continue
RETURN
delete:
PRINT TAB(15); "Delete a programme"
GOSUB wherefrom
valid(slot) = -1
prgname$(slot) = " "
RETURN
show:
PRINT TAB(15); "Display Programme"
GOSUB wherefrom
IF valid(slot) = 0 THEN
count = 0
FOR lp = 0 TO prglen(slot) - 2
sym$ = cast$(prog(lp, slot))
IF sym$ = "cr" OR sym$ = " - Disp -" OR sym$ = "END" THEN
IF sym$ = "cr" THEN
PRINT
count = count + 1
ELSE
IF sym$ = "END" THEN
PRINT
END IF
PRINT sym$
count = count + 1
END IF
ELSE
PRINT sym$;
END IF
IF count = 22 THEN
GOSUB continue
count = 0
END IF
NEXT
PRINT
INPUT " when ready"; temp$
ELSE
FOR c = 0 TO 3000: NEXT
END IF
RETURN
yorn:
DO
DO
question$ = INKEY$
LOOP WHILE question$ = ""
question$ = UCASE$(question$)
LOOP WHILE question$ <> "Y" AND question$ <> "N"
RETURN
continue:
PRINT " to Continue "
DO
LOOP WHILE INKEY$ = ""
RETURN
DATA "@","femto","pico","nano","micro","milli","kilo","mega"
DATA "giga","tera","peta","exa"," - Disp -","cr","->","exp"
DATA "=<","<>",">=","=>","f1","f2","f3","f4","f5","f6","A"
DATA "B","C","D","E","F"
DATA "@","Pol(","sin","cos","tan","h","ln","^0.5","(-)","P"
DATA "+","xnor","x2","[]","Integral(","Mo","Sigma x2","Pol("
DATA "sin-1","cos-1","tan-1","d","log","^1/3","Abs","C","-"
DATA " xor","-1"," degrees","Integral(","Med","Sigma x","Rec("
DATA "sinh","cosh","tanh","o","e","Int","Not","x^y"," x (times)"
DATA " or","!","r (radians)","Integral(","Min","n","Rec("
DATA "sinh-1","cosh-1","tanh-1","b","10^","Frac","Neg","^1/x"
DATA " divide"," and","_|","g (gradians)","Integral(","Max"
DATA "Sigma y2","Ans","Ran#","mean x","mean y","xon","xon-1"
DATA "yon","yon-1","A","B","r","peak x","peak y","r","theta"
DATA "Sigma y","pi","Cls","Mcl","Rnd","Dec","Hex","Bin","Oct"
DATA "Scl","Norm","Deg","Rnd","Gra","Eng","Intg","Sigma xy"
DATA "Plot","Line","Lbl","Fix","Sci","Defm","CL","DT","Dsz"
DATA "Isz","Factor","Range","Goto","Prog","Graph Y="
DATA "Graph Integral","Graph Y>","Graph Y<","Graph Y>="
DATA "Graph Y <=","Graph r=","Graph (X,Y)=","@","@","@","@"
DATA "@","P(","Q(","R(","t(","END"