Search Microcontrollers

Thursday, October 11, 2012

BeagleBone : Serial ports and multiplexing

Some months ago I released a couple of  Youtube videos where I was illustrating the basics of using java and the comm library RXTX to drive serial communications with the beaglebone.









Since then I keep getting a few questions and from time to time I get requests for a test class.
So I figured I could do a post here to explain few things.
(Ok, ok... if you just want the code and skip the blah blah, you can get it here, good luck with it)

First thing : RXTX is an open source communication library, maybe it's not perfect, but I find it great for a number of reasons, one of them being it's portability.
Driving hardware (like serial ports) in java is a bit tricky, because you need native code (i.e. written in C, ASM...) for the specific architecture you are using.
To put it in simple words : you need some code which is not executed in the JVM, so it's not java.
This is obviously an issue : java is designed to be portable cross platform, you normally just need a jvm for the specific architecture you are using and you are normally pretty much done.

If you need to execute native code, then you need the specific version that can work on your device.
The native part of the RXTX library has been successfully ported to the bone, which makes it possible to use the library in java on this device.

I am not going to provide a tutorial on rxtx here, if you want to use it and you have no knowledge on it, I strongly suggest you search for tutorials in the web and first learn how to use it on a pc.
I have a software logging data from a RS485 every 30 seconds, running since about 3 months, it was developed and tested on a PC and finally deployed (smoothly) on the bone.

So, what's special with the bone?
Not much honestly and in fact, if you use a usb/serial converter you probably don't need any bone specific instruction : what runs on your pc is supposed to run on the bone just the same.

However, the bone offers also some "internal" ttl uarts (3.3V !! beware) and to use those you need some bone specific code.
Those uarts are physically accessible from the P8 and P9 headers of the board, their pin mapping -extracted from the bbone user manual- is the following :


i.e. P9.21.1 means pin 21 on the P9 header and multiplex value = 1

You should probably be familiar with the multiplexing concept, if not, here's a very quick explanation :

Multiplexing 

Many of the modern processors and microcontrollers, provide a wide range of functionality.
At this point the issue became to export all those functions with physical electrical contacts (pins).
A solution was found in assigning multiple functions to the same pin and allowing the processor to be configured, via software, to set a specific function to a specific pin.
The ARM cortex processors use a lot this feature.
To get back to our serial ports, this means that the RX function of uart2 will normally be located at pin xxx, however at the same pin you can eventually find other 7 functions, which could be GPIO, timer output, etc...
So, what we want to do is to configure properly the function, direction (input/ output) etc of the pins we need.

But wait... that sounds like an issue if we are using java, right?
Again we would need to access the hardware, so we would need native code...

No, the Linux OS comes in help with that.
To allow an easy access to these functionality, the OS exports a virtual file system which acts as a sort of interface for all those hardware configuration.
From the java side, we just need to deal with files and directories.

For that I created a specific helper class, it's not really finished, but it does the job for me.
It can be found here and if you can read java code it should be quite self explanatory.
I use it to interface the beaglebone headers (it can do gpio read/writes), not just for setting the multiplex values.
This class uses an external dat file (gpiomux.dat) which is actually a text file in which I list the contacts on the P8 and P9 header.
Except for the serial ports, for which I provide a specific method, to configure the other pins (should you need to), you need to refer to the user manual, discover which pin is assigned to the function you are looking for and find also the function number.
With that info, the BBMux class will do the configuration for you.

Allowing RXTX to see the ttl uart ports

The RXTX library uses a list of known port names to discover your available serial ports, unfortunately this list does not include the beaglebone internal serial ports.
No worries, there is an easy fix, no coding required!
The solution is documented here : http://rxtx.qbang.org/wiki/index.php/Trouble_shooting
Check where it says : How does rxtx detect ports? Can I override it?

In my case I decided to specify the port list when running the program.
The internal serial ports are seen by the OS as ttyOx (O stands for Omap)


