Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 00:41 06 Jul 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Port of Adafruit graphics library: v4.6

Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10205
Posted: 12:29am 13 Nov 2014
Copy link to clipboard 
Print this post

Hi

I'm waiting on delivery of a couple of the very cheap OLED 128x64 i2c graphics displays.

In the meantime I have ported the Adafruit GFX library across to the micromite v4.6B20 ready to use. The example programs simulate the display using a character array and print statements and test all the functions but there should only be two places where changes are needed for any specific hardware display. These are the drawpixel and initdisplay routines. The routines support up to 256 colours but the colour parameters can be ignored for monochrome displays.

Hope this is of use.

If anyone has any suggestions for speed improvements or anyone wants to implement any of the routines as cfunctions and make these available this would be appreciated.

Best Regards

Peter

' Port of Adafruit graphics library
'
' assumes a graphics display where top left is point 0,0
'
'sub setRotation(x) 'sets screen rotation: 0=normal, 1=invert, 2=rotate right, 3-rotate left
'sub drawCircle(x0,y0,r,fg$) 'x,y coordinates of centre, radius, colour
'sub fillCircle(x0, y0, r, fg$) 'x,y coordinates of centre, radius, colour
'sub drawTriangle(x0, y0, x1, y1, x2, y2, fg$) 'three coordinate pairs, colour
'sub fillTriangle (x0, y0, x1, y1, x2, y2, fg$) 'three coordinate pairs, colour
'sub drawChar(x, y, c, fg$, bg$, size, orientation) 'x,y coordinates of top left of first character, ascii character, foreground colour, background colour, size, orientation
'sub printstring(xx0,yy0,text$,fg$,bg$,size,orientation) 'x,y coordinates of top left of first character, text string, foreground colour, background colour, size, orientation
'sub drawLine(xx0,yy0,xx1,yy1,fg$)' x,y of start line, x,y of end line, colour
'sub drawFastHLine(x, y,w,fg$)'draw horizontal line: x,y coordinates of left of line, width, colour
'sub drawFastVLine(x, y,h,fg$)'draw horizontal line: x,y coordinates of top of line, height, colour
'sub drawRect(x,y,w,h,fg$) 'x,y coordinate of top left, width, height,colour
'sub fillRect(x, y, w, h,fg$)'x,y coordinate of top left, width, height,colour
'sub drawRoundRect(x, y, w, h, r, fg$) 'x,y coordinates of top left, width, height, radius of corner, colour
'sub fillRoundRect(x, y, w,h, r, fg$) 'x,y coordinates of top left, width, height, radius of corner, colour
'sub fillscreen(f$) 'fill colour
'sub drawPixel(x,y,fg$) 'x,y coordinates, colour
'
cpu 48
option default integer
Option explicit
const WIDTH=64
const HEIGHT=64
const normal=0
const invert=1
const rotate_right=2
const rotate_left=3
dim c(255),col(5),bits(6,8)
dim screen$(height) length width 'set up array for screen map to mimic display
dim i,j,k,char
dim rotation
dim foreground$ length 1
dim background$ length 1
dim rot_width,rot_height
'
init:
loadchars 'load ascci character array
initdisplay 'initialise the display
foreground$="#"
background$=" "
'
Main: 'demonstrate all library functions in all orientations
for k=0 to 3
setrotation(k)
fillscreen(".")
drawrect(0,0,64,64,"*")
filltriangle(12,52,32,52,17,40,"T")
drawtriangle(6,40,26,32,11,30,"t")
fillroundrect(5,15,20,10,3,"R")
drawroundrect(2,12,26,16,5,"r")
fillrect(34,11,7,12,"O")
fillcircle(45,37,10,"C")
drawcircle(45,37,12,"c")
printstring(2,2,"normal",foreground$,background$,1,normal)
printstring(61,61,"inverted",foreground$,background$,1,inver t)
printstring(61,2,"down",foreground$,background$,1,rotate_rig ht)
printstring(2,61,"up",foreground$,background$,1,rotate_left)
print " 012345678901234567890123456789012345678901234567890123456789 0123"
for i=0 to rot_height-1
print str$(i,3)+" "+screen$(i)
next i
next k
end
'
sub initdisplay 'replace these lines with code for specific display
for i=0 to height-1
poke var screen$(i),0,64 'preset the string lengths
next i
end sub
'
sub drawCircle(x0,y0,r,fg$) 'x,y coordinates of centre, radius, colour
local f=1-r
local ddF_x=1
local ddF_y=-2 * r
local x=0
local y=r
drawPixel(x0 , y0+r,fg$)
drawPixel(x0 , y0-r,fg$)
drawPixel(x0+r, y0 ,fg$)
drawPixel(x0-r, y0 ,fg$)
do while (x<y)
if f >= 0 then
y=y-1
ddF_y = ddF_y+2
f = f+ddF_y
endif
x=x+1
ddF_x = ddF_x+2
f = f+ ddF_x

drawPixel(x0 + x, y0 + y,fg$)
drawPixel(x0 - x, y0 + y,fg$)
drawPixel(x0 + x, y0 - y,fg$)
drawPixel(x0 - x, y0 - y,fg$)
drawPixel(x0 + y, y0 + x,fg$)
drawPixel(x0 - y, y0 + x,fg$)
drawPixel(x0 + y, y0 - x,fg$)
drawPixel(x0 - y, y0 - x,fg$)
loop
end sub
'
sub drawTriangle(x0, y0, x1, y1, x2, y2, fg$) 'three coordinate pairs, colour
drawLine(x0, y0, x1, y1, fg$)
drawLine(x1, y1, x2, y2, fg$)
drawLine(x2, y2, x0, y0, fg$)
end sub
'
sub fillTriangle (x0, y0, x1, y1, x2, y2, fg$) 'three coordinate pairs, colour
local a, b, y, last
if (y0 > y1) then
swap(y0, y1)
swap(x0, x1)
endif
if (y1 > y2) then
swap(y2, y1)
swap(x2, x1)
endif
if (y0 > y1) then
swap(y0, y1)
swap(x0, x1)
endif
if(y0 = y2) then ' Handle awkward all-on-same-line case as its own thing
a = x0
b = x0
if(x1 < a) then
a = x1
else
if(x1 > b) then b = x1
endif
if(x2 < a) then
a = x2
else
if(x2 > b) then b = x2
endif
drawFastHLine(a, y0, b-a+1, fg$)
exit sub
endif
local dx01=x1 - x0
local dy01=y1 - y0
local dx02=x2 - x0
local dy02=y2 - y0
local dx12=x2 - x1
local dy12=y2 - y1

