![]() |
Hewlett Packard HP 41CX
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Caracteristics | Modules | Thermal printer | Card reader | Bar code reader wand | Commented program | Digital multimeter | Data Acquisition Unit | Tape recorder | MCODE programming | Serial interface |
|
![]() Redefining key 23 (SIN) to make it execute MYPRG wich is, in this example, the name of a personal program. |
|
![]() Time and date in english format(february, 12), seconds can be added, the day of week, french format (12 février) |
|
![]() |
![]() The four empty ports |
|
![]() Two ports for modules and the two spare ones are for the printer and the card reader. |
It contains lots of mathematic functions such as:
|
![]() I wrote a french summary of functions (format ![]() that you can download here. |
It brings 238 more registers for extended memory. Those registers can't be accessed directly. Its use is to make a RAMdisk to store data, text files and programs. Unfortunately, I own a module that is not compatible with the CX, it would give the HP 41C 64 more registers. |
![]() |
![]() |
On the printer you can set the intensity (5 steps), use the PRINT and ADVANCE buttons
and the mode selector (MAN, NORM, TRACE) that determines what informations are to be
printed.
It also brings a lot of functions to print registers, programs and to plot mathematical curves. In this document ![]() |
![]() PRP: print program, here the listing of a sample program from the manual. The instruction LIST allows you to print a specific part of a program. |
![]() PRREGX: prints the registers according to X value (here 10,012 for R10 to R12) |
![]() CAT 1: list of programs in memory. Other catalogs are available (alarms, modules, functions...). |
|
Here is the listing for a character redefinition. To start, I clear X and Y with 0 ENTER. Then I enter the binary definition for each column: * * * * * = 1 * * = 2 * * * * = 4 * * = 8 * * * * * = 16 * * = 32 * * * * * = 64For example, for the central column: 1+16+64 = 81. Every column is stored with BLDSPEC. Then the whole character is added to the output buffer with ACSPEC. Then ADV prints it. A similar method is use to print bitmaps with a maximal width of 43 columns (this is the buffer limit). |
![]() Don't miss the last line where the little face I created appears! |
![]() LThe magnetic card reader plugs on top of the calculator. A card is ready to be read. In this document ![]() |
This is a peripherial for data storage. Four card types are available:
|
Allows you toenter programs, values in registries either in direct mode or during the
execution of a program. It has the same capabilities as the card reader (except for saving!).
It's the tool the transfer programs from a PC to your HP 41!! |
![]() |
Firts, you edit the program as a text file with only one instruction per line. I use, as usual, Quick Editor that has editable menus. This makes it possible, from the editor, to run the compiler, print bar codes and use the emulator. | ![]() |
Then, you run the compiler HP41UC.EXE. The first call turn your text file into a
RAW file (a serie of bytes) that can be used with the V41 emulator for Windows.
The second call turns your RAW file into a PS file (PostScript) with the bar codes to be printed. I have written a BATCH file to make this automatic (Clic here to view the file) |
![]() |
Last, you run GSview (Ghost Script View) to view your PS file.
From the same program, you can print the bar codes.
On my laser printer, the output is really nice and clear for the bar code reader.
Reading is really fast: each line is stored in one or two seconds.
The example next is compiled from this program SUITE: ![]() The well know suite that always end at 1:
|
![]() |
![]() |
Now, just read it!! You can see this on the display: WD RDY 03I have read two lines and the HP tells me that it is ready for the 3rd one. With this system, you can get rid of problems with magnetic strips, saving your work on simple sheets of paper.. |
Here is a little program that I use to get informations from my WEB counter on this page. It computes the average visits per day since its installation (december 2007) and another average since the last saved data. This allows me to verify the "impact" of a new publication or modification on my pages.
This program uses:
register | content | register | content |
r00 | current counter | r04 | saved counter |
r01 | current date | r05 | saved date |
r02 | current time | r06 | saved time |
r03 | current average | r07 | saved average |
![]() |
To get the average, the calculator computes the counter difference and the duration.
For duration, the days difference is given by DDAYS and I add a decimal part using the hours, minutes and seconds.
To use it, it's simple: counter XEQ WEB STO 0 STO 1 and STO 2 store current counter, date and time. DDAYS computes the days difference since December, 15th, 2007. 12 HMS- computes the time difference as the counter was set at noon! Divided by 24 it is added as the decimal part for days difference. Then, the display is prepared with the form "AVRG = xx.xx" (AVRG = average), then STOP. After a R/S, the file "WEBDATA" is opened with pointer in first position with 0 SEEKPTA. The sequence 4.007 GETRX gets data in registers 4 to 7, and the previous average (R07) is displayed with "OLD = xx.xx". Another R/S and you get the average since your last saved data, so the calculator computes again the time and date difference and displays eveything with "LAST = xx.xx". A last R/S leads you to the saving routine, you can confirm that you want the new data to become the saved reference (Or, if you don't, the saved data remain the same). In order to do this, 0 SEEKPT puts the pointer back to the beginning of the file and the sequence 0.003 SAVERX saves registers 0 to 3. Before using the program, you have to create the file! Do it with: "WEBDATA" 4 XEQ CRFLD This creates a file names WEBDATA containing 4 registers. Then, when the program is laoded, type: counter XEQ WEBINIT to fill the file with the current counter, date and time for a first reference. Note that there's a BRANCH to the previous saving routine. Download: hp41web.zip. The file contains:
|
It is a multimeter (Volts/Amperes/Ohms for AC or DC) that can be used as a standalone unit with its keyboard and its digital display... | ![]() |
![]() |
... or remoted via its HP-IL interface! In this case, the HP-41 can fully control the multimeter and get readings for an automated treatment. |
![]() |
Program for AC Voltage observing: This programm allows you to take regular readings from an AC voltage source and keep the min, max an average value. (during 1h30, this is 90 readings, my house voltage ranged from 232V to 238V). XEQ OBSERVEinitialization routine: REMOTE: the multimeter becomes a slave. "F1R4Z1T1" OUTA: send a command string for AC Voltage (F1) range 300V (R4) with Autozéro (Z1) and continuous readings (T1). IND: input data, take a reading and stores it into R10 (average), R11 (max), R12 (min) and puts 1 in R13 (number of readings). Then the periodic alarm is programmed: "^^MESURE": the routine to be regularly executed. 0.01: every minute. 0: no date (so start today!). TIME 0.01 HMS+: and start in one minute! XYZALM: programs the alarm. MESUREperiodic routine: TONE 9: a beep when reading. 1 ST+ 13: one more reading. IND ST+ 10: take a new readind and cumulates it into R10. Then, compared to R11, if it's more, it's a new maximum and it displays "MAX "+value. Else, compared to R12, if it's less, it's a new minimum and it displays "MIN "+value. Else, the average is computed (R10/R13) and it displays "MOY "+value. |
Here is the whole stuff with my program running. We can improve things:
|
![]() |
![]() |
Program power consumption of a device: This program computes the power consumption of a device in KWH. Look at the picture: The cable from the power strip was rerouted to make the current go through the multimeter. Then I can measure the current used by one or more devices plugged into the strip. For this first attempt, I used a little fan. |
The routine "CONSO" initializes the program.
FIX 4 for a correct display of hours. REMOTE to put the multimeter in slave mode. "F6R2Z1T1" for AC (F6) up to 3A (R2) with AutoZero (Z1) and continuous reading (T1). The you are asked to input the voltage (230 for my home), the residual current (the little red DEL of the strip uses alone 0,0012A). For that, that's when I switch the strip ON and I make a reading with IND to give the value. Then, give the reading frequency you want, I put 0,0030 for 30 seconds. It's time to switch ON the device! Then R/S to start calculations. The routine "AMPERE" is the periodic routine that makes readings. You hear a BEEP, a reading is performed with IND, the residual current is substracted (R13) before accumulating into R10. This routine requieres 2 seconds to run. At every time, if you want to know the consumption, you run the "KWH" routine that displays the time passed since the beginning: ![]() and the current consumption: ![]() To stop the readings, CATALOG 5 lists the alarms, use R/S to stop on the one that runs "AMPERE" and key in Shift C to clear it. |
![]() |
This unit is mostly a shell that contains acqusition cards according to your needs.
It can have 3 of them:
|
![]() The front panel comes with several inputs allowing you to get AC, DC or Ohms values even if the shell has no cards inside. |
Inside: Apart from the frontal inputs and the LCD panel, you can find:
|
![]() |
For usage in France, I have to set the power voltage to 240V. No soldering is requiered, just a wire to move. | Equally, the power frequency has to be 50 Hz. On this picture, the HP-IL connectors are seen, the same for the 3 rear panels of the cards. One is currently unused. |
![]() |
![]() |
The HP-41 can indivudually address each one of the 10 channels from the 3 cards.
Channels are numbered 0-9 for card #0, 10-19 for card #1 et 20-29 for card #2. Example: alpha DCV13 alpha XEQ OUTA -> sends the command DCV13 to read a DC voltage from channel 3 on card #1. XEQ IND -> (IND = Input Data), retrieve the value read and put it in X.More than one channel can be read at a time! alpha ACV21-24 alpha XEQ OUTA -> ask for AC volatge readings on channels 1 to 4 from card #2. XEQ IND -> retrieve the value read from channel 21 XEQ IND -> the value from channel 22 ... etc. |
![]() |
It uses mini-cassettes: ![]() Each one can hold up to 128KB data. |
![]() |
Spot the BUSY led while the unit is working. |
|
![]() |
![]() |
First, place the file name you want to create in the ALPHA register, I simply call it BACKUP. |
|
![]() |
![]() |
![]() |
![]() |
I had the opportunity to get a CLONIX41 module that Emmanuel C. filled with the following:
|
![]() |
![]() Up above, QuickEditor with a source text being edited and the four programmable menus that allows you to:
|
Writing a program is made easy on the PC using the SDK from Warren Furlow. I like to use QuickEditor whose menus are programmable. The source code is edited in the main window, and then QuickEditor can call:
![]() |
1: You need to know the adress of register 00, it is stored in the system register "c". You type [RCL] [.] [C] and get this peculiar display: | ![]() |
2: You need to decode this register, so you have to type [XEQ] DECODE, the 3 underlined digits are the adress of R00, in this case 19C: | ![]() |
3: Then you switch to MCED and use the SVE command (for save), for example, to save the above program, you need to enter the addresses as it can be seen here, then [R/S]: | ![]() |
4: last, the command asks for the first register address, now you type 19C, then [R/S]: | ![]() |
![]() |
|
|
![]() |
|
|
|
![]() |
(spot the score that increases at each time!) Exchange Left : the 1 and the 2 on the left are exchanged. ![]() Rotate Left : shift pattern left, the 2 becomes the last digit. ![]() Exchange Ends : the 1 and the 2 at the ends are exchanged. ![]() Rotate Right : shift right, the 1 returns to the first position. ![]() Exchange Right: the 8 and the 9 are exchanged. ![]() run the game using 111182222 XEQ TWIXand try to get 222281111 in 14 steps!! ![]() ![]() Contents of twix.zip :
|
; 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ; A= x x N N N N N N N N N D S S ; NNN... the 9 digits ; D = character for separation ; SS how many steps in game ; B used to save A ; C used everywhere ; no other register, no flag. .JDA .ORG F000 F000 01F XROM 31 F001 001 FCNS 1 F002 00000A DEFR4K [TWIX] ;F00A F004 000 NOP F005 000 NOP .NAME "TWIX" F006 098 #098 ;"X" F007 009 #009 ;"I" F008 017 #017 ;"W" F009 014 #014 ;"T" ; initialization F00A 0F8 [TWIX] READ 3 ; copy X into C F00B 11A A=C M ; the mantissa into A F00C 39A RSHFA M ; 9 digits in positions 11 to 4 F00D 006 A=0 S&X ; clear exponent = number of steps, score F00E 2A0 SETDEC ; everything in decimal. ; DISPLAY routine F00F 130010 [DISP] LDIS&X 10 F011 270 RAMSLCT ; dummy ram zone F012 1300FD LDIS&X FD F014 3F0 PRPHSLCT ; select screen F015 0AE10E C=A ALL ; get the 9 digits + score F017 21C R= 2 F018 350 LD@R D ; code for separator in XS F019 1BC RCR 11 ; the first digit in correct position F01A 0A0 SLCTP F01B 35C R= 12 ; for the loop F01C 0E0 [L1] SLCTQ F01D 21C R= 2 F01E 010 LD@R 0 F01F 0D0 LD@R 3 ; prepare code 03N into C F020 3E8 WRIT 15 ; copy to screen F021 2FC RCR 13 ; next digit F022 0A0 SLCTP F023 3D4 R=R-1 ; one less F024 394 ?R= 0 ; until zero F025 3BB JNC [L1] ;-9 F01C F026 130000 LDIS&X 0 ; quit screen F028 3F0 PRPHSLCT F029 3C8 [WAIT] CLRKEY ; wait for a key F02A 3CC ?KEY F02B 3F3 JNC [WAIT] ;-2 F029 F02C 220 C=KEY ; key into 4-3 F02D 33C RCR 1 ; key into 3-2 F02E 166 A=A+1 S&X ; one more step in score F02F 08E B=A ALL ; save A ! F030 0AE A<>C ALL ; key in A 3-2 F031 21C R= 2 ; point to XS F032 0D0 LD@R 3 ; XS = 3 F033 376 ?A#C XS ; last nibble of key is 3 ? F034 3A0 ?NCRTN ; if so, END OF GAME (key from the line ENTER to <-) F035 356 ?A#0 XS ; last nibble of key is zero? F036 39F JC [WAIT] ;-13 F029 ; no, so invalid key ! F037 0F53C0 ?NCXQ [ACTION] ;F03D ; subprogram to treat the actions F039 3C8 [KOFF] CLRKEY ; wait for the key to be released F03A 3CC ?KEY F03B 3F7 JC [KOFF] ;-2 F039 F03C 29B JNC [DISP] ;-45 F00F ; and display new pattern ; ******************************** ; execute the action according to ; one of the 5 keys of first line ; ******************************** F03D 38E [ACTION] RSHFA ALL ; high nibble of KEY in XS F03E 15C R= 6 F03F 050 LD@R 1 F040 0D0 LD@R 3 F041 1D0 LD@R 7 F042 210 LD@R 8 F043 310 LD@R C ; codes for the 5 keys F044 376 ?A#C XS ; equal to C (key C0=LN) F045 0B3 JNC [XRIGHT] ;+22 F05B ; yes, exchange right F046 33C RCR 1 F047 376 ?A#C XS ; equal to 8 (key 80=LOG) F048 113 JNC [RRIGHT] ;+34 F06A ; yes, rotate right F049 33C RCR 1 F04A 376 ?A#C XS ; equal to 7 (key 70=SQR) F04B 093 JNC [XENDS] ;+18 F05D ; yes, exchange ends F04C 33C RCR 1 F04D 376 ?A#C XS ; equal to 3 (key 30=1/X) F04E 0BB JNC [RLEFT] ;+23 F065 ; yes, rotate left F04F 33C RCR 1 F050 376 ?A#C XS ; equal to 1 (key 10=S+) F051 360 ?CRTN ; no! bad key (impossible...) ; ******************************* ; (S+) exchange left ; ******************************* F052 0DC R= 10 F053 0EE [XCOMM] C<>B ALL ; old A value in C F054 10E A=C ALL ; and back in A F055 33C RCR 1 F056 102 A=C @R ; old a11 into a10 (or a4 into a3) F057 37C RCR 12 F058 3DC R=R+1 F059 102 [GETR] A=C @R ; old a10 into a11 (or a3 into a4) F05A 3E0 RTN ; ******************************* ; (LN) exchange right ; ******************************* F05B 01C [XRIGHT] R= 3 F05C 3BB JNC [XCOMM] ;-9 F053 ; ********************************* ; (SQR) exchange ends ; ********************************* F05D 0EE [XENDS] C<>B ALL ; old A value in C F05E 10E A=C ALL ; and back in A F05F 17C RCR 6 F060 19C R= 11 F061 102 A=C @R ; old a3 into a11 F062 23C RCR 2 F063 01C [GET3] R= 3 F064 3AB JNC [GETR] ;-11 F059 ; old a11 into a4 ; ***************************** ; (1/X) rotate left ; ***************************** F065 0EE [RLEFT] C<>B ALL ; old A value in C F066 10E A=C ALL ; and back in A F067 3FA LSHFA M ; shift mantissa, but one digit is lost! F068 13C RCR 8 ; put the old first digit in 3 F069 3D3 JNC [GET3] ;-6 F063 ; and get the lost digit ; ***************************** ; (LOG) rotate right ; ***************************** F06A 0EE [RRIGHT] C<>B ALL ; old A value in C F06B 10E A=C ALL ; and back in A F06C 39A RSHFA M ; shift mantissa, but one digit is lost! F06D 17C RCR 6 ; old last digit in 11 F06E 19C R= 11 F06F 353 JNC [GETR] ;-22 F059 ; and get the lost digit |
I made a version for Android using AppInventor. Downlaod TWIX application. |
![]() |
![]() |
This interface can be inserted into the HP-IL loop and allows you to dialog via a serial link.
The box I got was modified with an extra USB port for a connection to a PC with a simple printer cable. In this case you don't have to use the power unit as the USB provides enough intensity. On a PC, you'll use programs such as HyperTerminal to capture what the calculator is sending. ![]() |
![]() |
I wrote a simple program in FORTH that allows you to capture every byte sent by the HP-41:
By default, the program echoes every character received. The serial port must be configured as this: speed 9600 bauds, data 8 bits, no parity and 1 stop bit.
|
See the listing of the FORTH program | See a capture sample | Download the program |