小型有機LEDディスプレイを使ってみる

ちょっとしたグラフィック表示をする


4D systemsで開発販売している小型ディスプレイです。
ピン配置は以下のようになっています。


テストメインプログラム
using System;
using Microsoft.SPOT;
using System.Threading;         // 追加
using Microsoft.SPOT.Hardware;  // 追加、参照設定にも追加
using GHI.OSHW.Hardware;        // 追加、参照設定にも追加
using System.IO.Ports;
using BoeBotLib;
// com1--p36
// com2--p28
// com3--p32
namespace uOLED96G1Test
{
    public class Program
    {
        static DigitalOut LED = new DigitalOut(FEZCerberus.Pin.PC1, false);
        public static void Main()
        {
            int[] LineColor = { Color.Blue, Color.Cyan, Color.Green, Color.Magenta, Color.Red, Color.Yellow };
            uOLED96G1 LCD = new uOLED96G1();      // COM2を用いる
            byte[] invader = { 0x70, 0x18, 0x7d, 0xb6, 0xbc, 0x3c, 0xbc, 0xb6 };
            byte[] invader1 = { 0x7d, 0x18, 0x70, 0, 0, 0, 0, 0 };
            byte[] invader2 = { 0x1e, 0xb8, 0x7d, 0x36, 0x3c, 0x3c, 0x3c, 0x36 };
            byte[] invader3 = { 0x7d, 0xb8, 0x1e, 0, 0, 0, 0, 0 };
            LCD.AddBitmap(0, invader);
            LCD.AddBitmap(1, invader1);
            LCD.AddBitmap(2, invader2);
            LCD.AddBitmap(3, invader3);
            int convex = 5;
            int R = 8;
            byte[] colorLines = new byte[convex * 2];
            double theta = 2 * System.Math.PI / convex;
            for (byte x = 0; x < convex; x++)
            {
                colorLines[x * 2] = (byte)(55 + R * System.Math.Sin(theta * x));
                colorLines[x * 2 + 1] = (byte)(R + R * System.Math.Cos(theta * x));
            }
            bool flip = false;
            bool direction = false;
            LCD.EraseScreen();
            byte y = 30;
            int number = 0;
            while (true)
            {
                LED.Write(true);
                LCD.EraseScreen();
                LCD.DrawLine(0, 20, 40, 60, Color.Green);
                LCD.DrawCircle(32, 20, 15, Color.Red, true);
                LCD.DrawCircle(30, 70, 10, Color.Blue, false);
                LCD.DrawRectangle(45, 40, 55, 47, Color.Yellow, true);
                LCD.DrawRectangle(45, 48, 55, 55, Color.Magenta, true);
                LCD.DrawRectangle(45, 56, 55, 63, Color.Cyan, true);
                LCD.Print("Hello " + number++, LineColor[y % LineColor.Length]);
                LCD.DrawPlygon(colorLines, LineColor[number % LineColor.Length]);

                for (int x = 0; x < 96; x++)
                {
                    LCD.PutPixel((byte)x, (byte)90, LineColor[x % LineColor.Length]);
                }
                if (flip)
                {
                    LCD.DisplayBitmap(0, 0, y, Color.Yellow);
                    LCD.DisplayBitmap(1, 0, (byte)(y + 8), Color.Yellow);
                }
                else
                {
                    LCD.DisplayBitmap(2, 0, y, Color.Yellow);
                    LCD.DisplayBitmap(3, 0, (byte)(y + 8), Color.Yellow);
                }
                flip = !flip;
                y += (byte)(direction ? 4 : -4);
                if ((y < 30) || (y > 80)) direction = !direction;
                LED.Write(false);
                CPU.delay(200);
            }
        }
    }
}
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 色リスト
19 
20 インベーダーのデータ
21 
22 
23 
24 インベーダーのデータを登録する
25 
26 
27 
28 五角形を描く
29 
30 
31 
32 
33 
34 角の座標
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 画面消去
46 緑色で直線を描く
47 赤色で円を描く(塗りつぶし有)
48 青色で円を描く(塗りつぶし無)
49 四角を描く
50 
51 
52 文字を表示する
53 多角形を表示する
54 
55 
56 
57 1ドットずつ表示させる
58 
59 
60 
61 インベーダーを表示させる
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 


uOLED96G1関係クラス



uOLED96G1.cs
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;  // 追加、参照設定にも追加
using GHI.OSHW.Hardware;        // 追加、参照設定にも追加
using System.IO.Ports;
using BoeBotLib;

namespace BoeBotLib
{
    class Color
    {
        public static int Black  = 0;
        public static int White  = 0xffff;
        public static int Red    = 0xf800;
        public static int Green  = 0x07e0;
        public static int Blue   = 0x001f;
        public static int Yellow = Red | Green;
        public static int Magenta= Red | Blue;
        public static int Cyan   = Green | Blue;
    }

    // 基本的に以前のバージョンとは異なり、座標系がxとyは逆である(つまり、縦長)
    // Iコマンドは以前の座標系である
    class uOLED96G1
    {
        DigitalOut reset;
       // Microsoft.SPOT.Hardware.
        SerialPort serial;
        byte LineX, LineY;
        public uOLED96G1()
        {
            init("COM2", CPU.P22);
        }

        public uOLED96G1(String port, Cpu.Pin pin)
        {
            init(port, pin);
        }