local sa = 0
local sb = 0
if(y1 = y2) then
last = y1'Include y1 scanline
else
last = y1-1' Skip it
endif
for y=y0 to last
a = x0 + sa / dy01
b = x0 + sb / dy02
sa = sa + dx01
sb = sb + dx02
a = x0 + (x1 - x0) * (y - y0) / (y1 - y0)
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0)
if(a > b) then swap(a,b)
drawFastHLine(a, y, b-a+1, fg$)
next y
sa = dx12 * (y - y1)
sb = dx02 * (y - y0)
do while y<=y2
a = x1 + sa / dy12
b = x0 + sb / dy02
sa = sa+dx12
sb = sb+dx02
a = x1 + (x2 - x1) * (y - y1) / (y2 - y1)
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0)
if(a > b) then swap(a,b)
drawFastHLine(a, y, b-a+1, fg$)
y=y+1
loop
end sub
'
sub printstring(xx0,yy0,text$,fg$,bg$,size,orientation) 'x,y coordinates of top left of first character, text string, foreground colour, background colour, size, orientation
local i,c
local x = xx0
local y = yy0
if orientation=1 then
x=x-(6*size)+1
y=y-(8*size)+1
endif
if orientation=2 then
x=x-(8*size)+1
endif
if orientation=3 then
y=y-(6*size)+1
endif
for i=1 to len(text$)
c=asc(mid$(text$,i,1))
drawchar(x,y,c,fg$,bg$,size,orientation)
on orientation+1 goto pnormal,pinvert,protateright,protateleft
pnormal:
x=x+(6*size)
goto pcontinue
pinvert:
x=x-(6*size)
goto pcontinue
protateright:
y=y+(6*size)
goto pcontinue
protateleft:
y=y-(6*size)
pcontinue:
next i
end sub
'
sub drawLine(xx0,yy0,xx1,yy1,fg$)' x,y of start line, x,y of end line, colour
local dx, dy
local x0=xx0
local y0=yy0
local x1=xx1
local y1=yy1
local err,ystep
local steep = (abs(y1 - y0)) > (abs(x1 - x0))
if (steep) then
swap(x0, y0)
swap(x1, y1)
endif
if (x0 > x1) then
swap(x0, x1)
swap(y0, y1)
endif
dx = x1 - x0
dy = abs(y1 - y0)
err = dx / 2
if y0 < y1 then
ystep = 1
else
ystep = -1
endif
do while x0<=x1
if (steep) then
drawPixel(y0, x0,fg$)
else
drawPixel(x0, y0,fg$)
endif
err = err- dy
if err < 0) then
y0 = y0+ ystep
err = err+ dx
endif
x0=x0+1
loop
end sub
'
sub swap a,b
local t
t=b
b=a
a=t
end sub
'
sub drawRect(x,y,w,h,fg$) 'x,y coordinate of top left, width, height,colour
drawFastHLine(x, y, w,fg$)
drawFastHLine(x, y+h-1, w,fg$)
drawFastVLine(x, y, h,fg$)
drawFastVLine(x+w-1, y, h,fg$)
end sub
'
sub drawFastVLine(x, y,h,fg$)'draw horizontal line: x,y coordinates of top of line, height, colour
LOCAL i
for i=y to y+h-1
drawpixel(x, i,fg$)
next i
end sub
'
sub drawFastHLine(x, y,w,fg$)'draw horizontal line: x,y coordinates of left of line, width, colour
local i
for i=x to x+w-1
drawpixel(i, y, fg$)
next i
end sub
'
sub fillRect(x, y, w, h,fg$)'x,y coordinate of top left, width, height,colour
local i
for i=x to x+w-1
drawFastVLine(i, y, h,fg$)
next i
end sub
'
sub drawChar(x, y, c, fg$, bg$, size, orientation) 'x,y coordinates of top left of first character, ascii character, foreground colour, background colour, size, orientation
local i,j,LINE,xx,yy
getchar(c,bits()) 'loads the character into the bits array
on orientation+1 goto dnormal,dinvert,drotateright,drotateleft
dnormal:
for i=0 to 5 'step down the lines
for j = 0 to 7
if bits(i,j) then
if (size = 1) then
drawPixel(x+i, y+j,fg$)
else
fillRect(x+(i*size), y+(j*size), size, size,fg$)
endif
else
if (size = 1) then
drawPixel(x+i, y+j,bg$)
else
drawRect(x+(i*size), y+(j*size), size, size,bg$)
endif
endif
next j
next i
exit sub
'
dinvert:
for i=0 to 5 'step down the lines
for j = 0 to 7
if bits(5-i,7-j) then
if (size = 1) then
drawPixel(x+i, y+j,fg$)
else
fillRect(x+(i*size), y+(j*size), size, size,fg$)
endif
else
if (size = 1) then
drawPixel(x+i, y+j,bg$)
else
drawRect(x+(i*size), y+(j*size), size, size,bg$)
endif
endif
next j
next i
exit sub
'
drotateright:
for i=0 to 7 'step down the lines
for j = 0 to 5
if bits(j,7-i) then
if (size = 1) then
drawPixel(x+i, y+j,fg$)
else
fillRect(x+(i*size), y+(j*size), size, size,fg$)
endif
else
if (size = 1) then
drawPixel(x+i, y+j,bg$)
else
drawRect(x+(i*size), y+(j*size), size, size,bg$)
endif
endif
next j
next i
exit sub
drotateleft:
for i=0 to 7 'step down the lines
for j = 0 to 5
if bits(5-j,i) then
if (size = 1) then
drawPixel(x+i, y+j,fg$)
else
fillRect(x+(i*size), y+(j*size), size, size,fg$)
endif
else
if (size = 1) then
drawPixel(x+i, y+j,bg$)
else
drawRect(x+(i*size), y+(j*size), size, size,bg$)
endif
endif
next j
next i
end sub
'
sub fillscreen(f$) 'fill colour
fillrect(0,0,rot_width,rot_height,f$)
end sub
'
sub drawPixel(x,y,fg$) 'x,y coordinates, colour
local xp
local yp
on rotation+1 goto anormal,ainvert,arotateright,arotateleft
anormal:
xp=x+1 'string positions start at 1
yp=y
goto setpixel
ainvert:
xp=width-x
yp=height-y-1
goto setpixel
arotateright:
yp=x
xp=width-y
goto setpixel
arotateleft:
yp=height-x-1
xp=y+1
setpixel:
if xp<=rot_width and yp< rot_height and xp>=1 and yp>=0 then
' replace the next line with the call to a routine for the specific display used
poke var screen$(yp),xp,asc(fg$)
else
print xp,yp
endif
end sub
'
sub fillCircle(x0, y0, r, fg$) 'x,y coordinates of centre, radius, colour
drawFastVLine(x0, y0-r, 2*r+1, fg$);
fillCircleHelper(x0, y0, r, 3, 0, fg$);
end sub
'
sub drawRoundRect(x, y, w, h, r, fg$) 'x,y coordinates of top left, width, height, radius of corner, colour
drawFastHLine(x+r , y , w-2*r, fg$) ' Top
drawFastHLine(x+r , y+h-1, w-2*r, fg$) 'Bottom
drawFastVLine(x , y+r , h-2*r, fg$)'Left
drawFastVLine(x+w-1, y+r , h-2*r, fg$)'Right
drawCircleHelper(x+r , y+r , r, 1, fg$)
drawCircleHelper(x+w-r-1, y+r , r, 2, fg$)
drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, fg$)
drawCircleHelper(x+r , y+h-r-1, r, 8, fg$)
end sub
'
sub drawCircleHelper( x0, y0,r,cornername,fg$)
local f = 1 - r
local ddF_x = 1
local ddF_y = -2 * r
local x = 0
local y = r

