I was inspired by Hippy's thermometer and used it as the basis of this sine wave plot which was an exercise to familiarise myself with the graphic possibilities of an OLED. This uses the built-in 18M2 of an AXE131Y (8x5 characters) to draw a sine wave that gradually proceeds across the display.
A significant change from Hippy's method is to disable the auto-increment of the Data Register Address. This is achieved by writing $07 instead of $06 in the initialisation sequence, line 168. The program draws the top half and the bottom half of each column before moving to the next column, instead of drawing one complete row then the other row. The Data Register has to be set explicitly for each column, line 75.
The program should be easily adapted for an AXE133Y, 16x2 characters, by changing 47 to 95 (number of columns) in line 65.
Derek
A significant change from Hippy's method is to disable the auto-increment of the Data Register Address. This is achieved by writing $07 instead of $06 in the initialisation sequence, line 168. The program draws the top half and the bottom half of each column before moving to the next column, instead of drawing one complete row then the other row. The Data Register has to be set explicitly for each column, line 75.
The program should be easily adapted for an AXE133Y, 16x2 characters, by changing 47 to 95 (number of columns) in line 65.
Code:
; AXE131y Graph of Sin
; 31/1/19 DW
; .-----------------------------------------------------------------------------.
; | AXE131Y OLED draw a sin wave |
; `-----------------------------------------------------------------------------'
; Hippy's program from https://picaxeforum.co.uk/threads/oled-analogue-thermometer.29776/
; provides the setup and general arrangement
#Picaxe 18M2
#No_Data
; .-----------------------------------------------------------------------------.
; | Variables |
; `-----------------------------------------------------------------------------'
Symbol reserveb0 = b0 ; Argument for display commands
Symbol reserveb1 = b1 ; Used to initialise display
Symbol xflag = bit8; 0 x is Pos that's 0-90. 1 x neg is 91-180 etc
Symbol yflag = bit9; 0 y is pos
Symbol xflag0 = bit10; xflag at x=0
Symbol yflag0 = bit11; yflag at x=0
Symbol x = b2
Symbol ang = b3 ; angle/10 in deg.
Symbol ang0 = b4 ; angle/10 at start of display
Symbol sine = b5
Symbol angtab = b6 ; angle pointer in table
Symbol xskip = b7 ; Test for blank column between characters
; .-----------------------------------------------------------------------------.
; | LCD connections |
; `-----------------------------------------------------------------------------'
Symbol pinE = C.6 : Symbol dirE = dirC.6 ; 0 = Idle 1 = Active
Symbol pinRS = pinC.7 : Symbol dirRS = dirC.7 ; 0 = Command 1 = Data
Symbol pinD0 = pinB.0 : Symbol dirD0 = dirB.0 ; LCD Data Line 0
Symbol pinD1 = pinB.1 : Symbol dirD1 = dirB.1 ; LCD Data Line 1
Symbol pinD2 = pinB.2 : Symbol dirD2 = dirB.2 ; LCD Data Line 2
Symbol pinD3 = pinB.3 : Symbol dirD3 = dirB.3 ; LCD Data Line 3
Symbol pinD4 = pinB.4 : Symbol dirD4 = dirB.4 ; LCD Data Line 4
Symbol pinD5 = pinB.5 : Symbol dirD5 = dirB.5 ; LCD Data Line 5
Symbol pinD6 = pinB.6 : Symbol dirD6 = dirB.6 ; LCD Data Line 6
Symbol pinD7 = pinB.7 : Symbol dirD7 = dirB.7 ; LCD Data Line 7
; .-----------------------------------------------------------------------------.
; | Main Program |
; `-----------------------------------------------------------------------------'
Gosub InitialiseLcd
SetFreq M32
b0 = 1 : GOSUB SendInitCmdByte ; Clear Display
xflag0 = 0
yflag0 = 0
ang0 = 0
DO
ang = ang0 ; Set angle at start
ang0 = ang0 + 1
xflag = xflag0
yflag = yflag0
FOR x = 0 TO 47
IF x=1 THEN ' Save these flags for next start
xflag0 = xflag
yflag0 = yflag
ang0 = ang
ENDIF
xskip = x//6
IF xskip<>0 THEN ' Don't write at the between-characters gap
READTABLE ang, sine ; ang is angle in deg/10, sine is 8* true sine of angle
b0 = %10000000 + X : Gosub SendCmdByte; GXA Set the X pixel
IF yflag=0 THEN ' Fill in the top row
b0 = %01000000 : Gosub SendCmdByte ; GYA 0
SELECT CASE sine ' Define the Y pixel
CASE 0
b0 = 0
CASE 1
b0 = 128
CASE 2
b0 = 64
CASE 3
b0 = 32
CASE 4
b0 = 16
CASE 5
b0 = 8
CASE 6
b0 = 4
CASE 7
b0 = 2
CASE 8
b0 = 1
ENDSELECT
Gosub SendDataByte
b0 = %01000001 : Gosub SendCmdByte ; GYA 1
b0 = 0 : Gosub SendDataByte ; Blank in bottom row when yflag=0
ELSE ; Fill in bottom row (yflag=1)
b0 = %01000001 : Gosub SendCmdByte ; GYA 1
SELECT CASE sine ' Define the Y pixel
CASE 0
b0 = 0
CASE 1
b0 = 1
CASE 2
b0 = 2
CASE 3
b0 = 4
CASE 4
b0 = 8
CASE 5
b0 = 16
CASE 6
b0 = 32
CASE 7
b0 = 64
CASE 8
b0 = 128
ENDSELECT
Gosub SendDataByte
b0 = %01000000 : Gosub SendCmdByte ; GYA 0
b0 = 0 : Gosub SendDataByte ; Blank in top row when yflag=1
ENDIF
ENDIF
'Increment the angle even if there's no drawing at this pixel
IF xflag = 0 THEN
ang = ang + 1
IF ang > 9 THEN
ang = 8
xflag = 1
ENDIF
ELSE
ang = ang - 1
IF ang > 9 THEN
ang = 1
xflag = 0
yflag = yflag + 1
ENDIF
ENDIF
NEXT x
LOOP
; .-----------------------------------------------------------------------------.
; | LCD initialisation routine |
; `-----------------------------------------------------------------------------'
InitialiseLcd:
dirE = 1 ; Set LCD control lines as outputs
dirRS = 1
dirD0 = 1
dirD1 = 1
dirD2 = 1
dirD3 = 1
dirD4 = 1
dirD5 = 1
dirD6 = 1
dirD7 = 1
Pause 500
For b1 = 0 To 7
LookUp b1, ( $33,$33,$33, $3B,$0C,$07,$1F,$01 ), b0 : Gosub SendInitCmdByte
Next
; Nibble commands - To initialise 8-bit mode
;
; $33 %0011---- 8-bit
; $33 %0011---- 8-bit
; $33 %0011---- 8-bit
;
; Byte commands - To configure the LCD or OLED
;
; LNFff
; $3B %00111011 Display Format
;
; L : 0 = 4-bit Mode 1 = 8-bit Mode
; N : 0 = 1 Line 1 = 2 Lines
; F : 0 = 5x7 Pixels 1 = N/A
;
; f : OLED Font table 00 English-Japanese
; 01 Western European 1
; 10 English-Russian
; 11 Western European 2
;
; DCB
; $0C %00001100 Display Control
;
; D : 0 = Display Off 1 = Display On
; C : 0 = Cursor Off 1 = Cursor On
; B : 0 = Cursor Steady 1 = Cursor Flash
;
; IS
; $07 %00000111 Cursor Move
;
; I : 0 = Dec Cursor 1 = Inc Cursor
; S : 0 = Cursor Move 1 = Display Shift
;
; GP
; $1F %00011111 Graphics Mode
;
; G : 0 = Text Display 1 = Graphics Mode
; P : 0 = Int Power Off 1 = Int Power On
;
; $01 %00000001 Clear Screen
;
; Additional OLED Graphics commands
;
; $80 %1xxxxxxx GXA
;
; $40 %0100000y GYA
Return
; .-----------------------------------------------------------------------------.
; | LCD interfacing routines |
; `-----------------------------------------------------------------------------'
SendInitCmdByte:
Pause 15 ; Delay 15mS
SendCmdByte:
pinRS = 0 ; Send to Command register
Gosub SendDataByte
If b0 <= 3 Then ; Pause to allow Home or Clear to complete
Pause 10
End If
Return
SendDataByte:
pinsb=b0
pulsout pinE,1
pinRS = 1 ; Send to Data register next
Return
TABLE 0,(0,1,3,4,5,6,7,8,8,8) ; Sin at 10deg intervals scaled x8
; .-----------------------------------------------------------------------------.
; | End of program |
; `-----------------------------------------------------------------------------'