java
    -classpath ./:./rxtx/RXTXcomm.jar
    -Djava.library.path=/usr/lib/jni
    -Dgnu.io.rxtx.SerialPorts=/dev/ttyO1:/dev/ttyO2:/dev/ttyO3:/dev/ttyO4:/dev/ttyO5
   MyClass

My command line sets :
- the java classpath to include the rxtx java library (jar)
- the java library path to include the rxtx native library folder
- the rxtx serial ports to the list of ports I could use in my program


Note : I created the test class TestBBSerial by ripping code from my program, I hope it works, but it's really meant just to illustrate the concepts.
You can find great rxtx examples on the web,
Unfortunately I cannot post my other programs as they would be too complex to explain, I normally use some wrappers for rxtx to handle buffers, configurations, protocols etc.
These wrappers use json, webservices for remote configurations... so I would need to post tons of classes that would just confuse you more. 

12 comments:

Gregg Harrington said...

Hello. I just came across your article and it helped me a tremendous amount!!! Thank you for taking the time to write up your research.

Cheers!

Francesco Agosti said...

Hello, thanks for your comment.
I strongly believe in sharing information.
Most of the things I learnt were explained by others in Internet, so this is my attempt to give back a bit :)
Enjoy hacking & sharing knowledge.

pem said...

Thank you for these tutorials. Do you think it will work with the BeagleBone Black, or does it need to be changed?

Francesco Agosti said...

Hello, normally it should work, but did not try it yet

vishwa said...

Hi,

I just saw your article, the same thing which we are trying to achieve on Beaglebone black. we are doing college project on it. My question is , is this is the only way to achieve or do we get some api's which provide all the classes.? because your code looks like embedded c programming style.

Please help us..

Francesco Agosti said...

Hello,
multiplexing is achieved via via the Kernel file system in Linux.
This applies to the bone and to any other platform (that has some multiplexing) running a Linux distribution.

In fact you do not need APIs, you just interact with a virtual file system, you could do it from the shell using echo commands too.
I found it easier to manipulate the thing through a java class, but your mileage may vary.
The point of having this functionality exported to a virtual file system is to avoid machine dependent compiled code, since any programming language can deal with files and folders.
The Class I use is BBMux.java found in the com/powerup/beaglebone folder in the zip linked in my post (http://www.powerupbi.com/files/BBtest.zip)

luis sencion said...

Thank for your tutorial,

You mentioned that you are using the java code to log data from RS485, I've read somewhere else that for the Beagleboard to communicate using RS485 special hardware is needed. If it is so, what do you use?, any special consideration that we need to take into account if we want to use RXTX, for RS485 with java and the Beagleboard?

Best Regards

Francesco Agosti said...

Hello and thanks for your comment.
Yes, you need specific hardware as the beagle has ony a TTL uart.
A TTL uart can be fed into a RS232 chip (i.e. MAX232) or a RS485 (i.e. MAX485).
I created my own RS485 interface (it is quite simple actually), just make sure you use some chip that runs at 3.3V.
Alternatively you can buy a RS485 shield for the bone, I think I saw one of them somewhere.
Building your own anyways is a matter of a chip, a terminating resitor and some wires, no big deal there.

That said, for the RS485, since it is half-duplex, you also need a GPIO line to control the talk/listen pin of the RS485 chip (also 3.3V).
You can also use a double 485 chip to implement a full-duplex, but that also requires an additional connector on the line I guess, never tried.

JUHI said...

Hi
I am not able to see your code. Can you please help me?

Francesco Agosti said...

Ooops, guess the zip file was removed from there by mistake, sorry.
Need to look in some backups and hope to find it again!

JUHI said...

Did you find it? I am in need of the program. Please help.

Francesco Agosti said...

Hello again... well, yes and no.
I found a different version, which I uploaded at the same address, you should be abel to make it work.
This version uses some libraries I made as wrappers for serial routines, they are not specific for the BBone, so you should still be able to get the BB part out of them.
The link is the same in my post, still need to check some other backups, If I find the original version I will re-upload it and notify here.