Menu

Atan_CORDIC and GCBasic

Help
2014-09-20
2014-12-08
  • kent_twt4

    kent_twt4 - 2014-09-20

    Because you are trying to store an integer in eeprom (gcbasic doesn't do that per help)? Best of luck with this approach. I looked at the cordic function a long time ago when gcbasic wasn't as functional as it is today. Since my app was just looking at an inclinometer, then a table sufficed for just a single quadrant.

     
  • kent_twt4

    kent_twt4 - 2014-09-22

    Hopefully the RS232 debug gets you where you need to be.

    I said "looked at" not solved arctan function, haha. Basically I was trying to port the Microchip math library function. That was in assembly, and tried to port to gcb, but gave up on that.

    My mission at the time was to get readings from a Dimension Engr. DE-ACCM2G sensor which is a 2 dimensional accelerometer. The accelerometer in that sensor is the ADXL322.

    The code below really has no bearing on your magnetometer, but maybe the methods used might inspire someone? Here I have:
    1) Committed a Sin-1 table to word values
    2) Limited the table values up to 25 degrees as a test
    3) The confusing table code was implemented before or around the time that table values were limited to byte values.
    4) Initiated those values into an array on startup
    5) Read the AD value in and use a brute force method to sort thru the table/array values till it is exceeded. Then you know the Degree value (i.e. table location).
    6) I thought about using the eeprom, but discarded that approach.
    7) Sorry for the extra debug and general mess the code is in.

    'DimensionEngr DE-ACCM2G with Analog Devices ADXL322
    'Chip model 
    #chip 16f877a,20
    '#config MCLRE = On 
    
    #define LCD_IO 4
    #define LCD_DB4 PORTD.4
    #define LCD_DB5 PORTD.5
    #define LCD_DB6 PORTD.6
    #define LCD_DB7 PORTD.7
    #define LCD_RS PORTC.3
    #define LCD_RW PORTD.0
    #define LCD_Enable PORTD.1
    #define  Transmit PORTA.0
    dir PortA.0 out
    dir PortA.5 in  ;AN4
    
    dim YaxisG as word
    dim SINY as word
    dim Degree as word
    'dim Angle as word
    dim SINarray(52)
    
    'For AngleY = 1 to 180 Step 2
    
    'ReadTable SINinverse, AngleY, SINY_H
    'AngleY += 1
    'ReadTable SINinverse, AngleY, SINY
    'Angle(AngleY)= SINY
    
    'Angle(AngleY)= 256*SINY_H + SINY
    'Next
    '**********EEPROM CODE************
    'dim Angle(6)
    'For EPcount = 0 to 5
    EPWrite (0, 0)
    EPWrite (1, 174)
    EPWrite (2, 1)
    EPWrite (3, 93)
    EPWrite (4, 0x02)
    EPWrite (5, 0x0B)
    
        'EEPROM address, 
        'Angle(AngleY)= EEPROM address, 
    
    '**********************
    cls
    
    Print "Dimension Engr 2G Ac"
    
    ;Put SIN table values into SINarray for fast access
    ReadSINTable
    
    Main:
    
    'At 5V g = +/- 0.750V, and at 10bit ADC, 5V/1023bits = .00489V/bit
    'Then (.004888V/bit)/(0.750V/g) = 0.006517g/bits
    'For example ADC value is 560 bits
    'subtract the zero value (560-512=48 bits)
    'Sin-1(angle)= 48 bits * 0.006517 g/bits = 0.3128g OR the angle is 18.23 degrees
    
    YaxisG = ReadAD10(AN4)
    wait 10 ms
    YaxisG = (YaxisG-512)*65
    Locate 1,0
    If YaxisG >= 10000 then PRINT "Calc ":Print YaxisG
    If YaxisG >= 1000 AND YaxisG < 10000 then Print "Calc  ":PRINT YaxisG
    If YaxisG >= 100 AND YaxisG < 1000 then PRINT "Calc   ":PRINT YaxisG
    If YaxisG >= 10 AND YaxisG < 100 then Print "Calc    ":PRINT YaxisG
    If YaxisG < 10 AND YaxisG < 10 then Print "Calc     ":PRINT YaxisG
    
    SinY = 0
    'For SinAngle = 2 to 52 step 2
    SinAngle = 2
    Do Until SINY >= YaxisG
        'locate 2,1
        'Print SinAngle
    'SINY_H = SINarray(SinAngle)
    'nop
        'LCDHex SINarray(SinAngle):Print " "
    'SinAngle += 1
    '   SINY = SINarray(SinAngle)
    'nop
        'LCDHex SINarray(SinAngle)
    SINY = 256*SINarray(SinAngle) + SINarray(SinAngle+1)
    SinAngle += 2
    nop
    locate 2,0
    'Print SINY
    If SINY >= 10000 then PRINT "Table":Print SINY
    If SINY >= 1000 AND SINY < 10000 then Print "Table ":PRINT SINY
    If SINY >= 100 AND SINY < 1000 then PRINT "Table  ":PRINT SINY
    If SINY >= 10 AND SINY < 100 then Print "Table   ":PRINT SINY
    If SINY < 10 AND SINY < 10 then Print "Table    ":PRINT SINY
    Loop
    
    locate 3,0
    If (SinAngle-1) / 2 >= 10 Then
        Print "Angle ": Print ((SinAngle - 1) / 2)
    Else
        Print "Angle  ":Print ((SinAngle- 1) / 2)
    End if
    
    wait 1 s
    Goto Main 
    ;------------------------------------------------
    
    Sub ReadSINTable
    'locate 2,0
    'Print "SINtable"
    For tableNum = 2 to 51  ;i.e. 2 to 52 because of incr. 
        'locate 3,0
    ReadTable SINinverse, tableNum, SINY_H
    SINarray(tableNum) = SINY_H
    tableNum += 1
    ReadTable SINinverse, tableNum, SINY
        'SINY = 256*SIN_H + SINY
    SINarray(tableNum) = SINY
        'If YaxisG < SINY Then
        '   Print tableNum
        '   goto exitTable
        'End if
    
    'If SINY >= 10000 then PRINT SINY
    'If SINY >= 1000 AND SINY < 10000 then Print " ":PRINT SINY
    'If SINY >= 100 AND SINY < 1000 then PRINT "  ":PRINT SINY
    'If SINY >= 10 AND SINY < 100 then Print "   ":PRINT SINY
    'If SINY < 10 AND SINY < 10 then Print "    ":PRINT SINY
    'Wait 3 sec
    Next
    end sub
    
    'For Wordvalue = 1 to 3 ;number of words read
    Sub EPSinTable
    For NumDeg = 1 to 5 step 2 ;number of words read 
    'locate 1,0
    'Print " "  
    NumDeg -= 1  ;For/Next doesn't work with 0 to X
    'EPRead (NumDeg, DegreeH)
    NumDeg += 1
    'EPRead (NumDeg, DegreeL)
    Degree = DegreeH * 256 + DegreeL
        'Print (Degree)
        'Print "  "
        '0,174,01,93,01,211
    wait 1 s
    next
    end sub
    
    Table SINinverse  ;GCBasic likes decimal no.'s
    ;GCBasic inserts length of table in first bytes location
    0X00  ;bump table to even no. because 0(even) occcupied by size
    0x00  ;begin table values at addr. 2 (even no.)
    0xAE  ;dec 174  1 degree
    0x01
    0x5D  ;dec 349
    0x02
    0x0B  ;dec 523
    0x02
    0xBA  ;dec 698
    0x03
    0x68  ;dec 872  5 degrees
    0x04
    0x15  ;dec 1045
    0x04
    0xC3  ;dec 1219
    0x05
    0x70  ;dec 1392
    0x06
    0x1C  ;dec 1564
    0x06
    0xC8  ;dec 1736  10 degrees
    0x07
    0x74  ;dec 1908
    0x08
    0x1F  ;dec 2079
    0x08
    0xC9  ;dec 2249
    0x09
    0x73  ;dec 2419
    0x0A
    0x1C  ;dec 2588  15 degrees
    0x0A
    0xC4  ;dec 2756
    0x0B
    0x6C  ;dec 2924
    0x0C
    0x12  ;dec 3090
    0x0C
    0xB8  ;dec 3256
    0x0D
    0x5C  ;dec 3420  20 degrees
    0x0E
    0x00  ;dec 3584
    0x0E
    0xA2  ;dec 3746
    0x0F
    0x43  ;dec 3907
    0x0F
    0xE3  ;dec 4067
    0x10
    0x82  ;dec 4226  25 degrees
    
    '4384
    '4540
    '4695
    '4848
    '5000  30 degrees
    '5150
    '5299
    '5446
    '5592
    end table
    
     
  • alejandro1957

    alejandro1957 - 2014-09-23

    thanks.
    I did the math by hand CORDIC algorithm for the function ATAN.
    the result is the same as the program atan2 in Gambas2.
    see txt file

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.