Laden...

[erledigt] Presto KTP Bondrucker mit C# abfragen/steuern

Erstellt von sakanoue vor 14 Jahren Letzter Beitrag vor 14 Jahren 6.924 Views
S
sakanoue Themenstarter:in
46 Beiträge seit 2009
vor 14 Jahren
[erledigt] Presto KTP Bondrucker mit C# abfragen/steuern

Hi,

ich habe hier einen Bon Drucker: Presto KTP622-100 Bon Drucker von itp systems & solutions. Nun möchte ich diesem Drucker Steuersequenzen (ASCII Befehle) schicken und Nachrichten vom Drucker abfragen.

Im englischen Handbuch steht:" The special printer driver builds-up the required
command sequences and transfers them through the user interface (EP1 User Pipes) to the appliance. "

Also brauche ich ja einen speziellen Treiber mit dem ich die USB Schnittstelle als COM simulieren kann. Leider habe ich den gewünschten Treiber noch nicht bekommen.

Gibt es noch eine andere Möglichkeit diesen über C# anzusprechen?

Gruß,
saka

Gelöschter Account
vor 14 Jahren

ich würde eher sagen, das du nach einer möglichkeit suchen solltest, den treiber des druckers direkt anzusprechen.

S
sakanoue Themenstarter:in
46 Beiträge seit 2009
vor 14 Jahren

Ok ich habe das erstmal nach hinten geschoben.

Spreche nun den Drucker über die Serielle Schnittstelle V24 R232 an.

Ich kann ihm Befehle senden jedoch schickt er mir keine zurück. Auch nicht mit dem hier schon so oft gepostetem Template 😃

Im Portmon gibt er mir bei IRP_MJ_WRITE ein Timeout heraus.

Hier mein Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;
using System.Diagnostics;

namespace SerialTest
{
    class Program
    {
        
        static void Main(string[] args)
        {
            
            SerialPort com = new SerialPort("COM1", 9600, Parity.Odd, 8, StopBits.One);
            com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived);

            com.PinChanged += new SerialPinChangedEventHandler(com_PinChanged);
            com.Handshake = Handshake.RequestToSendXOnXOff;
            
            com.WriteTimeout = 500;
            com.Open();

            Console.WriteLine("RTS: {0} - CTS: {1}", com.DtrEnable, com.CtsHolding);

            try
            {
                com.DtrEnable = true;
                
                Console.WriteLine("RTS: {0} - CTS: {1}", com.DtrEnable, com.CtsHolding);
                com.Write(new byte[] { 0x40 }, 0, 1);
            
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }

            Console.WriteLine("press any key to continue...");
            Console.ReadKey();
            com.Close();
        }

        static void com_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Console.WriteLine("Data from SerialPort recieved");
            Thread.Sleep(1000);
        }

        static void com_PinChanged(object sender, SerialPinChangedEventArgs e)
        {
            Console.WriteLine(e.EventType.ToString());
        }
    }
}

Danke für jeden Tipp 😃

Edit: Handshake auf XonXoff gesetzt nun gibt es kein Timeout mehr. Jedoch bleibt CTS auf false.

Gruß,
saka

888 Beiträge seit 2007
vor 14 Jahren

Brauchst Du jetzt noch Hilfe?

S
sakanoue Themenstarter:in
46 Beiträge seit 2009
vor 14 Jahren

Hi Joe,

klar, brauche immer Hilfe 😃

Ich möchte gerne das er wenn er Daten empfängt mir schreibt: "Console.WriteLine("Data from SerialPort recieved");

Das geschieht nicht.

Auch bei deinem Template gibt er mir kein Output.

Edit: Ich möchte später Statusmeldungen erhalten, wie z.b. Papier ist bald leer, und diese dann weiterschicken oder bearbeiten...

Gruß,

saka

185 Beiträge seit 2005
vor 14 Jahren

Edit: Handshake auf XonXoff gesetzt nun gibt es kein Timeout mehr. Jedoch bleibt CTS auf false.

