private static void Main(string[] args) { if (args.Length != 1) { Console.WriteLine("Usage: led-matrix-weather <openweathermap.org API key>"); Console.WriteLine(); Console.WriteLine("If wrong key is used or there is no network connection"); Console.WriteLine("example data will be displayed."); Console.WriteLine(); Console.WriteLine("For the first 30 seconds of execution"); Console.WriteLine("IP addresses will be displayed instead of data."); return; } s_client = new Weather(args[0]); UpdateWeather(); Task.Run(WeatherUpdater); Task.Run(IpsGetter); PinMapping mapping = PinMapping.MatrixBonnetMapping32; RGBLedMatrix matrix = new RGBLedMatrix(mapping, 64, 64, 2, 2); Task drawing = Task.Run(() => { matrix.StartRendering(); while (s_scenario is object) { Action <RGBLedMatrix> scenario = s_scenario; Stopwatch sw = Stopwatch.StartNew(); scenario(matrix); if (sw.ElapsedMilliseconds < 100) { Debug.WriteLine("Scenario execution finished in less than 100ms. This is likely due to bug."); } } }); try { if (!Console.IsOutputRedirected) { while (s_scenario is object && Console.ReadKey(intercept: true).Key != ConsoleKey.Q) { Thread.Sleep(10); } s_scenario = null; } drawing.Wait(); } finally { matrix.Dispose(); } }
static unsafe void Demo1(RGBLedMatrix matrix) { play = true; try { BdfFont font = BdfFont.Load(@"fonts/10x20.bdf"); BdfFont font1 = BdfFont.Load(@"fonts/8x13B.bdf"); matrix.Fill(0, 0, 0); Thread.Sleep(100); int x = matrix.Width - 1; string text = "Hello .NET IoT"; int fullTextWidth = text.Length * font.Width; while (play) { matrix.DrawText(x, 0, text, font, 0, 0, 255, 0, 0, 0); x--; if (x == -fullTextWidth) { x = matrix.Width - 1; } string d = DateTime.Now.ToString("hh:mm:ss"); matrix.DrawText(0, font.Height + 1, d, font1, 128, 128, 0, 0, 0, 0); Thread.Sleep(25); } } catch (Exception e) { Console.WriteLine(e); } }
static void Demo8(RGBLedMatrix matrix) { play = true; try { var sw = Stopwatch.StartNew(); while (play) { float time = sw.ElapsedMilliseconds / 1000f; for (int ix = 0; ix < matrix.Width; ix++) { for (int iy = 0; iy < matrix.Height; iy++) { Vector2 uv = new Vector2(ix / (float)(matrix.Width - 1), iy / (float)(matrix.Height - 1)); Vector3 cv = Star(uv, time); Color c = ToSRGB(cv.X, cv.Y, cv.Z); matrix.SetPixel(ix, iy, c.R, c.G, c.B); } } } } catch (Exception e) { Console.WriteLine(e); } }
static int Main(string[] args) { if (args.Length < 1) { Console.WriteLine("font-example.exe [font_path] <text>"); return(-1); } string text = "Hello World!"; if (args.Length > 1) { text = args[1]; } var matrix = new RGBLedMatrix(32, 2, 1); var canvas = matrix.CreateOffscreenCanvas(); var font = new RGBLedFont(args[0]); canvas.DrawText(font, 1, 6, new Color(0, 255, 0), text); matrix.SwapOnVsync(canvas); while (!Console.KeyAvailable) { Thread.Sleep(250); } return(0); }
static void Demo2(RGBLedMatrix matrix) { int length = matrix.Width / 4; int height = matrix.Height / 4; play = true; while (play) { matrix.FillRectangle(0, 0, length, length, 255, 0, 0); matrix.FillRectangle(length, 0, length, length, 0, 255, 0); matrix.FillRectangle(2 * length, 0, length, length, 0, 0, 255); matrix.FillRectangle(3 * length, 0, length, length, 255, 255, 0); matrix.FillRectangle(0, height, length, length, 255, 0, 255); matrix.FillRectangle(length, height, length, length, 255, 255, 255); matrix.FillRectangle(2 * length, height, length, length, 0, 130, 0); matrix.FillRectangle(3 * length, height, length, length, 130, 0, 0); matrix.FillRectangle(0, 2 * height, length, length, 0, 0, 128); matrix.FillRectangle(length, 2 * height, length, length, 192, 192, 192); matrix.FillRectangle(2 * length, 2 * height, length, length, 128, 128, 0); matrix.FillRectangle(3 * length, 2 * height, length, length, 128, 128, 128); matrix.FillRectangle(0, 3 * height, length, length, 40, 40, 40); matrix.FillRectangle(length, 3 * height, length, length, 80, 80, 80); matrix.FillRectangle(2 * length, 3 * height, length, length, 120, 120, 120); matrix.FillRectangle(3 * length, 3 * height, length, length, 0, 120, 120); Thread.Sleep(5000); } }
static unsafe void Demo4(RGBLedMatrix matrix) { play = true; byte blue = 0x15; matrix.Fill(0, 0, blue); using (WebClient client = new WebClient()) { int lastMinute = -1; string temperature = ""; BdfFont font = BdfFont.Load(@"fonts/6x12.bdf"); BdfFont font1 = BdfFont.Load(@"fonts/5x7.bdf"); Bitmap weatherIcon = null; string lastIcon = null; string description = ""; while (play) { DateTime time = DateTime.Now; if (Math.Abs(time.Minute - lastMinute) > 4) { lastMinute = time.Minute; string xml = client.DownloadString("http://api.openweathermap.org/data/2.5/weather?q=Redmond,US&mode=xml&units=imperial&APPID=" + s_weatherKey); XDocument doc = XDocument.Parse(xml); XElement element = doc.Root.Element("temperature"); temperature = ((int)Math.Round(Double.Parse(element.Attribute("value").Value))).ToString(CultureInfo.InvariantCulture); element = doc.Root.Element("weather"); string icon = element.Attribute("icon").Value; description = element.Attribute("value").Value; if (lastIcon != icon) { weatherIcon = new Bitmap("bitmaps/" + icon + ".bmp"); } matrix.DrawBitmap(20, 2, weatherIcon, 255, 255, 255, 0, 0, blue); matrix.DrawText(Math.Max(0, matrix.Width - description.Length * font1.Width), 42, description, font1, 128, 128, 128, 0, 0, blue); matrix.DrawText(2, 2 + font.Height, temperature + "\u00B0", font, 128, 128, 128, 0, 0, blue); } matrix.DrawText(2, 2, time.ToString("ddd"), font, 128, 128, 128, 0, 0, blue); matrix.DrawText(2, matrix.Height - font.Height, time.ToString("hh:mm:sstt"), font, 128, 128, 128, 0, 0, blue); Thread.Sleep(200); } } }
static int Main(string[] args) { var matrix = new RGBLedMatrix(new RGBLedMatrixOptions { Rows = 32, Cols = 64 }); var canvas = matrix.CreateOffscreenCanvas(); var maxBrightness = matrix.Brightness; var count = 0; const int c = 255; while (!Console.KeyAvailable) { if (matrix.Brightness < 1) { matrix.Brightness = maxBrightness; count += 1; } else { matrix.Brightness -= 1; } switch (count % 4) { case 0: canvas.Fill(new Color(c, 0, 0)); break; case 1: canvas.Fill(new Color(0, c, 0)); break; case 2: canvas.Fill(new Color(0, 0, c)); break; case 3: canvas.Fill(new Color(c, c, c)); break; } canvas = matrix.SwapOnVsync(canvas); Thread.Sleep(20); } return(0); }
static int Main(string[] args) { Console.WriteLine("Program started"); //while (true) //{ // Console.WriteLine("waiting for debugger to attach..."); // if (Debugger.IsAttached) break; // System.Threading.Thread.Sleep(1000); //} var options = new RGBLedMatrixOptions { Rows = 64, Cols = 64, GpioSlowdown = 4, Brightness = 100, ChainLength = 1 }; Console.WriteLine("Starting to initialize Matrix"); var matrix = new RGBLedMatrix(options); var canvas = matrix.CreateOffscreenCanvas(); Console.WriteLine("Starting Visualization"); for (var i = 0; i < 1000; ++i) { canvas.Fill(new Color(100, 100, 100)); for (var y = 0; y < canvas.Height; ++y) { for (var x = 0; x < canvas.Width; ++x) { canvas.SetPixel(x, y, new Color(i & 0xff, x, y)); } } canvas.DrawCircle(canvas.Width / 2, canvas.Height / 2, 6, new Color(0, 0, 255)); canvas.DrawLine(canvas.Width / 2 - 3, canvas.Height / 2 - 3, canvas.Width / 2 + 3, canvas.Height / 2 + 3, new Color(0, 0, 255)); canvas.DrawLine(canvas.Width / 2 - 3, canvas.Height / 2 + 3, canvas.Width / 2 + 3, canvas.Height / 2 - 3, new Color(0, 0, 255)); canvas = matrix.SwapOnVsync(canvas); } Console.WriteLine("Done."); Console.ReadKey(); return(0); }
static unsafe void Demo6(RGBLedMatrix matrix) { play = true; try { matrix.Fill(0, 0, 0); Bitmap [] bitmaps = new Bitmap [] { new Bitmap(@"bitmaps/dotnet-bot-branded-32x32.bmp"), new Bitmap(@"bitmaps/i-love-dotnet.bmp") }; int x = matrix.Width - 1; int bitmapIndex = 0; while (play) { matrix.DrawBitmap(x, 0, bitmaps[bitmapIndex]); if (x + bitmaps[bitmapIndex].Width < matrix.Width) { matrix.FillRectangle(x + bitmaps[bitmapIndex].Width, 0, matrix.Width - x - bitmaps[bitmapIndex].Width, matrix.Height, 0, 0, 0); } x--; if (x == -bitmaps[bitmapIndex].Width) { bitmapIndex = (bitmapIndex + 1) % bitmaps.Length; x = matrix.Width - 1; } Thread.Sleep(25); } } catch (Exception e) { Console.WriteLine(e); } }
public Renderer(bool noRender = false) { this.NoRender = noRender; RGBLedMatrixOptions ledMatrixOptions = new RGBLedMatrixOptions(); ledMatrixOptions.Cols = 32; ledMatrixOptions.Rows = 32; ledMatrixOptions.GpioSlowdown = 2; if (!NoRender) { matrix = new RGBLedMatrix(ledMatrixOptions); canvas = matrix.CreateOffscreenCanvas(); Console.WriteLine("Matrix and Canvas initalized"); } updateTimer.Elapsed += new ElapsedEventHandler(_OnUpdate); updateTimer.Interval = 16; _thread = new Thread(new ThreadStart(Render)); }
static unsafe void Demo7(RGBLedMatrix matrix) { play = true; try { matrix.Fill(0, 0, 0); while (play) { matrix.SetPixel(matrix.Width / 2, matrix.Height / 2, 255, 0, 0); matrix.DrawCircle(matrix.Width / 2, matrix.Height / 2, 14, 255, 0, 0); matrix.DrawCircle(matrix.Width / 2, matrix.Height / 2, 9, 0, 255, 0); matrix.DrawCircle(matrix.Width / 2, matrix.Height / 2, 6, 0, 0, 255); } } catch (Exception e) { Console.WriteLine(e); } }
private static void ScrollText( RGBLedMatrix matrix, string text, BdfFont font, int startPos, int endPos, byte red, byte green, byte blue, byte bkRed, byte bkGreen, byte bkBlue) { if (startPos < endPos) { return; } text = text + " "; // to clear the text when scrolling int fullTextWidth = text.Length * font.Width; while (startPos >= endPos) { matrix.DrawText(startPos, 0, text, font, red, green, blue, bkRed, bkGreen, bkBlue); startPos--; Thread.Sleep(20); } }
static int Main(string[] args) { var matrix = new RGBLedMatrix(32, 2, 1); var canvas = matrix.CreateOffscreenCanvas(); for (var i = 0; i < 1000; ++i) { for (var y = 0; y < canvas.Height; ++y) { for (var x = 0; x < canvas.Width; ++x) { canvas.SetPixel(x, y, new Color(i & 0xff, x, y)); } } canvas.DrawCircle(canvas.Width / 2, canvas.Height / 2, 6, new Color(255, 0, 255)); canvas.DrawLine(canvas.Width / 2 - 3, canvas.Height / 2 - 3, canvas.Width / 2 + 3, canvas.Height / 2 + 3, new Color(0, 0, 255)); canvas.DrawLine(canvas.Width / 2 - 3, canvas.Height / 2 + 3, canvas.Width / 2 + 3, canvas.Height / 2 - 3, new Color(0, 0, 255)); canvas = matrix.SwapOnVsync(canvas); } return(0); }
static int Main(string[] args) { var matrix = new RGBLedMatrix(new RGBLedMatrixOptions { ChainLength = 2 }); var canvas = matrix.CreateOffscreenCanvas(); var rnd = new Random(); var points = new List <Point>(); var recycled = new Stack <Point>(); int frame = 0; var stopwatch = new Stopwatch(); while (!Console.KeyAvailable) { stopwatch.Restart(); frame++; if (frame % FRAME_STEP == 0) { if (recycled.Count == 0) { points.Add(new Point(rnd.Next(0, canvas.Width - 1), 0)); } else { var point = recycled.Pop(); point.x = rnd.Next(0, canvas.Width - 1); point.y = 0; point.recycled = false; } } canvas.Clear(); foreach (var point in points) { if (!point.recycled) { point.y++; if (point.y - MAX_HEIGHT > canvas.Height) { point.recycled = true; recycled.Push(point); } for (var i = 0; i < MAX_HEIGHT; i++) { canvas.SetPixel(point.x, point.y - i, new Color(0, 255 - i * COLOR_STEP, 0)); } } } canvas = matrix.SwapOnVsync(canvas); // force 30 FPS var elapsed = stopwatch.ElapsedMilliseconds; if (elapsed < 33) { Thread.Sleep(33 - (int)elapsed); } } return(0); }
static int Main(string[] args) { if (args.Length < 1) { Console.WriteLine("font-example.exe [font_path] <text>"); return(-1); } string text = "abcdefghijklmnopqrstuvwxyz"; string text_high = "AAPL 123.45"; string text_low = "@ 12.4%"; var matrix = new RGBLedMatrix(16, 0, 0); var canvas = matrix.CreateOffscreenCanvas(); var font = new RGBLedFont(args[0]); var x = -40; var top_y = 8; var bot_y = 16; for (var j = 0; j < 1000; j++) { for (var i = 0; i < 80; i++) { x = x + 1; // set all matrix low canvas.Clear(); // draw the top line canvas.DrawText(font, x, top_y, new Color(0, 255, 0), text_high); canvas.DrawText(font, x, bot_y, new Color(0, 255, 0), text_low); matrix.SwapOnVsync(canvas); Thread.Sleep(100); //while (!Console.KeyAvailable) //{ // Thread.Sleep(1000); //} } x = -40; top_y = 8; bot_y = 16; } /* * // row test * for(var i = 0; i < 1000; i++){ * canvas.Clear(); * * canvas.DrawText(font, x, i, new Color(0, 255, 0), text); * * matrix.SwapOnVsync(canvas); * * Thread.Sleep(100); * } */ return(0); }
private static void WeatherDemo(RGBLedMatrix matrix) { BdfFont font = BdfFont.Load(@"fonts/10x20.bdf"); BdfFont font1 = BdfFont.Load(@"fonts/8x13B.bdf"); matrix.Fill(0, 0, 0); Thread.Sleep(100); int textLeft = 0; const int feedUpdateMs = 500; const int drawIntervalMs = 25; const int iterations = feedUpdateMs / drawIntervalMs; byte Col(float x) { return((byte)Math.Clamp(x * 255, 0, 255)); } string text = string.Empty; int fullTextWidth = 0; Stopwatch sw = Stopwatch.StartNew(); while (s_scenario != null) { text = " * " + string.Join(" * ", WeatherFeed()); fullTextWidth = text.Length * font.Width; for (int i = 0; i < iterations && s_scenario != null; i++, textLeft--) { matrix.DrawText(textLeft, -2, text, font, 0, 0, 255, 0, 0, 0); if (textLeft + fullTextWidth < matrix.Width) { matrix.DrawText(textLeft + fullTextWidth, -2, text, font, 0, 0, 255, 0, 0, 0); } if (textLeft + fullTextWidth <= 0) { textLeft += fullTextWidth; } DateTimeOffset localNow = DateTimeOffset.Now; DateTimeOffset pstNow = TimeZoneInfo.ConvertTime(localNow, s_timeZonePst); string d = pstNow.ToString("hh:mm:ss"); matrix.DrawText(0, font.Height + 1 - 2, d, font1, 0, 255, 0, 0, 0, 0); int halfHeight = matrix.Height / 2; int halfWidth = matrix.Width / 2; float time = sw.ElapsedMilliseconds / 1000f; for (int x = 0; x < matrix.Width; x++) { if (x < halfWidth) { for (int y = halfHeight; y < matrix.Height; y++) { Vector3 col3 = Clock(new Vector2((float)x / halfWidth, (float)(y - halfHeight) / halfHeight), pstNow); Color color = Color.FromArgb(Col(col3.X), Col(col3.Y), Col(col3.Z)); matrix.SetPixel(x, y, color.R, color.G, color.B); } } else { for (int y = halfHeight; y < matrix.Height; y++) { Vector2 uv = new Vector2((float)(x - halfWidth) / halfWidth, (float)(y - halfHeight) / halfHeight); Vector3 col3 = OpenWeatherIcon(uv, s_weatherResponse.Weather[0].Icon, time); Color color = Color.FromArgb(Col(col3.X), Col(col3.Y), Col(col3.Z)); matrix.SetPixel(x, y, color.R, color.G, color.B); } } } Thread.Sleep(drawIntervalMs); } } }
private static void Main(string[] args) { Console.WriteLine($"Hello Matrix World!"); // If using 64x64 with Bonnet (https://www.adafruit.com/product/3211), you can just do // PinMapping mapping = PinMapping.MatrixBonnetMapping64; // If using 32x32 with Bonnet (https://www.adafruit.com/product/3211), you can just do PinMapping mapping = PinMapping.MatrixBonnetMapping32; // If not using Bonnet, will need to provide the manual GPIO mapping using PinMapping // To create RGBLedMatrix for 32x32 panel, do the following RGBLedMatrix matrix = new RGBLedMatrix(mapping, 32, 32); // To create RGBLedMatrix for 64x64 panel, do the following // RGBLedMatrix matrix = new RGBLedMatrix(mapping, 64, 64); // PinMapping mapping = PinMapping.MatrixBonnetMapping64; // RGBLedMatrix matrix = new RGBLedMatrix(mapping, 64, 64); // If you chain 4 32x32 panels serially, you can do // RGBLedMatrix matrix = new RGBLedMatrix(mapping, 128, 32); // If you chain 4 32x32 panels having 2 rows chaining (2 panels in first row an d2 panels in second row). // RGBLedMatrix matrix = new RGBLedMatrix(mapping, 64, 64, 2, 2); Task.Run(() => { matrix.StartRendering(); while (scenario != 0) { switch (scenario) { case 1: Demo1(matrix); break; case 2: Demo2(matrix); break; case 3: Demo3(matrix); break; case 4: Demo4(matrix); break; case 5: Demo5(matrix); break; case 6: Demo6(matrix); break; case 7: Demo7(matrix); break; case 8: Demo8(matrix); break; default: scenario = 2; break; } } }); ConsoleKeyInfo cki; Console.WriteLine($"Press q to exit."); System.Interop.ThreadHelper.SetCurrentThreadHighPriority(); do { cki = Console.ReadKey(); if (cki.KeyChar == '+') { matrix.PWMDuration = matrix.PWMDuration + 100; Console.WriteLine($" ({matrix.PWMDuration})"); } if (cki.KeyChar == '-') { matrix.PWMDuration = matrix.PWMDuration - 100; Console.WriteLine($" ({matrix.PWMDuration})"); } if (cki.KeyChar == 'f') { Console.WriteLine($"Frame Time: {matrix.FrameTime} \u00B5s"); Console.WriteLine($"Duration : { matrix.PWMDuration }"); } if (cki.KeyChar >= '1' && cki.KeyChar <= '9') { play = false; scenario = cki.KeyChar - '0'; Thread.Sleep(1000); } } while (cki.KeyChar != 'q'); play = false; scenario = 0; Thread.Sleep(1000); matrix.Dispose(); }
static void Demo3(RGBLedMatrix matrix) { try { play = true; byte blue = 0x10; matrix.Fill(0, 0, blue); TimeZoneInfo [] zones = new TimeZoneInfo [s_citiesData.Length]; string [] weatherUrls = new string [s_citiesData.Length]; for (int i = 0; i < s_citiesData.Length; i++) { weatherUrls[i] = String.Format("http://api.openweathermap.org/data/2.5/weather?q={0},{1}&mode=xml&units=imperial&APPID={2}", s_citiesData[i].City, s_citiesData[i].CountryCode, s_weatherKey); zones[i] = TimeZoneInfo.FindSystemTimeZoneById(s_citiesData[i].ZoneId); } using (WebClient client = new WebClient()) { BdfFont font = BdfFont.Load(@"fonts/6x12.bdf"); BdfFont font1 = BdfFont.Load(@"fonts/5x7.bdf"); BdfFont font2 = BdfFont.Load(@"fonts/4x6.bdf"); int cityIndex = 0; while (play) { string xml = client.DownloadString(weatherUrls[cityIndex]); XDocument doc = XDocument.Parse(xml); XElement element = doc.Root.Element("temperature"); string temperature = ((int)Math.Round(Double.Parse(element.Attribute("value").Value))).ToString(CultureInfo.InvariantCulture); element = doc.Root.Element("weather"); string description = element.Attribute("value").Value + " "; element = doc.Root.Element("humidity"); string humidity = element.Attribute("value").Value + element.Attribute("unit").Value + " "; element = doc.Root.Element("city").Element("sun"); string sunRise = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse(element.Attribute("rise").Value, CultureInfo.InvariantCulture), zones[cityIndex]).ToString("hh:mm tt"); string sunSet = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse(element.Attribute("set").Value, CultureInfo.InvariantCulture), zones[cityIndex]).ToString("hh:mm tt"); int pos = Math.Max(0, (matrix.Width - (s_citiesData[cityIndex].City.Length * font.Width))) / 2; ScrollText( matrix, s_citiesData[cityIndex].City, font, matrix.Width - 1, pos, 128, 128, 128, 0, 0, blue); int y = font.Height; matrix.DrawText((matrix.Width - (temperature.Length + 1) * font1.Width) / 2, y, temperature + "\u00B0", font1, 255, 255, 0, 0, 0, blue); y += font1.Height + 2; matrix.DrawText(2, y, description, font2, 128, 128, 128, 0, 0, blue); y += font2.Height + 2; matrix.DrawText(2, y, "humidity: ", font2, 128, 128, 128, 0, 0, blue); matrix.DrawText(font2.Width * "humidity: ".Length + 2, y, humidity, font2, 255, 255, 0, 0, 0, blue); y += font2.Height; string localTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, zones[cityIndex]).ToString("hh:mm tt"); matrix.DrawText((matrix.Width - localTime.Length * font.Width) / 2, y, localTime, font, 255, 255, 0, 0, 0, blue); y += font.Height + 2; matrix.DrawText(2, y, "Sun Rise: ", font2, 128, 128, 128, 0, 0, blue); matrix.DrawText(2 + "Sun Rise: ".Length * font2.Width, y, sunRise, font2, 255, 255, 0, 0, 0, blue); y += font2.Height + 2; matrix.DrawText(2, y, "Sun Set: ", font2, 128, 128, 128, 0, 0, blue); matrix.DrawText(2 + "Sun Set: ".Length * font2.Width, y, sunSet, font2, 255, 255, 0, 0, 0, blue); Thread.Sleep(4000); ScrollText( matrix, s_citiesData[cityIndex].City, font, pos, -(pos + s_citiesData[cityIndex].City.Length * font.Width), 128, 128, 128, 0, 0, blue); y = font.Height; matrix.DrawText((matrix.Width - (temperature.Length + 1) * font1.Width) / 2, y, temperature + "\u00B0", font1, 0, 0, blue, 0, 0, blue); y += font1.Height + 2; matrix.DrawText(2, y, description, font2, 0, 0, blue, 0, 0, blue); y += font2.Height + 2; matrix.DrawText(2, y, "humidity: ", font2, 0, 0, blue, 0, 0, blue); matrix.DrawText(font2.Width * "humidity: ".Length + 2, y, humidity, font2, 0, 0, blue, 0, 0, blue); y += font2.Height; matrix.DrawText((matrix.Width - localTime.Length * font.Width) / 2, y, localTime, font, 0, 0, blue, 0, 0, blue); y += font.Height + 2; matrix.DrawText(2, y, "Sun Rise: ", font2, 0, 0, blue, 0, 0, blue); matrix.DrawText(2 + "Sun Rise: ".Length * font2.Width, y, sunRise, font2, 0, 0, blue, 0, 0, blue); y += font2.Height + 2; matrix.DrawText(2, y, "Sun Set: ", font2, 0, 0, blue, 0, 0, blue); matrix.DrawText(2 + "Sun Set: ".Length * font2.Width, y, sunSet, font2, 0, 0, blue, 0, 0, blue); cityIndex = (cityIndex + 1) % s_citiesData.Length; } } } catch (Exception e) { Console.WriteLine(e); } }