do while (x<y)
if (f >= 0) then
y=y-1
ddF_y = ddF_y+ 2
f = f+ddF_y
endif
x=x+1
ddF_x =ddF_x+ 2
f = f+ddF_x
if (cornername and 4) then
drawPixel(x0 + x, y0 + y, fg$)
drawPixel(x0 + y, y0 + x, fg$)
endif
if (cornername and 2) then
drawPixel(x0 + x, y0 - y, fg$)
drawPixel(x0 + y, y0 - x, fg$)
endif
if (cornername and 8) then
drawPixel(x0 - y, y0 + x, fg$)
drawPixel(x0 - x, y0 + y, fg$)
endif
if (cornername and 1) then
drawPixel(x0 - y, y0 - x, fg$)
drawPixel(x0 - x, y0 - y, fg$)
endif
loop
end sub
'
sub fillCircleHelper(x0, y0, r,cornername, delta, fg$)

local f = 1 - r
local ddF_x = 1
local ddF_y = -2 * r
local x = 0
local y = r

do while x<y
if f >= 0 then
y=y-1
ddF_y =ddF_y+ 2
f = f+ddF_y
endif
x=x+1
ddF_x = ddF_x+2
f = f+ddF_x

if (cornername and 1) then
drawFastVLine(x0+x, y0-y, 2*y+1+delta, fg$)
drawFastVLine(x0+y, y0-x, 2*x+1+delta, fg$)
endif
if (cornername and 2) then
drawFastVLine(x0-x, y0-y, 2*y+1+delta, fg$)
drawFastVLine(x0-y, y0-x, 2*x+1+delta, fg$)
endif
loop
end sub
'
sub fillRoundRect(x, y, w,h, r, fg$) 'x,y coordinates of top left, width, height, radius of corner, colour
fillRect(x+r, y, w-2*r, h, fg$)
fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, fg$)
fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, fg$)
end sub
'
sub setRotation(x) 'sets screen rotation: 0=normal, 1=invert, 2=rotate right, 3-rotate left
rotation = (x and 3)
if rotation >=2 then
rot_width = WIDTH
rot_height = HEIGHT
else
rot_width=width
rot_height=height
endif

end sub
'
sub getchar(a,b()) 'get the bits for the character a and put them in array b
local shift
for j=4 to 0 step -1
shift=j*8
col(j)=c(a)>>shift and &H7F
for i=6 to 0 step -1
b(4-j,i)=col(j)>>i and 1
next i
next j
end sub
'
sub loadchars
for i=0 to 7
bits(5,i)=0
next i
for j=0 to 5
bits(j,7)=0
next j
c(0)=&H0000000000
c(1)=&H3E5B4F5B3E
c(2)=&H3E6B4F6B3E
c(3)=&H1C3E7C3E1C
c(4)=&H183C7E3C18
c(5)=&H1C577D571C
c(6)=&H1C5E7F5E1C
c(7)=&H00183C1800
c(8)=&HFFE7C3E7FF
c(9)=&H0018241800
c(10)=&HFFE7DBE7FF
c(11)=&H30483A060E
c(12)=&H2629792926
c(13)=&H407F050507
c(14)=&H407F05253F
c(15)=&H5A3CE73C5A
c(16)=&H7F3E1C1C08
c(17)=&H081C1C3E7F
c(18)=&H14227F2214
c(19)=&H5F5F005F5F
c(20)=&H06097F017F
c(21)=&H006689956A
c(22)=&H6060606060
c(23)=&H94A2FFA294
c(24)=&H08047E0408
c(25)=&H10207E2010
c(26)=&H08082A1C08
c(27)=&H081C2A0808
c(28)=&H1E10101010
c(29)=&H0C1E0C1E0C
c(30)=&H30383E3830
c(31)=&H060E3E0E06
c(32)=&H0000000000
c(33)=&H00005F0000
c(34)=&H0007000700
c(35)=&H147F147F14
c(36)=&H242A7F2A12
c(37)=&H2313086462
c(38)=&H3649562050
c(39)=&H0008070300
c(40)=&H001C224100
c(41)=&H0041221C00
c(42)=&H2A1C7F1C2A
c(43)=&H08083E0808
c(44)=&H0080703000
c(45)=&H0808080808
c(46)=&H0000606000
c(47)=&H2010080402
c(48)=&H3E5144953E
c(49)=&H00427F4000
c(50)=&H7249494946
c(51)=&H2141494D33
c(52)=&H1814127F10
c(53)=&H2745454539
c(54)=&H3C4A494931
c(55)=&H4121110907
c(56)=&H3649494936
c(57)=&H464949291E
c(58)=&H0000140000
c(59)=&H0040340000
c(60)=&H0008142241
c(61)=&H1414141414
c(62)=&H0041221408
c(63)=&H0201590906
c(64)=&H3E415D594E
c(65)=&H7C1211127C
c(66)=&H7F49494936
c(67)=&H3E41414122
c(68)=&H7F4141413E
c(69)=&H7F49494941
c(70)=&H7F09090901
c(71)=&H3E41415173
c(72)=&H7F0808087F
c(73)=&H00417F4100
c(74)=&H2040413F01
c(75)=&H7F08142241
c(76)=&H7F40404040
c(77)=&H7F021C027F
c(78)=&H7F0408107F
c(79)=&H3E4141413E
c(80)=&H7F09090906
c(81)=&H3E4151215E
c(82)=&H7F09192946
c(83)=&H2649494932
c(84)=&H03017F0103
c(85)=&H3F4040403F
c(86)=&H1F2040201F
c(87)=&H3F4038403F
c(88)=&H6314081463
c(89)=&H0304780403
c(90)=&H6159494D43
c(91)=&H007F414141
c(92)=&H0204081020
c(93)=&H004141417F
c(94)=&H0402010204
c(95)=&H4040404040
c(96)=&H0003070800
c(97)=&H2054547840
c(98)=&H7F28444438
c(99)=&H3844444428
c(100)=&H384444287F
c(101)=&H3854545418
c(102)=&H00087E0902
c(103)=&H18A4A49C78
c(104)=&H7F08040478
c(105)=&H00447D4000
c(106)=&H2040403D00
c(107)=&H7F10284400
c(108)=&H00417F4000
c(109)=&H7C04780478
c(110)=&H7C08040478
c(111)=&H3844444438
c(112)=&HFC18242418
c(113)=&H18242418FC
c(114)=&H7C08040408
c(115)=&H4854545424
c(116)=&H04043F4424
c(117)=&H3C4040207C
c(118)=&H1C2040201C
c(119)=&H3C4030403C
c(120)=&H4428102844
c(121)=&H4C9090907C
c(122)=&H4464544C44
c(123)=&H0008364100
c(124)=&H0000770000
c(125)=&H0041360800
c(126)=&H0201020402
c(127)=&H3C2623263C
c(128)=&H1EA1A16112
c(129)=&H3A4040207A
c(130)=&H3854545559
c(131)=&H2155557941
c(132)=&H2254547842
c(133)=&H2155547840
c(134)=&H2054557940
c(135)=&H0C1E527212
c(136)=&H3955555559
c(137)=&H3954545459
c(138)=&H3955545458
c(139)=&H0000457C41
c(140)=&H0002457D42
c(141)=&H0001457C40
c(142)=&H7D1211127D
c(143)=&HF0282528F0
c(144)=&H7C54554500
c(145)=&H2054547C54
c(146)=&H7C0A097F49
c(147)=&H3249494932
c(148)=&H3A4444443A
c(149)=&H324A484830
c(150)=&H3A4141217A
c(151)=&H3A42402078
c(152)=&H009DA0A07D
c(153)=&H3D4242423D
c(154)=&H3D4040403D
c(155)=&H3C24FF2424
c(156)=&H487E494366
c(157)=&H2B2FFC2F2B
c(158)=&HFF0929F620
c(159)=&HC0887E0903
c(160)=&H2054547941
c(161)=&H0000447D41
c(162)=&H3048484A32
c(163)=&H384040227A
c(164)=&H007A0A0A72
c(165)=&H7D0D19317D
c(166)=&H2629292F28
c(167)=&H2629292926
c(168)=&H30484D4020
c(169)=&H3808080808
c(170)=&H0808080838
c(171)=&H2F10C8ACBA
c(172)=&H2F102834FA
c(173)=&H00007B0000
c(174)=&H08142A1422
c(175)=&H22142A1408
c(176)=&HAA005500AA
c(177)=&HAA55AA55AA
c(178)=&H000000FF00
c(179)=&H101010FF00
c(180)=&H141414FF00
c(181)=&H1010FF00FF
c(182)=&H1010F010F0
c(183)=&H141414FC00
c(184)=&H1414F700FF
c(185)=&H0000FF00FF
c(186)=&H1414F404FC
c(187)=&H141417101F
c(188)=&H10101F101F
c(189)=&H1414141F00
c(190)=&H101010F000
c(191)=&H0000001F10
c(192)=&H1010101F10
c(193)=&H101010F010
c(194)=&H000000FF10
c(195)=&H1010101010
c(196)=&H101010FF10
c(197)=&H000000FF14
c(198)=&H0000FF00FF
c(199)=&H00001F1017
c(200)=&H0000FC04F4
c(201)=&H1414171017
c(202)=&H1414F404F4
c(203)=&H0000FF00F7
c(204)=&H1414141414
c(205)=&H1414F700F7
c(206)=&H1414141714
c(207)=&H10101F101F
c(208)=&H141414F414
c(209)=&H1010F010F0
c(210)=&H00001F101F
c(211)=&H0000001F14
c(212)=&H000000FC14
c(213)=&H0000F010F0
c(214)=&H1010FF10FF
c(215)=&H141414FF14
c(216)=&H1010101F00
c(217)=&H000000F010
c(218)=&HFFFFFFFFFF
c(219)=&HF0F0F0F0F0
c(220)=&HFFFFFF0000
c(221)=&H000000FFFF
c(222)=&H0F0F0F0F0F
c(223)=&H3844443844
c(224)=&HFC4A4A4A34
c(225)=&H7E02020606
c(226)=&H027E027E02
c(227)=&H6355494163
c(228)=&H3844443C04
c(229)=&H407E201E20
c(230)=&H06027E0202
c(231)=&H99A5E7A599
c(232)=&H1C2A492A1C
c(233)=&H4C7201724C
c(234)=&H304A4D4D30
c(235)=&H3048784830
c(236)=&HBC625A463D
c(237)=&H3E49494900
c(238)=&H7E0101017E
c(239)=&H2A2A2A2A2A
c(240)=&H44445F4444
c(241)=&H40514A4440
c(242)=&H40444A5140
c(243)=&H0000FF0103
c(244)=&HE080FF0000
c(245)=&H08086B6B08
c(246)=&H3612362436
c(247)=&H060F090F06
c(248)=&H0000181800
c(249)=&H0000101000
c(250)=&H3040FF0101
c(251)=&H001F01011E
c(252)=&H00191D1712
c(253)=&H003C3C3C3C
c(254)=&H0000000000
end sub
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 12:45am 13 Nov 2014
Copy link to clipboard 
Print this post

