261 lines
8.5 KiB
C#
261 lines
8.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.IO.Ports;
|
|
using Matomat.Helper;
|
|
|
|
|
|
namespace Matomat.Output
|
|
{
|
|
class LCDDisplay
|
|
{
|
|
private class Message
|
|
{
|
|
public string text;
|
|
public Status status;
|
|
public int time;
|
|
|
|
public Message(string text, Status status, int time)
|
|
{
|
|
this.text = text;
|
|
this.status = status;
|
|
this.time = time;
|
|
}
|
|
}
|
|
private class Beeb
|
|
{
|
|
public int frequency;
|
|
public int duration;
|
|
|
|
public Beeb(int frequency, int duration)
|
|
{
|
|
this.frequency = frequency;
|
|
this.duration = duration;
|
|
}
|
|
}
|
|
private static Dictionary<string,LCDDisplay> instances = new Dictionary<string,LCDDisplay>();
|
|
private Queue<Message> messages;
|
|
private Queue<Beeb> beeb;
|
|
private volatile bool _shouldStop;
|
|
private SerialPort serialPort;
|
|
private bool disable = false;
|
|
|
|
private LCDDisplay(string port)
|
|
{
|
|
this.serialPort = new SerialPort(port, 19200, Parity.None, 8, StopBits.One);
|
|
try
|
|
{
|
|
this.serialPort.Open();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
this.disable = true;
|
|
}
|
|
this.createChars();
|
|
this.messages = new Queue<Message>();
|
|
new Thread(this.DisplayThread).Start();
|
|
this.beeb = new Queue<Beeb>();
|
|
new Thread(this.BeebThread).Start();
|
|
}
|
|
private void BeebThread()
|
|
{
|
|
Beeb b;
|
|
while (!_shouldStop)
|
|
{
|
|
Thread.Sleep(1);
|
|
if (this.beeb.Count != 0)
|
|
{
|
|
b = this.beeb.Dequeue();
|
|
Console.Beep(b.frequency, b.duration);
|
|
}
|
|
}
|
|
}
|
|
private void DisplayThread()
|
|
{
|
|
Message m;
|
|
DateTime timeout = new DateTime();
|
|
while (!_shouldStop)
|
|
{
|
|
Thread.Sleep(1);
|
|
if (messages.Count != 0)
|
|
{
|
|
if (timeout.Ticks < DateTime.Now.Ticks)
|
|
{
|
|
m = messages.Dequeue();
|
|
timeout = DateTime.Now.AddSeconds(m.time);
|
|
display(m.text, m.status);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
private void beep(int frequency, int duration)
|
|
{
|
|
Beeb b = new Beeb(frequency, duration);
|
|
this.beeb.Enqueue(b);
|
|
}
|
|
private void display(string text, Status status)
|
|
{
|
|
if (status == Status.Warn)
|
|
{
|
|
this.beep(750, 750);
|
|
}
|
|
if (status == Status.Error)
|
|
{
|
|
this.beep(750, 500);
|
|
this.beep(37, 100);
|
|
this.beep(750, 500);
|
|
this.beep(37, 100);
|
|
this.beep(750, 500);
|
|
}
|
|
this.displayClear();
|
|
byte[] btext = text.ToCharArray("ÄÖÜäöüß²€µ", new byte[] { 0xE1, 0xEF, 0xF5, 0xE1, 0xEF, 0xF5, 0xE2, 0xFF, 0x80, 0x81 });
|
|
byte[] upper;
|
|
byte[] lower;
|
|
if (text.Length > 80)
|
|
{
|
|
upper = btext.Substring(0, 80);
|
|
lower = btext.Substring(80);
|
|
}
|
|
else
|
|
{
|
|
upper = btext;
|
|
lower = new byte[0];
|
|
}
|
|
this.displayEscCode("GTO0@");
|
|
this.displayCode(upper);
|
|
this.displayEscCode("GTO2@");
|
|
this.displayCode(lower);
|
|
|
|
text = text.PadRight(160, ' ');
|
|
text = text.Substring(0, 40) + "\n" + text.Substring(40, 40) + "\n" + text.Substring(80, 40) + "\n" + text.Substring(120, 40);
|
|
Console.WriteLine(text);
|
|
}
|
|
|
|
private void displayClear()
|
|
{
|
|
this.displayEscCode("GTO0@");
|
|
this.displayCode(new byte[] { 0x0c });
|
|
this.displayEscCode("GTO2@");
|
|
this.displayCode(new byte[] { 0x0c });
|
|
this.displayEscCode("GTO0@");
|
|
}
|
|
|
|
private void displayCode(byte[] p)
|
|
{
|
|
if (!disable)
|
|
{
|
|
this.serialPort.Write(p, 0, p.Length);
|
|
}
|
|
}
|
|
|
|
private void createChars()
|
|
{
|
|
this.displayEscCode("GTO0@");
|
|
this.specialChars();
|
|
this.displayEscCode("GTO2@");
|
|
this.specialChars();
|
|
}
|
|
|
|
private void specialChars()
|
|
{
|
|
this.displayEscCode("UDC0GH_H_HG@"); //[0, 0x80] Eurosymbol
|
|
this.displayEscCode("UDC1GGGGGGGG"); //[1, 0x81] Eurosymbol
|
|
this.displayEscCode("UDC2GH_H_HG@"); //[2] Eurosymbol
|
|
this.displayEscCode("UDC3GH_H_HG@"); //[3] Eurosymbol
|
|
}
|
|
|
|
private void displayEscCode(string code)
|
|
{
|
|
this.displayCode(new byte[] { 0x1b });
|
|
if (!disable)
|
|
{
|
|
this.serialPort.Write(code);
|
|
}
|
|
this.displayCode(new byte[] { 0x0d });
|
|
}
|
|
public enum Status
|
|
{
|
|
OK,
|
|
Warn,
|
|
Error
|
|
}
|
|
private void printb(string text, int time = 0, Status status = Status.OK)
|
|
{
|
|
string[] lines = text.Split('\n');
|
|
string line1 = "";
|
|
string line2 = "";
|
|
if (lines.Length == 1)
|
|
{
|
|
line1 = lines[0];
|
|
}
|
|
else
|
|
{
|
|
line1 = lines[0];
|
|
line2 = lines[1];
|
|
}
|
|
if(line1.Length > 38)
|
|
line1 = line1.Substring(0, 38);
|
|
double ll1 = ((38D - line1.Length) / 2);
|
|
|
|
line1 = line1.PadLeft((int)Math.Floor(ll1) + line1.Length, ' ');
|
|
line1 = line1.PadRight((int)Math.Ceiling(ll1) + line1.Length, ' ');
|
|
|
|
if (line2.Length > 38)
|
|
line2 = line2.Substring(0, 38);
|
|
double ll2 = ((38D - line2.Length) / 2);
|
|
|
|
line2 = line2.PadLeft((int)Math.Floor(ll2) + line2.Length, ' ');
|
|
line2 = line2.PadRight((int)Math.Ceiling(ll2) + line2.Length, ' ');
|
|
|
|
this.anzeige("²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²" +
|
|
"²" + line1 + "²" +
|
|
"²" + line2 + "²" +
|
|
"²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²", status, time);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prints a text on the display with the minimum duration of the time and beebcodes when status is not Status.OK
|
|
/// if the text is >= than 160 Chars it will display a border.
|
|
/// </summary>
|
|
/// <param name="text">Text to display. Break with \n, max length 38 chars each line</param>
|
|
/// <param name="time" value="0">Minimum duration of displaying the text</param>
|
|
/// <param name="status" value="Status.OK">Status code for that Item</param>
|
|
public void print(string text, int time = 0, Status status = Status.OK)
|
|
{
|
|
if (text.Length <= 80)
|
|
{
|
|
this.printb(text, time, status);
|
|
return;
|
|
}
|
|
this.anzeige(text, status, time);
|
|
}
|
|
private void anzeige(string text, Status status, int time)
|
|
{
|
|
Message m = new Message(text, status, time);
|
|
messages.Enqueue(m);
|
|
}
|
|
|
|
public static LCDDisplay getInstance(string port)
|
|
{
|
|
if (instances.Keys.Contains(port))
|
|
{
|
|
return instances[port];
|
|
}
|
|
instances.Add(port,new LCDDisplay(port));
|
|
return instances[port];
|
|
}
|
|
public void RequestStop()
|
|
{
|
|
while (messages.Count != 0) { Thread.Sleep(10); }
|
|
while (beeb.Count != 0) { Thread.Sleep(10); }
|
|
Thread.Sleep(100);
|
|
_shouldStop = true;
|
|
if (this.serialPort.IsOpen)
|
|
this.serialPort.Close();
|
|
}
|
|
}
|
|
}
|