Beispiel #1
0
        private static void DisplayClock(Ssd1306 ssd1306)
        {
            Console.WriteLine("Display clock");
            var fontSize = 25;
            var font     = "DejaVu Sans";
            var fontsys  = SystemFonts.CreateFont(font, fontSize, FontStyle.Italic);
            var y        = 0;

            foreach (var i in Enumerable.Range(0, 100))
            {
                using (Image <Rgba32> image = new Image <Rgba32>(128, 32))
                {
                    image.Mutate(ctx => ctx
                                 .Fill(Rgba32.Black)
                                 .DrawText(DateTime.Now.ToString("HH:mm:ss"), fontsys, Rgba32.White,
                                           new SixLabors.Primitives.PointF(0, y)));

                    using (Image <Gray16> image_t = image.CloneAs <Gray16>())
                    {
                        ssd1306.DisplayImage(image_t);
                    }

                    y++;
                    if (y >= image.Height)
                    {
                        y = 0;
                    }

                    Thread.Sleep(100);
                }
            }
        }
Beispiel #2
0
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello Ssd1306 Sample!");

#if SSD1327
            using (Ssd1327 device = GetSsd1327WithI2c())
            {
                Initialize(device);
                ClearScreen(device);
                //SendMessage(device, "Hello .NET IoT!");
                SendMessage(device, DisplayIpAddress());
            }
#else
            using (Ssd1306 device = GetSsd1306WithI2c())
            {
                Initialize(device);
                ClearScreen(device);
                // SendMessage(device, "Hello .NET IoT!!!");
                // SendMessage(device, DisplayIpAddress());
                DisplayImages(device);
                DisplayClock(device);
                ClearScreen(device);
            }
#endif
        }
 private static void SendMessage(Ssd1306 device, string message)
 {
     foreach (char character in message)
     {
         device.SendData(BasicFont.GetCharacterBytes(character));
     }
 }
Beispiel #4
0
        // Port from https://github.com/adafruit/Adafruit_Python_SSD1306/blob/8819e2d203df49f2843059d981b7347d9881c82b/Adafruit_SSD1306/SSD1306.py#L184
        internal static void DisplayImage(this Ssd1306 s, Image <Gray16> image)
        {
            Int16       width  = 128;
            Int16       pages  = 4;
            List <byte> buffer = new List <byte>();

            for (int page = 0; page < pages; page++)
            {
                for (int x = 0; x < width; x++)
                {
                    int bits = 0;
                    for (byte bit = 0; bit < 8; bit++)
                    {
                        bits  = bits << 1;
                        bits |= image[x, page * 8 + 7 - bit].PackedValue > 0 ? 1 : 0;
                    }

                    buffer.Add((byte)bits);
                }
            }

            int chunk_size = 16;

            for (int i = 0; i < buffer.Count; i += chunk_size)
            {
                s.SendData(buffer.Skip(i).Take(chunk_size).ToArray());
            }
        }
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            using (Ssd1306 device = GetSsd1306WithI2c())
            {
                Initialize(device);
                //SendMessage(device, "Hello .NET IoT!!!");
                SendMessageLine(device, "Tech Community");
                //SendMessageLine(device, "PAGE 1");
                //SendMessageLine(device, "PAGE 2");
                //SendImages(device);

                // for each page
                //for (int i = 0; i < 4; i++) {
                //    // for each column
                //    for (int j = 0; j < 64; j++) {
                //        device.SendData(new byte[] {0xff});
                //    }
                //    Console.WriteLine($"Page {i}");
                //    Thread.Sleep(100);
                //}



                Thread.Sleep(10000);
            }
        }
        void Initialize()
        {
            var onboardLed = new RgbPwmLed(
                device: Device,
                redPwmPin: Device.Pins.OnboardLedRed,
                greenPwmPin: Device.Pins.OnboardLedGreen,
                bluePwmPin: Device.Pins.OnboardLedBlue);

            onboardLed.SetColor(Color.Red);

            var i2CBus = Device.CreateI2cBus();

            radio = new Tea5767(i2CBus);

            var display = new Ssd1306(i2CBus, 60, Ssd1306.DisplayType.OLED128x32);

            graphics          = new MicroGraphics(display);
            graphics.Rotation = RotationType._180Degrees;

            btnNext          = new PushButton(Device, Device.Pins.D03);
            btnNext.Clicked += BtnNextClicked;

            btnPrevious          = new PushButton(Device, Device.Pins.D04);
            btnPrevious.Clicked += BtnPreviousClicked;

            onboardLed.SetColor(Color.Green);
        }
