440 lines
15 KiB
C#
440 lines
15 KiB
C#
/*
|
|
* Ten Wong (wangtengoo7@gmail.com) 2017 Seeed technology inc.
|
|
* Refer to: https://github.com/Seeed-Studio/OLED_Display_128X64
|
|
* MIT License
|
|
*/
|
|
using System;
|
|
using Windows.Devices.I2c;
|
|
|
|
namespace GrovePi.I2CDevices
|
|
{
|
|
public interface IOLEDDisplay128X64
|
|
{
|
|
void init();
|
|
|
|
void setNormalDisplay();
|
|
void setInverseDisplay();
|
|
|
|
void sendCommand(byte command);
|
|
void sendData(byte data);
|
|
|
|
void setPageMode();
|
|
void setHorizontalMode();
|
|
|
|
void setTextXY(byte row, byte column);
|
|
void clearDisplay();
|
|
void setBrightness(byte brightness);
|
|
void putChar(char c);
|
|
void putString(string str);
|
|
int putNumber(long n);
|
|
int putFloat(float floatNumber, byte deci);
|
|
int putFloat(float floatNumber);
|
|
void drawBitmap(byte[] bitmaparray, int bytes);
|
|
|
|
void setHorizontalScrollProperties(byte direction, byte startPage, byte endPage, byte scrollSpeed);
|
|
void activateScroll();
|
|
void deactivateScroll();
|
|
|
|
}
|
|
internal sealed class OLEDDisplay128X64: IOLEDDisplay128X64
|
|
{
|
|
private const byte SeeedOLED_Max_X = 127; //128 Pixels
|
|
private const byte SeeedOLED_Max_Y = 63; //64 Pixels
|
|
|
|
private const byte PAGE_MODE = 01;
|
|
private const byte HORIZONTAL_MODE = 02;
|
|
|
|
private const byte SeeedOLED_Address = 0x3c;
|
|
private const byte SeeedOLED_Command_Mode = 0x80;
|
|
private const byte SeeedOLED_Data_Mode = 0x40;
|
|
private const byte SeeedOLED_Display_Off_Cmd = 0xAE;
|
|
private const byte SeeedOLED_Display_On_Cmd = 0xAF;
|
|
private const byte SeeedOLED_Normal_Display_Cmd = 0xA6;
|
|
private const byte SeeedOLED_Inverse_Display_Cmd = 0xA7;
|
|
private const byte SeeedOLED_Activate_Scroll_Cmd = 0x2F;
|
|
private const byte SeeedOLED_Dectivate_Scroll_Cmd = 0x2E;
|
|
private const byte SeeedOLED_Set_Brightness_Cmd = 0x81;
|
|
|
|
private const byte Scroll_Left = 0x00;
|
|
private const byte Scroll_Right = 0x01;
|
|
|
|
private const byte Scroll_2Frames = 0x7;
|
|
private const byte Scroll_3Frames = 0x4;
|
|
private const byte Scroll_4Frames = 0x5;
|
|
private const byte Scroll_5Frames = 0x0;
|
|
private const byte Scroll_25Frames = 0x6;
|
|
private const byte Scroll_64Frames = 0x1;
|
|
private const byte Scroll_128Frames = 0x2;
|
|
private const byte Scroll_256Frames = 0x3;
|
|
|
|
// This font be freely used without any restriction(It is placed in public domain)
|
|
private byte[,] BasicFont = new byte[,]
|
|
{
|
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
|
|
{0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00},
|
|
{0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00},
|
|
{0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00},
|
|
{0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00},
|
|
{0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00},
|
|
{0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00},
|
|
{0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00},
|
|
{0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00},
|
|
{0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00},
|
|
{0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00},
|
|
{0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00},
|
|
{0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00},
|
|
{0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00},
|
|
{0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
|
|
{0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00},
|
|
{0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00},
|
|
{0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00},
|
|
{0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00},
|
|
{0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00},
|
|
{0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00},
|
|
{0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00},
|
|
{0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00},
|
|
{0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00},
|
|
{0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00},
|
|
{0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00},
|
|
{0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00},
|
|
{0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00},
|
|
{0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00},
|
|
{0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00},
|
|
{0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00},
|
|
{0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00},
|
|
{0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00},
|
|
{0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00},
|
|
{0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00},
|
|
{0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00},
|
|
{0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00},
|
|
{0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00},
|
|
{0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00},
|
|
{0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00},
|
|
{0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00},
|
|
{0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00},
|
|
{0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00},
|
|
{0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00},
|
|
{0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00},
|
|
{0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00},
|
|
{0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00},
|
|
{0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00},
|
|
{0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00},
|
|
{0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00},
|
|
{0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00},
|
|
{0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00},
|
|
{0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00},
|
|
{0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00},
|
|
{0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00},
|
|
{0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00},
|
|
{0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00},
|
|
{0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00},
|
|
{0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00},
|
|
{0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00},
|
|
{0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00},
|
|
{0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00},
|
|
{0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00},
|
|
{0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00},
|
|
{0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00},
|
|
{0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00},
|
|
{0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00},
|
|
{0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00},
|
|
{0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00},
|
|
{0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00},
|
|
{0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00},
|
|
{0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00},
|
|
{0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00},
|
|
{0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00},
|
|
{0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00},
|
|
{0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00},
|
|
{0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00},
|
|
{0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00},
|
|
{0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00},
|
|
{0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00},
|
|
{0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00},
|
|
{0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00},
|
|
{0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00},
|
|
{0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00},
|
|
{0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00},
|
|
{0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00},
|
|
{0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00},
|
|
{0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00},
|
|
{0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00},
|
|
{0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00},
|
|
{0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00},
|
|
{0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00},
|
|
{0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},
|
|
{0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00},
|
|
{0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00},
|
|
{0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00}
|
|
};
|
|
|
|
internal I2cDevice DirectAccess { get; }
|
|
|
|
internal byte addressingMode;
|
|
|
|
internal OLEDDisplay128X64(I2cDevice Device)
|
|
{
|
|
if (Device == null) throw new ArgumentNullException(nameof(Device));
|
|
|
|
DirectAccess = Device;
|
|
}
|
|
|
|
public void init()
|
|
{
|
|
sendCommand(SeeedOLED_Display_Off_Cmd); //display off
|
|
//delay(5);
|
|
sendCommand(SeeedOLED_Display_On_Cmd); //display on
|
|
//delay(5);
|
|
sendCommand(SeeedOLED_Normal_Display_Cmd); //Set Normal Display (default)
|
|
}
|
|
|
|
public void setNormalDisplay()
|
|
{
|
|
sendCommand(SeeedOLED_Normal_Display_Cmd);
|
|
}
|
|
|
|
public void setInverseDisplay()
|
|
{
|
|
sendCommand(SeeedOLED_Inverse_Display_Cmd);
|
|
}
|
|
|
|
public void sendCommand(byte command)
|
|
{
|
|
DirectAccess.Write(new byte[] { SeeedOLED_Command_Mode, command });
|
|
}
|
|
|
|
public void sendData(byte data)
|
|
{
|
|
DirectAccess.Write(new byte[] { SeeedOLED_Data_Mode, data });
|
|
}
|
|
|
|
public void setPageMode()
|
|
{
|
|
addressingMode = PAGE_MODE;
|
|
sendCommand(0x20); //set addressing mode
|
|
sendCommand(0x02); //set page addressing mode
|
|
}
|
|
|
|
public void setHorizontalMode()
|
|
{
|
|
addressingMode = HORIZONTAL_MODE;
|
|
sendCommand(0x20); //set addressing mode
|
|
sendCommand(0x00); //set horizontal addressing mode
|
|
}
|
|
|
|
public void setTextXY(byte row, byte column)
|
|
{
|
|
sendCommand((byte)(0xB0 + row)); //set page address
|
|
sendCommand((byte)(0x00 + (8 * column & 0x0F))); //set column lower address
|
|
sendCommand((byte)(0x10 + ((8 * column >> 4) & 0x0F))); //set column higher address
|
|
}
|
|
|
|
public void clearDisplay()
|
|
{
|
|
byte i, j;
|
|
sendCommand(SeeedOLED_Display_Off_Cmd); //display off
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
setTextXY(j, 0);
|
|
{
|
|
for (i = 0; i < 16; i++) //clear all columns
|
|
{
|
|
putChar(' ');
|
|
}
|
|
}
|
|
}
|
|
sendCommand(SeeedOLED_Display_On_Cmd); //display on
|
|
setTextXY(0, 0);
|
|
}
|
|
|
|
public void setBrightness(byte brightness)
|
|
{
|
|
sendCommand(SeeedOLED_Set_Brightness_Cmd);
|
|
sendCommand(brightness);
|
|
}
|
|
|
|
public void putChar(char c)
|
|
{
|
|
if (c < 32 || c > 127) //Ignore non-printable ASCII characters. This can be modified for multilingual font.
|
|
{
|
|
c = ' '; //Space
|
|
}
|
|
byte i = 0;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
//read bytes from code memory
|
|
sendData(BasicFont[c-32, i]); //font array starts at 0, ASCII starts at 32. Hence the translation
|
|
}
|
|
}
|
|
|
|
|
|
public void putString(string str)
|
|
{
|
|
foreach (var c in str)
|
|
{
|
|
putChar(c);
|
|
}
|
|
}
|
|
|
|
public int putNumber(long long_num)
|
|
{
|
|
char[] char_buffer = new char[10];
|
|
int i = 0;
|
|
int f = 0;
|
|
|
|
if (long_num < 0)
|
|
{
|
|
f = 1;
|
|
putChar('-');
|
|
long_num = -long_num;
|
|
}
|
|
else if (long_num == 0)
|
|
{
|
|
f = 1;
|
|
putChar('0');
|
|
return f;
|
|
}
|
|
|
|
while (long_num > 0)
|
|
{
|
|
char_buffer[i++] = (char)(long_num % 10);
|
|
long_num /= 10;
|
|
}
|
|
|
|
f = f + i;
|
|
for (; i > 0; i--)
|
|
{
|
|
putChar((char)('0' + (int)(char_buffer[i - 1])));
|
|
}
|
|
return f;
|
|
}
|
|
|
|
public int putFloat(float floatNumber, byte deci)
|
|
{
|
|
int temp = 0;
|
|
float decy = 0.0F;
|
|
float rounding = 0.5F;
|
|
int f = 0;
|
|
if (floatNumber < 0.0F)
|
|
{
|
|
putString("-");
|
|
floatNumber = -floatNumber;
|
|
f += 1;
|
|
}
|
|
for (int i = 0; i < deci; ++i)
|
|
{
|
|
rounding /= 10.0F;
|
|
}
|
|
floatNumber += rounding;
|
|
|
|
temp = (int)floatNumber;
|
|
f += putNumber(temp);
|
|
if (deci > 0)
|
|
{
|
|
putChar('.');
|
|
f += 1;
|
|
}
|
|
decy = floatNumber - temp;//decimal part,
|
|
for (int i = 0; i < deci; i++)//4
|
|
{
|
|
decy *= 10;// for the next decimal
|
|
temp = (int)decy;//get the decimal
|
|
putNumber(temp);
|
|
decy -= temp;
|
|
}
|
|
f += deci;
|
|
return f;
|
|
}
|
|
|
|
public int putFloat(float floatNumber)
|
|
{
|
|
int deci= 2;
|
|
int temp = 0;
|
|
float decy = 0.0F;
|
|
float rounding = 0.5F;
|
|
int f = 0;
|
|
if (floatNumber < 0.0)
|
|
{
|
|
putString("-");
|
|
floatNumber = -floatNumber;
|
|
f += 1;
|
|
}
|
|
for (int i = 0; i < deci; ++i)
|
|
{
|
|
rounding /= 10.0F;
|
|
}
|
|
floatNumber += rounding;
|
|
|
|
temp = (int)floatNumber;
|
|
f += putNumber(temp);
|
|
if (deci > 0)
|
|
{
|
|
putChar('.');
|
|
f += 1;
|
|
}
|
|
decy = floatNumber - temp;//decimal part,
|
|
for (int i = 0; i < deci; i++)//4
|
|
{
|
|
decy *= 10;// for the next decimal
|
|
temp = (int)decy;//get the decimal
|
|
putNumber(temp);
|
|
decy -= temp;
|
|
}
|
|
f += deci;
|
|
return f;
|
|
}
|
|
|
|
public void drawBitmap(byte[] bitmaparray, int bytes)
|
|
{
|
|
byte localAddressMode = addressingMode;
|
|
if (addressingMode != HORIZONTAL_MODE)
|
|
{
|
|
//Bitmap is drawn in horizontal mode
|
|
setHorizontalMode();
|
|
}
|
|
|
|
for (int i = 0; i < bytes; i++)
|
|
{
|
|
sendData(bitmaparray[i]);
|
|
}
|
|
|
|
if (localAddressMode == PAGE_MODE)
|
|
{
|
|
//If pageMode was used earlier, restore it.
|
|
setPageMode();
|
|
}
|
|
|
|
}
|
|
|
|
public void setHorizontalScrollProperties(byte direction, byte startPage, byte endPage, byte scrollSpeed)
|
|
{
|
|
if (Scroll_Right == direction)
|
|
{
|
|
//Scroll Right
|
|
sendCommand(0x26);
|
|
}
|
|
else
|
|
{
|
|
//Scroll Left
|
|
sendCommand(0x27);
|
|
|
|
}
|
|
sendCommand(0x00);
|
|
sendCommand(startPage);
|
|
sendCommand(scrollSpeed);
|
|
sendCommand(endPage);
|
|
sendCommand(0x00);
|
|
sendCommand(0xFF);
|
|
}
|
|
|
|
public void activateScroll()
|
|
{
|
|
sendCommand(SeeedOLED_Activate_Scroll_Cmd);
|
|
}
|
|
|
|
public void deactivateScroll()
|
|
{
|
|
sendCommand(SeeedOLED_Dectivate_Scroll_Cmd);
|
|
}
|
|
}
|
|
}
|