02-24-2016, 08:48 PM
Hi All,
I have always had a fascination with early scientific calculators, and I'm impressed by how the engineers in the 1970's did so much with so little. So earlier this month I decided to take a stab at putting some scientific calculator firmware together -- and what better hardware base than the excellent Ardunio-based Spikenzielabs Calculator kit! I started the project focused on just the visible 6 digits of precision and native CORDIC routines for the transcendentals, but quickly learned that we needed more guard digits for it to be truly useful as a "daily driver." Plus, the Spikenzie guys may eventually build a model with more display digits... So I pivoted to an Arduino port of the BigNumber arbitrary precision library, coded up high precision Taylor series approximations for the transcendental functions, and voila! SciCalc was born. The attached defines internal precision to 12 digits (defined by INTDIGITS); feel free to dial this up or down depending on the precision / time tradeoff you are happy with. If you are familiar with well-known Calculator Forensics calculation, the SciCalc returns 9.000076557818 -- not too bad for a lowly Atmel processor!
A few notes before you download the attached sketch:
0. Hardware-wise you'll need to solder a 6 pin header to the edge of the board, extending out of the top of the calculator. By leaving out the small plastic cross-piece which sits UNDER the top edge of the circuit board, there is room for the connector to protrude. I programmed with a SiLABS USB-Serial programmer, but use whatever you have (see photo). If you provide power through the programmer, be sure to remove the battery first!!!
1. The = key is now the Enter key
2. With only 17 keys, I needed a function key. So by pressing and holding the decimal (.) key, each key has an alternate shifted function as below (I have also attached a photo of my labeled keyboard):
. 7 = sin
. 8 = cos
. 9 = tan
. / = square root
. 4 = arcsin
. 5 = arccos
. 6 = arctan
. x = e^x
. 1 = deg / rad toggle
. 2 = x/y exchange
. 3 = stack roll down
. - = chs
3. I modeled stack behavior after the HP-15c, with x (bottom), y, z, t (top) registers. I also track Last x in the software, but ran out of buttons to recall it. With #define DEBUG uncommented, serial logging includes the entire stack with every keypress, so you can sort out what is happening.
4. By holding the Clear key for 3+ seconds, the calculator goes into self-test mode. The string 'testkeys' is looped forever, until you hit the Clear key again. This stops the looping, and shows the number of iterations completed on the display (left in the x register).
5. Internal precision is set to 12 digits; although x is rounded to 6 digits prior to displaying. The rounding occurs at display time, and does not affect the internal precision.
6. As provided, the sin / arcsin, cos / arccos and arctan functions are accurate to +/- 0.00000002. tan begins to become less accurate as cos(x) approaches zero. (I can provide an error chart in Excel format if you are interested, with results from the trig functions on one degree increments, from -360 to +360 degrees). If you do any fine tuning with the algorithms, comment out #define DEBUG and uncomment #define TRIGTEST. At the next restart, the calculator will automatically compute and print a table of the sin, asin, cos, acos, tan, atan for every degree, +/- 360 degrees (serial logging port)
7. I carried power management to the max, and even disabled the brownout detector in the Atmel chip. As a result, when the calculator goes to sleep, the power draw is barely measurable (a microamp or less). I'm guessing the battery life will be several months, or longer? Of course, depending on use.
Have fun, and let me know if you find any bugs!
So attached please find:
- photos of programming connector installed and the labeled keys
- scicalc sketch (unzip and move this and open it in the Arduino IDE)
- BigNumber library (unzip and move this to your Arduino library location)
- as a bonus, I also included the Excel spreadsheet of trig errors for every degree +/- 360 deg, as generated by SciCalc with #define TRIGTEST uncommented
I have always had a fascination with early scientific calculators, and I'm impressed by how the engineers in the 1970's did so much with so little. So earlier this month I decided to take a stab at putting some scientific calculator firmware together -- and what better hardware base than the excellent Ardunio-based Spikenzielabs Calculator kit! I started the project focused on just the visible 6 digits of precision and native CORDIC routines for the transcendentals, but quickly learned that we needed more guard digits for it to be truly useful as a "daily driver." Plus, the Spikenzie guys may eventually build a model with more display digits... So I pivoted to an Arduino port of the BigNumber arbitrary precision library, coded up high precision Taylor series approximations for the transcendental functions, and voila! SciCalc was born. The attached defines internal precision to 12 digits (defined by INTDIGITS); feel free to dial this up or down depending on the precision / time tradeoff you are happy with. If you are familiar with well-known Calculator Forensics calculation, the SciCalc returns 9.000076557818 -- not too bad for a lowly Atmel processor!
A few notes before you download the attached sketch:
0. Hardware-wise you'll need to solder a 6 pin header to the edge of the board, extending out of the top of the calculator. By leaving out the small plastic cross-piece which sits UNDER the top edge of the circuit board, there is room for the connector to protrude. I programmed with a SiLABS USB-Serial programmer, but use whatever you have (see photo). If you provide power through the programmer, be sure to remove the battery first!!!
1. The = key is now the Enter key
2. With only 17 keys, I needed a function key. So by pressing and holding the decimal (.) key, each key has an alternate shifted function as below (I have also attached a photo of my labeled keyboard):
. 7 = sin
. 8 = cos
. 9 = tan
. / = square root
. 4 = arcsin
. 5 = arccos
. 6 = arctan
. x = e^x
. 1 = deg / rad toggle
. 2 = x/y exchange
. 3 = stack roll down
. - = chs
3. I modeled stack behavior after the HP-15c, with x (bottom), y, z, t (top) registers. I also track Last x in the software, but ran out of buttons to recall it. With #define DEBUG uncommented, serial logging includes the entire stack with every keypress, so you can sort out what is happening.
4. By holding the Clear key for 3+ seconds, the calculator goes into self-test mode. The string 'testkeys' is looped forever, until you hit the Clear key again. This stops the looping, and shows the number of iterations completed on the display (left in the x register).
5. Internal precision is set to 12 digits; although x is rounded to 6 digits prior to displaying. The rounding occurs at display time, and does not affect the internal precision.
6. As provided, the sin / arcsin, cos / arccos and arctan functions are accurate to +/- 0.00000002. tan begins to become less accurate as cos(x) approaches zero. (I can provide an error chart in Excel format if you are interested, with results from the trig functions on one degree increments, from -360 to +360 degrees). If you do any fine tuning with the algorithms, comment out #define DEBUG and uncomment #define TRIGTEST. At the next restart, the calculator will automatically compute and print a table of the sin, asin, cos, acos, tan, atan for every degree, +/- 360 degrees (serial logging port)
7. I carried power management to the max, and even disabled the brownout detector in the Atmel chip. As a result, when the calculator goes to sleep, the power draw is barely measurable (a microamp or less). I'm guessing the battery life will be several months, or longer? Of course, depending on use.
Have fun, and let me know if you find any bugs!
So attached please find:
- photos of programming connector installed and the labeled keys
- scicalc sketch (unzip and move this and open it in the Arduino IDE)
- BigNumber library (unzip and move this to your Arduino library location)
- as a bonus, I also included the Excel spreadsheet of trig errors for every degree +/- 360 deg, as generated by SciCalc with #define TRIGTEST uncommented