Picaxe 18m2 to a 128 x 64 oled

captnemo

New Member
This program was originally created by paraglider_nut. I added more comments and also a variable data section, wich I believe was created by Hippy. I also added a "top of page" subroutine, as the program did not always start at the top of the display and was also scrolling left to right, one column of pixels, at a time. The display commands I don't understand and therefore could not explain, have question marks after them.
 

Attachments

OLDmarty

Senior Member
Hi Captnemo,

I tried your code on a 20X2, but all i see on my OLED is a full screen of small separated lines.

I only changed the code to use a 20X2 instead of an 18M2 etc, is there something else within the code i should be adjusting too?

2605626057
 

AllyCat

Senior Member
Hi,

Conversion from an M2 series PICaxe to X2 is not always "trivial", for example because the X2's default clock frequency is twice as high.

The text and Program in #1 does not specify the OLED's "controller" chip on the OLED breakout board, nor the size of the display which might be "0.9" inches or 1.3 inches diagonal. This can be important because it appears that the 1.3 inch boards may use a different controller chip to the 0.9+ inch (128 x 32 or x 64 pixel) displays.

I have posted quite a lot on using these displays, including a reply to one started by you (OLDmarty) HERE. That leads to links to two of my other relevant posts HERE and HERE. Somewhere, I also posted the data for a corresponding Greek Character Set which might be quite appropriate for some. :)

Cheers, Alan.
 

OLDmarty

Senior Member
Hi,

Conversion from an M2 series PICaxe to X2 is not always "trivial", for example because the X2's default clock frequency is twice as high.

The text and Program in #1 does not specify the OLED's "controller" chip on the OLED breakout board, nor the size of the display which might be "0.9" inches or 1.3 inches diagonal. This can be important because it appears that the 1.3 inch boards may use a different controller chip to the 0.9+ inch (128 x 32 or x 64 pixel) displays.

I have posted quite a lot on using these displays, including a reply to one started by you (OLDmarty) HERE. That leads to links to two of my other relevant posts HERE and HERE. Somewhere, I also posted the data for a corresponding Greek Character Set which might be quite appropriate for some. :)

Cheers, Alan.
I can never get your codes to work, they're always broken into different pieces (due to forum text limits), but it's never been clear how/where they glue together.
I used one of your OLED codes which i *THINK* was meant to display 7 lines of text, but all i get was diagonal lines.

I now have 2 of the small .96"displays, both doing the same thing, but i'm not even sure what chipset they are. The ebay listings both say they the popular chip 1306? , but is that really true? i don't know.
 

AllyCat

Senior Member
Hi,

Thanks @kjfl, it looks as if OLDmarty nearly has it running correctly. The issue is probably that my code was written for the 128 x 32 pixels display (not 64 lines) set by the i2cout command in about line 34 of the listing. I'm not sure "off the top of my head" what the equivalent should be for the 64 line display, but I certainly have written code for that display as well.

It's always best if an OP posts a copy of the exact code which "doesn't work" for them, but I notice that the code posted by captnemo contains the line #no_data but then contains EEPROM (DATA) lines ! The #no_data needs to be commented out for the first time that the program is run (at least). It's an easy mistake to make because after the first download/run, the data will remain in the EEPROM (until deleted by a new program download) so the program will then continue to run after subsequent changes (without the need for a (new) data download), unless the EEPROM/DATA itself is changed.

EDIT: Ah, I had assumed that the post immediately above was from OLDmarty, so we need to wait to see if either of the posts above (or this one) helps him. By The Way, my program (as listed) can use the #no_data command even on the first run, because the characters are NOT stored in the EEPROM. That program was particularly intended for the 08M2 (but should work with almost all PICaxes) and in some respects the EEPROM is almost the worst place to store character fonts for most PICaxes, because I believe it can hold only 256 bytes in even the largest chips. For most PICaxes the TABLE ROM is probably the best location, except for "User Defined" (on-the-fly) characters (and the 08M2 which doesn't have any Table ROM).

Cheers, Alan.
 
Last edited:

AllyCat

Senior Member
Hi,
I used one of your OLED codes which i *THINK* was meant to display 7 lines of text, but all i get was diagonal lines.
That was possibly in the thread HERE which was primarily intended to document (all of) the Setup and "Default" parameters for the SSD1306 and SH1106 controller chips, and to show how little needed to be changed for a chip after it had been "Hard Reset". If you look at the "Clear Screen" routine at the foot of the program it says:
Code:
ClearScreen:    ; Or FILL screen (with something) 
........
            hi2cout $40,(1, 2, 4, 8, 16, 32, 64, 128)    ; Diagonal Line
so it looks as if it was working as intended. If you alter that hi2cout instruction to change the data (in the brackets) to (8 bytes of) data for any character, it should be repeated over all of the screen. If I had included complete screen-writing code with its fonts, it would have made the program MUCH larger (and was intended for the SH1106 anyway). :(

I'm not certain exactly what needs to be changed to convert from the 32 line to 64 line OLEDs, but it appears that in the initialisation data sequence, a "$A8 , $1F" (or "0xA8 , 0x1F" in captnemo's program) needs to be changed to "$A8 , $3F", and obviously the whole screen area (in RAM) needs to be cleared (e.g. to " " or $20), or filled with a test pattern. Also, I see that I used S_W1 as a "spare" register (which it is in all M2s) but this has another allocated function in X2 devices.

