Windows IoT - USB Printer - printing

The question is similar to question in this thread Windows IoT - Zebra Bluetooth Printer .
I have a Zebra GX420d printer. The only difference is, it is not connected via Bluetooth but via USB. I can't seem to get it paired with my raspberry pi 2. I need to print something out (like "Hello world"). Please help.
Update:
So, i installed the usb driver for the printer, now the Raspberry can see it, but i still can't write anything to the printer. Now i get the "Attempted to read or write protected memory" Exception.
My code:
private async void getObject()
{
var devices = await DeviceInformation.FindAllAsync();
UInt32 vid = 0x0A5F;
UInt32 pid = 0x0084;
//Guid winusbInterfaceGuid = new Guid("532C0D5D-1122-4378-96D3-1BCDF8FB31A2");
string aqs = UsbDevice.GetDeviceSelector(vid, pid);
var myDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs, null);
if (myDevices.Count == 0)
{
return;
}
String str = "ABCDEFGH";
IBuffer buffUTF8 = CryptographicBuffer.ConvertStringToBinary(str, BinaryStringEncoding.Utf8);
UsbDevice device = await UsbDevice.FromIdAsync(myDevices[0].Id);
var send = await device.SendControlOutTransferAsync(new UsbSetupPacket(buffUTF8));

You likely need to also allow the USB capability. Here's how:
<DeviceCapability Name="usb">
<Device Id="vidpid:xxxx xxxx">
<Function Type="classId:xx xx xx"/>
<Function Type="name:xxxxx"/>
<Function Type="winUsbId:xxxxx"/>
</Device>
</DeviceCapability>
Details here:
https://msdn.microsoft.com/en-us/library/windows/apps/dn263092.aspx
and here:
https://msdn.microsoft.com/en-us/library/windows/hardware/dn303351(v=vs.85).aspx

Related

i2cdetect doesn't showing any address

I'm using an OLED 128*64 display screen with NodeMCU ESP8266.
when I tried to detect the screen address, the serial monitor shows:
enter image description here
It would be kind if someone can tell me what is the problem ? and how t solve it ?
Hi Mari please try this I2c tester: it will give you the number of devices and their addresses
#include <Wire.h>
byte errorResult; // error code returned by I2C
byte i2c_addr; // I2C address being pinged
byte lowerAddress = 0x08; // I2C lowest valid address in range
byte upperAddress = 0x77; // I2C highest valid address in range
byte numDevices; // how many devices were located on I2C bus
void setup() {
Wire.begin(); // I2C init
Serial.begin(115200); // search results show up in serial monitor
}
void loop() {
if (lowerAddress < 0x10) // pad single digit addresses with a leading "0"
Serial.print("0");
Serial.print(lowerAddress, HEX);
Serial.print(" to 0x");
Serial.print(upperAddress, HEX);
Serial.println(".");
numDevices = 0;
for (i2c_addr = lowerAddress; i2c_addr <= upperAddress; i2c_addr++ )
// loop through all valid I2C addresses
{
Wire.beginTransmission(i2c_addr); // initiate communication at current address
errorResult = Wire.endTransmission(); // if a device is present, it will send an ack and "0" will be returned from function
if (errorResult == 0) // "0" means a device at current address has acknowledged the serial communication
{
Serial.print("I2C device found at address 0x");
if (i2c_addr < 0x10) // pad single digit addresses with a leading "0"
Serial.print("0");
Serial.println(i2c_addr, HEX); // display the address on the serial monitor when a device is found
numDevices++;
}
}
Serial.print("Scan complete. Devices found: ");
Serial.println(numDevices);
Serial.println();
delay(10000); // wait 10 seconds and scan again to detect on-the-fly bus changes
}
the wiring should be for I2C connection:
D2 -> SDA, D1 -> SCL, GND -> GND, (*) -> Vcc
(*) check what oled model you have, some work at +5V other at +3.3V that might be the issue
Moreover usually the pullup resistor is not needed (check your model specs)
Check also the specification of your oled, sometimes some jumper setup is needed
I found the problem: I didn't insert the nodemcu properly inside the board.

IBM HP5Si Print Stream to XPS print driver

I am hoping someone can have suggestions about this issue.
We have a custom driver taken from https://learn.microsoft.com/en-us/samples/microsoft/windows-driver-samples/xpsdrv-driver-and-filter-sample/
The print driver works well and outputs XPS when the documents are opened in MS word or PDF. But when a document is printed from HP5Si series printer, the driver returns 0 bytes. The job is sent from HP5Si printer to the XPS driver. Why is the driver rejecting this input when the source is a HP series printer. What can I do to fix it?
The printer on the AS400 is setup with an IBM HP5Si driver and sends the job to a windows service on a server. This windows service routes the job to XPS driver as if it were an HP series printer. The XPS driver processes this job and returns XPS to the windows service. The windows service then converts to a tiff file.
For some reason if printing is done using this workflow XPS driver returns 0.
If the same document is opened in word or notepad or any not AS400+ HP, it works and XPS is returned.
To prove my theory, I sent a PCL file in C# code to the driver and it returned 0 bytes.
public static void SendBytesToPrinterPCL(string printerName, string szFileName) {
IntPtr lhPrinter;
OpenPrinter(printerName, out lhPrinter, new IntPtr(0));
if (lhPrinter.ToInt32() == 0) return; //Printer not found!!
var rawPrinter = new DOCINFOA() {
pDocName = "My Document",
pDataType = "RAW"
};
StartDocPrinter(lhPrinter, 1, rawPrinter);
using(var b = new BinaryReader(File.Open(szFileName, FileMode.Open))) {
var length = (int) b.BaseStream.Length;
const int bufferSize = 8192;
var numLoops = length / bufferSize;
var leftOver = length % bufferSize;
for (int i = 0; i < numLoops; i++) {
var buffer = new byte[bufferSize];
int dwWritten;
b.Read(buffer, 0, bufferSize);
IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length);
WritePrinter(lhPrinter, unmanagedPointer, bufferSize, out dwWritten);
Marshal.FreeHGlobal(unmanagedPointer);
}
if (leftOver > 0) {
var buffer = new byte[leftOver];
int dwWritten;
b.Read(buffer, 0, leftOver);
IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length);
WritePrinter(lhPrinter, unmanagedPointer, leftOver, out dwWritten);
Marshal.FreeHGlobal(unmanagedPointer);
}
}
EndDocPrinter(lhPrinter);
ClosePrinter(lhPrinter);
}
string filePath = #"C:\Users\tom\Desktop\form.PCL";
string szPrinterName = #"\\server\xpsdrv";
Print.SendBytesToPrinterPCL(szPrinterName, filePath);
Then I sent a regular text file to the driver and it successfully converted to XPS.
public static void SendToPrinterNonPCL(string filePath)
{
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "print";
info.FileName = filePath;
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
Process p = new Process();
p.StartInfo = info;
p.Start();
p.WaitForInputIdle();
System.Threading.Thread.Sleep(3000);
if (false == p.CloseMainWindow())
p.Kill();
}
string filePath = #"C:\Users\tom\Desktop\form.txt";
string szPrinterName = #"\\server\xpsdrv";
Print.SendToPrinterNonPCL(filePath);
Why doesn't the driver in Microsoft samples accept PCL? What should I do. I am not a driver developer. This project was given to me.
EDIT:
Initally I didn't know of this printing from AS400. Our legacy driver was built 15 years back. The developer wrote a custom print driver to PCL and a Custom converter to Tiff. But the driver only supported monochrome. I am not a driver expert or a PCL expert or a converter expert. In order to support color and less pixelated feel for the final Tiff, I decided to change it to a XPS driver. Also it is less custom code and could use Microsoft's XPS conversion in WPF. It is not a very big learning curve for a non-driver development person compared to learning PCL and then changing the converter to accomodate color Tiff. But I guess it is falling apart since the users also print from AS400 which sends PCL.
Do you know any good products which we could purchase a license to? We need a PCL driver and a converter to Tiff
Thank you

Cannot upload data get xivelyclient.put returned -1

Background:
I am trying to upload data from a simple on off sensor to learn the Xively methods. I am using an Arduino Uno with a WiFi Shield. I made some simple alterations to an example sketch from the Xively library to keep it very simple. I have read the documentation and the FAQ's plus searched the web. There was a similar question (Can't connect to Xively using Arduino + wifi shield, "ret = -1 No sockets available) and the answer was to reduce the number of libraries loaded. I'm using the same library list recommended in that post.I have also updated my Arduino IDE and downloaded the latest xively and HTTP library. The code compiles without error. I re-loaded my device on the xively website and got a new API key and number as well. Plus, I ensured the channel was added with the correct sensor name. I have also checked my router and ensured the WiFi shield was connecting properly.
Problem: I can't see the data on the Xively website and I keep getting the following error messages on the serial monitor from the Arduino:
xivelyclint.put returned -1
also, after several tries, I get "No socket available"
Question: Is there an problem with the code or is it something else?
Current Arduino code (actual ssid, password and API key and number removed):
#include <SPI.h>
#include <WiFi.h>
#include <HttpClient.h>
#include <Xively.h>
char ssid[] = "ssid"; // your network SSID (name)
char pass[] = "password"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
// Your Xively key to let you upload data
char xivelyKey[] = "api_key";
// Analog pin which we're monitoring (0 and 1 are used by the Ethernet shield)
int sensorPin = 2;
// Define the strings for our datastream IDs
char sensorId[] = "sensor_id";
XivelyDatastream datastreams[] = {
XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_INT),
};
// Finally, wrap the datastreams into a feed
XivelyFeed feed(feed no., datastreams, 1 /* number of datastreams */);
WiFiClient client;
XivelyClient xivelyclient(client);
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("Starting single datastream upload to Xively...");
Serial.println();
// attempt to connect to Wifi network:
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to wifi");
printWifiStatus();
}
void loop() {
int sensorValue = digitalRead(sensorPin);
datastreams[0].setInt(sensorValue);
Serial.print("Read sensor value ");
Serial.println(datastreams[0].getInt());
Serial.println("Uploading it to Xively");
int ret = xivelyclient.put(feed, xivelyKey);
Serial.print("xivelyclient.put returned ");
Serial.println(ret);
Serial.println();
delay(15000);
}

Can the Arduino's LiquidCrystal library interfere with the Wi-Fi library?

