AsyncStream: ttyS0 as java.io.InputStream / OutputStream ?

robotop

Member
Licensed User
Longtime User
Hello, my Android tablet has a serial port available (ttyS0) and I modified the rom adding the line chmod 777 /dev/ttyS0 to the device initialization script, so I suppose it will be available for input and output. My question is: how can I bind the /dev/ttyS0 to the java.io.InputStream and java.io_OutputStream that are required as parameters in the AStreams.Initialize method ? In other words, what will be the correct Astreams.Initialize(?InputStream?, False, ?OutputStream?, "SerPortEvent") syntax ?
Thank you in advance, bye
 
Last edited:

robotop

Member
Licensed User
Longtime User
Hello Erel, thank you for quick answer. I will try the solution you proposed. So, I must open a file called "/dev/ttyS0" for random (or binary) and use normal print # and input # ? This means that I have to periodically check the input queue for the presence of pending characters ? I was interested by the AsyncStream 'cause it can rise an event on character input (or on packet input in the other version) and this doesn't need for any periodic timer event. Ok, now I'm going to test the procedure, Thank you again for suggestion :)

OOPS--- edited my post after short time :)
this is the prototype of OpenOutput:
OpenOutput (Dir As String, FileName As String, Append As Boolean) As OutputStream
ok, here are Dir and FileName as strings. Now, my "file" is on /dev/ttyS0. This means that I have to use "/dev" as Dir and "/ttyS0" as Filename ?
Can you point me to some example using system devices like /dev/console or similar ? Thank you.
 
Last edited:
Upvote 0

robotop

Member
Licensed User
Longtime User
Finally, I can transmit data on my ttyS0 port :sign0142: Now, next step will be the receiving part... when this part will proved to be working, I'll post the small code involved in this process. Thank you for helping, Erel.
 
Upvote 0

robotop

Member
Licensed User
Longtime User
rs232 working as I/O (modified rom tablet)

Hello Erel, as promised, here is the rs232 input/output working in my tablet. Note that I modified the ROM with chmod 0777 ttyS0 and console=null,9600 in order to gain access in read/write and disable the console messages running on underlaying Linux kernel.

B4X:
Process Globals
---------------
   Dim sout As OutputStream ' serial out stream
   Dim sinp As InputStream ' serial in stream

   Dim outpkt(128) As Byte ' serial comm output packet (buffer)
   Dim inpkt(128) As Byte ' serial comm input packet (buffer)

Activity Create
---------------
   sout = File.OpenOutput("","/dev/ttyS0",True) ' open serial output
   sinp = File.OpenInput("","/dev/ttyS0") ' open serial input

   outpkt(0) = 0x2E ' init output packet (example)
   outpkt(1) = 0x30 '  :00<cr><lf>
   outpkt(2) = 0x30 '
   outpkt(3) = 0x0D '
   outpkt(4) = 0x0A '

Main Timer 
----------
Dim c, rxlen As Int
Dim s As String

' do receive job

   rxlen = sinp.BytesAvailable ' check if bytes available on serial input
   If rxlen > 0 Then
      sinp.ReadBytes(inpkt,0,rxlen) ' read pending characters
      s = "" ' clear string
      For c = 0 To rxlen-1 ' build string from characters
         s = s & Chr(inpkt(c))
      Next
      txt1_200.Text = s ' show string to textbox
   End If

' do transmit job

   sout.WriteBytes(outpkt, 0, 5) ' prepare 5 bytes packet
   sout.Flush ' send to serial port
   outpkt(2) = outpkt(2)+1 ' increment character (as test)
   If outpkt(2) > 0x39 Then outpkt(2) = 0x30 ' stay between '0' and '9'

hope this will be useful for someone ... bye
 
Last edited:
Upvote 0

gemasoft

Member
Licensed User
Longtime User
serial

"I modified the ROM with chmod 0777 ttyS0 and console=null,9600" how to do this on my tablet and I find this issue useful.
 
Upvote 0

robotop

Member
Licensed User
Longtime User
Hello, you must add this command in the init.rc file that's in android package. Also, in the same file, disable the console service that's started as default, then you can use your ttyS0. Bye.
 
Upvote 0

casella

Member
Licensed User
Longtime User
Rs232 ???

Hi Robotop and every one,

I dont understood what `s ttySO.
I have the path /dev/ and many files tty1, tty2 to tty60 and much more but I dont see the directory /dev/ttySO/.

I think it`s very useful for me, because I need comunication between my phone and an ATM then have a RS232 serial connector.

Is it possible to receive data whith your example whith USB cable?

Thnx and best regards.
 
Upvote 0

robotop