Cheers, Alan.
 

OLDmarty

Senior Member
Here's what I get running AllyCat's code:
I'm not sure the second screen is as it should be.
Thanks kfjl,
I have the same result as you, firstly the screen fills with characters and then 2-3 seconds later that middle section fills with small dashed lines, which i (now) believe is something to do with Allycats code for 128x32 display instead of the 64 line displays, but 'm progressing at last ;-)
 

OLDmarty

Senior Member
Hi Allycat,

Thanks for highlighting some of the issues of the different displays and memory storage issues etc.

For now, i have your code running, but of course there's the 64/128 line issue, but at least the core code and OLED commands now give me an insight to tinker with my own coding to control small OLEDS in future.

Thanks again for your coding and input. ;-)
 

AllyCat

Senior Member
Hi,

I was searching the forum for a "definitive" initialisation routine for the SSD1306 chips, but couldn't find one (however, post #1 HERE gives some useful links). Most are just long hi2cout lists of "numbers" with no explanation, including my own (but I did disclaim that my configuration was not intended for general use). Perhaps my Comparison between SSD1306 and SH1106 drivers is a good starting point because it gives a fairly complete listing of the available options and IIRC demonstrates that hardly any "initialisation" is generally essential (only a few bytes). Basically just power-up (Cold Start), initialise the i2c bus, start the "Charge Pump" (SSD1306), enable the display, if necessary set the number of display lines (default is 64 anyway), and fill the display RAM with something recognisable.
Code:
symbol OLEDSPEED = I2CFAST_32       ; Assume that SETFREQ M32 might be used
symbol OLEDadd = $78                ; Slave Address ($7A also possible)
; Required Initialisation
symbol MULTIPLEX_ = $A8            ; +$3F (Default)    ; For 64 line screen (32 lines = +$1F)
symbol CHGPUMP_ = $8D              ; Enable Charge pump ($14); Default OFF ($10) SSD1306 ONLY
symbol DISPON = $AF                ; Switch Display ON (Default Off = $AE)
   hi2csetup i2cmaster,OLEDadd,OLEDspeed,i2cbyte
   hi2cout 0,(CHGPUMP_,$14, DISPON)
   call ClearScreen                ; Include a suitable subroutine
If that gives a recognisable display then you can add the "optional" user parameters such as Brightness, Inverse (video), Mirror (horizontally), Flip (vertically), etc. and maybe scroll or toggle the (32 line) display, etc..

Also, I have now found an interesting post #5 from @hippy HERE. From his addendum:
It appears the Grove 128x64 OLED which Blockly supports is an SSD1306. That uses I2CBYTE and "HI2cOut $80, ( command )" or "HI2cOut $40, ( data... )", which is what I would have expected from reading the datasheet.
That is also the same protocol and I2C format used with the 128x128 and 96x96 OLED which use similar chips. And we know all three worked because we tested them.
All those linked threads are quite old, and from a time before we had used the SSD1306 ourselves, so I am not sure if they are correct or not.

I would say that our Blockly code should be the 'reference design', so it would be interesting to see Zander's code if it is different from that, as it appears to be.
Blockly can be run from within PE6 (New Blockly > Extension > Grove Displays) and then viewed in Basic (File > Export > Convert to Basic), which gives the following list. : [EDIT] : I've added comments to describe the command codes and added an update to the thread containing hippy's post above.

Code:
grove_oled_init:
    HI2cSetup I2CMASTER, $78, I2CSLOW, I2CBYTE
    HI2cOut $80, (0xAE)    ; Display OFF
    HI2cOut $80, (0xA4)    ; NOT AllOn (NOT All pixels lit)
    HI2cOut $80, (0x20)    ; Mode :
    HI2cOut $80, (0x02)    ;       Page (Mode)
    HI2cOut $80, (0xA1)    ; Mirror (Horizontally)
    HI2cOut $80, (0xC8)    ; Flip (Vertically)
    HI2cOut $80, (0xAF)    ; Display ON
    pause 100
grove_oled_clearScreen:
    HI2cSetup I2CMASTER, $78, I2CSLOW, I2CBYTE
    For grove_oled_row = $B0 To $B7
        For grove_oled_col = 0 To 127 Step 8
            HI2cOut $80, (grove_oled_row)
            grove_oled_temp = grove_oled_col & 0x0F
            HI2cOut $80, (grove_oled_temp)
            grove_oled_temp = grove_oled_col / 16 + 0x10
            HI2cOut $80, (grove_oled_temp)
            HI2cOut $40,(0,0,0,0,0,0,0,0)
        Next
    Next
Note that it uses the "Page Scan Mode" ($20 , $02) which is generally NOT used by most threads on this forum, but IS required for compatibility with the SH1106 chips that are commonly used with the 1.3 inch OLED displays. This might explain why the Clear Screen routine is a little more complex than is usual. The listing also includes quite a comprehensive set of character shapes. Unfortunately, Grove don't appear to use the 128 x 32 OLED displays, but hopefully this has now been adequately covered (AFAIK, the initialisation adding or changed to $A8 , $1F ).

Cheers, Alan.
 
Last edited:
Top