That looks like a very serious bit of code !
The only Konstant is Change
 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 01:43am 13 Nov 2014
Copy link to clipboard 
Print this post

This is great! Can't wait to give it a try. Good Job Matherp!!!!
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3282
Posted: 03:19am 13 Nov 2014
Copy link to clipboard 
Print this post

Impressive.

I am also fascinated with how you used the new features in 4.6 to good effect (ie, OPTION DEFAULT INTEGER, LOCAL xx = nn, etc).

Geoff
Geoff Graham - http://geoffg.net
 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1573
Posted: 03:43am 13 Nov 2014
Copy link to clipboard 
Print this post

Hi matherp,

this is for SSD1306 (driver chip) displays, right?
I think it's useful (not tested yet).
I like this I2C stuff! Very easy to connect!

Regards

Michael

causality ≠ correlation ≠ coincidence
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2932
Posted: 04:20am 13 Nov 2014
Copy link to clipboard 
Print this post

Has anyone out there got an OLED to try out this excellent code??

I am in the market to buy a quantity of OLEDs (various types) and this looks like a fantastic starting point.

Surely someone has an OLED lying around (I used all mine up on aPIC project several years ago - only damaged ones left in my possession)

WW
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 05:42am 13 Nov 2014
Copy link to clipboard 
Print this post

I not see any use of codes being send to an oled. I presume it is still unclear which controller is used for the old.
All functions boil down to a 'pixel'. Not a bad way to do graphics, although it can slow down things.

I am not sure what kind of functionalities OLED controllers have but I would think they would support some form of basic drawing and using fonts.

Edited by TZAdvantage 2014-11-14
Microblocks. Build with logic.
 
micronut
Newbie

Joined: 03/09/2014
Location: United States
Posts: 37
Posted: 07:28am 13 Nov 2014
Copy link to clipboard 
Print this post

Thank you for doing this! I've been trying to get a ST7781R working with CFunctions and cannot make it work. I was about to give up. I'll convert your code to see if I can make it work just using Basic then slowly translate the code to C so it can run faster using CFunctions.

Edit - I just noticed this is for oLeds not TFTs but it should be able to be modified easily if I can get the TFT driver to work.Edited by micronut 2014-11-14
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10205
Posted: 07:52am 13 Nov 2014
Copy link to clipboard 
Print this post

Adafruit separate their graphics libraries for the various displays into two parts. One part handles the hardware and the vagaries of the specific display, The other part is the GFX library which contains generic routines that are not display specific but provide the basic drawing and text primitives.

My code above is just the GFX part and I'm using a string array and print functions as a test harness to make sure the drawing works properly. The code needs modifying to suit any specific actual display.

To demonstrate I attach a fully working version for the monochrome Nokia 5110 display which I happened to have around. The GFX routines have been stripped of the "colour" capability to try and speed things up.

I'm bit-banging the SPI interface - this would be much better using hardware SPI.

Most of these simple displays do not have an onboard character sets hence the need to include this in the program. They do have various types of hardware acceleration for things like line drawing, scrolling etc. Adafruit handle this by allowing hardware-specific sub-classes to override the pixel based GFX versions.
This can be included in a micromite program by special casing functions as applicable for any particular display controller.

My code is currently too slow depending on the application but by slowly migrating functions to cfunctions this can be addressed.

Best Regards

Peter