One day I was playing around with my Arduino and had a cool idea. Maybe I could do a wireless connection WITHOUT the serial monitor! I could use an LCD display instead! So, I went to work. I replaced all of the serial stuff with LCD stuff.
Finally I had no errors in my code (according to the Arduino client, that is).
Here is my code:
#include <LiquidCrystal.h>
#include <WiFi.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
char ssid[] = "Fake Network"; // Your network SSID (name)
char key[] = "1"; // your network key
int keyIndex = 0; // Your network key Index number
int status = WL_IDLE_STATUS; // The Wi-Fi radio's status
void setup() {
lcd.begin(16, 2);
// Check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
lcd.println("WiFi shield not present");
// Don't continue:
while(true);
}
// Attempt to connect to Wi-Fi network:
while ( status != WL_CONNECTED) {
lcd.print("Attempting to connect to WEP network, SSID: ");
lcd.println(ssid);
status = WiFi.begin(ssid, keyIndex, key);
// Wait 10 seconds for connection:
delay(10000);
}
// Once you are connected:
lcd.print("You're connected to the network");
printCurrentNet();
printWifiData();
}
void loop() {
// Check the network connection once every 10 seconds:
delay(10000);
printCurrentNet();
}
void printWifiData() {
// Print your Wi-Fi shield's IP address:
IPAddress IPaddr = WiFi.localIP();
lcd.print("IP Address: ");
lcd.println(IPaddr);
lcd.println(IPaddr);
// Print your MAC address:
byte MACaddr[6];
WiFi.macAddress(MACaddr);
lcd.print("MAC address: ");
lcd.print(MACaddr[5],HEX);
lcd.print(":");
lcd.print(MACaddr[4],HEX);
lcd.print(":");
lcd.print(MACaddr[3],HEX);
lcd.print(":");
lcd.print(MACaddr[2],HEX);
lcd.print(":");
lcd.print(MACaddr[1],HEX);
lcd.print(":");
lcd.println(MACaddr[0],HEX);
}
void printCurrentNet() {
// Print the SSID of the network you're attached to:
lcd.print("SSID: ");
lcd.println(WiFi.SSID());
// Print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
lcd.print("BSSID: ");
lcd.print(bssid[5],HEX);
lcd.print(":");
lcd.print(bssid[4],HEX);
lcd.print(":");
lcd.print(bssid[3],HEX);
lcd.print(":");
lcd.print(bssid[2],HEX);
lcd.print(":");
lcd.print(bssid[1],HEX);
lcd.print(":");
lcd.println(bssid[0],HEX);
// Print the received signal strength:
long rssi = WiFi.RSSI();
lcd.print("signal strength (RSSI):");
lcd.println(rssi);
// Print the encryption type:
byte encryption = WiFi.encryptionType();
lcd.print("Encryption Type:");
lcd.println(encryption,HEX);
lcd.println();
}
And the result was....... Nothing. Nothing displayed.
Then I went and did my version of debugging. Note that I started at the bottom of the code.
lcd.print("bug");
I put this under every line of my code. Finally, I got to the top, under this line:
lcd.begin(16, 2);
AND GUESS WHAT! No display in any of the lines! I looked everywhere and I checked the display pins.
FINALLY, I found the problem!
It's a horrible bug that I can't get rid of! The display won't show with the WiFi.h library! I don't know why, But if I even #include <WiFi.h> into my program (or any program with the LiquidCrystal library... Things go exactly the same way!
What is the reason for this problem and how can I fix it? I haven't got any luck yet.
According to the documentation:
Arduino communicates with both the Wifi shield's processor and SD card using the SPI bus (through the ICSP header). This is on digital pins 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega. On Uno 11 is MOSI, and 12 is MISO.
According to your code
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
you are using pins 11 and 12 for the LCD. Now if the LCD was using SPI, then the LCD could share pins 11 and 12 with the Wi-Fi shield, because the same set of pins used for SS (Slave Select) function would tell the peripherals which one of them should be listening. However, the LiquidCrystal library uses its first two argument pins for RS and Enable respectively, making it incompatible with SPI. The solution: move your LCD onto different pins.

Sending raw data to FedEx Label printer

I'm working on a .NET WinForms app that needs to print a FEDEX shipping label. As part of the FedEx api, I can get raw label data for the printer.
I just don't know how to send that data to the printer through .NET (I'm using C#). To be clear, the data is already pre formatted into ZPL (Zebra printer language) I just need to send it to the printer without windows mucking it up.
C# doesn't support raw printing, you'll have to use the win32 spooler, as detailed in this KB article How to send raw data to a printer by using Visual C# .NET.
Hope this helps.
-Adam
I think you just want to send the ZPL (job below) directly to your printer.
private void SendPrintJob(string job)
{
TcpClient client = null;
NetworkStream ns = null;
byte[] bytes;
int bytesRead;
IPEndPoint remoteIP;
Socket sock = null;
try
{
remoteIP = new IPEndPoint( IPAddress.Parse(hostName), portNum );
sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
sock.Connect(remoteIP);
ns = new NetworkStream(sock);
if (ns.DataAvailable)
{
bytes = new byte[client.ReceiveBufferSize];
bytesRead = ns.Read(bytes, 0, bytes.Length);
}
byte[] toSend = Encoding.ASCII.GetBytes(job);
ns.Write(toSend, 0, toSend.Length);
if (ns.DataAvailable)
{
bytes = new byte[client.ReceiveBufferSize];
bytesRead = ns.Read(bytes, 0, bytes.Length);
}
}
finally
{
if( ns != null )
ns.Close();
if( sock != null && sock.Connected )
sock.Close();
if (client != null)
client.Close();
}
}
A little late, but you can use this CodePlex Project for easy ZPL printing
http://sharpzebra.codeplex.com/
Zebra printers don't use a spooler, it isn't raw printing. It's a markup called ZPL. It's text based, not binary.
I've been working with a printer and ZPL for a while now, but with a Ruby app. Sending the ZPL out to the printer via socket works fine.
To check that it works, I often telnet to the printer and type ^XA^PH^XZ to feed a single label. Hope that helps.

Resources