Tech Talk with Gus 02 - 0.96" 128x64 OLED display

:clap: :clap:

Gus,

I just got my 128x64 LED. I copied the code from this post set the references and got this error:

The name ‘xActions’ does not exist in the current context

The line of code that caused the error was:

xActions[0] = I2CDevice.CreateWriteTransaction(img);

I added this just above the error line and it works great.

//added this
I2CDevice.I2CTransaction[] xActions =
new I2CDevice.I2CTransaction[1];

Thanks for sharing the code I am exited about using the little LED in future projects.

Once again great job
;D

Microsoft.spot.hardware assembly needs to be in your project. Post some pictures when you get it to work please :slight_smile:

Gus,

This is my new LED!

3 Likes

Gus,

Thought might might like this picture.

Did you use the Bitmap class to show the bitmap? The picture is blurry so I can’t really tell what it is :wink:

The quality is bad. If you know a better way is render in image please post. This is my code:

 Dim bmpbytes As Byte() = Resources.GetBytes(Resources.BinaryResources.Cam)
            Dim bmp As Bitmap = New Bitmap(bmpbytes, Bitmap.BitmapImageType.Jpeg)


            'oled is my new class libray I will post when complete
            'The libray is on its own tread 
            oled.LCD.DrawImage(0, 20, bmp, 0, 0, bmp.Width, bmp.Height)
            oled.WriteText("My Grandson Cam", fnt, 10, 0)
            Dim img1 As Byte() = GHI.Utilities.Bitmaps.Convert(oled.LCD, GHI.Utilities.Bitmaps.Format.Bpp1x128)
            oled.WriteImage(img1)

@ dweaver - I mean the image is out of focus.

Gus,

This one is a little better quality. Once again I think the image rendering is poor. If there is a better way of rendering in image I would like to improve the quality.

Thanks again for post.

Every pixel that is not back (including grey or any slightly non black) will become white on the display. You need a 2 color (1 bit) image. Try attached image

Gus,

Thanks for the rendering tips. I resized the picture to 128 x 64. Unfortunately the pig didn’t have enough black and rendered a poor quality picture. However a used some shapes in Paint that were solid black that displayed a higher quality picture.

Here is my new vb class library that can be used in vb or C#. I have also included a test application in vb and c#.


'Code is from adafruit origianlly https://github.com/adafruit/Adafruit_SSD1306/
'Translated from C# by Gus here https://www.ghielectronics.com/community/forum/topic?id=23832&page=1
'Translated to VB class library by David Weaver
'To use with C# application start a vb class library named OLD128x64
'Add this code, build the application, reference the new OLD128x64.dll 


'Need reference to GHI.Hardware
'Need reference to Microsoft.SPOT.Graphics
Imports System
Imports Microsoft.SPOT
Imports Microsoft.SPOT.Hardware
Imports System.Threading