' Monochrome Port of Adafruit graphics library
'
' assumes a graphics display where top left is point 0,0
'
'sub setRotation(x) 'sets screen rotation: 0=normal, 1=invert, 2=rotate right, 3-rotate left
'sub drawCircle(x0,y0,r,fg$) 'x,y coordinates of centre, radius
'sub fillCircle(x0, y0, r, fg$) 'x,y coordinates of centre, radius
'sub drawTriangle(x0, y0, x1, y1, x2, y2, fg$) 'three coordinate pairs
'sub fillTriangle (x0, y0, x1, y1, x2, y2, fg$) 'three coordinate pairs
'sub drawChar(x, y, c, fg$, bg$, size, orientation) 'x,y coordinates of top left of first character, ascii character, size, orientation
'sub printstring(xx0,yy0,text$,fg$,bg$,size,orientation) 'x,y coordinates of top left of first character, text string, size, orientation
'sub drawLine(xx0,yy0,xx1,yy1,fg$)' x,y of start line, x,y of end line
'sub drawFastHLine(x, y,w,fg$)'draw horizontal line: x,y coordinates of left of line, width
'sub drawFastVLine(x, y,h,fg$)'draw horizontal line: x,y coordinates of top of line, height
'sub drawRect(x,y,w,h,fg$) 'x,y coordinate of top left, width, height
'sub fillRect(x, y, w, h,fg$)'x,y coordinate of top left, width, height
'sub drawRoundRect(x, y, w, h, r, fg$) 'x,y coordinates of top left, width, height, radius of corner
'sub fillRoundRect(x, y, w,h, r, fg$) 'x,y coordinates of top left, width, height, radius of corner
'sub fillscreen() 'fill
'sub drawPixel(x,y,fg$) 'x,y coordinates
'
' These routines now just update the memory image of the display
' Use the refresh command to write to the display
'
cpu 48
OPTION EXPLICIT
OPTION DEFAULT INTEGER
const WIDTH=84
const HEIGHT=48
const NUM_ROWS = Height/8
const MAX_ROWS = NUM_ROWS - 1
const MAX_COLS = width - 1
const normal=0
const invert=1
const rotate_right=2
const rotate_left=3
'
' pin assignments
'
const RST=24
const CE=23
const DC=15
const Datain=14
const CLK=6
const VCC=7
'
' Nokia 5110 specific commands
'
const EXTENDED_COMMAND = &H21
const BASIC_COMMAND = &H20
const TEMP_COEFFICIENT = &H05
const BIAS = &H14
' display modes
const BLANK = &H08
const ALL_ON = &H09
const D_NORMAL = &H0C
const D_INVERSE = &H0D
const xcursor=&H80
const ycursor=&H40
'
const CONTRAST = &HB3 'adjust for individual display
'
dim c(255),col(5),bits(6,8)
dim screen(width+1),displayed(width+1) 'set up arrays for screen map to mimic display
dim i,j,k,char
dim rotation
dim rot_width,rot_height
'
init:
loadchars 'load ascci character array
initdisplay 'initialise the display
setrotation(normal)
'
Main:
drawrect(0,0,width,height)
printstring(2,44,"up",1,rotate_left)
refresh
end
'
sub initdisplay 'Nokia5110
for i=0 to width
screen(i)=0
displayed(i)=0
next i
setpin RST, dout
SETPIN CE, DOUT
SETPIN DC, DOUT
SETPIN Datain, DOUT
SETPIN CLK, DOUT
SETPIN VCC, DOUT
'
PIN(VCC)=0 'turn off display power
PIN(CLK)=1 'clock idles high
pause 1000
pin(RST)=1 'set RESET high
PIN(VCC)=1 'Turn on the power
PIN(RST)=0
PIN(RST)=1 'reset the display
SendCommand(EXTENDED_COMMAND)
SendCommand(TEMP_COEFFICIENT)
SendCommand(BIAS)
SendCommand(BASIC_COMMAND)
SendCommand(D_NORMAL)
ClearScreen
setcontrast
end sub
'
sub Home
SendCommand(xcursor)
SendCommand(ycursor)
end sub
'
Sub SendCommand(command)
pin(DC)=0 ' Send this byte as a command
PIN(CE)=0
Spiout(command)
PIN(CE)=1
end sub
'
sub refresh
local i,j,now,was
for i=1 to width
if screen(i)<>displayed(i) then
now=screen(i)
was=displayed(i)
for j=0 to max_rows
if (now and &HFF) <> (was and &HFF) then
cursor(i-1,j)
senddata(now and &HFF)
endif
now=now>>8
was=was>>8
next j
displayed(i)=screen(i)
endif
next i
end sub
'
Sub ClearScreen
local i,j
home
for i=0 to max_rows
for j=0 to max_cols
SendData(0)
next j
next i
home
end sub
'
sub Cursor(x,y)
SendCommand(x or xcursor)
SendCommand(y OR ycursor)
end sub
'
Sub setcontrast
SendCommand(EXTENDED_COMMAND)
SendCommand(CONTRAST OR &H80)
SendCommand(BASIC_COMMAND)
end sub
'
sub SendData(Dchar)
PIN(DC)=1 ' Send this byte as data
PIN(CE)=0
Spiout(Dchar)
PIN(CE)=1
end sub
'
sub spiout(char)
local i,j as integer
j=char
for i=0 to 7
If j and &H80 then
pin(datain)=1
else
pin(datain)=0
endif
pin(CLK)=0
pin(clk)=1
j=j<<1
next i
end sub
'
sub drawCircle(x0,y0,r) 'x,y coordinates of centre, radius
local f=1-r
local ddF_x=1
local ddF_y=-2 * r
local x=0
local y=r
drawPixel(x0 , y0+r)
drawPixel(x0 , y0-r)
drawPixel(x0+r, y0 )
drawPixel(x0-r, y0 )
do while (x<y)
if f >= 0 then
y=y-1
ddF_y = ddF_y+2
f = f+ddF_y
endif
x=x+1
ddF_x = ddF_x+2
f = f+ ddF_x