Member
Licensed User
Longtime User
Hello casella, my reference to ttyS0 was for an Android tablet based on WM8650 processor. Obviously, if you don't have in your /dev/ folder that peripheral, it can't be used. The various tty1..tty60 aren't hardware devices, but "logical" connections used by the system. If your device has some USB socket (HOST mode), you can try to connect a simple "USB to RS232" converter and then look in the /dev/ folder for any ttyUSBx where x can be (generally) 0..9 : if the device is recognized, you can use it as in the example shown at the top of this thread, simply substituting "ttyUSB5" to "ttyS0" (if the recognized port is ttyUSB5). I used that way to get data from one USB "GPS mouse", directly reading the NMEA sentences at 4800,N,8,1 without having any location service enabled (my China clone cheap tablet hadn't location support).
For additional examples, you can take a look at my personal blog here: ficara.altervista.org ; put the ttyS0 text in the search form and then you can have a summary of the articles in wich that word is mentioned. There are, also, some informations on the various hardware and software experiments I did with Android tablets (a MIDI output, a TV remote control, etc) ; may be you can find something useful for your needs. Don't be afraid if you read something in my natural language (Italian) ; most of technical articles are in English, or (better) in my very personal version of that language :)
 
Last edited:
Upvote 0

casella

Member
Licensed User
Longtime User
RS232 to USB

Hello casella, my reference to ttyS0 was for an Android tablet based on WM8650 processor. Obviously,

Thank you very much for your quick response. I will see it and try.

I have just a more question: Is it possible receive data from external RS232 (via USB cable) to USB conector of my smartphone whit this converter?

I have an ATM that send a data string and I need receive it whith my smartphone.

Thank you again.
Best Regards.
 
Upvote 0

robotop

Member
Licensed User
Longtime User
Hello, it strictly depends upon your smartphone's model and its hardware. If the underlying Linux Kernel has a driver for "usb to rs232" interfaces (like PL2303 from Prolific or CP210x from Silicon Labs) and if the usb connector of the phone is HOST type, it will be possible. As I've written in my previous message, you can easily look in the /dev/ folder to see if there is a peripheral called ttyUSBx when you "plug in" the usb converter in the smartphone. Note that I don't know anything about your model (and even if you send me what is it, I probably don't know, again), so I'm speaking of theorycal chance.
Anyway, if your smartphone has the Bluetooth interface, you can attach on the external ATM a Bluetooth to RS232 converter, then create a pairing with your phone and use the serial connection "wireless". The B4A language has a library to do this job. Look in the "help" for this topic.
See you
 
Upvote 0

Alex Chan Chee Wah

Member
Licensed User
Longtime User
Hello RoboTop,

I am total alien to linux and android programming, but with Basic4PPC, i am now able to write simple Apps using the my favorite programming language VB.

Currently I am tasked to create an apps that will require to talk to external device using the serial port (ttyS1) at 115200 (8-N-1) with no flowcontrol. But the android device comes with default 9600 bps whenever it restarted.

after some researched, i use the SuCommand library that is able to send shell command and managed to change the baud rate to 115200, but it seems like there is still some comm error occurring.

May I know what is the actually "stty" and "chmod" commands i need to send to the android device in order to meet my communication baud rate?

Thanks in advance.

Regards,
Novice Alex
 
Upvote 0

robotop

Member
Licensed User
Longtime User
Hello Alex, I have a working (downloadable) apk for one application using ttyusb5 at 115200 on my blog here: http://ficara.altervista.org/?p=859
If I remember correctly, all the program was written only using B4A, nothing else. Actually I'm not at home and can't access the source file, may be I can find it tomorrow. Please, note that the application uses an EXTERNAL usb to rs232 adapter (PL2303 based) that's recognized as ttyUSB5 on my (old) tablet. Also note that the internal serial port (ttyS0 on my tablet) may not have ALL the baud rates. In my experiece, the (very useful) baud rate of 4800, can't be obtained, probably for internal hardware clock divisor, and the program automatically "shifts" to 9600, even if 4800 is requested. In practice, when you set the baud rate, the software looks in a table, then sets the nearest value from the ones that are implemented.
Hope this helps... bye
 
Upvote 0

robotop

Member
Licensed User
Longtime User
Hello, here I am, again. This is part of the application that uses external usb-rs232 interface:
B4X:
' Serial I/O example from SIRC2 project by Emilio P.G. Ficara (robotop)
'
Sub Process_Globals
    Dim Arh() As String ' used for shell
    Dim StdOut, StdErr As StringBuilder ' used for shell
    Dim Result As Int ' used for shell
    Dim Ph As Phone ' used for shell

    Dim inpkt(256) As Byte ' serial comm input packet buffer
    Dim outpkt(32) As Byte ' serial comm output packet buffer
    ...
End Sub

Sub Globals
    Dim sout As OutputStream ' serial out stream
    Dim sinp As InputStream ' serial in stream
    ...
End Sub

