Menu

Trig version of GLCD routine closes circles

Anonymous
2014-04-16
2014-04-18
  • Anonymous

    Anonymous - 2014-04-16

    I had rather supposed that doing circles parametrically would automatically create closed circles, and it does.

    Here's the code for my initial trial. I haven't generalized it yet, nor worked in the rounding and optimization for speed, but the results are very good. This demo simply prints a single, centered circle of radius 20. I'm using sine and cosine values to two decimal places.

    See what you think. It runs on the simulator and the real LCD nicely.

    ;----- Configuration
    
    #chip 16F88, 8                  ;PIC16F88 running at 8 MHz
    #config mclr=off                ;reset handled internally
    #config osc=int                 ;use internal clock
    
    #include <GLCD.h>
    
    ;----- Constants
    
    ;Pinout is shown for the LCM12864H-FSB-FBW
    ;graphical LCD available from Amazon.
    
    ;       +5V                 ;LCD pin 1
    ;       ground              ;LCD pin 2
    ;       Vo = wiper of pot   ;LCD pin 3
    #define GLCD_DB0 PORTB.0    ;LCD pin 4
    #define GLCD_DB1 PORTB.1    ;LCD pin 5
    #define GLCD_DB2 PORTB.2    ;LCD pin 6
    #define GLCD_DB3 PORTB.3    ;LCD pin 7
    #define GLCD_DB4 PORTB.4    ;LCD pin 8
    #define GLCD_DB5 PORTB.5    ;LCD pin 9
    #define GLCD_DB6 PORTB.6    ;LCD pin 10
    #define GLCD_DB7 PORTB.7    ;LCD pin 11
    #define GLCD_CS2 PORTA.0    ;LCD pin 12
    #define GLCD_CS1 PORTA.1    ;LCD pin 13
    #define GLCD_RESET PORTA.2  ;LCD pin 14
    #define GLCD_RW PORTA.3     ;LCD pin 15
    #define GLCD_RS PORTA.4     ;LCD pin 16
    #define GLCD_ENABLE PORTA.6 ;LCD pin 17
    ;       Vee = pot low side  ;LCD pin 18
    ;       backlight anode     ;LCD pin 19
    ;       backlight cathode   ;LCD pin 20
    
    #define GLCD_WIDTH 128
    #define GLCD_HEIGHT 64
    
    ;----- Variables
    
    dim index, tabVal as byte
    dim i as word
    dim sign as integer
    
    ;----- Program
    
    InitGLCD
    GLCDCLS
    
    for i = 0 to 359
      cx = 63 - (20 * cos(i))/100
      cy = 31 - (20 * sin(i))/100
    
      Pset(cx, cy, on)
    next i
    
    ;----- Subroutines
    
    function ref(in arg1 as integer) as integer
      ;create reference angle (0 to 90) for the argument
    
      if (arg1 > 270) then          ;Quadrant IV
        ref = 360 - arg1
      else
        if (arg1 > 180) then        ;Quadrant III
          ref = arg1 - 180
        else                        ;Quadrant II
          if (arg1 > 90) then
            ref = 180 - arg1
          else
            ref = arg1              ;Quadrant I by default
          end if
        end if
      end if
    end function
    
    ;-----
    
    function sin(in arg2 as integer) as integer
      ;get sine of angle
    
      sign = 1                      ;assume positive first
    
      if arg2 > 180 then
        sign = -1                   ;negative in III and IV
      end if
    
      arg2 = ref(arg2)              ;get the reference angle
    
      index = [byte]arg2+1          ;index into the table
      readTable sineTab, index, tabVal
      sin = [integer]tabVal * sign
    end function
    
    ;-----
    
    function cos(in arg2 as integer) as integer
      ;get cosine of angle
    
      sign = 1                      ;assume result is positive
      if arg2>90 and arg2<270 then
        sign = -1                   ;but negative in II and III
      end if
    
      arg2 = ref(arg2)              ;get the reference angle
      arg2 = 90 - arg2              ;use cofunction identity
      index = [byte]arg2+1          ;index into the table
    
      readTable sineTab, index, tabVal
      cos = [integer]tabVal * sign  ;factor in sign
    end function
    
    ;----- Data
    
    table sineTab store data
      ;Sine data for 0 through 90 degrees, scaled up by 100.
    
      0
      2
      3
      5
      7
      9
      10
      12
      14
      16
      17
      19
      21
      22
      24
      26
      28
      29
      31
      33
      34
      36
      37
      39
      41
      42
      44
      45
      47
      48
      50
      52
      53
      54
      56
      57
      59
      60
      62
      63
      64
      66
      67
      68
      69
      71
      72
      73
      74
      75
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      87
      88
      89
      90
      91
      91
      92
      93
      93
      94
      95
      95
      96
      96
      97
      97
      97
      98
      98
      98
      99
      99
      99
      99
      100
      100
      100
      100
      100
      100
    end table
    
     
  • Anonymous

    Anonymous - 2014-04-16

    Oh, here's a pic.

     
  • Anonymous

    Anonymous - 2014-04-16

    Okay, things are coming along. I worked in the rounding now, and some error detection to keep within the bounds of the screen, and have also made a filled circle command. See the attached figure.

    ;Thomas Henry -- 4/16/2014
    
    ;----- Configuration
    
    #chip 16F88, 8                  ;PIC16F88 running at 8 MHz
    #config mclr=off                ;reset handled internally
    #config osc=int                 ;use internal clock
    
    #include <GLCD.h>
    
    ;----- Constants
    
    ;Pinout is shown for the LCM12864H-FSB-FBW
    ;graphical LCD available from Amazon.
    
    ;       +5V                 ;LCD pin 1
    ;       ground              ;LCD pin 2
    ;       Vo = wiper of pot   ;LCD pin 3
    #define GLCD_DB0 PORTB.0    ;LCD pin 4
    #define GLCD_DB1 PORTB.1    ;LCD pin 5
    #define GLCD_DB2 PORTB.2    ;LCD pin 6
    #define GLCD_DB3 PORTB.3    ;LCD pin 7
    #define GLCD_DB4 PORTB.4    ;LCD pin 8
    #define GLCD_DB5 PORTB.5    ;LCD pin 9
    #define GLCD_DB6 PORTB.6    ;LCD pin 10
    #define GLCD_DB7 PORTB.7    ;LCD pin 11
    #define GLCD_CS2 PORTA.0    ;LCD pin 12
    #define GLCD_CS1 PORTA.1    ;LCD pin 13
    #define GLCD_RESET PORTA.2  ;LCD pin 14
    #define GLCD_RW PORTA.3     ;LCD pin 15
    #define GLCD_RS PORTA.4     ;LCD pin 16
    #define GLCD_ENABLE PORTA.6 ;LCD pin 17
    ;       Vee = pot low side  ;LCD pin 18
    ;       backlight anode     ;LCD pin 19
    ;       backlight cathode   ;LCD pin 20
    
    #define GLCD_WIDTH 128
    #define GLCD_HEIGHT 64
    
    ;----- Variables
    
    dim index, tabVal as byte
    dim i as word
    dim sign as integer
    
    ;----- Program
    
    InitGLCD
    GLCDCLS
    
    circle(10,10,10)
    circle(117,10,10)
    filled(63,31,10)
    circle(63,31,20)
    filled(10,53,10)
    filled(117,53,10)
    
    sub filled(cenX, cenY, rad)
      for i = 0 to 358 step 2
        cx = cenX - ((10*rad * cos(i))/100+5)/10
        cy = cenY - ((10*rad * sin(i))/100+5)/10
    
        edge = 2 * cenX - cx
        for j = cx to edge
        Pset(j,cy,on)
        next j
      next i
    end sub
    
    sub circle(cenX, cenY, rad)
      for i = 0 to 358 step 2
        cx = cenX - ((10*rad * cos(i))/100+5)/10
        cy = cenY - ((10*rad * sin(i))/100+5)/10
    
        if (cx>=0 and cx<=128 and cy>=0 and cy<=64) then
          Pset(cx, cy, on)
        end if  
      next i
    end sub
    
    ;----- Subroutines
    
    function ref(in arg1 as integer) as integer
      ;create reference angle (0 to 90) for the argument
    
      if (arg1 > 270) then          ;Quadrant IV
        ref = 360 - arg1
      else
        if (arg1 > 180) then        ;Quadrant III
          ref = arg1 - 180
        else                        ;Quadrant II
          if (arg1 > 90) then
            ref = 180 - arg1
          else
            ref = arg1              ;Quadrant I by default
          end if
        end if
      end if
    end function
    
    ;-----
    
    function sin(in arg2 as integer) as integer
      ;get sine of angle
    
      sign = 1                      ;assume positive first
    
      if arg2 > 180 then
        sign = -1                   ;negative in III and IV
      end if
    
      arg2 = ref(arg2)              ;get the reference angle
    
      index = [byte]arg2+1          ;index into the table
      readTable sineTab, index, tabVal
      sin = [integer]tabVal * sign
    end function
    
    ;-----
    
    function cos(in arg2 as integer) as integer
      ;get cosine of angle
    
      sign = 1                      ;assume result is positive
      if arg2>90 and arg2<270 then
        sign = -1                   ;but negative in II and III
      end if
    
      arg2 = ref(arg2)              ;get the reference angle
      arg2 = 90 - arg2              ;use cofunction identity
      index = [byte]arg2+1          ;index into the table
    
      readTable sineTab, index, tabVal
      cos = [integer]tabVal * sign  ;factor in sign
    end function
    
    ;----- Data
    
    table sineTab store data
      ;Sine data for 0 through 90 degrees, scaled up by 100.
    
      0
      2
      3
      5
      7
      9
      10
      12
      14
      16
      17
      19
      21
      22
      24
      26
      28
      29
      31
      33
      34
      36
      37
      39
      41
      42
      44
      45
      47
      48
      50
      52
      53
      54
      56
      57
      59
      60
      62
      63
      64
      66
      67
      68
      69
      71
      72
      73
      74
      75
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      87
      88
      89
      90
      91
      91
      92
      93
      93
      94
      95
      95
      96
      96
      97
      97
      97
      98
      98
      98
      99
      99
      99
      99
      100
      100
      100
      100
      100
      100
    end table
    
     
  • MBB

    MBB - 2014-04-17

    Thomas,

    I tried to run your software (the second post) but it would not compile. It gave me two "Else outside End If block" errors and two "End If without If" errors. I traced this to the 'function ref" section. Since I couldn't find anything wrong with the code I removed the "ELSEs" and then it compiled.

    I may have made some mistakes by removing these else statments because all I got on my display was a bunch of horizontal lines.

    Any ideas?

     
  • kent_twt4

    kent_twt4 - 2014-04-17

    Check this line for the Table:

    table sineTab store data
    
    Should be:
    table sineTab  'store data
    
     
  • Anonymous

    Anonymous - 2014-04-17

    MBB, unless I did something funny with cut and paste, I can't understand why it doesn't compile for you. Just to make sure, I've attached the program here. And I tested it again just now, and it compiles and runs for me.

    Kent, that won't hurt anything to comment out "store data" option, but by leaving it in, the table goes to EEPROM. Commenting it out puts the table in program memory.

     
  • kent_twt4

    kent_twt4 - 2014-04-17

    Thomas, I was having a similar problem to what MBB had, only I got some random pixels.

    My bad on the store data command, hadn't used that before. But "as is" code for me, the compile went O.K. sorta, as PicKit2 complained about the hex file being too big for my 16f1783, which shouldn't be the case. Commented out the "store data", thinking it was in need of commenting (hah), and all good for PicKit2. Output got some semblance of circles, but experiencing detached arcs of approx. 45 degrees.

    I'm using Steini's GCB SYNWrite, with 0.9 22/9/2013. What are you using?

     
  • Anonymous

    Anonymous - 2014-04-17

    I'm using 0.9 17/02/2014, which I think is the version in the Hot Release package.

     
  • MBB

    MBB - 2014-04-17

    I tried your GLCD.gcb post but I still couldn't compile it.

    I'm using version 1.0 21/9/2013.

    Something else I had a problem with is this line in your program:

    chip 16F88, 8 ;PIC16F88 running at 8 MHz

    I get a Microsoft.NET Framework unhandled exception saying

    Conversion from string "8 ;PIC1F88 run" to type Double is
    not valid

    If I delete the comment so I have only: #chip 16F88, 8
    then GCB can open the file. This makes no sense.

    I had the same problem when I downloaded your Sine program.

     
  • Anonymous

    Anonymous - 2014-04-18

    Hey guys,

    I'm sorry to learn that this is causing you grief. I just got a real GLCD and tried it. It sure works for me. (See the attached pic). It really does sound like it's a GCB Version problem. I think Anobium manages to keep the versions straight; maybe he'll weigh in with a comment. Wasn't there a problem with integer arithmetic previously?

    I've attached the code I used for the picture. It's very short and sweet, since it now calls upon the trig include file I've described in another thread. And I added some explanatory comments. I'm not sure who is maintaining the GLCD include file, but maybe this would be suitable for inclusion (circle and filled circle commands).

    Since MBB seems to be having a PC related problem, I'll mention that I've done this on two separate laptops, both XP, and using both MPASM and GCASM.

    I'll be working on some diagonal line and triangle commands next.

    ;Circle and filled circle commands on a graphic LCD.
    ;This uses the 2-place trigonometric routines found in
    ;the include file.
    
    ;Thomas Henry -- 4/17/2014
    
    ;----- Configuration
    
    #chip 16F88, 8              ;PIC16F88 running at 8 MHz
    #config mclr=off            ;reset handled internally
    #config osc=int             ;use internal clock
    
    #include <GLCD.h>
    #include <Trig2Places.h>
    
    ;----- Constants
    
    ;Pinout is shown for the LCM12864H-FSB-FBW
    ;graphical LCD available from Amazon.
    
    ;       +5V                 ;LCD pin 1
    ;       ground              ;LCD pin 2
    ;       Vo = wiper of pot   ;LCD pin 3
    #define GLCD_DB0 PORTB.0    ;LCD pin 4
    #define GLCD_DB1 PORTB.1    ;LCD pin 5
    #define GLCD_DB2 PORTB.2    ;LCD pin 6
    #define GLCD_DB3 PORTB.3    ;LCD pin 7
    #define GLCD_DB4 PORTB.4    ;LCD pin 8
    #define GLCD_DB5 PORTB.5    ;LCD pin 9
    #define GLCD_DB6 PORTB.6    ;LCD pin 10
    #define GLCD_DB7 PORTB.7    ;LCD pin 11
    #define GLCD_CS2 PORTA.0    ;LCD pin 12
    #define GLCD_CS1 PORTA.1    ;LCD pin 13
    #define GLCD_RESET PORTA.2  ;LCD pin 14
    #define GLCD_RW PORTA.3     ;LCD pin 15
    #define GLCD_RS PORTA.4     ;LCD pin 16
    #define GLCD_ENABLE PORTA.6 ;LCD pin 17
    ;       Vee = pot low side  ;LCD pin 18
    ;       backlight anode     ;LCD pin 19
    ;       backlight cathode   ;LCD pin 20
    
    #define GLCD_TYPE GLCD_TYPE_KS0108
    #define GLCD_WIDTH 128
    #define GLCD_HEIGHT 64
    
    ;----- Variables
    
    dim cx, cy, edge, j as byte
    dim i as word
    
    ;----- Program
    
    InitGLCD
    GLCDCLS
    
    circle(10,10,10)            ;upper left
    circle(117,10,10)           ;upper right
    filled(63,31,10)            ;center
    circle(63,31,20)            ;center
    filled(10,53,10)            ;lower left
    filled(117,53,10)           ;lower right
    
    ;----- Subroutines
    
    sub circle(cenX, cenY, rad)
      ;Center of circle = (cenX,cenY), radius = rad
    
      for i = 0 to 358 step 2                 ;every two degrees
        cx = cenX-((10*rad*cos(i))/100+5)/10  ;properly rounded x value
        cy = cenY-((10*rad*sin(i))/100+5)/10  ;properly rounded y value
    
        ;the following ignores the pixel if off the screen
        if (cx>=0 and cx<=GLCD_WIDTH and cy>=0 and cy<=GLCD_HEIGHT) then
          Pset(cx, cy, on)                    
        end if  
      next i
    end sub
    
    sub filled(cenX, cenY, rad)
      ;Center of circle = (cenX,cenY), radius = rad
    
      for i = 0 to 358 step 2
        cx = cenX -((10*rad*cos(i))/100+5)/10
        cy = cenY -((10*rad*sin(i))/100+5)/10
        edge = 2 * cenX - cx                  ;compute right edge
    
        for j = cx to edge                    ;fill entire line
          Pset(j,cy,on)
        next j
      next i
    end sub
    
     
  • Anobium

    Anobium - 2014-04-18

    I have watching.... and reading with interest. Well done. This is excellent work. I will just tried on the new GCLD code - compiles with no issues.

    Then, I tried on the Simulator.... no issues. Worked as expected.

    Then, the I tried on the new ST7920 GLCD driver code.... no issues. EXCELLENT!!

    Great job. (I am please too... this is the first piece of external code to be tested on the ST7920 uber cheapo GLCD device...! It was £4.00 GBP)

    My thoughts on the @MBB issues. The release from Sept 13 did have some stack issues where the stack was not handled correctly. I would advise using the Hot Release. Just backup you existing config. FYI: When I was using the Sept 13 release I was getting very odd results during runtime (when the Pic is running) with stack errors - this would show up as corruption on.... the LCD......

     
  • kent_twt4

    kent_twt4 - 2014-04-18

    I want to apologize to everyone for reporting some problems which were of my own doing. I'm going to sit in the corner with the dunce cap one.

    When I moved the GLCD data lines over to PortC, so as not to conflict with programming, I had crossed two adjacent data wires, no wonder I was seeing goofy results.

    I did upgrade to the newest Hot release, but may not have made any difference.

    With the AGM1264F:

     

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.