WhiteSpace
Well-known member
I'm fairly new to Picaxe and would welcome a steer as to whether I'm overlooking something obvious.
I bought one of these small 128 x 64 OLEDs (in this case from Amazon but they also have them on eBay). It worked more or less out of the box with the code for small 5x7 characters from post #7 off this thread: https://picaxeforum.co.uk/threads/i2c-oled-display.27651/. It's a very sharp and responsive display.
I've succeeded in creating double size characters, based on the method in this thread: https://picaxeforum.co.uk/threads/ssd1306-oled-128x32-test-code.31467/
I used a different font, based on the design here: https://fontstruct.com/fontstructions/show/243719/command_prompt_12x16 . I hope that I haven't overlooked a simple way of converting this to the SSD1306 format. I found that the easiest way was to map out each character in a blank table in a Word document (like below) before identifying the correct binary/hex code (this conversion table was useful: https://ascii.cl/conversion.htm). It's very time-consuming.
The font needs a few tweaks - for example "g" goes below the line and will need some adjustment, but as you can see from the photo of the display, the font is very clear on the small display.
So here's my code. At the moment it's just intended to load a starting figure onto the display, then subtract one for each press of a button.
(Omitting the OLED set-up instructions...)
and then the same principle for "a", "d" and ":"
Now the counter:
and so on for cases "2" to "18"
Then
and so on for the remaining digits
Then
This is a very thirsty approach, and 0 to 9 characters and the select... code take up just under 2000 bytes. There are a number of threads that show how to put the characters into memory and then send them to the display, eg. post #10 of this one: https://picaxeforum.co.uk/threads/ssd1306-oled-screen-help.30783/ . I have to confess that I don't really understand how this bit works:
If I understand correctly, it puts a long string of hex codes for all characters sequentially into the memory, and then retrieves the 5 that code for a particular character, and sends them to the display, but I don't understand how it identifies which 5 relate to a particular character. Presumably if I created or found a similar string for all of the double height characters, I could do something similar - with two times 0x00 added in each case to provide the spacing. But I would somehow need to do that twice for each character - one for the top row and one for the bottom. Would I need to have two separate strings in the memory, one top half and one bottom half? And how would I send them to the right place in the display? The threads I mentioned seem to rely on the OLED advancing one character space automatically for each new character, but with the double size characters I would need to set the address manually each time. Or could I somehow set the column and row by reference to the previous, so the next character is [column +12] and the bottom row of the character is [top row + 8]?
All thoughts very gratefully received.
I've posted the entire code here in case the work I've done on the characters is useful to anyone.
I bought one of these small 128 x 64 OLEDs (in this case from Amazon but they also have them on eBay). It worked more or less out of the box with the code for small 5x7 characters from post #7 off this thread: https://picaxeforum.co.uk/threads/i2c-oled-display.27651/. It's a very sharp and responsive display.
I've succeeded in creating double size characters, based on the method in this thread: https://picaxeforum.co.uk/threads/ssd1306-oled-128x32-test-code.31467/
I used a different font, based on the design here: https://fontstruct.com/fontstructions/show/243719/command_prompt_12x16 . I hope that I haven't overlooked a simple way of converting this to the SSD1306 format. I found that the easiest way was to map out each character in a blank table in a Word document (like below) before identifying the correct binary/hex code (this conversion table was useful: https://ascii.cl/conversion.htm). It's very time-consuming.
The font needs a few tweaks - for example "g" goes below the line and will need some adjustment, but as you can see from the photo of the display, the font is very clear on the small display.
So here's my code. At the moment it's just intended to load a starting figure onto the display, then subtract one for each press of a button.
(Omitting the OLED set-up instructions...)
Code:
gosub ClearDisplay
WriteLoad: 'writes "Load:" on the OLED, double height. Each character fits within 4 6-column by 8-row blocks, resulting in a character 12 wide and 16 high. Of these the 2 right hand rows and 2 top columns are blank to provide character and row spacing.
' "L" as 12 x 16
'top row
row = 0 : col = 0 ' rows are 0 to 7 top to bottom (each row 8 pixels high); columns are 0 to 127. SetPosition at multiples of 12 - 0, 12, 24, etc
gosub SetPosition
hi2cout (0x40, 0xFC, 0xFC, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) '0x40 is the command to receive data, then follow 12 hex characters which equate to 12 bytes, with each binary byte representing a column of 8 bits, 1s and/or 0s, with the 1s representing lit pixels. The bytes run from the bottom (MSB) to the top (LSB), so 0xFC represents 11111100 to give 6 lit pixels in the top half of the vertical leg of the L, with two spaces at the top. The bottom half of the vertical leg of the L is coded in the second row below, in which 0xFF represents a full column of 11111111
'2nd row
row = 1 : col = 0
gosub SetPosition
hi2cout (0x40, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0,0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00)
'"o" as 12 x 16
row = 0 : col = 12
gosub SetPosition
hi2cout (0x40, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,0x00, 0x00, 0x00, 0x00)
row = 1 : col = 12
gosub SetPosition
hi2cout (0x40, 0x3E, 0x7F, 0xE3, 0xC1, 0xC1, 0xC1, 0xC1, 0xE3, 0x7F, 0x3E, 0x00, 0x00)
Now the counter:
Code:
Let b8 = 18 'sets the counter to 18, which is the starting number
let b9 = b8 ' allows us to check whether there has been any change in b8
goto CountAndDisplay
CheckCount:
If pinC.1 = 1 then 'C.1 in this instance is a push button
pause 75 ' debounce
let b8 = b8 - 1 'decrease the value of b8
else goto CheckCount 'keep looping until there is a button press
endif
if b8 <> b9 then goto CountAndDisplay ' not sure that this is necessary - if b8 = b9 then b8 won't have decreased and CheckCount will still be looping
CountAndDisplay:
select case b8
case 0 'if b8 = zero, then go to the subroutines to display "0". There must be a simpler way than this.
row = 0 : col = 60
gosub SetPosition
gosub DisplayTop0
row = 1 : col = 60
gosub SetPosition
gosub DisplayBottom0
row = 0 : col = 72 'need to add a space to single digit figures because otherwise as the figures count down below 10, the second digit (0) from the 10 remains undeleted. So load a blank space in order to suppress the second digit from earlier numbers. Could otherwise selectively clear that character if I could work out how to do it
gosub SetPosition
gosub DisplayTopSpace
row = 1 : col = 72
gosub SetPosition
gosub DisplayBottomSpace
case 1 'if b8 = 1, then go to the subroutines to display "1"
row = 0 : col = 60
gosub SetPosition
gosub DisplayTop1
row = 1 : col = 60
gosub SetPosition
gosub DisplayBottom1
row = 0 : col = 72
gosub SetPosition
gosub DisplayTopSpace
row = 1 : col = 72
gosub SetPosition
gosub DisplayBottomSpace
Then
Code:
case 10 'if b8 = 10, then go to the subroutines to display "1"followed by "0"
row = 0 : col = 60
gosub SetPosition
gosub DisplayTop1
row = 1 : col = 60
gosub SetPosition
gosub DisplayBottom1
row = 0 : col = 72
gosub SetPosition
gosub DisplayTop0
row = 1 : col = 72
gosub SetPosition
gosub DisplayBottom0
Then
Code:
EndSelect
dec b9 'decrease b9 by 1 so that when the code loops back to the start of CheckCount and compares the counter b8 with b9, the counter displays a lower figure only if b8 changes
goto CheckCount
end
'Characters are set out here as subroutines - 2 subroutines (top and bottom) per character. There need to be two separate subroutines because each half of the character is posted to a different row address. Unless it is possible to address/create a double height column in the OLED setup menu
'"space" as 12 x 16
DisplayTopSpace:
hi2cout (0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
return
DisplayBottomSpace:
hi2cout (0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
return
'"0" as 12 x 16
DisplayTop0:
hi2cout (0x40, 0xE0, 0xF8, 0x18, 0x0C, 0x0C, 0x8C, 0xCC, 0x7C, 0xF8, 0xE0, 0x00, 0x00)
return
DisplayBottom0:
hi2cout (0x40, 0x1F, 0x7F, 0x7C, 0xCE, 0xC3, 0xC1, 0xC0, 0x60, 0x7F, 0x1F, 0x00, 0x00)
return
'"1" as 12 x 16 - top and bottom halves
DisplayTop1: 'displays the upper 12 columns of the digit "1"
hi2cout (0x40, 0x30, 0x30, 0x38, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
return
DisplayBottom1: 'displays the lower 12 columns of the digit "1"
hi2cout (0x40, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00)
return
Code:
b1 = 0 : do : LookUp b1, ( "HELLO WORLD",0 ), b0
if b0 <> 0 then : Gosub ShowChar : endif : inc b1
loop until b0 = 0
do : loop
end
ShowChar:
' sertxd(b0)
if b0 >= "A" and b0 <= "Z" then
bptr = b0 - "A" * 5 + A_addr ' point to 5 unique char bytes in upper ram
hi2cout (0x40, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, 0)
endif
return
All thoughts very gratefully received.
I've posted the entire code here in case the work I've done on the characters is useful to anyone.
Attachments
-
21.5 KB Views: 6