Public Class oled

    Shared SSD1306_LCDHEIGHT As Integer = 64
    Shared SSD1306_LCDWIDTH As Integer = 128
    Shared SSD1306_I2C_ADDRESS As UShort = (&H3C)
    Shared con As New I2CDevice.Configuration(SSD1306_I2C_ADDRESS, 400)
    Shared I2C As New I2CDevice(con)
    Private oledThread As Thread = Nothing
    Public Shared LCD As New Bitmap(128, 64)

    Public Sub New()

        InitDisplay()

        Me.oledThread = New Thread(AddressOf StartOledThread)

    End Sub
    Private Sub StartOledThread()

        While True
            Thread.Sleep(100)
        End While

    End Sub


    Public Shared Sub WriteText(text As String, fnt As Font, XDst As Integer, yDst As Integer, Optional Color As Microsoft.SPOT.Presentation.Media.Color = Presentation.Media.Color.White)

        LCD.DrawText(text, fnt, Color, XDst, yDst)

        Dim img As Byte() = GHI.Utilities.Bitmaps.Convert(LCD, GHI.Utilities.Bitmaps.Format.Bpp1x128)

        Render(img)

    End Sub


    Public Shared Sub WriteImage(img As Byte())

        Render(img)

    End Sub

    Public Shared Sub Clear()

        LCD.Clear()

    End Sub
    Private Shared Sub ssd1306_command(cmd As Integer)

        Dim xActions As I2CDevice.I2CTransaction() = New I2CDevice.I2CTransaction(0) {}

        ' create write buffer (we need one byte)
        Dim buff As Byte() = New Byte(1) {}

        buff(1) = CByte(cmd)

        xActions(0) = I2CDevice.CreateWriteTransaction(buff)

        If I2C.Execute(xActions, 1000) = 0 Then
            Debug.Print("Failed to perform I2C transaction")
        End If

    End Sub
    Private Shared Sub InitDisplay()

        ' Init sequence
        ssd1306_command(&HAE)
        ' SSD1306_DISPLAYOFF);                    // 0xAE
        ssd1306_command(&HD5)
        ' SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
        ssd1306_command(&H80)
        ' the suggested ratio 0x80
        ssd1306_command(&HA8)
        ' SSD1306_SETMULTIPLEX);                  // 0xA8
        ssd1306_command(SSD1306_LCDHEIGHT - 1)

        ssd1306_command(&HD3)
        ' SSD1306_SETDISPLAYOFFSET);              // 0xD3
        ssd1306_command(&H0)
        ' no offset
        ssd1306_command(&H40)
        ' SSD1306_SETSTARTLINE | 0x0);            // line #0
        ssd1306_command(&H8D)
        
        ssd1306_command(&H14)
        'vccstate
        ssd1306_command(&H20)
        ' SSD1306_MEMORYMODE);                    // 0x20
        ssd1306_command(&H0)
        ' 0x0 act like ks0108
        ssd1306_command(&HA1)
        ' SSD1306_SEGREMAP | 0x1);
        ssd1306_command(&HC8)
        ' SSD1306_COMSCANDEC);

        ssd1306_command(&HDA)
        ' SSD1306_SETCOMPINS);                    // 0xDA
        ssd1306_command(&H12)
        ssd1306_command(&H81)
        ' SSD1306_SETCONTRAST);                   // 0x81
        
        ssd1306_command(&HCF)

        ssd1306_command(&HD9)
        ' SSD1306_SETPRECHARGE);                  // 0xd9
        
        ssd1306_command(&HF1)
        ' vccstate

        ssd1306_command(&HD8)
        ' SSD1306_SETVCOMDETECT);                 // 0xDB
        ssd1306_command(&H40)
        ssd1306_command(&HA4)
        'SSD1306_DISPLAYALLON_RESUME);           // 0xA4
        ssd1306_command(&HA6)
        ' SSD1306_NORMALDISPLAY);                 // 0xA6
        ssd1306_command(&H2E)
        ' SSD1306_DEACTIVATE_SCROLL);
        ssd1306_command(&HAF)
        ' SSD1306_DISPLAYON);//--turn on oled panel
        '''////////////////
        '''////////////////

    End Sub

    Private Shared Sub Render(data As Byte())
        ssd1306_command(&H21)
        ' SSD1306_COLUMNADDR);
        ssd1306_command(0)
        ' Column start address (0 = reset)
        ssd1306_command(SSD1306_LCDWIDTH - 1)
        ' Column end address (127 = reset)
        ssd1306_command(&H22)
        ' SSD1306_PAGEADDR);
        ssd1306_command(0)
        ' Page start address (0 = reset)
        ssd1306_command(7)
        ' Page end address


        Dim img As Byte() = New Byte((1024)) {}
        img(0) = &H40
        Array.Copy(data, 0, img, 1, 1024)

        Dim xActions As I2CDevice.I2CTransaction() = New I2CDevice.I2CTransaction(0) {}

        xActions(0) = I2CDevice.CreateWriteTransaction(img)

        If I2C.Execute(xActions, 1000) = 0 Then
            Debug.Print("Failed to perform I2C transaction")
        End If

    End Sub
   
    Public Sub Dispose()

        Dispose(True)
        GC.SuppressFinalize(Me)

    End Sub

    
    Protected Overridable Sub Dispose(disposing As Boolean)

        If disposing Then
            oledThread = Nothing
        End If

    End Sub



End Class




Option Explicit On
Option Strict On