Beispiel #7
0
        void InitializePeripherals()
        {
            var led = new RgbLed(Device, Device.Pins.OnboardLedRed, Device.Pins.OnboardLedGreen, Device.Pins.OnboardLedBlue);

            led.SetColor(RgbLed.Colors.Red);

            var i2CBus = Device.CreateI2cBus();

            display           = new Ssd1306(i2CBus, 60, Ssd1306.DisplayType.OLED128x32);
            graphics          = new GraphicsLibrary(display);
            graphics.Rotation = GraphicsLibrary.RotationType._180Degrees;

            rowPorts[0] = Device.CreateDigitalInputPort(Device.Pins.D15, InterruptMode.EdgeRising, ResistorMode.InternalPullDown, 0, 50);
            rowPorts[1] = Device.CreateDigitalInputPort(Device.Pins.D14, InterruptMode.EdgeRising, ResistorMode.InternalPullDown, 0, 50);
            rowPorts[2] = Device.CreateDigitalInputPort(Device.Pins.D13, InterruptMode.EdgeRising, ResistorMode.InternalPullDown, 0, 50);
            rowPorts[3] = Device.CreateDigitalInputPort(Device.Pins.D12, InterruptMode.EdgeRising, ResistorMode.InternalPullDown, 0, 50);

            columnPorts[0] = Device.CreateDigitalOutputPort(Device.Pins.D01);
            columnPorts[1] = Device.CreateDigitalOutputPort(Device.Pins.D02);
            columnPorts[2] = Device.CreateDigitalOutputPort(Device.Pins.D03);
            columnPorts[3] = Device.CreateDigitalOutputPort(Device.Pins.D04);

            currentColumn = 0;

            led.SetColor(RgbLed.Colors.Green);
        }
Beispiel #8
0
        void Initialize()
        {
            var onboardLed = new RgbPwmLed(
                device: Device,
                redPwmPin: Device.Pins.OnboardLedRed,
                greenPwmPin: Device.Pins.OnboardLedGreen,
                bluePwmPin: Device.Pins.OnboardLedBlue);

            onboardLed.SetColor(Color.Red);

            var i2CBus  = Device.CreateI2cBus();
            var display = new Ssd1306(i2CBus, 60, Ssd1306.DisplayType.OLED128x32);

            graphics          = new MicroGraphics(display);
            graphics.Rotation = RotationType._180Degrees;

            rowPorts[0] = Device.CreateDigitalInputPort(Device.Pins.D15, InterruptMode.EdgeRising, ResistorMode.InternalPullDown, 0, 50);
            rowPorts[1] = Device.CreateDigitalInputPort(Device.Pins.D14, InterruptMode.EdgeRising, ResistorMode.InternalPullDown, 0, 50);
            rowPorts[2] = Device.CreateDigitalInputPort(Device.Pins.D13, InterruptMode.EdgeRising, ResistorMode.InternalPullDown, 0, 50);
            rowPorts[3] = Device.CreateDigitalInputPort(Device.Pins.D12, InterruptMode.EdgeRising, ResistorMode.InternalPullDown, 0, 50);

            columnPorts[0] = Device.CreateDigitalOutputPort(Device.Pins.D01);
            columnPorts[1] = Device.CreateDigitalOutputPort(Device.Pins.D02);
            columnPorts[2] = Device.CreateDigitalOutputPort(Device.Pins.D03);
            columnPorts[3] = Device.CreateDigitalOutputPort(Device.Pins.D04);

            currentColumn = 0;

            onboardLed.SetColor(Color.Green);
        }