drawPixel(x0 + x, y0 + y)
drawPixel(x0 - x, y0 + y)
drawPixel(x0 + x, y0 - y)
drawPixel(x0 - x, y0 - y)
drawPixel(x0 + y, y0 + x)
drawPixel(x0 - y, y0 + x)
drawPixel(x0 + y, y0 - x)
drawPixel(x0 - y, y0 - x)
loop
end sub
'
sub drawTriangle(x0, y0, x1, y1, x2, y2) 'three coordinate pairs
drawLine(x0, y0, x1, y1)
drawLine(x1, y1, x2, y2)
drawLine(x2, y2, x0, y0)
end sub
'
sub fillTriangle (x0, y0, x1, y1, x2, y2) 'three coordinate pairs
local a, b, y, last
if (y0 > y1) then
swap(y0, y1)
swap(x0, x1)
endif
if (y1 > y2) then
swap(y2, y1)
swap(x2, x1)
endif
if (y0 > y1) then
swap(y0, y1)
swap(x0, x1)
endif
if(y0 = y2) then ' Handle awkward all-on-same-line case as its own thing
a = x0
b = x0
if(x1 < a) then
a = x1
else
if(x1 > b) then b = x1
endif
if(x2 < a) then
a = x2
else
if(x2 > b) then b = x2
endif
drawFastHLine(a, y0, b-a+1)
exit sub
endif
local dx01=x1 - x0
local dy01=y1 - y0
local dx02=x2 - x0
local dy02=y2 - y0
local dx12=x2 - x1
local dy12=y2 - y1
local sa = 0
local sb = 0
if(y1 = y2) then
last = y1 'Include y1 scanline
else
last = y1-1 ' Skip it
endif
for y=y0 to last
a = x0 + sa / dy01
b = x0 + sb / dy02
sa = sa + dx01
sb = sb + dx02
a = x0 + (x1 - x0) * (y - y0) / (y1 - y0)
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0)
if(a > b) then swap(a,b)
drawFastHLine(a, y, b-a+1)
next y
sa = dx12 * (y - y1)
sb = dx02 * (y - y0)
do while y<=y2
a = x1 + sa / dy12
b = x0 + sb / dy02
sa = sa+dx12
sb = sb+dx02
a = x1 + (x2 - x1) * (y - y1) / (y2 - y1)
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0)
if(a > b) then swap(a,b)
drawFastHLine(a, y, b-a+1)
y=y+1
loop
end sub
'
sub printstring(xx0,yy0,text$,size,orientation) 'x,y coordinates of top left of first character, text string, size, orientation
local i,c
local x = xx0
local y = yy0
if orientation=1 then
x=x-(6*size)+1
y=y-(8*size)+1
endif
if orientation=2 then
x=x-(8*size)+1
endif
if orientation=3 then
y=y-(6*size)+1
endif
for i=1 to len(text$)
c=asc(mid$(text$,i,1))
drawchar(x,y,c,size,orientation)
on orientation+1 goto pnormal,pinvert,protateright,protateleft
pnormal:
x=x+(6*size)
goto pcontinue
pinvert:
x=x-(6*size)
goto pcontinue
protateright:
y=y+(6*size)
goto pcontinue
protateleft:
y=y-(6*size)
pcontinue:
next i
end sub
'
sub drawLine(xx0,yy0,xx1,yy1) ' x,y of start line, x,y of end line
local dx, dy
local x0=xx0
local y0=yy0
local x1=xx1
local y1=yy1
local err,ystep
local steep = (abs(y1 - y0)) > (abs(x1 - x0))
if (steep) then
swap(x0, y0)
swap(x1, y1)
endif
if (x0 > x1) then
swap(x0, x1)
swap(y0, y1)
endif
dx = x1 - x0
dy = abs(y1 - y0)
err = dx / 2
if y0 < y1 then
ystep = 1
else
ystep = -1
endif
do while x0<=x1
if (steep) then
drawPixel(y0, x0)
else
drawPixel(x0, y0)
endif
err = err- dy
if err < 0) then
y0 = y0+ ystep
err = err+ dx
endif
x0=x0+1
loop
end sub
'
sub swap a,b
local t
t=b
b=a
a=t
end sub
'
sub drawRect(x,y,w,h) 'x,y coordinate of top left, width, height
drawFastHLine(x, y, w)
drawFastHLine(x, y+h-1, w)
drawFastVLine(x, y, h)
drawFastVLine(x+w-1, y, h)
end sub
'
sub drawFastVLine(x, y,h) 'draw horizontal line: x,y coordinates of top of line, height
LOCAL i
for i=y to y+h-1
drawpixel(x, i)
next i
end sub
'
sub clearFastVLine(x, y,h) 'draw horizontal line: x,y coordinates of top of line, height
LOCAL i
for i=y to y+h-1
clearpixel(x, i)
next i
end sub
'
sub drawFastHLine(x, y,w) 'draw horizontal line: x,y coordinates of left of line, width
local i
for i=x to x+w-1
drawpixel(i, y)
next i
end sub
'
sub fillRect(x, y, w, h) 'x,y coordinate of top left, width, height
local i
for i=x to x+w-1
drawFastVLine(i, y, h)
next i
end sub
'
sub clearRect(x, y, w, h) 'x,y coordinate of top left, width, height
local i
for i=x to x+w-1
clearFastVLine(i, y, h)
next i
end sub
'
sub drawChar(x, y, c, size, orientation) 'x,y coordinates of top left of first character, ascii character, size, orientation
local i,j,LINE,xx,yy
getchar(c,bits()) 'loads the character into the bits array
on orientation+1 goto dnormal,dinvert,drotateright,drotateleft
dnormal:
for i=0 to 5 'step down the lines
for j = 0 to 7
if bits(i,j) then
if (size = 1) then
drawPixel(x+i, y+j)
else
fillRect(x+(i*size), y+(j*size), size, size)
endif
else
if (size = 1) then
clearPixel(x+i, y+j)
else
clearRect(x+(i*size), y+(j*size), size, size)
endif
endif
next j
next i
exit sub
'
dinvert:
for i=0 to 5 'step down the lines
for j = 0 to 7
if bits(5-i,7-j) then
if (size = 1) then
drawPixel(x+i, y+j)
else
fillRect(x+(i*size), y+(j*size), size, size)
endif
else
if (size = 1) then
clearPixel(x+i, y+j)
else
clearRect(x+(i*size), y+(j*size), size, size)
endif
endif
next j
next i
exit sub
'
drotateright:
for i=0 to 7 'step down the lines
for j = 0 to 5
if bits(j,7-i) then
if (size = 1) then
drawPixel(x+i, y+j)
else
fillRect(x+(i*size), y+(j*size), size, size)
endif
else
if (size = 1) then
clearPixel(x+i, y+j)
else
clearRect(x+(i*size), y+(j*size), size, size)
endif
endif
next j
next i
exit sub
drotateleft:
for i=0 to 7 'step down the lines
for j = 0 to 5
if bits(5-j,i) then
if (size = 1) then
drawPixel(x+i, y+j)
else
fillRect(x+(i*size), y+(j*size), size, size)
endif
else
if (size = 1) then
clearPixel(x+i, y+j)
else
clearRect(x+(i*size), y+(j*size), size, size)
endif
endif
next j
next i
end sub
'
sub fillscreen 'fill colour
fillrect(0,0,rot_width,rot_height)
end sub
'
sub drawPixel(x,y) 'x,y coordinates
local xp
local yp
on rotation+1 goto anormal,ainvert,arotateright,arotateleft
anormal:
xp=x+1 'string positions start at 1
yp=y
goto setpixel
ainvert:
xp=width-x
yp=height-y-1
goto setpixel
arotateright:
yp=x
xp=width-y
goto setpixel
arotateleft:
yp=height-x-1
xp=y+1
setpixel:
if xp<=rot_width and yp< rot_height and xp>=1 and yp>=0 then
' The Nokia 5510 is organised as 84 columns and 6 rows with each row 8 bits high
screen(xp)=screen(xp) OR 1<<yp
endif
end sub
'
sub clearPixel(x,y) 'x,y coordinates
local xp
local yp
on rotation+1 goto vnormal,vinvert,vrotateright,vrotateleft
vnormal:
xp=x+1 'string positions start at 1
yp=y
goto clearthepixel
vinvert:
xp=width-x
yp=height-y-1
goto clearthepixel
vrotateright:
yp=x
xp=width-y
goto clearthepixel
vrotateleft:
yp=height-x-1
xp=y+1
clearthepixel:
if xp<=rot_width and yp< rot_height and xp>=1 and yp>=0 then
' The Nokia 5510 is organised as 84 columns and 6 rows with each row 8 bits high
screen(xp)=screen(xp) and (&HFFFFFFFFFFFFFFFF xor (1<<yp))
endif
end sub
'
sub fillCircle(x0, y0, r) 'x,y coordinates of centre, radius
drawFastVLine(x0, y0-r, 2*r+1);
fillCircleHelper(x0, y0, r, 3, 0);
end sub
'
sub drawRoundRect(x, y, w, h, r) 'x,y coordinates of top left, width, height, radius of corner
drawFastHLine(x+r , y , w-2*r) ' Top
drawFastHLine(x+r , y+h-1, w-2*r) 'Bottom
drawFastVLine(x , y+r , h-2*r) 'Left
drawFastVLine(x+w-1, y+r , h-2*r) 'Right
drawCircleHelper(x+r , y+r , r, 1)
drawCircleHelper(x+w-r-1, y+r , r, 2)
drawCircleHelper(x+w-r-1, y+h-r-1, r, 4)
drawCircleHelper(x+r , y+h-r-1, r, 8)
end sub
'
sub drawCircleHelper( x0, y0,r,cornername)
local f = 1 - r
local ddF_x = 1
local ddF_y = -2 * r
local x = 0
local y = r

