AriCalculator is a home made pocket calculator. - Printable Version +- HP Forums (https://www.hpmuseum.org/forum) +-- Forum: Not HP Calculators (/forum-7.html) +--- Forum: Not remotely HP Calculators (/forum-9.html) +--- Thread: AriCalculator is a home made pocket calculator. (/thread-7773.html) Pages: 1 2 3 4 RE: AriCalculator is a home made pocket calculator. - grsbanks - 10-30-2018 06:43 AM I've read a document somewhere that explains how CORDIC can be used to do pretty much everything except hang the washing out. Regardless, I used straightforward long multiplication and long division and a nifty algorithm that gets you a digit of precision for each iteration to calculate sqrt(x). CORDIC got me sin/cos and I just divide one by the other to get tan. I have a good algorithm that uses 1+10^(-i) constants for exp(x) and ln(x) but have found a way to get sinh/cosh & co. using CORDIC so will no doubt use that. Results are encouraging. I'm using a DM42 to calculate the constants I need and to check my results. I'd be stuffed if I didn't have that starting point For now I'm just using the standard gcc toolchain in 64-bit Linux and producing a static library that I'm linking to a test program to obtain/test results. When the time comes to start testing on LPC1115 hardware, I'll be using the ARM-embedded toolchain. It's the same one as for the DM42. RE: AriCalculator is a home made pocket calculator. - grsbanks - 10-31-2018 08:06 AM The library will be fully open source once I'm satisfied that it's working properly. I'm writing it in C that's as portable as I can make it so it should work on pretty much any 32- or 64-bit system. As far as usage is concerned, this small test program in C is linked to the library: Code: ```#include  #include  #include "decfp.h" void prt(_NUM*); int main(int argc, char** argv) {          _NUM x, sn, cs, tn;     RealToNum(&CONST_PI_2,&x);     prt(&x);     NumSinCos(&x,&sn,&cs);     NumScaleTrigVector(&sn,&cs);     prt(&sn);     prt(&cs);          Setting_ErrorOnOverflow = TRUE;     /* NumTan does this anyway */     DECFP_ERR res = NumDivide(&sn,&cs,&tn);     if (res)         printf("ERROR: %s\n",ErrorMessage(res));     else         prt(&tn);          Setting_ErrorOnOverflow = FALSE;     res = NumDivide(&sn,&cs,&tn);     if (res)         printf("ERROR: %s\n",ErrorMessage(res));     else         prt(&tn);     NumNegate(&x,&x);          NumSinCos(&x,&sn,&cs);     NumScaleTrigVector(&sn,&cs);     prt(&sn);     prt(&cs);          Setting_ErrorOnOverflow = TRUE;     res = NumDivide(&sn,&cs,&tn);     if (res)         printf("ERROR: %s\n",ErrorMessage(res));     else         prt(&tn);          Setting_ErrorOnOverflow = FALSE;     res = NumDivide(&sn,&cs,&tn);     if (res)         printf("ERROR: %s\n",ErrorMessage(res));     else         prt(&tn);          return 0; } void prt(_NUM* x) {     char* bfr = NumOutFullPrecision(x);     printf("%s\n",bfr);     free(bfr); }``` Gives this output: Code: ```\$ bin/decfp +1.57079632679489661923132e+0000 +1.00000000000000000000000e+0000 +0.00000000000000000000000e+0000 ERROR: Divide by zero +9.99999999999999999999999e+9999 -1.00000000000000000000000e+0000 +0.00000000000000000000000e+0000 ERROR: Divide by zero -9.99999999999999999999999e+9999``` RE: AriCalculator is a home made pocket calculator. - Dan - 03-13-2019 05:58 AM And here it is, two years in the making, the absolute assembly file for a scientific, keystroke programmable RPN calculator (click on "View Raw"). I've started rewriting the code in C++ for the TI Tiva-C LaunchPad, which features a 32-bit ARM Cortex-M4F CPU. It can be programmed using TI's free Code Composer Studio, which is available for Windows, Mac OS and Linux. RE: AriCalculator is a home made pocket calculator. - KeithB - 03-13-2019 08:30 PM If you have a Mac, do not be in too much of a rush to get CCS. Version 9, which will be fully 64-bit on the Mac, will be out in a few weeks to a month. Commercial: CCS and the TI launchpads are a great way to get into Arduino-like embedded hobbying. The SimpleLink boards incorporate a radio transceiver and an MCU for low cost wireless applications. RE: AriCalculator is a home made pocket calculator. - Dan - 03-26-2019 08:48 AM I've ported quite a bit of functionality across, if anyone has C/C++ code for displaying the values stored on the stack to share that would save me some time. At the moment I am using: sprint(valueString, %f, userStack[index]) to convert the double precision stack value stored in the array userStack to a string. I then display the string (valueString). The problem is the values are all left justified, with a decimal point when it is not needed, e.g. a sample display I get is 5 5.000000 4 125.360000 3 134.000000 2 23.000000 1 100.000000 RE: AriCalculator is a home made pocket calculator. - KeithB - 03-26-2019 01:44 PM You might have to write some code to decide what to print, but there are a bunch of field specifiers to control that kind of behavior. I usually turn to K&R, but here is one resource: https://www.geeksforgeeks.org/format-specifiers-in-c/ RE: AriCalculator is a home made pocket calculator. - Dan - 04-18-2019 03:55 AM I ended up writing a double to string conversion function because of problems with "sprint" and "snprint" in Code Composer Studio. I used this algorithm. Code: ``` void doubleToString(double x) {               unsigned char i = 0;   unsigned char n = 2;   double k = 0.0;   double m = 1.0;   unsigned char dinteger;   for (i = 0; i < Exponent + 1; i++) {     valueString[i] = 0;   }   if (x < 0.0) valueString[0] = 0x0C;   else valueString[0] = 0x0B;   x = fabs(x);   xminus = predecessor(x);   xplus = successor(x);   l = (xminus + x)/2.0;   u = (x + xplus)/2.0;   while (u > pow(10.0,k)) {     k += 1.0;   }   valueString[Exponent] = (unsigned char) k;   W = x / pow(10.0,k - 1);   d = floor(W);   W = W - d;   dinteger = (unsigned char) d;   valueString[n] = dinteger;   while (((d * pow(10.0,k - m)) <= l) && (((d + 1.0) * pow(10.0,k - m)) >= u)) {     m += 1.0;     n += 1;     ddigit = floor(10.0 * W);     W = 10.0 * W - ddigit;     d = 10.0 * d + ddigit;     dinteger = (unsigned char) ddigit;     valueString[n] = dinteger;   }   if (((d * pow(10.0,k - m)) > l) && (((d + 1.0) * pow(10.0,k - m)) >= u)) {   }                                                                  //no change to valueString[n]   else {     if (((d * pow(10.0,k - m)) <= l) && (((d + 1.0) * pow(10.0,k - m)) < u))       valueString[n] = dinteger + 1;     else {                                                          //return the value closest to x       if (fabs(d * pow(10.0,k - m) - x) > fabs((d + 1.0) * pow(10.0,k - m) - x))         valueString[n] = dinteger + 1;     }   }   for (i = Exponent - 1; i > 1; i--) {     if (valueString[i] == 0x0A) {       valueString[i] = 0;       valueString[i-1] += 1;     }   } }``` RE: AriCalculator is a home made pocket calculator. - Dan - 05-02-2019 08:36 AM I've added some drawing commands (at the moment just to turn a pixel on/off) to the keystroke programming language on the calculator, and want to try drawing the Mandelbrot set. Some references I've come across are: http://warp.povusers.org/Mandelbrot/ and http://jonisalonen.com/2013/lets-draw-the-mandelbrot-set/ Interesting, if the absolute value of Z remains less than 2 for all of the iterations, the pixel is turned on. I wonder how many iterations are required to generate the pattern on a black and white 128 x 64 GLCD? EDIT: Looking at the C code in the first link 30 iterations have been used. RE: AriCalculator is a home made pocket calculator. - Chasfield - 05-02-2019 12:33 PM I found an old bit of Casio graphic calculator code I wrote for a 100x60 screen pixel grid. It seemed OK at 20 iterations per pixel position: Code: ``` ClrGraph For 1->P To 100  #for each screen position on a 100x60 grid   For 1->Q To 60    (P-50)/30->A #turn the screen pos. into a complex plane location    (P-30)/30->B    A->C     #buffer the complex number coefficients    B->D    0->N     # zero the iteration count    1->S     # initially, assume the complex number is in the set    Do     1+N->N           #increment the iteration count     A*A-B*B+C->G     #compute next real coefficient - hold in G     2*A*B+D->B       #compute next imaginary coefficient     G->A             #update A, ready for next iteration     If A*A+B*B > 4   #test to see if we are still in the set     Then     0->S              #set S to 0 if break-out has occurred     IfEnd    LpWhile N < 20 And S=1 #repeat until N limit reached or breakout    If S=1    Then   #if in the set, then turn on current pixel (row, col)    PxlOn Q, P    IfEnd   Next Next``` RE: AriCalculator is a home made pocket calculator. - Dan - 05-03-2019 09:05 AM Very nice, thanks Chasfield. What Casio calculator did you use? 76 program steps, about 23 seconds to draw with 40 iterations per pixel. Look forward to drawing the set on a higher resolution colour GLCD. RE: AriCalculator is a home made pocket calculator. - Chasfield - 05-03-2019 05:21 PM The model used was the FX-9860G. I was comparing it to the HP39GII, which was able to generate the Mandelbrot image many times faster. RE: AriCalculator is a home made pocket calculator. - Chasfield - 05-06-2019 12:25 PM The execution times were: HP39G11 44 seconds FX9860G 643 seconds So the HP was way better than an order of size faster for the 100x60 pixel plot. RE: AriCalculator is a home made pocket calculator. - Dan - 05-10-2019 08:51 AM Thanks, I wanted to see how my calculator performs compared to others. It's not bad, 13 seconds with doubles and 7 seconds with floats. Code and pictures here RE: AriCalculator is a home made pocket calculator. - Dan - 06-05-2019 08:41 AM (05-10-2019 08:51 AM)Dan Wrote:  Thanks, I wanted to see how my calculator performs compared to others. It's not bad, 13 seconds with doubles and 7 seconds with floats. Actually, that was the timing with the default 16MHz clock. Setting the clock to the maximum 80MHz gives 2.6 seconds for doubles and 1.4 seconds for floats, so should get good performance on the 120MHz microcontroller and 320 x 240 colour GLCD I received today. The trade off is the higher power consumption, so I'll make the clock speed adjustable by the user. As I am now using different hardware to the AriCalculator, I have started a new thread here.