Beispiel #9
0
 // Display size 128x32.
 private static void Initialize(Ssd1306 device)
 {
     device.SendCommand(new SetDisplayOff());
     device.SendCommand(new Ssd1306Cmnds.SetDisplayClockDivideRatioOscillatorFrequency(0x00, 0x08));
     device.SendCommand(new SetMultiplexRatio(0x1F));
     device.SendCommand(new Ssd1306Cmnds.SetDisplayOffset(0x00));
     device.SendCommand(new Ssd1306Cmnds.SetDisplayStartLine(0x00));
     device.SendCommand(new Ssd1306Cmnds.SetChargePump(true));
     device.SendCommand(
         new Ssd1306Cmnds.SetMemoryAddressingMode(Ssd1306Cmnds.SetMemoryAddressingMode.AddressingMode
                                                  .Horizontal));
     device.SendCommand(new Ssd1306Cmnds.SetSegmentReMap(true));
     device.SendCommand(new Ssd1306Cmnds.SetComOutputScanDirection(false));
     device.SendCommand(new Ssd1306Cmnds.SetComPinsHardwareConfiguration(false, false));
     device.SendCommand(new SetContrastControlForBank0(0x8F));
     device.SendCommand(new Ssd1306Cmnds.SetPreChargePeriod(0x01, 0x0F));
     device.SendCommand(
         new Ssd1306Cmnds.SetVcomhDeselectLevel(Ssd1306Cmnds.SetVcomhDeselectLevel.DeselectLevel.Vcc1_00));
     device.SendCommand(new Ssd1306Cmnds.EntireDisplayOn(false));
     device.SendCommand(new Ssd1306Cmnds.SetNormalDisplay());
     device.SendCommand(new SetDisplayOn());
     device.SendCommand(new Ssd1306Cmnds.SetColumnAddress());
     device.SendCommand(new Ssd1306Cmnds.SetPageAddress(Ssd1306Cmnds.PageAddress.Page1,
                                                        Ssd1306Cmnds.PageAddress.Page3));
 }
        void InitializePeripherals()
        {
            var led = new RgbLed(Device, Device.Pins.OnboardLedRed, Device.Pins.OnboardLedGreen, Device.Pins.OnboardLedBlue);

            led.SetColor(RgbLed.Colors.Red);

            var i2CBus = Device.CreateI2cBus();

            display           = new Ssd1306(i2CBus, 60, Ssd1306.DisplayType.OLED128x32);
            graphics          = new GraphicsLibrary(display);
            graphics.Rotation = RotationType._180Degrees;
            DisplayText("MUSIC PLAYER", 16);
            Thread.Sleep(1000);
            DisplayText("Song.mp3");

            btnNext          = new PushButton(Device, Device.Pins.D02, ResistorMode.InternalPullUp);
            btnNext.Clicked += BtnNextClicked;

            btnPrevious          = new PushButton(Device, Device.Pins.D03, ResistorMode.InternalPullUp);
            btnPrevious.Clicked += BtnPreviousClicked;

            btnPlayPause          = new PushButton(Device, Device.Pins.D04, ResistorMode.InternalPullUp);
            btnPlayPause.Clicked += BtnPlayPauseClicked;

            led.SetColor(RgbLed.Colors.Green);
        }
Beispiel #11
0
        public OLED128x32Wing(II2cBus i2cBus, IDigitalInputPort portA, IDigitalInputPort portB, IDigitalInputPort portC)
        {
            Display = new Ssd1306(i2cBus, 0x3C, Ssd1306.DisplayType.OLED128x32);

            ButtonA = new PushButton(portA, ResistorMode.PullUp);
            ButtonB = new PushButton(portB); // has physical resistor
            ButtonC = new PushButton(portC, ResistorMode.PullUp);
        }
Beispiel #12
0
        public OLED128x32Wing(II2cBus i2cBus, IDigitalInputPort portA, IDigitalInputPort portB, IDigitalInputPort portC)
        {
            Display = new Ssd1306(i2cBus, 0x3C, Ssd1306.DisplayType.OLED128x32);
            Display.IgnoreOutOfBoundsPixels = true;

            ButtonA = new PushButton(portA);
            ButtonB = new PushButton(portB);
            ButtonC = new PushButton(portC);
        }
Beispiel #13
0
        /// <summary>
        /// This command switches the default 63 multiplex mode to any multiplex ratio, ranging from 15 to 63.
        /// The output pads COM0-COM63 will be switched to the corresponding COM signal.
        /// </summary>
        /// <param name="multiplexRatio">Multiplex ratio with a range of 15-63.</param>
        public SetMultiplexRatio(byte multiplexRatio = 63)
        {
            if (!Ssd1306.InRange(multiplexRatio, 0x0F, 0x3F))
            {
                throw new ArgumentException("The multiplex ratio is invalid.", nameof(multiplexRatio));
            }

            MultiplexRatio = multiplexRatio;
        }