Das ist ja klar, entweder du nimmst den Hardwarehandshake (RTS/CTS) oder Softwarehandshake (Xon/Xoff)

S
sakanoue Themenstarter:in
46 Beiträge seit 2009
vor 14 Jahren

Ah ok.
Laut Manual soll ich DTR/CTS nehmen.

// geändert von XonXoff auf RTS
com.Handshake = Handshake.RequestToSend; // <==
 try
            {
                com.DtrEnable = true;
                Thread.Sleep(200);

                Console.WriteLine("RTS: {0} - CTS: {1}", com.DtrEnable, com.CtsHolding);
// Fehler
               com.Write(new byte[] { 0x40 }, 0, 1); // <=======
            
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }

Nun kommt natürlich wieder der Fehler: The Write timed out.
Portmon: SerialTest.vsho IRP_MJ_WRITE Serial0 TIMEOUT Length 1: @

888 Beiträge seit 2007
vor 14 Jahren

Schick mal zum Befehlsabschluß ein "\r\n" mit.

S
sakanoue Themenstarter:in
46 Beiträge seit 2009
vor 14 Jahren

Schick mal zum Befehlsabschluß ein "\r\n" mit.

Bei "com.Write(new byte[] { 0x40 }, 0, 1 );" ? Und wie soll ich das da einbauen? 🙂

🛈 📗 :rtfm:

888 Beiträge seit 2007
vor 14 Jahren

Muss ich Dir mal ganz unprofessionel raten ein wenig rum zuprobieren.
Google mal nach "carriage return line feed in byte" oder so...

K
133 Beiträge seit 2009
vor 14 Jahren

Schick mal zum Befehlsabschluß ein "\r\n" mit.

Bei "com.Write(new byte[] { 0x40 }, 0, 1 );" ? Und wie soll ich das da einbauen? 😃

lol ^^ vllt "com.Write(new byte[] { 0x40, (byte)'\r', (byte)'\n' }, 0, 3);" ? ich mein ja nur?

185 Beiträge seit 2005
vor 14 Jahren

oder einfach eine Ascii-Tabelle zu rate ziehen:

LF = 0x0A
CR = 0x0D

S
sakanoue Themenstarter:in
46 Beiträge seit 2009
vor 14 Jahren

:rtfm: wiki: "Unter Microsoft Windows wird mit der Kombination „Carriage Return“ + „Line Feed“ eine Zeile beendet." Ok. Damit sollte ich quasi den weiterlauf erzwingen?!

Leider wirft er mir immernoch den Fehler "The write timed out" heraus.
Ich werde mal das Kabel überprüfen, vielleicht könnte es auch daran liegen, da es ein selbst zusammengebasteltes Kabel mit Westernstecker RJ45 und D-Sub 9 Pin ist.

Oder hat noch einer eine Idee?
Danke aber schonmal für jede Hilfe und Kritik.

888 Beiträge seit 2007
vor 14 Jahren

Probier mal so:


string message = "0x400x0D ";
byte[] buffer = new byte[message.Length / 2];

//Fill Byte Array
for (int i = 0; i < buffer.Length; i++)
{
	//2 Chars --> to 1 byte
	string bString = message.Substring(2 * i, 2);
	byte b = byte.Parse(bString, NumberStyles.HexNumber);

	//Add parsed byte
	buffer[i] = b;
}
SerialPort.Write(buffer, 0, buffer.Length);

S
sakanoue Themenstarter:in
46 Beiträge seit 2009
vor 14 Jahren

Ich kann nun kommunizieren. Es lag wirklich am Kabel.
Nun bekomme ich wenn ich z.b. 0x1D absende den Dezimal Wert 29 zurückgeschickt.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;
using System.Diagnostics;

namespace SerialTest
{
    class Program
    {
        static SerialPort com;