do while (x<y)
if (f >= 0) then
y=y-1
ddF_y = ddF_y+ 2
f = f+ddF_y
endif
x=x+1
ddF_x =ddF_x+ 2
f = f+ddF_x
if (cornername and 4) then
drawPixel(x0 + x, y0 + y)
drawPixel(x0 + y, y0 + x)
endif
if (cornername and 2) then
drawPixel(x0 + x, y0 - y)
drawPixel(x0 + y, y0 - x)
endif
if (cornername and 8) then
drawPixel(x0 - y, y0 + x)
drawPixel(x0 - x, y0 + y)
endif
if (cornername and 1) then
drawPixel(x0 - y, y0 - x)
drawPixel(x0 - x, y0 - y)
endif
loop
end sub
'
sub fillCircleHelper(x0, y0, r,cornername, delta)

local f = 1 - r
local ddF_x = 1
local ddF_y = -2 * r
local x = 0
local y = r

do while x<y
if f >= 0 then
y=y-1
ddF_y =ddF_y+ 2
f = f+ddF_y
endif
x=x+1
ddF_x = ddF_x+2
f = f+ddF_x

if (cornername and 1) then
drawFastVLine(x0+x, y0-y, 2*y+1+delta)
drawFastVLine(x0+y, y0-x, 2*x+1+delta)
endif
if (cornername and 2) then
drawFastVLine(x0-x, y0-y, 2*y+1+delta)
drawFastVLine(x0-y, y0-x, 2*x+1+delta)
endif
loop
end sub
'
sub fillRoundRect(x, y, w,h, r) 'x,y coordinates of top left, width, height, radius of corner
fillRect(x+r, y, w-2*r, h)
fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1)
fillCircleHelper(x+r , y+r, r, 2, h-2*r-1)
end sub
'
sub setRotation(x) 'sets screen rotation: 0=normal, 1=invert, 2=rotate right, 3-rotate left
rotation = (x and 3)
if rotation >=2 then
rot_width = WIDTH
rot_height = HEIGHT
else
rot_width=width
rot_height=height
endif

end sub
'
sub getchar(a,b()) 'get the bits for the character a and put them in array b
local shift
for j=4 to 0 step -1
shift=j*8
col(j)=c(a)>>shift and &H7F
for i=6 to 0 step -1
b(4-j,i)=col(j)>>i and 1
next i
next j
end sub
'
sub loadchars
for i=0 to 7
bits(5,i)=0
next i
for j=0 to 5
bits(j,7)=0
next j
c(0)=&H0000000000
c(1)=&H3E5B4F5B3E
c(2)=&H3E6B4F6B3E
c(3)=&H1C3E7C3E1C
c(4)=&H183C7E3C18
c(5)=&H1C577D571C
c(6)=&H1C5E7F5E1C
c(7)=&H00183C1800
c(8)=&HFFE7C3E7FF
c(9)=&H0018241800
c(10)=&HFFE7DBE7FF
c(11)=&H30483A060E
c(12)=&H2629792926
c(13)=&H407F050507
c(14)=&H407F05253F
c(15)=&H5A3CE73C5A
c(16)=&H7F3E1C1C08
c(17)=&H081C1C3E7F
c(18)=&H14227F2214
c(19)=&H5F5F005F5F
c(20)=&H06097F017F
c(21)=&H006689956A
c(22)=&H6060606060
c(23)=&H94A2FFA294
c(24)=&H08047E0408
c(25)=&H10207E2010
c(26)=&H08082A1C08
c(27)=&H081C2A0808
c(28)=&H1E10101010
c(29)=&H0C1E0C1E0C
c(30)=&H30383E3830
c(31)=&H060E3E0E06
c(32)=&H0000000000
c(33)=&H00005F0000
c(34)=&H0007000700
c(35)=&H147F147F14
c(36)=&H242A7F2A12
c(37)=&H2313086462
c(38)=&H3649562050
c(39)=&H0008070300
c(40)=&H001C224100
c(41)=&H0041221C00
c(42)=&H2A1C7F1C2A
c(43)=&H08083E0808
c(44)=&H0080703000
c(45)=&H0808080808
c(46)=&H0000606000
c(47)=&H2010080402
c(48)=&H3E5144953E
c(49)=&H00427F4000
c(50)=&H7249494946
c(51)=&H2141494D33
c(52)=&H1814127F10
c(53)=&H2745454539
c(54)=&H3C4A494931
c(55)=&H4121110907
c(56)=&H3649494936
c(57)=&H464949291E
c(58)=&H0000140000
c(59)=&H0040340000
c(60)=&H0008142241
c(61)=&H1414141414
c(62)=&H0041221408
c(63)=&H0201590906
c(64)=&H3E415D594E
c(65)=&H7C1211127C
c(66)=&H7F49494936
c(67)=&H3E41414122
c(68)=&H7F4141413E
c(69)=&H7F49494941
c(70)=&H7F09090901
c(71)=&H3E41415173
c(72)=&H7F0808087F
c(73)=&H00417F4100
c(74)=&H2040413F01
c(75)=&H7F08142241
c(76)=&H7F40404040
c(77)=&H7F021C027F
c(78)=&H7F0408107F
c(79)=&H3E4141413E
c(80)=&H7F09090906
c(81)=&H3E4151215E
c(82)=&H7F09192946
c(83)=&H2649494932
c(84)=&H03017F0103
c(85)=&H3F4040403F
c(86)=&H1F2040201F
c(87)=&H3F4038403F
c(88)=&H6314081463
c(89)=&H0304780403
c(90)=&H6159494D43
c(91)=&H007F414141
c(92)=&H0204081020
c(93)=&H004141417F
c(94)=&H0402010204
c(95)=&H4040404040
c(96)=&H0003070800
c(97)=&H2054547840
c(98)=&H7F28444438
c(99)=&H3844444428
c(100)=&H384444287F
c(101)=&H3854545418
c(102)=&H00087E0902
c(103)=&H18A4A49C78
c(104)=&H7F08040478
c(105)=&H00447D4000
c(106)=&H2040403D00
c(107)=&H7F10284400
c(108)=&H00417F4000
c(109)=&H7C04780478
c(110)=&H7C08040478
c(111)=&H3844444438
c(112)=&HFC18242418
c(113)=&H18242418FC
c(114)=&H7C08040408
c(115)=&H4854545424
c(116)=&H04043F4424
c(117)=&H3C4040207C
c(118)=&H1C2040201C
c(119)=&H3C4030403C
c(120)=&H4428102844
c(121)=&H4C9090907C
c(122)=&H4464544C44
c(123)=&H0008364100
c(124)=&H0000770000
c(125)=&H0041360800
c(126)=&H0201020402
c(127)=&H3C2623263C
c(128)=&H1EA1A16112
c(129)=&H3A4040207A
c(130)=&H3854545559
c(131)=&H2155557941
c(132)=&H2254547842
c(133)=&H2155547840
c(134)=&H2054557940
c(135)=&H0C1E527212
c(136)=&H3955555559
c(137)=&H3954545459
c(138)=&H3955545458
c(139)=&H0000457C41
c(140)=&H0002457D42
c(141)=&H0001457C40
c(142)=&H7D1211127D
c(143)=&HF0282528F0
c(144)=&H7C54554500
c(145)=&H2054547C54
c(146)=&H7C0A097F49
c(147)=&H3249494932
c(148)=&H3A4444443A
c(149)=&H324A484830
c(150)=&H3A4141217A
c(151)=&H3A42402078
c(152)=&H009DA0A07D
c(153)=&H3D4242423D
c(154)=&H3D4040403D
c(155)=&H3C24FF2424
c(156)=&H487E494366
c(157)=&H2B2FFC2F2B
c(158)=&HFF0929F620
c(159)=&HC0887E0903
c(160)=&H2054547941
c(161)=&H0000447D41
c(162)=&H3048484A32
c(163)=&H384040227A
c(164)=&H007A0A0A72
c(165)=&H7D0D19317D
c(166)=&H2629292F28
c(167)=&H2629292926
c(168)=&H30484D4020
c(169)=&H3808080808
c(170)=&H0808080838
c(171)=&H2F10C8ACBA
c(172)=&H2F102834FA
c(173)=&H00007B0000
c(174)=&H08142A1422
c(175)=&H22142A1408
c(176)=&HAA005500AA
c(177)=&HAA55AA55AA
c(178)=&H000000FF00
c(179)=&H101010FF00
c(180)=&H141414FF00
c(181)=&H1010FF00FF
c(182)=&H1010F010F0
c(183)=&H141414FC00
c(184)=&H1414F700FF
c(185)=&H0000FF00FF
c(186)=&H1414F404FC
c(187)=&H141417101F
c(188)=&H10101F101F
c(189)=&H1414141F00
c(190)=&H101010F000
c(191)=&H0000001F10
c(192)=&H1010101F10
c(193)=&H101010F010
c(194)=&H000000FF10
c(195)=&H1010101010
c(196)=&H101010FF10
c(197)=&H000000FF14
c(198)=&H0000FF00FF
c(199)=&H00001F1017
c(200)=&H0000FC04F4
c(201)=&H1414171017
c(202)=&H1414F404F4
c(203)=&H0000FF00F7
c(204)=&H1414141414
c(205)=&H1414F700F7
c(206)=&H1414141714
c(207)=&H10101F101F
c(208)=&H141414F414
c(209)=&H1010F010F0
c(210)=&H00001F101F
c(211)=&H0000001F14
c(212)=&H000000FC14
c(213)=&H0000F010F0
c(214)=&H1010FF10FF
c(215)=&H141414FF14
c(216)=&H1010101F00
c(217)=&H000000F010
c(218)=&HFFFFFFFFFF
c(219)=&HF0F0F0F0F0
c(220)=&HFFFFFF0000
c(221)=&H000000FFFF
c(222)=&H0F0F0F0F0F
c(223)=&H3844443844
c(224)=&HFC4A4A4A34
c(225)=&H7E02020606
c(226)=&H027E027E02
c(227)=&H6355494163
c(228)=&H3844443C04
c(229)=&H407E201E20
c(230)=&H06027E0202
c(231)=&H99A5E7A599
c(232)=&H1C2A492A1C
c(233)=&H4C7201724C
c(234)=&H304A4D4D30
c(235)=&H3048784830
c(236)=&HBC625A463D
c(237)=&H3E49494900
c(238)=&H7E0101017E
c(239)=&H2A2A2A2A2A
c(240)=&H44445F4444
c(241)=&H40514A4440
c(242)=&H40444A5140
c(243)=&H0000FF0103
c(244)=&HE080FF0000
c(245)=&H08086B6B08
c(246)=&H3612362436
c(247)=&H060F090F06
c(248)=&H0000181800
c(249)=&H0000101000
c(250)=&H3040FF0101
c(251)=&H001F01011E
c(252)=&H00191D1712
c(253)=&H003C3C3C3C
c(254)=&H0000000000
end sub