Beispiel #14
0
        private static void SendMessage(Ssd1306 device, string message)
        {
            device.SendCommand(new Ssd1306Cmnds.SetColumnAddress());
            device.SendCommand(new Ssd1306Cmnds.SetPageAddress(Ssd1306Cmnds.PageAddress.Page0, Ssd1306Cmnds.PageAddress.Page3));

            foreach (char character in message)
            {
                device.SendData(BasicFont.GetCharacterBytes(character));
            }
        }
Beispiel #15
0
        private static Ssd1306 GetSsd1306WithI2c()
        {
            Console.WriteLine("Using I2C protocol");

            var connectionSettings = new I2cConnectionSettings(1, 0x3C);
            var i2cDevice          = new UnixI2cDevice(connectionSettings);
            var ssd1306            = new Ssd1306(i2cDevice);

            return(ssd1306);
        }
Beispiel #16
0
        private static void SendMessage(Ssd1306 ssd1306, string message)
        {
            ssd1306.SendCommand(new SetColumnAddress());
            ssd1306.SendCommand(new SetPageAddress(PageAddress.Page0, PageAddress.Page3));

            foreach (char character in message)
            {
                ssd1306.SendData(BasicFont.GetCharacterBytes(character));
            }
        }
        void CreateI2CDisplay()
        {
            Console.WriteLine("Create Display with I2C...");

            display = new Ssd1306
                      (
                i2cBus: Device.CreateI2cBus(),
                address: 60,
                displayType: Ssd1306.DisplayType.OLED128x32
                      );
        }
 private static void SendImages(Ssd1306 device)
 {
     foreach (var image_name in Directory.GetFiles(".", "*.bmp").OrderBy(f => f))
     {
         using (Image <Gray16> image = Image.Load <Gray16>(image_name))
         {
             device.DisplayImage(image);
             Thread.Sleep(1000);
         }
     }
 }
Beispiel #19
0
        public MeadowApp()
        {
            Console.WriteLine("Start...");
            var rgbLed = new RgbLed(
                Device,
                Device.Pins.OnboardLedRed,
                Device.Pins.OnboardLedGreen,
                Device.Pins.OnboardLedBlue);

            rgbLed.SetColor(RgbLed.Colors.Red);

            Console.Write("Initializing I2C...");
            displayI2C              = new Ssd1306(Device.CreateI2cBus(), 60, Ssd1306.DisplayType.OLED128x32);
            graphicsI2C             = new GraphicsLibrary(displayI2C);
            graphicsI2C.CurrentFont = new Font8x12();
            graphicsI2C.Clear();
            graphicsI2C.Stroke = 1;
            graphicsI2C.DrawRectangle(0, 0, 128, 32);
            graphicsI2C.DrawText(5, 12, "I2C WORKING");
            graphicsI2C.Show();
            Console.WriteLine("done");

            Console.Write("Initializing SPI...");
            displaySPI = new Ili9163(
                device: Device,
                spiBus: Device.CreateSpiBus(),
                chipSelectPin: Device.Pins.D14,
                dcPin: Device.Pins.D11,
                resetPin: Device.Pins.D10,
                width: 128, height: 160);
            graphicsSPI          = new GraphicsLibrary(displaySPI);
            graphicsSPI.Rotation = GraphicsLibrary.RotationType._90Degrees;
            graphicsSPI.Clear();
            graphicsSPI.Stroke = 1;
            graphicsSPI.DrawRectangle(0, 0, 160, 128);
            graphicsSPI.CurrentFont = new Font8x12();
            graphicsSPI.DrawText(7, 7, "SPI WORKING!", Color.White);
            graphicsSPI.Show();
            Console.WriteLine("done");

            temperatures = new List <AnalogTemperature>
            {
                new AnalogTemperature(Device, Device.Pins.A00, AnalogTemperature.KnownSensorType.LM35),
                new AnalogTemperature(Device, Device.Pins.A01, AnalogTemperature.KnownSensorType.LM35),
                new AnalogTemperature(Device, Device.Pins.A02, AnalogTemperature.KnownSensorType.LM35),
                new AnalogTemperature(Device, Device.Pins.A03, AnalogTemperature.KnownSensorType.LM35),
                new AnalogTemperature(Device, Device.Pins.A04, AnalogTemperature.KnownSensorType.LM35),
                new AnalogTemperature(Device, Device.Pins.A05, AnalogTemperature.KnownSensorType.LM35),
            };

            rgbLed.SetColor(RgbLed.Colors.Green);

            TestTemperatures();
        }
