Post Reply 
AriCalculator is a home made pocket calculator.
10-30-2018, 06:43 AM
Post: #61
RE: AriCalculator is a home made pocket calculator.
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 Smile

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.
Find all posts by this user
Quote this message in a reply
10-31-2018, 08:06 AM (This post was last modified: 10-31-2018 09:45 AM by grsbanks.)
Post: #62
RE: AriCalculator is a home made pocket calculator.
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 <stdlib.h>
#include <stdio.h>

#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
Find all posts by this user
Quote this message in a reply
03-13-2019, 05:58 AM (This post was last modified: 06-06-2019 04:15 AM by Dan.)
Post: #63
RE: AriCalculator is a home made pocket calculator.
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.
Find all posts by this user
Quote this message in a reply
03-13-2019, 08:30 PM
Post: #64
RE: AriCalculator is a home made pocket calculator.
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.
Find all posts by this user
Quote this message in a reply
03-26-2019, 08:48 AM (This post was last modified: 03-26-2019 08:51 AM by Dan.)
Post: #65
RE: AriCalculator is a home made pocket calculator.
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
Find all posts by this user
Quote this message in a reply
03-26-2019, 01:44 PM
Post: #66
RE: AriCalculator is a home made pocket calculator.
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/
Find all posts by this user
Quote this message in a reply
04-18-2019, 03:55 AM (This post was last modified: 04-18-2019 03:59 AM by Dan.)
Post: #67
RE: AriCalculator is a home made pocket calculator.
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;
    }
  }
}
Find all posts by this user
Quote this message in a reply
05-02-2019, 08:36 AM (This post was last modified: 05-02-2019 08:46 AM by Dan.)
Post: #68
RE: AriCalculator is a home made pocket calculator.
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-th...lbrot-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.
Find all posts by this user
Quote this message in a reply
05-02-2019, 12:33 PM
Post: #69
RE: AriCalculator is a home made pocket calculator.
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
Find all posts by this user
Quote this message in a reply
05-03-2019, 09:05 AM (This post was last modified: 07-10-2019 05:54 AM by Dan.)
Post: #70
RE: AriCalculator is a home made pocket calculator.
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.

[Image: 48246818276_07e00d4f14_o.jpg]
Find all posts by this user
Quote this message in a reply
05-03-2019, 05:21 PM
Post: #71
RE: AriCalculator is a home made pocket calculator.
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.
Find all posts by this user
Quote this message in a reply
05-06-2019, 12:25 PM
Post: #72
RE: AriCalculator is a home made pocket calculator.
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.
Find all posts by this user
Quote this message in a reply
05-10-2019, 08:51 AM
Post: #73
RE: AriCalculator is a home made pocket calculator.
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
Find all posts by this user
Quote this message in a reply
06-05-2019, 08:41 AM (This post was last modified: 06-07-2019 09:32 AM by Dan.)
Post: #74
RE: AriCalculator is a home made pocket calculator.
(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.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: