I have an Epson CW-C6000 that I'm trying to control with ESC commands. I've gotten text to print, so I know I have the IP address, port, etc correct but cannot for the life of me get an image printed.
Here is my code (running from a Ruby on Rails server, with most of the image truncated):
streamSock = TCPSocket.new( "X.X.X.X", 9100 )
str = "~DYR:PRODIMG,B,P,183208,0,89504E470D...4AE426082" + "^XA" + "^FO150,150^IMR:PRODIMG.PNG^FS" + "^XZ"
streamSock.send( str , 0)
streamSock.close
The image is a .png I converted to hexadecimal with this site:
http://tomeko.net/online_tools/file_to_hex.php?lang=en
I'm mostly using page 10 of this PDF for reference:
https://files.support.epson.com/pdf/pos/bulk/esclabel_apg_en_forcw-c6000series_reve.pdf
Does anyone have a hint? Epson support staff was spectacularly unhelpful.
Also I'm sorry if my formatting is bad; I'm new here and will happily edit my post if something is wrong.
Alright I finally got it working. The command for printing a color .PNG is this:
~DYE:[Image Name].PNG,p,p,[Image Size],0,:B64:[Base64 String]:[CRC]
Things that tripped me up:
-You seem to need the .PNG extension on the file name, even though the Epson manual doesn't show that.
-[Image Size] is the number of characters in the Base64 string, even though the Epson manual says it should be the size of the original .PNG image file. If this is wrong the printer will hang and no longer accept input of any kind until restarted.
-There may be other options, but I could only get it working with a CRC of the hex CRC-16/XMODEM type.
Thanks to K J for his/her suggestions and coming along with me!
Perhaps this material can be used as an additional reference.
They seem to have a completely different command/data format than ESC/POS.
ESC/Label Command Reference Guide
Page 12
1.3.4 About Saving the Graphics and Label Formats in the Printer
With ESC/Label command, you can save graphics and label formats in the printer. The printer has a file system. Data saved in the printer is handled as files and is managed in the following way.
The file system does not have a hierarchy.
The printer has a non-volatile saving device, such as Flash ROM, and a volatile saving device, such as RAM, and different drive letters are allocated for each device.
Files are designated as
"<drive letter> colon <:> <file name> dot <.> <extension>".
Page 40-41
2.8 Printing Graphics
...Details have been omitted. Please refer to the actual document...
2.8.1 Registering a Graphic in a Printer and Printing It
...Pick up some from the content. Please refer to the actual document...
Delete the files that remain in the printer (^ID command).
Register the graphic in the printer (~DY command).
When registering a color graphic, you can use the PNG format. When registering a monochrome graphic, you can register the PNG format or the GRF format.
PNG format Monochrome and color graphics
GRF format Monochrome graphics
The reason to execute the step 1.
To ensure capacity of the storage memory necessary for print which application will perform.
2.8.2 Embedding a Graphic in the Field and Printing It
...Details have been omitted. Please refer to the actual document...
In Addition:
Page 104-106
~DY
[Name]
Save File
[Format]
~DY d: o ,f ,x ,t ,w ,data
...A table detailing the parameters is due, but omitted...
[Function]
...Further detailed explanations and figures of functions and parameters are due, but omitted...
Graphic data is handled as follows.
If the data format is binary, you can use any binary data as Parameter data. At this time, the size of Parameter data must be matched to the size specified in Parameter t.
If the data format is a hexadecimal character string, one character from 1. to 3. below is used as Parameter data. At this time, the size of Parameter data written in binary must be matched to the size specified in Parameter t.
0 to 9, A to F, and a to f in ASCII can be used as hexadecimal graphic data.
ASCII comma <,>, the parameter separator character, is used to separate lines. If a comma is input, processing is carried out as if ASCII 0 was input for the remainder of the line.
G to Y and g to z in ASCII can be used as repetition characters. For example, if I9 is input, processing is carried out as if 999 were input. The following table indicates the number of repetitions.
...Characters and repeat specified number of times table omitted...
Looking at the contents of this Technical Reference Guide, it seems that you can register images with tools instead of commands.
CW-C6000/C6500 Series Technical Reference Guide
Page 173-174
And page 288 outlines the Epson Inkjet Label Printer SDK and also describes the existence of sample programs.
#Farmbot26. I have been attempting this same using vb.Net and as you noted Epson support is not helpful. I'm not sure if it's the actual image data that is wrong, CRC, or the ZPL code as nothing helps. Here's 2 examples that have not worked.
`Dim binaryData As Byte() = System.IO.File.ReadAllBytes(txtPNGFile.Text)
zplImageData = Convert.ToBase64String(binaryData)
crc = calcrc(binaryData, binaryData.Length).ToString("X4")
Dim zplToSend As String = "~DYE:" & Path.GetFileName(txtPNGFile.Text).ToUpper & ",P,P," & zplImageData.Length & ",0,:B64:" & zplImageData & ":" & crc & "^XZ"`
`Dim binaryData As Byte() = System.IO.File.ReadAllBytes(txtPNGFile.Text)
crc = calcrc(binaryData, binaryData.Length).ToString("X4") 'Calculate CRC
zplImageData = BitConverter.ToString(binaryData).Replace("-", "")
Dim zplToSend As String = "~DYE:" & Path.GetFileName(txtPNGFile.Text).ToUpper & ",A,P," & zplImageData.Length & ",0,:B64:" & zplImageData & ":" & crc & "^XZ"`
This is the CRC example I have.
`Function calcrc(ByVal data() As Byte, ByVal count As Integer) As Integer
Dim crc As Integer = 0
For Each b As Byte In data
Dim d As Integer = CInt(b)
crc = crc Xor (d << 8)
For j = 0 To 7
If ((crc And &H8000) <> 0) Then
crc = (crc << 1) Xor &H1021
Else
crc = (crc << 1)
End If
Next
Next
Return crc And &HFFFF
End Function`
I have figured out another solution. Save the PNG Image using the Binary data. I found this when reading the Saved Backup file of Image data using the Epson Settings Utility.
~DYE:FILENAME.PNG,B,P,BINARYFILESIZE,0, BINARYIMGDATA
` Try
Dim binaryData As Byte() = System.IO.File.ReadAllBytes(txtPNGFile.Text)
Dim client As System.Net.Sockets.TcpClient = New System.Net.Sockets.TcpClient()
client.Connect(IP_TextBox1.Text.Replace(" ", ""), txtPort.Text)
Dim writer As System.IO.StreamWriter = New System.IO.StreamWriter(client.GetStream(), Encoding.UTF8)
Using mStream As New MemoryStream(binaryData)
Dim zplToSend As String = "~DYE:" & Path.GetFileName(txtPNGFile.Text).ToUpper & ",B,P," & mStream.Length & ",0,"
writer.Write(zplToSend)
writer.Flush()
mStream.WriteTo(client.GetStream())
writer.Flush()
End Using
writer.Close()
client.Close()
MsgBox("Send Complete", MsgBoxStyle.OkOnly, "Complete")
Catch ex As Exception
MsgBox(ex.Message.ToString, MsgBoxStyle.OkOnly, "ERROR")
End Try`
You can also open the image file in an IMAGE object and resize it as needed. I had to do this for the label size of the printer.
I need to parse all data from Character Viewer on Mac, how can I do it? Or where is it stored?
I need this format:
☀︎
BLACK SUN WITH RAYS
Unicode: U+2600 U+FE0E, UTF-8: E2 98 80 EF B8 8E
☼
WHITE SUN WITH RAYS
Unicode: U+263C, UTF-8: E2 98 BC
and so on.
Thanks!
In OS X El Capitan (Version 10.11.6), the "Character Viewer" data can be found inside the package of the "Character Palette" system application located at /System/Library/Input Methods/CharacterPalette.app, in the SQLite database file: /System/Library/Input Methods/CharacterPalette.app/Contents/Resources/CharacterDB.sqlite3.
You can use an appropriate application (such as DB Browser for SQLite) to open the database file and export its main table to a file in CSV format, then extract the data by yourself.
In JavaScript (Node.js), provided you already know how to read the file lines, that would be something like:
let lines =
[
"☼ WHITE SUN WITH RAYS|||||||||||||||",
"☀︎ BLACK SUN WITH RAYS|||||||||||||||",
"☀️ BLACK SUN WITH RAYS|||||||||||||||",
"☀ BLACK SUN WITH RAYS|||||||||||||||"
];
for (let line of lines)
{
let fields = line.split ('\t');
let characterSequence = fields[0];
let name = fields[1].split ('|')[0];
let codePoints = Array.from (characterSequence).map (char => "U+" + char.codePointAt (0).toString (16).toUpperCase ().padStart (4, "0")).join (" ");
console.log (characterSequence, name, "Unicode:", codePoints);
}
Notes:
The name of the main table (unihan_dict) is somehow misleading, but it contains data for all non-Unihan characters as well, with minimal information though.
The Unicode character codes are not stored in the database file, since this would be redundant, but they can be easily computed.
My goal is to write a string to a file where the size of the string will vary. At the moment I have made the string very large so that there is no overflow but is there a way to make it so that the size of the string is the exact number of characters I'm placing into it? I've tried something like the code below but it gives me an error unknown identifier "address count" I think it is because address count is a variable declared in a process and address count is constantly changing. Is there any way around this?
signal address_map :string (1 to address_count);
many thanks
leo
"My goal is to write a string to a file." Hence, lets just focus on that.
Step 1: reference the file IO packages (recommended to turn on VHDL-2008):
use std.textio.all ;
-- use ieee.std_logic_textio.all ; -- include if not using VHDL-2008
Step 2: Declare your file
file MyFile : TEXT open WRITE_MODE is "MyFile.txt";
Step 3: Create a buffer:
TestProc : process
variable WriteBuf : line ;
begin
write ... -- see step 4
writeline ... -- see step 5
Step 4: Use write to write into the buffer (in the process TestProc):
write(WriteBuf, string'("State = ") ) ; -- Any VHDL version
write(WriteBuf, StateType'image(State)) ;
swrite(WriteBuf, " at time = " ); -- VHDL-2008 simplification
write(WriteBuf, NOW, RIGHT, 12) ;
Step 5: Write the buffer to the file (in the process TestProc):
writeline(MyFile, WriteBuf) ;
Alternate Steps 3-5: Use built-in VHDL Write with to_string:
Write(MyFile, "State = " & to_string(State) &
", Data = " & to_hstring(Data) &
" at time " & to_string(NOW, 1 ns) ) ;
Alternate Steps 1-5: Use OSVVM (see http://osvvm.org) (requires VHDL-2008):
library osvvm ;
use osvvm.transcriptpkg.all ; -- all printing goes to same file
. . .
TestProc : process
begin
TranscriptOpen("./results/test1.txt") ;
Print("State = " & to_string(State) &
", Data = " & to_hstring(Data) &
" at time " & to_string(NOW, 1 ns) ) ;
One hard but flexible solution is to use dynamic allocation features of VHDL (copied from ADA).
You have to use an access of string (it is roughly like a "pointer to a string" in C)
type line is access string;
you event don't have to do it because line is already declared in std.textio package.
Ok, the problem next is that you can't use an access type for a signal, so you have to use a shared variable:
shared variable address_map: line;
And finally you have to allocate, read and write to this line:
--Example in a function/procedure/process:
--free a previously allocated string:
if address_map /= NULL then
deallocate(address_map);
end if;
--allocate a new string:
address_map:=new string (1 to address_count);
address_map(1 to 3):="xyz";
--we have here:
-- address_map(1)='y'
-- address_map(2 to 3)="yz"
-- address_map.all = "xyz"
Notice the use of new/deallocate (like malloc/free in C or free/delete in C++).
It is not easy to handle this kind of code, I recommend you to read the documentation of VHDL keywords "new", "deallocate" and "access" (easily found with your favorite search engine) or feel free to ask more questions.
You can also use the READ (read the whole line into a string) and WRITE (append a string to the line) functions from std.textio package.
So i am trying to make this program open a file that the user chooses so i have them first
enter their file that is already on the desktop and put the .txt extension after the name and then i try to add the name at the end of the directory and it says on line: 10 column: 1 Type mismatch any help would be appreciated thanks. I am new to this :)
Option Explicit
Dim a, b, c, d, e
Set a = createobject("wscript.shell")
c = msgbox("Welcome to my word finding program!", vbInformation+vbOkCancel+vbDefaultButton1+vbSystemModal, "Information: ")
b = inputbox("MAKE SURE THAT YOUR FILE IS ON YOUR DESKTOP!" &vbLf& "Please enter the name of your .txt file" &vbLf& "Rembmer to add .txt after it" &vbLf& "EX: Name.txt")
a.run"C:\Users\%username%\Desktop\", b
Space is missing after a.run
http://msdn.microsoft.com/en-us/library/d5fk67ky%28v=vs.84%29.aspx
Folder and filename are not two seperate parameters.
a.run "C:\Users\%username%\Desktop\" & b
However, path and filename might contain spaces, so you should always quote them (quotes inside strings are written as two quotes)
a.run """C:\Users\%username%\Desktop\" & b & """"
I have a Raspberry Pi with a Siri Proxy that is controlling my garage door, the garage door has only one command for open and close. To check if the garage door is opened to not I bought a magnet switch and I builded a flout point button. I already tried
doorstate = `gpio read 5`.chomp #gives value 1 or 0, 1 is opened, 0 is closed
print doorstate
if doorstate == "1"
print "The garage door is already opened.\n"
elsif doorstate == "0"
print "OK, I'll open it for you!\n"
else
print "Error, please open it manually.\n"
end
Can someone please tell me how I can check fi the returned value or string from doorstate = 'gpio read 5' is equal to a string?
I'm guessing here that the result of 'gpio read 5' contains a line ending.
Try chomping it off:
doorstate = `gpio read 5`.chomp
To verify the class of doorstate, insert p doorstate.class at line 2.
You need to change your single quotes (') to backticks (`, the little thing with the tilde on your keyboard). That will execute the command. The rest of your code is fine.