Beispiel #20
0
        private static void ClearScreen(Ssd1306 device)
        {
            device.SendCommand(new Ssd1306Cmnds.SetColumnAddress());
            device.SendCommand(new Ssd1306Cmnds.SetPageAddress(Ssd1306Cmnds.PageAddress.Page0, Ssd1306Cmnds.PageAddress.Page3));

            for (int cnt = 0; cnt < 32; cnt++)
            {
                byte[] data = new byte[16];
                device.SendData(data);
            }
        }
Beispiel #21
0
        private static void ClearScreen(Ssd1306 ssd1306)
        {
            ssd1306.SendCommand(new SetColumnAddress());
            ssd1306.SendCommand(new SetPageAddress(PageAddress.Page0, PageAddress.Page3));

            for (int cnt = 0; cnt < 32; cnt++)
            {
                byte[] data = new byte[16];
                ssd1306.SendData(data);
            }
        }
Beispiel #22
0
 private static void DisplayImages(Ssd1306 ssd1306)
 {
     Console.WriteLine("Display Images");
     foreach (var image_name in Directory.GetFiles("images", "*.bmp").OrderBy(f => f))
     {
         using (Image <Gray16> image = Image.Load <Gray16>(image_name))
         {
             ssd1306.DisplayImage(image);
             Thread.Sleep(1000);
         }
     }
 }
Beispiel #23
0
        static void Main(string[] args)
        {
            Console.WriteLine("Hello Ssd1306 Sample!");

            using (Ssd1306 ssd1306 = GetSsd1306WithI2c())
            {
                InitializeSsd1306(ssd1306);
                ClearScreen(ssd1306);
                //SendMessage(ssd1306, "Hello .NET IoT!!!");
                DisplayIpAddress(ssd1306);
            }
        }
Beispiel #24
0
        void Setup(string i2cBus, GpioPin portA, GpioPin portB, GpioPin portC)
        {
            this.i2cBus = i2cBus;
            Display     = new Ssd1306(this.i2cBus, 0x3C, Ssd1306.DisplayType.OLED128x32);

            //Bug? Resistor Mode is being set properly from the above constructor but unless it is set again it doesn't work.
            //portA.Resistor = portA.Resistor;
            //portC.Resistor = portC.Resistor;

            ButtonA = new PushButton(portA);
            ButtonB = new PushButton(portB);
            ButtonC = new PushButton(portC);
        }
Beispiel #25
0
        public OLED128x32Wing(II2cBus i2cBus, IDigitalInputPort portA, IDigitalInputPort portB, IDigitalInputPort portC)
        {
            this.i2cBus = i2cBus;
            Display     = new Ssd1306(this.i2cBus, 0x3C, Ssd1306.DisplayType.OLED128x32);

            //Bug? Resistor Mode is being set properly from the above constructor but unless it is set again it doesn't work.
            portA.Resistor = portA.Resistor;
            portC.Resistor = portC.Resistor;

            ButtonA = new PushButton(portA);
            ButtonB = new PushButton(portB);
            ButtonC = new PushButton(portC);
        }
Beispiel #26
0
        private static void DisplayIpAddress(Ssd1306 ssd1306)
        {
            string ipAddress = GetIpAddress();

            if (ipAddress != null)
            {
                SendMessage(ssd1306, $"IP: {ipAddress}");
            }
            else
            {
                SendMessage(ssd1306, $"Error: IP Address Not Found");
            }
        }
        private static void ClearScreen(Ssd1306 device)
        {
            // OLED 64x32
            // for each page
            for (int i = 0; i < 4; i++)
            {
                device.SendData(new byte[64]);
                // for each column

                /*for (int j = 0; j < 64; j++) {
                 *  device.SendData(new byte[] {0x00});
                 * }*/
            }
        }
