OledDisplaySSD1306
SwordfishUser.OledDisplaySSD1306 History
Hide minor edits - Show changes to output
Added lines 1-885:
This is a library is for the monchroom Oled Display SSD1306. The module got his own graphic routines and make use of a framebuffer before it is send to the display.
This is a array of 1023 byte.
To test the module
=code [=
Include "Oled.inc"
Include "Bitmap.inc"
//Include "Arial.bas"
Include "BookAntiqua.bas"
Dim x1 As Byte
Dim y1 As Byte
Dim z1 As Byte
Oled.Init()
Oled.ClearBuffer(0)
Oled.VLine(0, 0, 10, 1)
Oled.HLine(0, 0, 10, 1)
//DrawRectangle(5,5,122,60,1)
//Oled.DrawRectangle(10, 10, 20, 20, 1)
//Oled.FillRectangle(20, 20, 100, 40, 1)
//Oled.DrawCircle(20, 20, 10, 1)
//Oled.DrawCircle(18, 18, 10, 1)
//Oled.DrawCircle(16, 16, 10, 1)
//FilledCircle(70, 30, 10, 1)
LoadImage(30, 0, 1, BatteryImage)
SetFont(BookAntiqua)
Print(80,0,"Testrun")
x1 = 20
y1 = 15
z1 = 0
While true
Oled.DrawCircle(x1, y1, 10, 0)
Oled.DrawCircle(x1+2, y1+2, 10, 0)
Oled.DrawCircle(x1+4, y1+4, 10, 0)
If z1 = 0 Then
Inc(x1)
Inc(y1)
EndIf
If z1 = 1 Then
Dec(x1)
Dec(y1)
EndIf
If x1 = 20 Then z1 = 0 EndIf
If x1 = 50 Then z1 = 1 EndIf
Oled.DrawCircle(x1, y1, 10, 1)
Oled.DrawCircle(x1+2, y1+2, 10, 1)
Oled.DrawCircle(x1+4, y1+4, 10, 1)
If z1 = 0 Then
If x1 = 25 Then DrawRectangle(80,20,100,30,1) EndIf
If x1 = 30 Then DrawRectangle(80,20,100,30,0) EndIf
If x1 = 30 Then FillRectangle(80,20,100,30,1) EndIf
If x1 = 35 Then FillRectangle(80,20,100,30,0) EndIf
If x1 = 35 Then DrawCircle(90,30,10,1) EndIf
If x1 = 40 Then DrawCircle(90,30,10,0) EndIf
If x1 = 40 Then FilledCircle(90,30,10,1) EndIf
If x1 = 45 Then FilledCircle(90,30,10,0) EndIf
EndIf
Oled.UpdateDisplay()
Wend
=]
module bitmap
=code [=
module Bitmap
public Const BatteryImage() As Byte =
(1,11,6,0,
$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$FF,
$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$00,$FF,
$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$00,$00,
$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$00,$00,
$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$00,$FF,
$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$FF)
=]
Oled module
=code [=
'******************************************************************************
'* Name : Oled Library for the SSD1306 display *
'* Author : Frank Sloep (Yoepie) *
'* Notice : This source code is provided 'as is' *
'* : *
'* : *
'* Date : 06/01/16 *
'* Version : *
'* Notes : 0.3 Initial release for SwordFish *
'* Notes : 0.2 add ImageFromCode *
'* Notes : 0.1 Initial release For Proton (never released) *
'******************************************************************************
' The most inportend thing about Oled-displays you can not write directly to
' the cords of the display. This Oled module works fromout a buffer of 1024bytes
' for a 128x64 display. Everytime you do a write to the display, it will go to
' the buffer. You have to update the buffer, to see somthing on the display,
' with the commands UpdateDisplay() or UpdateRow(Row).
'
' Oled Initialize : Oled.Init()
' Clear Buffer : Oled.ClearBuffer(Color (0/1))
' Clear Row : Oled.ClearRow(Row (0/7), Color (0/1))
' Update Display : Oled.UpdateDisplay()
' Update Row : Oled.UpdateRow(Row (0/7))
' Draw horizontal line : Oled.Hline(startX , StartY , Length, Color (0/1))
' Draw Vertical line : Oled.Vline(startX , StartY , Length, Color (0/1))
' Draw Rectangle : Oled.DrawRectangle(StartX , StartY, EndX , EndY, Color (0/1))
' Draw filled Rectangle : Oled.DrawRectangle(StartX , StartY, EndX , EndY, Color (0/1))
' Draw Circle : Oled.DrawCircle(StartX, StartY, Radius (in pixel), Color (0/1))
' Draw filled Circle : Oled.DrawCircle(StartX, StartY, Radius (in pixel), Color (0/1))
' Display on / off : Oled.Power(0/1)
' SetFont : Oled.SetFont(fontname)
' Print string : Olet.Print(StartX, StartY, string)
' Load Image from mem : Oled.LoadImage(startX,StartY,Invert,Imagename)
'
' ----------------------------------------------------------------------------------------
' The Oled work at the moment only with I2C.
' Oled_Hardware = I2C
' Oled_MODEL = SSD1306/??
' LetterSpacing = On/Off
' Debug = On/Off
Module Oled
Include "Convert.bas"
//Include "SPI.bas"
Include "i2c.bas"
// output in debug
Include "USART.bas"
#option Oled_MODEL = SSD1306
// SSD1306
#option Oled_Hardware = I2C
// i2C - SPI
#option LetterSpacing = On
// LetterSpacing = On - 1 pixel row after each character
// LetterSpacing = Off - No pixel row after each character.
#option Debug = Off
'==== Change to your needs ==============================================================================='
Const
Adres = $78, // I2C adress, Oled display
Buffer = 1024, // maxX * MaxY / 8 Pixels
OledMaxX = 128, // max Horizontal display size
OledMaxY = 64 // max vertical display size
'========================================================================================================='
Private Dim
Framebuffer(Buffer) As Byte, // Oled display buffer
OledRow As Byte, // Oled row 0/7
OledIndex As Word, //
OledData As Byte, //
Oledi As Word, // counter
Oledii As Word, // counter
Olediii As Word, // counter
Temp As Byte
// Font structure...
Public Structure TFont
Header As Word
Data As Word
Width As Word
Height As Byte
RealWidth As Byte
IsFixed As Header.Booleans(0)
IsVariable As Header.Booleans(1)
End Structure
// Image structure...
Public Structure TImage
Width As Word
Height As Byte
Size As Byte
End Structure
Public Dim
Font As TFont,
Image As TImage
// local variables...
Dim
FFontTableOffset As Byte,
FFontTableWidth As Byte
(*********************************************************************
* Start and Write command to oled display
* Input1 : Command
* Output : none
**********************************************************************)
Sub WriteCommand(pCommand As Byte)
#if Oled_Hardware = I2C
I2C.Start()
I2C.WriteByte(Adres)
I2C.WriteByte($00)
I2C.WriteByte(pCommand)
I2C.Stop()
#endif
#if Oled_Hardware = SPI
#endif
End Sub
(*********************************************************************
* Start and Write data to the oled display
* Input1 :
* Output : none
**********************************************************************)
Sub WriteStart(pData As Bit)
#if Oled_Hardware = I2C
I2C.Start()
I2C.WriteByte(Adres)
If pData = 0 Then
I2C.WriteByte($80)
Else
I2C.WriteByte($40)
EndIf
#endif
#if Oled_Hardware = SPI
#endif
End Sub
(*********************************************************************
* Helper routine - Write data to the oled display
* Input1 :
* Output : none
**********************************************************************)
Sub WriteDataWord(pData As Byte)
#if Oled_Hardware = I2C
I2C.WriteByte(pData)
#endif
#if Oled_Hardware = SPI
#endif
End Sub
(*********************************************************************
* Initialize for the oled display SSD1306
* Input1 : none
* Output : none
**********************************************************************)
Public Sub Init()
#if Oled_Hardware = I2C
I2C.Initialize(I2C_400_KHZ)
#endif
#if Oled_Hardware = SPI
#endif
#if Oled_MODEL = SSD1306
WriteCommand($AE) // \Turn display off
WriteCommand($00) // /
WriteCommand($10) //
WriteCommand($40) //
WriteCommand($B0) // Set COM Output Scan Direction
WriteCommand($81) // set Low column address
WriteCommand($CF) // set High column address
WriteCommand($A1) // set Start line address
WriteCommand($A6) // set contrast control register
WriteCommand($A8) // set normal display
WriteCommand($3F) // set segment re-map 0 To 127
WriteCommand($c8) // set normal display
WriteCommand($d3) // set multiplex ratio(1 To 64)
WriteCommand($00) //
WriteCommand($d5) // 0xa4,Output follows RAM content;0xa5,Output ignores RAM content
WriteCommand($80) // set display offset
WriteCommand($d9) // Not offset
WriteCommand($f1) // set display Clock divide ratio/oscillator frequency
WriteCommand($da) // set divide ratio
WriteCommand($12) // set pre-charge period
WriteCommand($db) //
WriteCommand($40) // set com pins hardware configuration
WriteCommand($8d) // set vcomh
WriteCommand($14) // 0x20,0.77xVcc
WriteCommand($AF) // set DC-DC Enable
WriteCommand($AF) // Set COM Output Scan Direction 64 To 0
DelayMS(10)
#endif
End Sub
(*********************************************************************
* Turn display on / off
* Input1 : 0 = off | 1 = on
* Output : None
**********************************************************************)
Public Sub Power(pData As Bit)
If pData = 0 Then
WriteCommand($AE)
WriteCommand($00)
ElseIf pdata = 1 Then
WriteCommand($AF)
WriteCommand($01)
EndIf
End Sub
(*********************************************************************
* Clear Buffer
* Input1 : color 0=off 1=on
* Output : none
**********************************************************************)
Public Sub ClearBuffer(pColor As Byte)
If pColor = 0 Then OledData = $00 EndIf
If pColor = 1 Then OledData = $FF EndIf
Oledi = 0
For Oledi = 0 To Buffer
Framebuffer(Oledi) = OledData
Next
End Sub
(*********************************************************************
* Clear a row in the Buffer
* Input1 : row 0/7
* Input2 : color 0=off 1=on
* Output : none
**********************************************************************)
Public Sub ClearRow(pRow As Byte, pColor As Byte)
If pColor = 0 Then OledData = $00 EndIf
If pColor = 1 Then OledData = $FF EndIf
If pRow = 0 Then Oledii = 0 EndIf
If pRow = 1 Then Oledii = 128 EndIf
If pRow = 2 Then Oledii = 256 EndIf
If pRow = 3 Then Oledii = 384 EndIf
If pRow = 4 Then Oledii = 512 EndIf
If pRow = 5 Then Oledii = 640 EndIf
If pRow = 6 Then Oledii = 768 EndIf
If pRow = 7 Then Oledii = 896 EndIf
Oledi = Oledii
For Oledi = Oledii To Oledii + 127
Framebuffer(Oledi) = OledData
Next
End Sub
(*********************************************************************
* Update display
* Input1 : none
* Output : none
**********************************************************************)
Public Sub UpdateDisplay()
Oledi = 0
For OledRow = $b0 To $b7
WriteCommand(OledRow) //
WriteCommand($00) // Low column start address
WriteCommand($10) // High column start address
WriteStart(1)
For Oledii = 0 To OledMaxX -1
WriteDataWord(Framebuffer(Oledi))
Inc(Oledi)
Next
I2C.Stop()
Next
End Sub
(*********************************************************************
* Update display with one row 0/7
* Input1 : row 0/7
* Output : none
**********************************************************************)
Public Sub UpdateRow(pRow As Byte)
WriteCommand($B0 + pRow) // Row0 .. Row7
WriteCommand($00) // Low column Start address
WriteCommand($10) // High column Start address
WriteStart(1)
For Oledi = 0 To OledMaxX -1
OledIndex = pRow * 128 + Oledi
WriteDataWord(Framebuffer(OledIndex))
Next
I2C.Stop()
End Sub
(*********************************************************************
* Place Graphics to buffer
* Input1 : X start cords 0-127
* Input2 : Y start cords 0-63
* Input3 : Color 0=off 1=on
* Output : Framebuffer(buffer)
**********************************************************************)
Public Sub DrawPixel(pXPixel As Byte,pYPixel As Byte,pColor As Byte)
Dim OledOffset As Byte
Dim PreData As Byte
OledRow = pYpixel / 8
OledOffset = pYpixel Mod 8
OledIndex = OledRow * 128 + pXpixel
PreData = Framebuffer(OledIndex)
Oledi = 1 << OledOffset
If pColor = 1 Then
Framebuffer(OledIndex) = PreData Or Oledi
Else
Framebuffer(OledIndex) = PreData And (Not Oledi)
EndIf
#if debug = On
USART.Write("_SETLED_", 13)
USART.Write("X = ", DecToStr(pXpixel), 13)
USART.Write("Y = ", DecToStr(pYpixel),13)
USART.Write("Value = ", DecToStr(pColor), 13)
USART.Write("Row = ", DecToStr(OledRow), 13)
USART.Write("Offset = ", DecToStr(OledOffset), 13)
USART.Write("Index = ", DecToStr(OledIndex), 13)
USART.Write("Pre = ", DecToStr(PreData), 13)
USART.Write("Buffer = ", DecToStr(Framebuffer(OledIndex)), 13)
USART.Write("Oledi = ", DecToStr(Oledi), 13)
USART.Write(13)
#endif
End Sub
(*********************************************************************
* draw Horizontal line on display
* Input1 : X start cords 0-127
* Input2 : Y start cords 0-63
* Input3 : Line length 0-127
* Output : to DrawPixel
**********************************************************************)
Public Sub HLine(StartXpos As Word, StartYpos As Byte, pLength As Word, pColor As Byte)
Repeat
DrawPixel((StartXpos + pLength), StartYpos, pColor)
Dec(pLength)
Until pLength = 0
End Sub
(*********************************************************************
* draw vertical line on display
* Input1 : X start cords 0-127
* Input2 : Y start cords 0-63
* Input3 : Line length 0-63
* Output : to DrawPixel
**********************************************************************)
Public Sub VLine(StartXpos As Word, StartYpos As Byte, pLength As Word, pColor As Byte)
Repeat
DrawPixel(StartXpos, (StartYpos + pLength), pColor)
Dec(pLength)
Until pLength = 0
End Sub
(*********************************************************************
* Helper routine for drawpixel to buffer
* Input1 : X start cords 0-127
* Input2 : Y start cords 0-63
* Input3 : X end cords 0-127
* Input4 : Y end cords 0-63
* Input5 : Color 0=off - 1=on
* Output : to DrawPixel
**********************************************************************)
Private Sub DrawLine(StartXpos As Word, StartYpos As Byte, EndXpos As Word, EndYpos As Byte, pColor As Byte)
Dim DX As Byte
Dim DY As Byte
If StartXpos = EndXpos And StartYpos = EndYpos Then
Exit
EndIf
If StartXpos > EndXpos Then
Temp = EndXpos
EndXpos = StartXpos
StartXpos = Temp
EndIf
If StartYpos > EndYpos Then
Temp = EndYpos
EndYpos = StartYpos
StartYpos = Temp
EndIf
DX = EndXpos - StartXpos
DY = EndYpos - StartYpos
If DX = 0 Then
Temp = StartYpos
Repeat
DrawPixel(StartXpos, Temp, pColor)
Inc(Temp)
Until Temp = EndYpos
Exit
EndIf
If DY = 0 Then
Temp = StartXpos
Repeat
DrawPixel(Temp, StartYpos, pColor)
Inc(Temp)
Until Temp = EndXpos + 1
Exit
EndIf
If DX > DY Then
Temp = (2 * DY) - DX
While StartXpos <> EndXpos
DrawPixel(StartXpos, StartYpos, pColor)
Inc(StartXpos)
If Temp > 0 Then
Inc(StartYpos)
Temp = 2 * DY - 2 * DX
Else
Temp = 2 * DY
DrawPixel(StartXpos, StartYpos, pColor)
EndIf
Wend
Else
Temp = (2 * DX) - DY
While StartYpos <> EndYpos
DrawPixel(StartXpos, StartYpos, pColor)
Inc(StartYpos)
If Temp > 0 Then
Inc(StartXpos)
Temp = (2 * DY) - (2 * DX)
Else
Temp = 2 * DY
DrawPixel(StartXpos, StartYpos, pColor)
EndIf
Wend
EndIf
End Sub
(*********************************************************************
* Draw Rectangle on the display
* Input1 : X start cords 0-127
* Input2 : Y start cords 0-63
* Input3 : X end cords 0-127
* Input4 : Y end cords 0-63
* Input5 : Color 0=off - 1=on
* Output : to drawline
**********************************************************************)
Public Sub DrawRectangle(StartXpos As Word, StartYpos As Byte, EndXpos As Word, EndYpos As Byte, pColor As Byte)
DrawLine(StartXpos, StartYpos, EndXpos , StartYpos, pColor)
DrawLine(StartXpos, EndYpos , EndXpos , EndYpos , pColor)
DrawLine(StartXpos, StartYpos, StartXpos, EndYpos , pColor)
DrawLine(EndXpos , StartYpos, EndXpos , EndYpos , pColor)
End Sub
(*********************************************************************
* Draw Filled Rectangle on the display
* Input1 : X start cords 0-127
* Input2 : Y start cords 0-63
* Input3 : X end cords 0-127
* Input4 : Y end cords 0-63
* Input5 : Color 0=off - 1=on
* Output : to drawline
**********************************************************************)
Public Sub FillRectangle(StartXpos As Word, StartYpos As Byte, EndXpos As Word, EndYpos As Byte, pColor As Byte)
If StartXpos > EndXpos Then
Temp = EndXpos
EndXpos = StartXpos
StartXpos = Temp
EndIf
If StartYpos > EndYpos Then
Temp = EndYpos
EndYpos = StartYpos
StartYpos = Temp
EndIf
Repeat
DrawLine(StartXpos, StartYpos, EndXpos, StartYpos, pColor)
Inc(StartYpos)
Until StartYpos = EndYpos
End Sub
(*********************************************************************
* Draw Circle on the display
* Input1 : X cords 0-127
* Input2 : Y cords 0-63
* Input3 : Radius in pixels
* Input4 : Color 0=off - 1=on
* Output : to DrawPixel
* Note : Radius is the center of the circle
**********************************************************************)
Public Sub DrawCircle(OledX0 As Byte, OledY0 As Byte, pRadius As Byte, pColor As Byte)
Dim OledparL As Byte
Dim OledparR As Byte
Dim Oled_X As Byte
Dim Oled_Y As Byte
Dim OledCircle As LongInt
OledCircle = -pRadius
Oled_X = pRadius
Oled_Y = 0
While Oled_X >= Oled_Y
OledparL = OledX0 + Oled_X
OledparR = OledY0 + Oled_Y
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 - Oled_X
OledparR = OledY0 + Oled_Y
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 + Oled_X
OledparR = OledY0 - Oled_Y
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 - Oled_X
OledparR = OledY0 - Oled_Y
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 + Oled_Y
OledparR = OledY0 + Oled_X
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 - Oled_Y
OledparR = OledY0 + Oled_X
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 + Oled_Y
OledparR = OledY0 - Oled_X
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 - Oled_Y
OledparR = OledY0 - Oled_X
DrawPixel(OledparL , OledparR, pColor)
OledCircle = OledCircle + Oled_Y
Oled_Y = Oled_Y + 1
OledCircle = OledCircle + Oled_Y
If OledCircle >= 0 Then
Oled_X = Oled_X - 1
OledCircle = OledCircle - Oled_X
OledCircle = OledCircle - Oled_X
EndIf
Wend
End Sub
(*********************************************************************
* Draw filled Circle on the display
* Input1 : X cords 0-127
* Input2 : Y cords 0-63
* Input3 : Radius in pixels
* Input4 : Color 0=off - 1=on
* Output : to DrawPixel
* Note : Radius is the center of the circle
**********************************************************************)
Public Sub FilledCircle(OledX0 As Byte, OledY0 As Byte, pRadius As Byte, pColor As Byte)
Dim OledcX0 As Byte
Dim OledcY0 As Byte
Dim OledcX1 As Byte
Dim OledcY1 As Byte
Dim Oled_X As Byte
Dim Oled_Y As Byte
Dim OledCircle As LongInt
OledCircle = -pRadius
Oled_X = pRadius
Oled_Y = 0
While Oled_X >= Oled_Y
OledcX0 = OledX0 - Oled_X
OledcY0 = OledY0 + Oled_Y
OledcX1 = OledX0 + Oled_X
OledcY1 = OledY0 + Oled_Y
DrawLine(OledcX0, OledcY0, OledcX1, OledcY1, pColor)
OledcX0 = OledX0 - Oled_X
OledcY0 = OledY0 - Oled_Y
OledcX1 = OledX0 + Oled_X
OledcY1 = OledY0 - Oled_Y
DrawLine(OledcX0, OledcY0, OledcX1, OledcY1, pColor)
OledcX0 = OledX0 - Oled_Y
OledcY0 = OledY0 + Oled_X
OledcX1 = OledX0 + Oled_Y
OledcY1 = OledY0 + Oled_X
DrawLine(OledcX0, OledcY0, OledcX1, OledcY1, pColor)
OledcX0 = OledX0 - Oled_Y
OledcY0 = OledY0 - Oled_X
OledcX1 = OledX0 + Oled_Y
OledcY1 = OledY0 - Oled_X
DrawLine(OledcX0, OledcY0, OledcX1, OledcY1, pColor)
OledCircle = OledCircle + Oled_Y
Oled_Y = Oled_Y + 1
OledCircle = OledCircle + Oled_Y
If OledCircle >= 0 Then
Oled_X = Oled_X - 1
OledCircle = OledCircle - Oled_X
OledCircle = OledCircle - Oled_X
EndIf
Wend
End Sub
(*********************************************************************
* Helper routine - Read byte from the table(name)
* Input1 : none
* Output : position in the table
**********************************************************************)
Public Inline Function ReadFromTable() As Byte
Asm-
TBLRD *+
movff TABLAT, result
End Asm
End Function
Function ReadByte(pIndex As Byte) As Byte
TABLEPTR = Font.Data + pIndex
Asm-
TBLRD *+
movff TABLAT, Result
End Asm
End Function
Function ReadWord(pIndex As Word) As Word
TABLEPTR = Font.Data + pIndex * 2
Asm-
TBLRD *+
movff TABLAT, Result
TBLRD *+
movff TABLAT, Result + 1
End Asm
End Function
(*********************************************************************
* Place fontname in system for simple accses to print characters
* Input1 : Name of font
* Output : None
**********************************************************************)
Public Sub SetFont(ByRefConst pFontTable() As Byte)
Dim FontHeaderSize As Byte
Font.Data = @pFontTable // address of font table
Font.Header = ReadWord(0) // font type, number of characters
Font.Width = ReadByte(2) // character width
Font.Height = ReadByte(3) // character height
FontHeaderSize = 4 // default header size
FFontTableOffset = 32 // default character offset
// calculate fixed font table width...
If Font.IsFixed Then
FFontTableWidth = Byte(Font.Height + 7) / 8 * Font.Width
EndIf
// skip over header information and point to font table...
Inc(Font.Data, FontHeaderSize)
#if debug = On Then
USART.Write("** Font **",13)
USART.Write("Font.Data + 4 ", DecToStr(Font.Data),13)
USART.Write("Font.Header ", DecToStr(Font.Header),13)
USART.Write("Font.Width ", DecToStr(Font.Width),13)
USART.Write("Font.Height ", DecToStr(Font.Height),13)
USART.Write("FontHeaderSize ", DecToStr(FontHeaderSize),13)
USART.Write("FFontTableOffset ", DecToStr(FFontTableOffset),13)
USART.Write("FFontTableWidth ", DecToStr(FFontTableWidth),13)
USART.Write("IsFixed ", DecToStr(Font.IsFixed),13)
USART.Write("IsVariable ", DecToStr(Font.IsVariable),13)
#endif
End Sub
(*********************************************************************
* Helper routine to print character to buffer
* Input1 : x coords
* Input2 : y coords
* Input3 : Character
* Output : None
**********************************************************************)
Sub PrintChar(pXpos, pYpos, pChar As Byte)
Dim HeightCount, WidthCount, PixelRowCount, pixels As Byte
Dim X1, y1 As Byte
HeightCount = Font.Height
PixelRowCount = 0
X1 = pXpos
y1 = pYpos
Dec(pChar, FFontTableOffset)
TABLEPTR = Font.Data + ReadWord(pChar)
If Font.IsVariable Then
Font.Width = ReadFromTable()
EndIf
WidthCount = Font.Width
Repeat
Repeat
If PixelRowCount = 0 Then
PixelRowCount = 8
pixels = ReadFromTable()
EndIf
If pixels.0 = 0 Then // do we need to set a pixel
DrawPixel(X1, y1, 0) // no
ElseIf pixels.0 = 1 Then
DrawPixel(X1, y1, 1) // yes
EndIf
pixels = pixels >> 1 // Move each pixel into bit-0
Inc(Y1)
Dec(PixelRowCount)
Dec(HeightCount)
Until HeightCount = 0
PixelRowCount = 0
Inc(X1)
y1 = pYpos
HeightCount = Font.Height
Dec(WidthCount)
Until WidthCount = 0
Font.RealWidth = Font.RealWidth + Font.Width //
#if LetterSpacing = On Then
Inc(Font.RealWidth)
#EndIf
End Sub
(*********************************************************************
* Print string routine
* Input1 : x coords
* Input2 : y coords
* Input3 : String
* Output : Single character + coords
**********************************************************************)
Public Sub Print(pXpos, pYpos As Byte, pText As String)
Dim CharIndex, CharData As Byte
CharIndex = 0
CharData = pText(0)
Font.RealWidth = pXpos
While CharData <> 0
PrintChar(Font.RealWidth, pYpos, CharData)
Inc(CharIndex)
CharData = pText(CharIndex)
Wend
End Sub
(*********************************************************************
* Load image from mem to display
* Input1 : X cords 0-127
* Input2 : y Cords 0-63
* Input3 : Invert the pixel
* Input4 : ImageName
* Output : None
**********************************************************************)
Public Sub LoadImage(pXpos, pYpos As Byte, pInvert As Bit, ByRefConst pImageTable() As Byte)
Dim Result As Byte
TABLEPTR = @pImageTable
ReadFromTable
Image.Width = ReadFromTable
Image.Height = ReadFromTable
ReadFromTable
Image.Size = Image.Width * Image.Height
Temp = Image.Size
Olediii = 0
Oledii = pXpos
Repeat
Result = ReadFromTable
If Result = 0 Then
If pInvert = 0 Then
DrawPixel(Oledii, pYpos, 0)
Else
DrawPixel(Oledii, pYpos, 1)
EndIf
ElseIf Result > 0 Then
If pInvert = 0 Then
DrawPixel(Oledii, pYpos, 1)
Else
DrawPixel(Oledii, pYpos, 0)
EndIf
EndIf
Inc(Olediii)
Inc(Oledii)
If Olediii = Image.Width Then
Olediii = 0
Oledii = pXpos
Inc(pYpos)
EndIf
Dec(Image.Size)
Until Image.Size = 0
#if debug = On Then
USART.Write("** Image **",13)
USART.Write("ImageWidth ", DecToStr(Image.Width),13)
USART.Write("ImageHeight ", DecToStr(Image.Height),13)
USART.Write("ImageSize ", DecToStr(Temp),13)
#endif
End Sub
=]
This is a array of 1023 byte.
To test the module
=code [=
Include "Oled.inc"
Include "Bitmap.inc"
//Include "Arial.bas"
Include "BookAntiqua.bas"
Dim x1 As Byte
Dim y1 As Byte
Dim z1 As Byte
Oled.Init()
Oled.ClearBuffer(0)
Oled.VLine(0, 0, 10, 1)
Oled.HLine(0, 0, 10, 1)
//DrawRectangle(5,5,122,60,1)
//Oled.DrawRectangle(10, 10, 20, 20, 1)
//Oled.FillRectangle(20, 20, 100, 40, 1)
//Oled.DrawCircle(20, 20, 10, 1)
//Oled.DrawCircle(18, 18, 10, 1)
//Oled.DrawCircle(16, 16, 10, 1)
//FilledCircle(70, 30, 10, 1)
LoadImage(30, 0, 1, BatteryImage)
SetFont(BookAntiqua)
Print(80,0,"Testrun")
x1 = 20
y1 = 15
z1 = 0
While true
Oled.DrawCircle(x1, y1, 10, 0)
Oled.DrawCircle(x1+2, y1+2, 10, 0)
Oled.DrawCircle(x1+4, y1+4, 10, 0)
If z1 = 0 Then
Inc(x1)
Inc(y1)
EndIf
If z1 = 1 Then
Dec(x1)
Dec(y1)
EndIf
If x1 = 20 Then z1 = 0 EndIf
If x1 = 50 Then z1 = 1 EndIf
Oled.DrawCircle(x1, y1, 10, 1)
Oled.DrawCircle(x1+2, y1+2, 10, 1)
Oled.DrawCircle(x1+4, y1+4, 10, 1)
If z1 = 0 Then
If x1 = 25 Then DrawRectangle(80,20,100,30,1) EndIf
If x1 = 30 Then DrawRectangle(80,20,100,30,0) EndIf
If x1 = 30 Then FillRectangle(80,20,100,30,1) EndIf
If x1 = 35 Then FillRectangle(80,20,100,30,0) EndIf
If x1 = 35 Then DrawCircle(90,30,10,1) EndIf
If x1 = 40 Then DrawCircle(90,30,10,0) EndIf
If x1 = 40 Then FilledCircle(90,30,10,1) EndIf
If x1 = 45 Then FilledCircle(90,30,10,0) EndIf
EndIf
Oled.UpdateDisplay()
Wend
=]
module bitmap
=code [=
module Bitmap
public Const BatteryImage() As Byte =
(1,11,6,0,
$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$FF,
$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$00,$FF,
$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$00,$00,
$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$00,$00,
$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$00,$FF,
$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$FF)
=]
Oled module
=code [=
'******************************************************************************
'* Name : Oled Library for the SSD1306 display *
'* Author : Frank Sloep (Yoepie) *
'* Notice : This source code is provided 'as is' *
'* : *
'* : *
'* Date : 06/01/16 *
'* Version : *
'* Notes : 0.3 Initial release for SwordFish *
'* Notes : 0.2 add ImageFromCode *
'* Notes : 0.1 Initial release For Proton (never released) *
'******************************************************************************
' The most inportend thing about Oled-displays you can not write directly to
' the cords of the display. This Oled module works fromout a buffer of 1024bytes
' for a 128x64 display. Everytime you do a write to the display, it will go to
' the buffer. You have to update the buffer, to see somthing on the display,
' with the commands UpdateDisplay() or UpdateRow(Row).
'
' Oled Initialize : Oled.Init()
' Clear Buffer : Oled.ClearBuffer(Color (0/1))
' Clear Row : Oled.ClearRow(Row (0/7), Color (0/1))
' Update Display : Oled.UpdateDisplay()
' Update Row : Oled.UpdateRow(Row (0/7))
' Draw horizontal line : Oled.Hline(startX , StartY , Length, Color (0/1))
' Draw Vertical line : Oled.Vline(startX , StartY , Length, Color (0/1))
' Draw Rectangle : Oled.DrawRectangle(StartX , StartY, EndX , EndY, Color (0/1))
' Draw filled Rectangle : Oled.DrawRectangle(StartX , StartY, EndX , EndY, Color (0/1))
' Draw Circle : Oled.DrawCircle(StartX, StartY, Radius (in pixel), Color (0/1))
' Draw filled Circle : Oled.DrawCircle(StartX, StartY, Radius (in pixel), Color (0/1))
' Display on / off : Oled.Power(0/1)
' SetFont : Oled.SetFont(fontname)
' Print string : Olet.Print(StartX, StartY, string)
' Load Image from mem : Oled.LoadImage(startX,StartY,Invert,Imagename)
'
' ----------------------------------------------------------------------------------------
' The Oled work at the moment only with I2C.
' Oled_Hardware = I2C
' Oled_MODEL = SSD1306/??
' LetterSpacing = On/Off
' Debug = On/Off
Module Oled
Include "Convert.bas"
//Include "SPI.bas"
Include "i2c.bas"
// output in debug
Include "USART.bas"
#option Oled_MODEL = SSD1306
// SSD1306
#option Oled_Hardware = I2C
// i2C - SPI
#option LetterSpacing = On
// LetterSpacing = On - 1 pixel row after each character
// LetterSpacing = Off - No pixel row after each character.
#option Debug = Off
'==== Change to your needs ==============================================================================='
Const
Adres = $78, // I2C adress, Oled display
Buffer = 1024, // maxX * MaxY / 8 Pixels
OledMaxX = 128, // max Horizontal display size
OledMaxY = 64 // max vertical display size
'========================================================================================================='
Private Dim
Framebuffer(Buffer) As Byte, // Oled display buffer
OledRow As Byte, // Oled row 0/7
OledIndex As Word, //
OledData As Byte, //
Oledi As Word, // counter
Oledii As Word, // counter
Olediii As Word, // counter
Temp As Byte
// Font structure...
Public Structure TFont
Header As Word
Data As Word
Width As Word
Height As Byte
RealWidth As Byte
IsFixed As Header.Booleans(0)
IsVariable As Header.Booleans(1)
End Structure
// Image structure...
Public Structure TImage
Width As Word
Height As Byte
Size As Byte
End Structure
Public Dim
Font As TFont,
Image As TImage
// local variables...
Dim
FFontTableOffset As Byte,
FFontTableWidth As Byte
(*********************************************************************
* Start and Write command to oled display
* Input1 : Command
* Output : none
**********************************************************************)
Sub WriteCommand(pCommand As Byte)
#if Oled_Hardware = I2C
I2C.Start()
I2C.WriteByte(Adres)
I2C.WriteByte($00)
I2C.WriteByte(pCommand)
I2C.Stop()
#endif
#if Oled_Hardware = SPI
#endif
End Sub
(*********************************************************************
* Start and Write data to the oled display
* Input1 :
* Output : none
**********************************************************************)
Sub WriteStart(pData As Bit)
#if Oled_Hardware = I2C
I2C.Start()
I2C.WriteByte(Adres)
If pData = 0 Then
I2C.WriteByte($80)
Else
I2C.WriteByte($40)
EndIf
#endif
#if Oled_Hardware = SPI
#endif
End Sub
(*********************************************************************
* Helper routine - Write data to the oled display
* Input1 :
* Output : none
**********************************************************************)
Sub WriteDataWord(pData As Byte)
#if Oled_Hardware = I2C
I2C.WriteByte(pData)
#endif
#if Oled_Hardware = SPI
#endif
End Sub
(*********************************************************************
* Initialize for the oled display SSD1306
* Input1 : none
* Output : none
**********************************************************************)
Public Sub Init()
#if Oled_Hardware = I2C
I2C.Initialize(I2C_400_KHZ)
#endif
#if Oled_Hardware = SPI
#endif
#if Oled_MODEL = SSD1306
WriteCommand($AE) // \Turn display off
WriteCommand($00) // /
WriteCommand($10) //
WriteCommand($40) //
WriteCommand($B0) // Set COM Output Scan Direction
WriteCommand($81) // set Low column address
WriteCommand($CF) // set High column address
WriteCommand($A1) // set Start line address
WriteCommand($A6) // set contrast control register
WriteCommand($A8) // set normal display
WriteCommand($3F) // set segment re-map 0 To 127
WriteCommand($c8) // set normal display
WriteCommand($d3) // set multiplex ratio(1 To 64)
WriteCommand($00) //
WriteCommand($d5) // 0xa4,Output follows RAM content;0xa5,Output ignores RAM content
WriteCommand($80) // set display offset
WriteCommand($d9) // Not offset
WriteCommand($f1) // set display Clock divide ratio/oscillator frequency
WriteCommand($da) // set divide ratio
WriteCommand($12) // set pre-charge period
WriteCommand($db) //
WriteCommand($40) // set com pins hardware configuration
WriteCommand($8d) // set vcomh
WriteCommand($14) // 0x20,0.77xVcc
WriteCommand($AF) // set DC-DC Enable
WriteCommand($AF) // Set COM Output Scan Direction 64 To 0
DelayMS(10)
#endif
End Sub
(*********************************************************************
* Turn display on / off
* Input1 : 0 = off | 1 = on
* Output : None
**********************************************************************)
Public Sub Power(pData As Bit)
If pData = 0 Then
WriteCommand($AE)
WriteCommand($00)
ElseIf pdata = 1 Then
WriteCommand($AF)
WriteCommand($01)
EndIf
End Sub
(*********************************************************************
* Clear Buffer
* Input1 : color 0=off 1=on
* Output : none
**********************************************************************)
Public Sub ClearBuffer(pColor As Byte)
If pColor = 0 Then OledData = $00 EndIf
If pColor = 1 Then OledData = $FF EndIf
Oledi = 0
For Oledi = 0 To Buffer
Framebuffer(Oledi) = OledData
Next
End Sub
(*********************************************************************
* Clear a row in the Buffer
* Input1 : row 0/7
* Input2 : color 0=off 1=on
* Output : none
**********************************************************************)
Public Sub ClearRow(pRow As Byte, pColor As Byte)
If pColor = 0 Then OledData = $00 EndIf
If pColor = 1 Then OledData = $FF EndIf
If pRow = 0 Then Oledii = 0 EndIf
If pRow = 1 Then Oledii = 128 EndIf
If pRow = 2 Then Oledii = 256 EndIf
If pRow = 3 Then Oledii = 384 EndIf
If pRow = 4 Then Oledii = 512 EndIf
If pRow = 5 Then Oledii = 640 EndIf
If pRow = 6 Then Oledii = 768 EndIf
If pRow = 7 Then Oledii = 896 EndIf
Oledi = Oledii
For Oledi = Oledii To Oledii + 127
Framebuffer(Oledi) = OledData
Next
End Sub
(*********************************************************************
* Update display
* Input1 : none
* Output : none
**********************************************************************)
Public Sub UpdateDisplay()
Oledi = 0
For OledRow = $b0 To $b7
WriteCommand(OledRow) //
WriteCommand($00) // Low column start address
WriteCommand($10) // High column start address
WriteStart(1)
For Oledii = 0 To OledMaxX -1
WriteDataWord(Framebuffer(Oledi))
Inc(Oledi)
Next
I2C.Stop()
Next
End Sub
(*********************************************************************
* Update display with one row 0/7
* Input1 : row 0/7
* Output : none
**********************************************************************)
Public Sub UpdateRow(pRow As Byte)
WriteCommand($B0 + pRow) // Row0 .. Row7
WriteCommand($00) // Low column Start address
WriteCommand($10) // High column Start address
WriteStart(1)
For Oledi = 0 To OledMaxX -1
OledIndex = pRow * 128 + Oledi
WriteDataWord(Framebuffer(OledIndex))
Next
I2C.Stop()
End Sub
(*********************************************************************
* Place Graphics to buffer
* Input1 : X start cords 0-127
* Input2 : Y start cords 0-63
* Input3 : Color 0=off 1=on
* Output : Framebuffer(buffer)
**********************************************************************)
Public Sub DrawPixel(pXPixel As Byte,pYPixel As Byte,pColor As Byte)
Dim OledOffset As Byte
Dim PreData As Byte
OledRow = pYpixel / 8
OledOffset = pYpixel Mod 8
OledIndex = OledRow * 128 + pXpixel
PreData = Framebuffer(OledIndex)
Oledi = 1 << OledOffset
If pColor = 1 Then
Framebuffer(OledIndex) = PreData Or Oledi
Else
Framebuffer(OledIndex) = PreData And (Not Oledi)
EndIf
#if debug = On
USART.Write("_SETLED_", 13)
USART.Write("X = ", DecToStr(pXpixel), 13)
USART.Write("Y = ", DecToStr(pYpixel),13)
USART.Write("Value = ", DecToStr(pColor), 13)
USART.Write("Row = ", DecToStr(OledRow), 13)
USART.Write("Offset = ", DecToStr(OledOffset), 13)
USART.Write("Index = ", DecToStr(OledIndex), 13)
USART.Write("Pre = ", DecToStr(PreData), 13)
USART.Write("Buffer = ", DecToStr(Framebuffer(OledIndex)), 13)
USART.Write("Oledi = ", DecToStr(Oledi), 13)
USART.Write(13)
#endif
End Sub
(*********************************************************************
* draw Horizontal line on display
* Input1 : X start cords 0-127
* Input2 : Y start cords 0-63
* Input3 : Line length 0-127
* Output : to DrawPixel
**********************************************************************)
Public Sub HLine(StartXpos As Word, StartYpos As Byte, pLength As Word, pColor As Byte)
Repeat
DrawPixel((StartXpos + pLength), StartYpos, pColor)
Dec(pLength)
Until pLength = 0
End Sub
(*********************************************************************
* draw vertical line on display
* Input1 : X start cords 0-127
* Input2 : Y start cords 0-63
* Input3 : Line length 0-63
* Output : to DrawPixel
**********************************************************************)
Public Sub VLine(StartXpos As Word, StartYpos As Byte, pLength As Word, pColor As Byte)
Repeat
DrawPixel(StartXpos, (StartYpos + pLength), pColor)
Dec(pLength)
Until pLength = 0
End Sub
(*********************************************************************
* Helper routine for drawpixel to buffer
* Input1 : X start cords 0-127
* Input2 : Y start cords 0-63
* Input3 : X end cords 0-127
* Input4 : Y end cords 0-63
* Input5 : Color 0=off - 1=on
* Output : to DrawPixel
**********************************************************************)
Private Sub DrawLine(StartXpos As Word, StartYpos As Byte, EndXpos As Word, EndYpos As Byte, pColor As Byte)
Dim DX As Byte
Dim DY As Byte
If StartXpos = EndXpos And StartYpos = EndYpos Then
Exit
EndIf
If StartXpos > EndXpos Then
Temp = EndXpos
EndXpos = StartXpos
StartXpos = Temp
EndIf
If StartYpos > EndYpos Then
Temp = EndYpos
EndYpos = StartYpos
StartYpos = Temp
EndIf
DX = EndXpos - StartXpos
DY = EndYpos - StartYpos
If DX = 0 Then
Temp = StartYpos
Repeat
DrawPixel(StartXpos, Temp, pColor)
Inc(Temp)
Until Temp = EndYpos
Exit
EndIf
If DY = 0 Then
Temp = StartXpos
Repeat
DrawPixel(Temp, StartYpos, pColor)
Inc(Temp)
Until Temp = EndXpos + 1
Exit
EndIf
If DX > DY Then
Temp = (2 * DY) - DX
While StartXpos <> EndXpos
DrawPixel(StartXpos, StartYpos, pColor)
Inc(StartXpos)
If Temp > 0 Then
Inc(StartYpos)
Temp = 2 * DY - 2 * DX
Else
Temp = 2 * DY
DrawPixel(StartXpos, StartYpos, pColor)
EndIf
Wend
Else
Temp = (2 * DX) - DY
While StartYpos <> EndYpos
DrawPixel(StartXpos, StartYpos, pColor)
Inc(StartYpos)
If Temp > 0 Then
Inc(StartXpos)
Temp = (2 * DY) - (2 * DX)
Else
Temp = 2 * DY
DrawPixel(StartXpos, StartYpos, pColor)
EndIf
Wend
EndIf
End Sub
(*********************************************************************
* Draw Rectangle on the display
* Input1 : X start cords 0-127
* Input2 : Y start cords 0-63
* Input3 : X end cords 0-127
* Input4 : Y end cords 0-63
* Input5 : Color 0=off - 1=on
* Output : to drawline
**********************************************************************)
Public Sub DrawRectangle(StartXpos As Word, StartYpos As Byte, EndXpos As Word, EndYpos As Byte, pColor As Byte)
DrawLine(StartXpos, StartYpos, EndXpos , StartYpos, pColor)
DrawLine(StartXpos, EndYpos , EndXpos , EndYpos , pColor)
DrawLine(StartXpos, StartYpos, StartXpos, EndYpos , pColor)
DrawLine(EndXpos , StartYpos, EndXpos , EndYpos , pColor)
End Sub
(*********************************************************************
* Draw Filled Rectangle on the display
* Input1 : X start cords 0-127
* Input2 : Y start cords 0-63
* Input3 : X end cords 0-127
* Input4 : Y end cords 0-63
* Input5 : Color 0=off - 1=on
* Output : to drawline
**********************************************************************)
Public Sub FillRectangle(StartXpos As Word, StartYpos As Byte, EndXpos As Word, EndYpos As Byte, pColor As Byte)
If StartXpos > EndXpos Then
Temp = EndXpos
EndXpos = StartXpos
StartXpos = Temp
EndIf
If StartYpos > EndYpos Then
Temp = EndYpos
EndYpos = StartYpos
StartYpos = Temp
EndIf
Repeat
DrawLine(StartXpos, StartYpos, EndXpos, StartYpos, pColor)
Inc(StartYpos)
Until StartYpos = EndYpos
End Sub
(*********************************************************************
* Draw Circle on the display
* Input1 : X cords 0-127
* Input2 : Y cords 0-63
* Input3 : Radius in pixels
* Input4 : Color 0=off - 1=on
* Output : to DrawPixel
* Note : Radius is the center of the circle
**********************************************************************)
Public Sub DrawCircle(OledX0 As Byte, OledY0 As Byte, pRadius As Byte, pColor As Byte)
Dim OledparL As Byte
Dim OledparR As Byte
Dim Oled_X As Byte
Dim Oled_Y As Byte
Dim OledCircle As LongInt
OledCircle = -pRadius
Oled_X = pRadius
Oled_Y = 0
While Oled_X >= Oled_Y
OledparL = OledX0 + Oled_X
OledparR = OledY0 + Oled_Y
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 - Oled_X
OledparR = OledY0 + Oled_Y
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 + Oled_X
OledparR = OledY0 - Oled_Y
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 - Oled_X
OledparR = OledY0 - Oled_Y
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 + Oled_Y
OledparR = OledY0 + Oled_X
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 - Oled_Y
OledparR = OledY0 + Oled_X
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 + Oled_Y
OledparR = OledY0 - Oled_X
DrawPixel(OledparL , OledparR, pColor)
OledparL = OledX0 - Oled_Y
OledparR = OledY0 - Oled_X
DrawPixel(OledparL , OledparR, pColor)
OledCircle = OledCircle + Oled_Y
Oled_Y = Oled_Y + 1
OledCircle = OledCircle + Oled_Y
If OledCircle >= 0 Then
Oled_X = Oled_X - 1
OledCircle = OledCircle - Oled_X
OledCircle = OledCircle - Oled_X
EndIf
Wend
End Sub
(*********************************************************************
* Draw filled Circle on the display
* Input1 : X cords 0-127
* Input2 : Y cords 0-63
* Input3 : Radius in pixels
* Input4 : Color 0=off - 1=on
* Output : to DrawPixel
* Note : Radius is the center of the circle
**********************************************************************)
Public Sub FilledCircle(OledX0 As Byte, OledY0 As Byte, pRadius As Byte, pColor As Byte)
Dim OledcX0 As Byte
Dim OledcY0 As Byte
Dim OledcX1 As Byte
Dim OledcY1 As Byte
Dim Oled_X As Byte
Dim Oled_Y As Byte
Dim OledCircle As LongInt
OledCircle = -pRadius
Oled_X = pRadius
Oled_Y = 0
While Oled_X >= Oled_Y
OledcX0 = OledX0 - Oled_X
OledcY0 = OledY0 + Oled_Y
OledcX1 = OledX0 + Oled_X
OledcY1 = OledY0 + Oled_Y
DrawLine(OledcX0, OledcY0, OledcX1, OledcY1, pColor)
OledcX0 = OledX0 - Oled_X
OledcY0 = OledY0 - Oled_Y
OledcX1 = OledX0 + Oled_X
OledcY1 = OledY0 - Oled_Y
DrawLine(OledcX0, OledcY0, OledcX1, OledcY1, pColor)
OledcX0 = OledX0 - Oled_Y
OledcY0 = OledY0 + Oled_X
OledcX1 = OledX0 + Oled_Y
OledcY1 = OledY0 + Oled_X
DrawLine(OledcX0, OledcY0, OledcX1, OledcY1, pColor)
OledcX0 = OledX0 - Oled_Y
OledcY0 = OledY0 - Oled_X
OledcX1 = OledX0 + Oled_Y
OledcY1 = OledY0 - Oled_X
DrawLine(OledcX0, OledcY0, OledcX1, OledcY1, pColor)
OledCircle = OledCircle + Oled_Y
Oled_Y = Oled_Y + 1
OledCircle = OledCircle + Oled_Y
If OledCircle >= 0 Then
Oled_X = Oled_X - 1
OledCircle = OledCircle - Oled_X
OledCircle = OledCircle - Oled_X
EndIf
Wend
End Sub
(*********************************************************************
* Helper routine - Read byte from the table(name)
* Input1 : none
* Output : position in the table
**********************************************************************)
Public Inline Function ReadFromTable() As Byte
Asm-
TBLRD *+
movff TABLAT, result
End Asm
End Function
Function ReadByte(pIndex As Byte) As Byte
TABLEPTR = Font.Data + pIndex
Asm-
TBLRD *+
movff TABLAT, Result
End Asm
End Function
Function ReadWord(pIndex As Word) As Word
TABLEPTR = Font.Data + pIndex * 2
Asm-
TBLRD *+
movff TABLAT, Result
TBLRD *+
movff TABLAT, Result + 1
End Asm
End Function
(*********************************************************************
* Place fontname in system for simple accses to print characters
* Input1 : Name of font
* Output : None
**********************************************************************)
Public Sub SetFont(ByRefConst pFontTable() As Byte)
Dim FontHeaderSize As Byte
Font.Data = @pFontTable // address of font table
Font.Header = ReadWord(0) // font type, number of characters
Font.Width = ReadByte(2) // character width
Font.Height = ReadByte(3) // character height
FontHeaderSize = 4 // default header size
FFontTableOffset = 32 // default character offset
// calculate fixed font table width...
If Font.IsFixed Then
FFontTableWidth = Byte(Font.Height + 7) / 8 * Font.Width
EndIf
// skip over header information and point to font table...
Inc(Font.Data, FontHeaderSize)
#if debug = On Then
USART.Write("** Font **",13)
USART.Write("Font.Data + 4 ", DecToStr(Font.Data),13)
USART.Write("Font.Header ", DecToStr(Font.Header),13)
USART.Write("Font.Width ", DecToStr(Font.Width),13)
USART.Write("Font.Height ", DecToStr(Font.Height),13)
USART.Write("FontHeaderSize ", DecToStr(FontHeaderSize),13)
USART.Write("FFontTableOffset ", DecToStr(FFontTableOffset),13)
USART.Write("FFontTableWidth ", DecToStr(FFontTableWidth),13)
USART.Write("IsFixed ", DecToStr(Font.IsFixed),13)
USART.Write("IsVariable ", DecToStr(Font.IsVariable),13)
#endif
End Sub
(*********************************************************************
* Helper routine to print character to buffer
* Input1 : x coords
* Input2 : y coords
* Input3 : Character
* Output : None
**********************************************************************)
Sub PrintChar(pXpos, pYpos, pChar As Byte)
Dim HeightCount, WidthCount, PixelRowCount, pixels As Byte
Dim X1, y1 As Byte
HeightCount = Font.Height
PixelRowCount = 0
X1 = pXpos
y1 = pYpos
Dec(pChar, FFontTableOffset)
TABLEPTR = Font.Data + ReadWord(pChar)
If Font.IsVariable Then
Font.Width = ReadFromTable()
EndIf
WidthCount = Font.Width
Repeat
Repeat
If PixelRowCount = 0 Then
PixelRowCount = 8
pixels = ReadFromTable()
EndIf
If pixels.0 = 0 Then // do we need to set a pixel
DrawPixel(X1, y1, 0) // no
ElseIf pixels.0 = 1 Then
DrawPixel(X1, y1, 1) // yes
EndIf
pixels = pixels >> 1 // Move each pixel into bit-0
Inc(Y1)
Dec(PixelRowCount)
Dec(HeightCount)
Until HeightCount = 0
PixelRowCount = 0
Inc(X1)
y1 = pYpos
HeightCount = Font.Height
Dec(WidthCount)
Until WidthCount = 0
Font.RealWidth = Font.RealWidth + Font.Width //
#if LetterSpacing = On Then
Inc(Font.RealWidth)
#EndIf
End Sub
(*********************************************************************
* Print string routine
* Input1 : x coords
* Input2 : y coords
* Input3 : String
* Output : Single character + coords
**********************************************************************)
Public Sub Print(pXpos, pYpos As Byte, pText As String)
Dim CharIndex, CharData As Byte
CharIndex = 0
CharData = pText(0)
Font.RealWidth = pXpos
While CharData <> 0
PrintChar(Font.RealWidth, pYpos, CharData)
Inc(CharIndex)
CharData = pText(CharIndex)
Wend
End Sub
(*********************************************************************
* Load image from mem to display
* Input1 : X cords 0-127
* Input2 : y Cords 0-63
* Input3 : Invert the pixel
* Input4 : ImageName
* Output : None
**********************************************************************)
Public Sub LoadImage(pXpos, pYpos As Byte, pInvert As Bit, ByRefConst pImageTable() As Byte)
Dim Result As Byte
TABLEPTR = @pImageTable
ReadFromTable
Image.Width = ReadFromTable
Image.Height = ReadFromTable
ReadFromTable
Image.Size = Image.Width * Image.Height
Temp = Image.Size
Olediii = 0
Oledii = pXpos
Repeat
Result = ReadFromTable
If Result = 0 Then
If pInvert = 0 Then
DrawPixel(Oledii, pYpos, 0)
Else
DrawPixel(Oledii, pYpos, 1)
EndIf
ElseIf Result > 0 Then
If pInvert = 0 Then
DrawPixel(Oledii, pYpos, 1)
Else
DrawPixel(Oledii, pYpos, 0)
EndIf
EndIf
Inc(Olediii)
Inc(Oledii)
If Olediii = Image.Width Then
Olediii = 0
Oledii = pXpos
Inc(pYpos)
EndIf
Dec(Image.Size)
Until Image.Size = 0
#if debug = On Then
USART.Write("** Image **",13)
USART.Write("ImageWidth ", DecToStr(Image.Width),13)
USART.Write("ImageHeight ", DecToStr(Image.Height),13)
USART.Write("ImageSize ", DecToStr(Temp),13)
#endif
End Sub
=]