        private void init(String port, Cpu.Pin resetPin)
        {
            reset = new DigitalOut(resetPin, false);
            serial = new SerialPort(port, 250000, Parity.None, 8, StopBits.One);
            serial.Open();
            reset.Write(false);     // reset
            CPU.delay(1);           // 1ms
            reset.Write(true);
            CPU.delay(400);        // 推奨は4秒
            int ch=0;
            int count = 0;
            do
            {
                serial.WriteByte((byte)'U');    // LCDイニシャライズ
                if (serial.BytesToRead > 0) ch = serial.ReadByte();
                CPU.delay(5);
                if (count++ > 100)
                {
                    count = 0;
                    reset.Write(false);     // reset
                    CPU.delay(1);           // 1ms
                    reset.Write(true);
                    CPU.delay(400);        // 推奨は4秒
                }
            } while (ch != 0x06);
            LineX = LineY=0;
        }

        public void EraseScreen()
        {
            serial.WriteByte((byte)'E');
            waitAck();
        }
        
        public void VersionInfo()
        {
            byte[] cmd = { (byte)'V', 1 };
            serial.Write(cmd, 0, cmd.Length);
            int n = serial.BytesToRead;
            if (n > 0)
            {
                for (int i = 0; i < 5; i++)
                {
                    serial.ReadByte();
                }
            }
        }
        public void Print(byte x, byte y, String str, int color)
        {
            byte[] cmd = { (byte)'S', x, y, 0,(byte)(color>>8), (byte)(color&0xff), 1, 1 };
            serial.Write(cmd, 0, cmd.Length);
            for (int i = 0; i < str.Length; i++) serial.WriteByte((byte)str[i]);
            serial.WriteByte(0);
            waitAck();
        }

        public void Print(String str, int color)
        {
            if (LineY >= 96) LineY = 0;
            Print(LineX, LineY, str, color);
            LineY += 8;
        }
        public void Print(String str)
        {
            if (LineY >= 96)
            {
                LineY = 0;
                EraseScreen();
            }
            Print(LineX, LineY, str, Color.White);
            LineY += 8;
        }
        public void DrawLine(byte x1, byte y1, byte x2, byte y2, int color)
        {
            byte[] cmd = { (byte)'L', x1, y1, x2, y2, (byte)(color>>8), (byte)(color&0xff) };
            serial.Write(cmd, 0, cmd.Length);
            waitAck();
        }
        public void DrawCircle(byte x, byte y, byte rad, int color)
        {
            DrawCircle(x, y, rad, color, true);
        }
        public void DrawCircle(byte x, byte y, byte rad, int color, bool fill)
        {
            SetPenSize(fill ?(byte) 0 : (byte)1);
            byte[] cmd = { (byte)'C', x, y, rad, (byte)(color >> 8), (byte)(color & 0xff) };
            serial.Write(cmd, 0, cmd.Length);
            waitAck();
        }
        public void SetPenSize(byte size)
        {
            byte[] cmd = { (byte)'p', size};
            serial.Write(cmd, 0, cmd.Length);
        }
        public void DrawRectangle(byte x1, byte y1, byte x2, byte y2, int color)
        {
            DrawRectangle(x1, y1, x2, y2, color, true);
        }
        public void DrawRectangle(byte x1, byte y1, byte x2, byte y2, int color, bool fill)
        {
            SetPenSize(fill ? (byte)0 : (byte)1);
            byte[] cmd = { (byte)'r', x1, y1, x2, y2, (byte)(color >> 8), (byte)(color & 0xff) };
            serial.Write(cmd, 0, cmd.Length);
            waitAck();
        }
        public void PutPixel(byte x, byte y, int color)
        {
            byte[] cmd = { (byte)'P', x, y, (byte)(color >> 8), (byte)(color & 0xff) };
            serial.Write(cmd, 0, cmd.Length);
        }
        public void AddBitmap(byte Num, byte[] ch)
        {
            byte[] cmd = { (byte)'A', Num };
            serial.Write(cmd, 0, cmd.Length);
            serial.Write(ch, 0, 8);
        }
        public void DisplayBitmap(byte Num, byte x, byte y, int color)
        {
            byte[] cmd = { (byte)'D', Num, x, y, (byte)(color >> 8), (byte)(color & 0xff) };
            serial.Write(cmd, 0, cmd.Length);
            waitAck();
        }
        public void DrawPlygon(byte[] point, int color)
        {
            byte[] cmd = { (byte)'g', (byte)(point.Length/2)};
            byte[] cmd2= { (byte)(color >> 8), (byte)(color & 0xff) };
            serial.Write(cmd, 0, cmd.Length);
            serial.Write(point, 0, point.Length);
            serial.Write(cmd2, 0, cmd2.Length);
            waitAck();
        }
        // このコマンドは普通の座標系のようである
        public void drawImage(byte[] img, byte xorg, byte yorg, byte x, byte y)
        {
            byte[] I_cmd = { (byte)'I', xorg, yorg, x, y, 16 };
            serial.Write(I_cmd, 0, I_cmd.Length);
            int length = x * y * 2;
            serial.Write(img, 0, length);
            waitAck();
        }
        public void drawImage(byte[] img, byte x, byte y)
        {
            byte[] I_cmd = { (byte)'I', 0,0, x, y, 16 };
            serial.Write(I_cmd, 0, I_cmd.Length);
            serial.Write(img, 0, img.Length);
            waitAck();
        }

        private void waitAck()
        {
            int ch=0;
            int timeout = 10;       //  10ms経てば処理は終わっていると仮定する
            while (serial.BytesToRead > 0) serial.ReadByte();   // ゴミを取る
            do
            {
                CPU.delay(1);
                if (serial.BytesToRead > 0) ch = serial.ReadByte();
                if (timeout-- == 0) break;
            } while (ch != 0x06);
        }
    }
}