Sub Activity_Create(FirstTime As Boolean)
    sinp = File.OpenInput("","/dev/ttyUSB5") ' open serial input
    sout = File.OpenOutput("","/dev/ttyUSB5",True) ' open serial output
    StdOut.Initialize ' initialize string builder for StdOut
    StdErr.Initialize ' initialize string builder for StdErr
    Result = Ph.Shell("stty -F /dev/ttyUSB5 115200 cs7 -parenb -cstopb -crtscts", Arh, StdOut, StdErr) ' set 115200,N,7,1
    ...
End Sub

Sub Activity_Resume
    sinp = File.OpenInput("","/dev/ttyUSB5") ' open serial input
    sout = File.OpenOutput("","/dev/ttyUSB5",True) ' open serial output
    ...
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    sinp.Close ' close serial input
    sout.Close ' close serial output
    ...
End Sub

... in main process, check if char pending on input :
(define rxlen as integer)
    rxlen = sinp.BytesAvailable ' check if bytes available on serial input
    If rxlen > 0 Then
        sinp.ReadBytes(inpkt,0,rxlen) ' read pending characters
        ...
       

... when needed, send packet to serial port out

    sout.WriteBytes(outpkt, 0, 30) ' write 30 bytes packet to serial
As you can see, there is the stty command sent via Ph.shell to set the baud rate, bits, etc. In my application the serial port is used as 115200,n,7,1 , so change the stty command for your needs.
Hope this helps, bye
 
Upvote 0

ManuelGG

Member
Licensed User
Longtime User
Hi, I'm doing a similar application to communicate with an RS232 port direct on plate (Direct UART -> "/dev/ttyO0") and work me less well this line:

Result = Ph.Shell("stty -F /dev/ttyO0 115200 cs8 -parenb -cstopb -crtscts", Arh, StdOut, StdErr) ' set 115200,N,8,1

As much as I try do not change the port configuration settings... Would someone know tell me why?
 
Upvote 0

robotop

Member
Licensed User
Longtime User
Hi, may be that's just a typo error. The peripheral "ttyO0" doesn't exists, basing this sentence on my knowledge. The standard serial port is ttyS0. Anyway, look in the /dev/ directory to see if the ttyS0 exists in your system. Also note that the "stty" command may have success only if you have root rights.
 
Upvote 0

ManuelGG

Member
Licensed User
Longtime User
If it exists in the "dev" folder and also works perfectly... I can open the port, write and read. What can not is change parameters baud rate, Stop Bits, parity bit.
A is very interesting Industrial Rugerizada DPA to work in hard environments and so far is the only one I've found to have OnBoard serial port:
http://download.winmate.com.tw/$Productfile/TabletPC/13_0134/S430T-T1.pdf

I have tested with the following application:
https://play.google.com/store/apps/details?id=android_serialport_api.sample
http://code.google.com/p/android-serialport-api/wiki/android_to_rs232_guideline?tm=6
... and this is able to change the baud rate.

Using the application "APK_Extractor" have generated the APK from this application and extracted the file "classes.dex" and with the application "dex2jar" have created the JAR file ("serialport_api.jar") herein. Would there be any chance of generating the file "serialport_api.xml" to be able to incorporate this library Basic4Android?

Thank you.
 

Attachments

  • serialport_api.jar
    23.5 KB · Views: 370
Upvote 0

robotop

Member
Licensed User
Longtime User
Hi, the command "stty" is the canonical way to change the serial port parameters on Linux systems. There is a limit in the baud rates: if you use one that can't be achieved due to hardware configuration, the command assigns automatically the one that's closest to the desidered one, but is compatible with the hardware. Just for example, the ttyS0 on my tablet based on WM8650 SOC, cannot set the baud rate to 4800 BPS and if you try that, it assigns 9600, while if you try to set 19200 or 38400 it goes well. I don't know what Android version is running on your specific hardware. The example I proposed on my post, works on a tablet based on Android 2.2 (so, it's very old), but newer version have changed many and many things, diverting much more from classical Linux substrate, so may be the command "stty" has been modified or is unsupported. On a terminal, try if it's possible to get some information about the command using something like "man stty". About your question, I don't know if the file you extracted ("serialport_api.jar") can be inserted in a B4A library, the person that can give you a full answer may be Erel or some of other "gurus" of B4A. You can take a look in the jar file just to discover what part of source that handles the serial port parameters, then reproduce that behaviour with available shell commands, but this is just a suggestion. Anyway, for serial applications on modern tablets and smartphones, I actually use an USB converter (USB-RS232 or USB-RS485 or USB-TTL), that gives me full control by means of existent USB_Serial library. Note that USB-RS485 doesn't need for a control pin to set the flow direction, 'cause FTDI chips (and many others) automatically handle it. So, in order to control devices on RS485 bus you just need to send your packet on the serial port at the right moment. Hope this can help... bye
 
Upvote 0
Top