        static void Main(string[] args)
        {
            // Create a new SerialPort object
            com = new SerialPort("COM1", 9600, Parity.Odd, 8, StopBits.One);
            com.Encoding = Encoding.ASCII;
            com.Handshake = Handshake.RequestToSend;

            com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived);
            com.PinChanged += new SerialPinChangedEventHandler(com_PinChanged);

            // set Read/Write Timeouts
            com.ReadTimeout = 500;
            com.WriteTimeout = 500;

            com.Open();

            Console.WriteLine("RTS: {0} - CTS: {1}", com.DtrEnable, com.CtsHolding);

            try
            {
                com.DtrEnable = true;
                Thread.Sleep(50);

                Console.WriteLine("RTS: {0} - CTS: {1}", com.DtrEnable, com.CtsHolding);
                com.Write(new byte[] { 0x1D }, 0, 1);
            
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }

            Console.WriteLine("press any key to continue");
            Console.ReadKey();
            com.Close();
        }

        static void com_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort tmp = (SerialPort)sender;

            byte[] buffer = new byte[tmp.BytesToRead];
            tmp.Read(buffer, 0, buffer.Length);

            string tmpStr = decodeBuffer(buffer);

            Console.WriteLine("Data from SerialPort recieved: {0}", tmpStr);
            Thread.Sleep(1000);
        }

        private static string decodeBuffer(byte[] buffer)
        {
            string ret = "";

            for (int i = 0; i < buffer.Length; i++)
            {
                ret += buffer[i].ToString() + " ";
            }
            return ret;
        }

        static void com_PinChanged(object sender, SerialPinChangedEventArgs e)
        {
            Console.WriteLine(e.EventType.ToString());
        }
    }
}

Nun möchte ich z.b. den Status des Druckers herausfinden/abfragen.

6.6.2 GS Statusabfrage 
Format: ASCII Zeichen:  GS      
 Dezimal: 29      
 Hexadezimal: 1D      
Beschreibung: 
Der aktuelle Zustand des Druckers wird gemeldet. Die Information der Rückmeldung besteht aus 2 
Bytes. 
Anmerkungen: 
Eventuell können laufende Vorgänge den gemeldeten Status noch ändern. Ist eine Kontrolle aller 
ausgeführten Abläufe erforderlich, sollte vorher die Steuersequenz für Kontrollpunkt (ETX) verwendet 
werden. 
Zu einem späteren Zeitpunkt kann das unbenutzten Informationsbit 7 mit Zusatzinformationen belegt 
werden. Deshalb sollte dieses bei der Auswertung ausgeblendet werden. 
Aufbau der Rückmeldung: 
Byte Beschreibung 
1  Kennzeichnung der Antwort für GS (0x1D) 
2 Statusinformation 
Bit0: Betriebsbereitschaft 
Bit1: Empfangsbereitschaft 
Bit2: Datenbearbeitung läuft 
Bit3: Vorende Papier erkannt 
Bit4: Papierende oder offenes Druckmodul erkannt 
Bit5: Erweiterte Fehlermeldung 
Bit6: Erweiterte Statusinformation 
Bit7: (Immer 0) 
Ein gesetztes Bit stellt den aktiven Zustand der entsprechenden Meldung dar. 
Das Bit5 gibt an, dass Fehlermeldung(en) vorliegen, die mit Hilfe einer erweiterten Fehlerabfrage 
ausgelesen werden können. 
Das Bit6 gibt an, dass Statusinformation(en) vorliegen, die mit Hilfe einer erweiterten Statusabfrage 
ausgelesen werden können. 

Daran werde ich mal arbeiten 😃 Für Tipps und Anregungen bin ich immer offen.

S
sakanoue Themenstarter:in
46 Beiträge seit 2009
vor 14 Jahren

Hi,

nun kann ich dem Drucker meine ASCII Befehle schicken, jedoch reagiert dieser mit komischen Rückantworten.

Wenn ich ihm 0x1D (Dez: 29) schicke, schickt er mir 63 246, obwohl er mir laut manual 29 246 schicken müsste. Also den Statusabfragewert 29 + 2. byte welches dann im binärsystem mir den Status übergibt wie z.b. Papierende.