Edited by matherp 2014-11-14
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1329
Posted: 06:53pm 13 Nov 2014
Copy link to clipboard 
Print this post

Rather than bit banging it, there's the SPI function to use. I've just noticed that Geoff's Micromite Manual doesn't have the SPI function listed and I assume that's an inadvertent omission because he did list it in the (Maximite) MMBasic V4.5 Manual (note that these do have a different format because of the fixed SPI pins used with the Micromite). The example Geoff shows in the SPI Appendix (very last page) of the Micromite Manual shows the use of the SPI function.

The SPI function is used in conjunction with the SPI OPEN and SPI CLOSE commands and these are also not listed with the other commands - that was also true of the Maximite MMBasic V4.5 Manual.

Greg
 
plasma
Guru

Joined: 08/04/2012
Location: Germany
Posts: 437
Posted: 09:05pm 13 Nov 2014
Copy link to clipboard 
Print this post

Is anyone working on this for i2c oled?
I get the display running with arduino
And discovered the first commands for.
If it works with MkII i thing we need
this as cfunction.

Btw: these small oleds are awesome..
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10205
Posted: 10:25pm 13 Nov 2014
Copy link to clipboard 
Print this post

SPI is listed in the 4.6 manual.
I've modified the code to use it and it makes a big difference. Just replace the two routines given below in the Nokia code above.
I'll start work on OLED display as soon as it arrives from China!
I can't currently do any work on CFunctions as I have a problem with MPLabX which isn't generating the symbol listings. Googling this it seems to be a problem for others as well but no-one seems to supply a solution so I'm stuck.


sub initdisplay 'Nokia5110
spi open 6000000,3,8
for i=0 to width
screen(i)=0
displayed(i)=0
next i
setpin RST, dout
SETPIN CE, DOUT
SETPIN DC, DOUT
' SETPIN Datain, DOUT : set by SPI OPEN
' SETPIN CLK, DOUT : set by SPI OPEN
SETPIN VCC, DOUT
'
PIN(VCC)=0 'turn off display power
' PIN(CLK)=1 'clock idles high
pause 1000
pin(RST)=1 'set RESET high
PIN(VCC)=1 'Turn on the power
PIN(RST)=0
PIN(RST)=1 'reset the display
SendCommand(EXTENDED_COMMAND)
SendCommand(TEMP_COEFFICIENT)
SendCommand(BIAS)
SendCommand(BASIC_COMMAND)
SendCommand(D_NORMAL)
ClearScreen
setcontrast
end sub


sub spiout(char)
local i=spi(char)
end sub
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1329
Posted: 01:28am 14 Nov 2014
Copy link to clipboard 
Print this post

  matherp said   SPI is listed in the 4.6 manual.
I've modified the code to use it and it makes a big difference. Just replace the two routines given below in the Nokia code above.

It's not in the Micromite MMBasic functions table definitions like it is in the Maximite MMBasic V4.5 Manual, but it is described in the SPI Appendix - last page of the Manual.
Well done for all this and good to see the speed gain.

Greg
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025