Imports Microsoft.SPOT
Imports Microsoft.SPOT.Hardware
Imports System
Imports System.Threading
Namespace LEDVBTest

    Public Module Module1
        
        Sub Main()

            'Read this to add fonts and images
            'https://msdn.microsoft.com/en-us/library/cc533017.aspx

            'Fonts are located here (used the default install)
            'C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.3\Fonts

            'Add the font to the project
            Dim fnt As Font = Resources.GetFont(Resources.FontResources.NinaB)

            'First srceen message
            Dim mOLED As New oled
            oled.WriteText("Hello World!", fnt, 20, 20)
            Thread.Sleep(3000)
            oled.Clear()

            'Next screen message
            oled.WriteText("Drawing Ellipse", fnt, 10, 20)
            Thread.Sleep(3000)
            oled.Clear()
            oled.LCD.DrawEllipse(Microsoft.SPOT.Presentation.Media.Color.White, 20, 50, 5, 5)
            Dim img As Byte() = GHI.Utilities.Bitmaps.Convert(oled.LCD, GHI.Utilities.Bitmaps.Format.Bpp1x128)
            oled.WriteImage(img)
            Thread.Sleep(2000)
            oled.WriteText("Clearing Ellipse", fnt, 10, 20)
            Thread.Sleep(3000)

            '*******Add image resource to use this
            'The image size must be 128x64 only two colors are rendered
            'Use black and white every pixel that is not BLACK will be white 


            'Dim bmpbytes As Byte() = Resources.GetBytes(Resources.BinaryResources.Cam)
            'Dim bmp As Bitmap = New Bitmap(bmpbytes, Bitmap.BitmapImageType.Jpeg)

            'oled.LCD.DrawImage(0, 0, bmp, 0, 0, bmp.Width, bmp.Height)
            'oled.WriteText("My Picture", fnt, 10, 0)
            'Dim img1 As Byte() = GHI.Utilities.Bitmaps.Convert(oled.LCD, GHI.Utilities.Bitmaps.Format.Bpp1x128)
            'oled.WriteImage(img1)


            Debug.Print(Debug.GC(True).ToString)

            mOLED.Dispose()

            Debug.Print(Debug.GC(True).ToString)

        End Sub

    End Module

End Namespace

using System;
using Microsoft.SPOT;
using System.Threading;
using Microsoft.SPOT.Hardware;

//This is the vb class library oled built using the namespace OLD128x64
using OLD128x64;

namespace LEDCTest
{
    public class Program
    {
        public static void Main()
        {
            Debug.Print(Resources.GetString(Resources.StringResources.String1));
            //Read this to add fonts and images
			//https://msdn.microsoft.com/en-us/library/cc533017.aspx

			//Fonts are located here (used the default install)
			//C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.3\Fonts

			//Add the font to the project
			Font fnt = Resources.GetFont(Resources.FontResources.NinaB);

           //initiate the class library
			oled mOLED = new oled();

            //First srceen message
			oled.WriteText("Hello World!", fnt, 20, 20);
			Thread.Sleep(3000);
			oled.Clear();

			//Next screen message
			oled.WriteText("Drawing Ellipse", fnt, 10, 20);
			Thread.Sleep(3000);
			oled.Clear();
			oled.LCD.DrawEllipse(Microsoft.SPOT.Presentation.Media.Color.White, 20, 50, 5, 5);
			byte[] img = GHI.Utilities.Bitmaps.Convert(oled.LCD, GHI.Utilities.Bitmaps.Format.Bpp1x128);
			oled.WriteImage(img);
			Thread.Sleep(2000);
			oled.WriteText("Clearing Ellipse", fnt, 10, 20);
			Thread.Sleep(3000);
            //oled.WriteText(" ", fnt, 10, 0);
            oled.Clear();


			//*******Add image resource to use this
            //byte[] bmpbytes = Resources.GetBytes(Resources.BinaryResources.Cam);
			//Bitmap bmp = new Bitmap(bmpbytes, Bitmap.BitmapImageType.Jpeg);
			//oled.LCD.DrawImage(0, 20, bmp, 0, 0, bmp.Width, bmp.Height);
			//oled.WriteText("My Grandson Cam", fnt, 10, 0);
			//byte[] img1 = GHI.Utilities.Bitmaps.Convert(oled.LCD, GHI.Utilities.Bitmaps.Format.Bpp1x128);
			//oled.WriteImage(img1);


			Debug.Print(Debug.GC(true).ToString());

			mOLED.Dispose();

			Debug.Print(Debug.GC(true).ToString());

		}

	}

        }










3 Likes

@ dweaver
Its so nice to see postings in VB. So much easier to read.
:smiley:

2 Likes

Thanks rockybooth,

I just thought some users may not understand why the thread. Most projects would benefit a clock for debugging or application use. Adding a clock will be very easy.

I agree with @ rockybooth, very nice to see some VB code… :slight_smile:

May I suggest changing those lines to be Const(ant). If you do not specify a scope they will be Public by default.


Const SSD1306_LCDHEIGHT As Integer = 64
Const SSD1306_LCDWIDTH As Integer = 128
Const SSD1306_I2C_ADDRESS As UShort = &H3C

1 Like

marius,

Thanks for the help good point.

I’m having trouble adapting the code to display sizes. Whenever I I try to move to 128 x 32 the circles disappear. However running it at 128 x 64 they are present. How is that possible ?

EDIT: Nvmd, I figured it out.

[url]https://drive.google.com/file/d/1TaqyKQJK0CXHqk69cxQbRTR1KriP1zoQGg/view?usp=sharing[/url]