timer1_tick: 28 29 83 9 
com_PinChanged : 63 86 63 117 63 71 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
com_PinChanged : 125 255 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
com_PinChanged : 63 215 63 29 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
timer1_tick: 28 29 83 9 
com_PinChanged : 63 63 111 63 103 
timer1_tick: 28 29 83 9 
com_PinChanged : 63 246 255 
timer1_tick: 28 29 83 9 

Könnte es sein das 63 246 eine Fehlermeldung ist? Hatte vielleicht sogar einer schon diesen Fehler?

using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO.Ports;
using System.Threading;

namespace Printer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived);
            //com.PinChanged += new SerialPinChangedEventHandler(com_PinChanged);

            com.ReadTimeout = 500;
            com.WriteTimeout = 500;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (com.IsOpen)
            {
                textBox1.Text += "Portstatus: OPEN \r\n";
            }
            else
            {
                // SerialPort com öffnen
                com.Open();
                // Buffer leeren
                //com.DiscardOutBuffer();
                // //Data Terminal Ready = true
                //com.DtrEnable = true;
                //textBox1.Text += "RTS: "+ com.DtrEnable +" CTS: "+ com.CtsHolding +"\r\n";
                //com.Write(new byte[] { 0x1D }, 0, 1);
                //Thread.Sleep(1000);
                timer1.Start();
            }
        }

        private void textBox1_TextChanged_1(object sender, EventArgs e)
        {

        }

        private void com_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            
            
            byte[] buffer = new byte[com.BytesToRead];
            com.Read(buffer, 0, buffer.Length);

            string tmpStr = decodeBuffer(buffer);

            //textBox1.Text += "Data from SerialPort recieved: " + tmpStr + "\r\n";
            Debug.WriteLine(tmpStr, "com_DataReceived");
            com.DiscardInBuffer();
        }

        private void com_PinChanged(object sender, System.IO.Ports.SerialPinChangedEventArgs e)
        {
            //Console.WriteLine(e.EventType.ToString());

            if (com.BytesToRead > 0)
            {
                byte[] buffer = new byte[com.BytesToRead];
                com.Read(buffer, 0, buffer.Length);

                string tmpStr = decodeBuffer(buffer);

                //textBox1.Text += "Data from SerialPort recieved: " + tmpStr + "\r\n";
                Debug.WriteLine(tmpStr, "com_PinChanged ");
            }
        }

        private static string decodeBuffer(byte[] buffer)
        {
            string ret = "";

            for (int i = 0; i < buffer.Length; i++)
            {
                ret += buffer[i].ToString() + " ";
            }
            return ret;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            com.Close();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (com.IsOpen)
            {
                if (com.BytesToRead > 0)
                {
                    byte[] buffer = new byte[com.BytesToRead];
                    com.Read(buffer, 0, buffer.Length);

                    string tmpStr = decodeBuffer(buffer);

                    //textBox1.Text += "Data from SerialPort recieved: " + tmpStr + "\r\n";
                    Debug.WriteLine(tmpStr, "com_PinChanged ");
                }

                com.DiscardOutBuffer();
                // Data Terminal Ready = true
                com.DtrEnable = true;
                textBox1.Text += "RTS: " + com.DtrEnable + " CTS: " + com.CtsHolding + "\r\n";
                byte[] data = new byte[] { 0x1c, 0x1d, 0x53, 0x09 };
                com.Write(data, 0, data.Length);
                Debug.WriteLine(decodeBuffer(data), "timer1_tick");
                com.DtrEnable = false;
            }
        }
    }
}
S
sakanoue Themenstarter:in
46 Beiträge seit 2009
vor 14 Jahren

Erledigt.

Der fehler lag bei Parity.Odd. Dieser muss auf None.
Obwohl in der Manual Stand: Parity.Odd .. naja 😉

Danke an alle 😃