Beispiel #28
0
        public void ConfigurePorts()
        {
            Console.WriteLine("Creating Outputs...");
            this.redPwm = Device.CreatePwmPort(Device.Pins.OnboardLedRed, pwmFrequency, 0f);
            this.bluPwm = Device.CreatePwmPort(Device.Pins.OnboardLedBlue, pwmFrequency, 0f);
            this.grePwm = Device.CreatePwmPort(Device.Pins.OnboardLedGreen, pwmFrequency, 0f);

            var busForDisplay = Device.CreateI2cBus( ) as I2cBus;

            busForDisplay.Frequency = i2cFrequency;

            Console.WriteLine("I2C bus frequency: {0}", busForDisplay.Frequency);

            this.display = new Ssd1306(busForDisplay, 0x3C, Ssd1306.DisplayType.OLED128x32);
            this.display.SendUGdash2832HSWEG02Startup();
            this.display.InvertDisplay = true;
            this.display.Clear(true);

            this.chicagoFont = new ShikaakwaProportionalFont();
            this.cornerFont  = new CornerProportionalFont();

            var yPosition = 3;

            this.line1     = this.chicagoFont.GetBitmapFromString("Programmed in C#").ShiftLsbToMsb(yPosition);
            this.line1Page = 0;
            yPosition     += this.chicagoFont.Spacing;
            var shiftLineTwo = yPosition % 8;

            this.line2     = this.chicagoFont.GetBitmapFromString("by SupraBitKid").ShiftLsbToMsb(shiftLineTwo);
            this.line2Page = ( byte )(yPosition / 8);

            this.topLeftCorner     = this.cornerFont.GetCharacter('a');
            this.topRightCorner    = this.cornerFont.GetCharacter('b');
            this.bottomLeftCorner  = this.cornerFont.GetCharacter('c');
            this.bottomRightCorner = this.cornerFont.GetCharacter('d');

            this.redColorText   = this.chicagoFont.GetBitmapFromString("red").ShiftLsbToMsb(shiftLineTwo);
            this.greenColorText = this.chicagoFont.GetBitmapFromString("green").ShiftLsbToMsb(shiftLineTwo);
            this.blueColorText  = this.chicagoFont.GetBitmapFromString("blue").ShiftLsbToMsb(shiftLineTwo);

            this.display.Clear(false);
            this.display.DrawBitmap(0, 0, this.topLeftCorner, Ssd1306Extensions.BitmapOp.Or);
            this.display.DrawBitmap(( byte )(this.display.Width - this.topRightCorner.Width), 0, this.topRightCorner, Ssd1306Extensions.BitmapOp.Or);
            this.display.DrawBitmap(0, ( byte )(this.display.GetPageCount() - 1), this.bottomLeftCorner, Ssd1306Extensions.BitmapOp.Or);
            this.display.DrawBitmap(( byte )(this.display.Width - this.bottomRightCorner.Width),
                                    ( byte )(this.display.GetPageCount() - 1), this.bottomRightCorner, Ssd1306Extensions.BitmapOp.Or);
            this.display.DrawBitmap(6, this.line1Page, this.line1, Ssd1306Extensions.BitmapOp.Or);
            this.display.DrawBitmap(6, this.line2Page, this.line2, Ssd1306Extensions.BitmapOp.Or);
            this.display.Show();
        }
        void CreateSpiDisplay()
        {
            Console.WriteLine("Create Display with SPI...");

            display = new Ssd1306
                      (
                device: Device,
                spiBus: Device.CreateSpiBus(),
                chipSelectPin: Device.Pins.D02,
                dcPin: Device.Pins.D01,
                resetPin: Device.Pins.D00,
                displayType: Ssd1306.DisplayType.OLED128x64
                      );
        }
Beispiel #30
0
        /// <summary>
        /// This command is used to set the duration of the pre-charge period.
        /// The interval is counted in number of DCLK, where RESET equals 2 DCLKs.
        /// </summary>
        /// <param name="phase1Period">Phase 1 period with a range of 1-15.</param>
        /// <param name="phase2Period">Phase 2 period with a range of 1-15.</param>
        public SetPreChargePeriod(byte phase1Period = 0x02, byte phase2Period = 0x02)
        {
            if (!Ssd1306.InRange(phase1Period, 0x01, 0x0F))
            {
                throw new ArgumentException("The phase 1 period is invalid.", nameof(phase1Period));
            }

            if (!Ssd1306.InRange(phase2Period, 0x01, 0x0F))
            {
                throw new ArgumentException("The phase 2 period is invalid.", nameof(phase2Period));
            }

            Phase1Period = phase1Period;
            Phase2Period = phase2Period;
        }
        static async Task App()
        {
            var board = await ConnectionService.Instance.GetFirstDeviceAsync();
            await board.ConnectAsync();
            var display = new Ssd1306(board.I2c);

            Console.WriteLine("Press any key to clear display and exit...");

            while (!Console.KeyAvailable)
            {
                await display.Print(DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString());
                await Task.Delay(250);
            }

            await display.Clear();
        }