How to write to serial port?

I have a project where I am trying to convert a Windows based app that sends data over USB/serial to Android. I've downloaded and examined https://bitbucket.org/lusovu/xamarinusbserial but I can't for the life of me find or figure out how to use the write() method the documentation refers to. I can't find anywhere in the example file that shows using a write command, and SerialIoManager.Write() doesn't exist. What am I missing?

Answers

  • daPyr0xdaPyr0x CAMember

    I've tried running the code below after serialIoManager.open is confirmed successful but I get a crash.

    byte[] msg = new byte[1]; msg[1] = Convert.ToByte('S'); port.Write(msg, 1);

    Any examples of a successful write command would be appreciated.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    I have done an app for android that connect to usb printer and print some data. Can be useful?

  • daPyr0xdaPyr0x CAMember

    It could. Could you share the write portion?

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭
    using System;
    using Xamarin.Forms;
    using Comanda.Droid;
    using Comanda.Interfaces;
    using Android.Hardware.Usb;
    using Android.Content;
    using System.Collections.Generic;
    using System.Linq;
    using Android.App;
    
    [assembly: Dependency (typeof (Usb))]
    namespace Comanda.Droid
    {
        public class Usb : IUsb
        {
            public Usb ()
            {
            }
    
            #region IUsb implementation
    
            public List<string> Devices ()
            {
    
                List<string> lista = new List<string> ();
    
                //Voglio vedere una lista di tutti i dispositivi attualmente collegati
                Context c = Android.App.Application.Context;
                UsbManager manager = (UsbManager)c.GetSystemService (Context.UsbService);
                try {
                    if (manager.DeviceList.Count != 0)
                    {
                        foreach (UsbDevice dispositivi in manager.DeviceList.Values) {
                            lista.Add ( dispositivi.DeviceName + " " + dispositivi.ProductId + " " + dispositivi.VendorId);
                        } 
                    }
                    else
                    {
                        //lista.Add ( "-Attenzione non vedo dispositivi");
                    }
    
                } catch (Exception ex) {
                    //lista.Add (ex.ToString ());
                    throw new Exception (ex.Message);
                }
    
                return lista;
            }
    
            #endregion
    
            protected static string ACTION_USB_PERMISSION = "it.mobi-ware.android.USB"; 
    
            public void ConnectAndSend (byte [] bytesToPrint, int productId, int vendorId)
            {
                // Get a usbManager that can access all of the devices
                var usbManager = (UsbManager)Forms.Context.GetSystemService (Context.UsbService);
    
                // Get the device you want to access from the DeviceList
                // I know the vendorId and ProductId but you can iterate to find the one you want
                var matchingDevice = usbManager.DeviceList.FirstOrDefault (item => item.Value.VendorId == vendorId && item.Value.ProductId == productId);
                if (usbManager.DeviceList.Count == 0)
                    throw new Exception ("Nessun dispositivo collegato all'USB");
                if (matchingDevice.Value == null)
                    throw new Exception ("Dispositivo non trovato, provare a configurarlo in Impostazioni");
    
    //          var usbDevice = usbManager.DeviceList.First ();
    //          if (usbManager.DeviceList.Count == 1)
    //              usbDevice = usbManager.DeviceList.First ();
    
    //          // DeviceList is a dictionary with the port as the key, so pull out the device you want.  I save the port too
                var usbPort = matchingDevice.Key;
                var usbDevice = matchingDevice.Value;
    
                // Get permission from the user to access the device (otherwise connection later will be null)
                if (!usbManager.HasPermission (usbDevice)) {
                    try {
                        PendingIntent pi = PendingIntent.GetBroadcast (Forms.Context, 0, new Intent(ACTION_USB_PERMISSION), 0);
                        usbManager.RequestPermission (usbDevice, pi);
                        throw new Exception ("Rilanciare la stampa");
                    }
                    catch (Exception ex) {
                        throw new Exception (ex.Message);
                    }
                }
    
                // Open a connection with the device
                // I wrap in a try so you can close it if it errors out or you're done.
                UsbDeviceConnection deviceConnection = null;
                try {
                    deviceConnection = usbManager.OpenDevice (usbDevice);
    
                    // Get the usbInterface for the device.  It and usbEndpoint implement IDisposable, so wrap in a using
                    // You may want to loop through the interfaces to find the one you want (instead of 0)
                    using (var usbInterface = usbDevice.GetInterface (0)) {
    
                        // Get the endpoint, again implementing IDisposable, and again the index you need
                        using (var usbEndpoint = usbInterface.GetEndpoint(0)) {
                            byte[] encodingSetting = 
                                new byte[] {(byte)0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08 };
                            // Make request or whatever you need to do
                            deviceConnection.ControlTransfer (
                                UsbAddressing.Out,
                                0x20,   //SET_LINE_CODING
                                0,      //value
                                0,      //index
                                encodingSetting,  //buffer
                                7,      //length
                                0);     //timeout
    //                      byte[] bytesHello = 
    //                          new byte[] {(byte)'H',(byte) 'e',(byte) 'l', (byte)'l', (byte)'o', (byte)' ', 
    //                          (byte)'f', (byte)'r', (byte)'o',(byte) 'm',(byte) ' ', 
    //                          (byte)'A',(byte) 'n', (byte)'d', (byte)'r',(byte) 'o', (byte)'i',(byte) 'd', (byte) 13, (byte)10};
                            deviceConnection.BulkTransfer (usbEndpoint,bytesToPrint,bytesToPrint.Length,0);
    
                        }
                    }
                } catch (Exception ex){
                    // log or handle
                } finally {
    
                    // Close the connection
                    if (deviceConnection != null) {
                        deviceConnection.Close ();
                    }
                }
            }
        }
    }
    
  • Unicorn7Unicorn7 USMember ✭✭

    @AlessandroCaliaro Thank you very much for the example. I know you didn't need it for this project, but how would you open UsbDeviceConnection to receive/read a byte[] response (of unknown length) in reply to sending a message?

  • RahulKumar.3337RahulKumar.3337 USMember

    You can enable the write functionality in "xamarinusbserial" library by adding bellow function in "SerialInputOutputManager.cs" class.

    public int Write(String str, int timeout)
    {
    int bytesWritten = 0;
    try
    {
    byte[] buff = Encoding.ASCII.GetBytes(str);
    bytesWritten = port.Write(buff, timeout);
    }
    catch (Exception ex)
    {
    // log or handle
    }
    return bytesWritten;
    }

    To access this function use serialIoManager instance

  • Hello, I need a support to send data to the serial port using the "xamarinusbserial". I already have the "xamarinusbserial" package (NuGet) in my project but I can not find code examples that can help me. I need to monitor the serial port (rx) and send packets on it (tx). Thanks in advance!!

  • PaulParkinsPaulParkins USMember ✭✭

    @AlessandroCaliaro Thanks for your post. How did you determine the value for ACTION_USB_PERMISSION? I'm writing code for accessing a serial USB accessory (rather than USB device), but the process is similar and I need to request permission to use the accessory. But using "it.mobi-ware.android.USB" or "com.android.example.USB_PERMISSION" (as in this article) both give me an "unknown permission" exception.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Hi @PaulParkins

    Really, I don't know. Maybe you have to request permission at runtime?

  • PaulParkinsPaulParkins USMember ✭✭

    Yes that's exactly what I'm doing (or trying to)

Sign In or Register to comment.