Skip to content
April 13, 2010 / ygramulqc

Serial to IRC bridge

I’m playing around with Java and RXTX. My first hopefully useful program is a bridge between a serial connection and an irc bot. This can be used as some kind of remote diagnostic for microcontroller stuff .. like my quadrocopter UAVP-NG.

And here is the code:

package com.wordpress.ygramulqc;

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;

import org.jibble.pircbot.PircBot;

/**
 * A simple IRC  COM port gateway. Only useful for text based communication.
 *
 * Required: http://rxtx.org/ and http://www.jibble.org/pircbot.php
 *
 * @author ygramul
 *
 */
public class UART2IRC extends PircBot {

	protected String callerNick;
	protected String command;
	protected boolean commandActive;
	protected Properties prop;

	public UART2IRC() throws Exception {
		super();
		prop = new Properties();
		try {
			FileInputStream stream = new FileInputStream("uart2irc.properties");
			prop.load(stream);
			stream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		this.setName(prop.getProperty("botname", "UARTBot"));
		this.connect(prop.getProperty("server"));
		this.joinChannel(prop.getProperty("channel"));
		this.connectSerial(prop.getProperty("device"));
		if (prop.getProperty("debug").equalsIgnoreCase("true")) {
			this.setVerbose(true);
		}
		callerNick = "";
		command = "";
		commandActive = false;
	}

	public void onPrivateMessage(String sender, String login, String hostname,
			String message) {
		if (!commandActive) {
			callerNick = sender;
			command = message;
			commandActive = true;
		}
	}

	public void connectSerial(String portName) throws Exception {
		CommPortIdentifier portIdentifier = CommPortIdentifier
				.getPortIdentifier(portName);
		if (portIdentifier.isCurrentlyOwned()) {
			System.err.println("Error: Port is currently in use");
		} else {
			CommPort commPort = portIdentifier.open(this.getClass().getName(),
					2000);

			if (commPort instanceof SerialPort) {
				SerialPort serialPort = (SerialPort) commPort;
				serialPort.setSerialPortParams(Integer.parseInt(prop.getProperty("baud", "57600")),
						SerialPort.DATABITS_8,
						SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

				InputStream in = serialPort.getInputStream();
				OutputStream out = serialPort.getOutputStream();

				(new Thread(new SerialWriter(out, this))).start();

				serialPort.addEventListener(new SerialReader(in, this));
				serialPort.notifyOnDataAvailable(true);

			} else {
				System.err
						.println("Error: Only serial ports are handled by this example.");
			}
		}
	}

	/**
	 * Handles the input coming from the serial port. A new line character is
	 * treated as the end of a block in this example.
	 */
	public class SerialReader implements SerialPortEventListener {
		private InputStream in;
		private byte[] buffer = new byte[1024];
		private UART2IRC uart2irc = null;

		public SerialReader(InputStream in, UART2IRC parent) {
			this.in = in;
			this.uart2irc = parent;
		}

		public void serialEvent(SerialPortEvent arg0) {
			int data;

			try {
				int len = 0;
				while ((data = in.read()) > -1) {
					if (data == '\n') {
						break;
					}
					buffer[len++] = (byte) data;
				}
				if (len > 0) {
					uart2irc.sendMessage(uart2irc.callerNick, new String(
							buffer, 0, len));
				}
			} catch (IOException e) {
				e.printStackTrace();
				System.exit(-1);
			}
		}

	}

	public class SerialWriter implements Runnable {
		OutputStream out;
		private UART2IRC uart2irc = null;

		public SerialWriter(OutputStream out, UART2IRC parent) {
			this.out = out;
			this.uart2irc = parent;
		}

		public void run() {
			char[] charArray = null;
			byte[] byteArray = null;
			while (true) {
				if (uart2irc.commandActive) {
					charArray = new char[uart2irc.command.length() + 1];
					byteArray = new byte[uart2irc.command.length() + 1];
					charArray = uart2irc.command.toCharArray();
					for (int i = 0; i < uart2irc.command.length(); i++) {
						byteArray[i] = (byte) charArray[i];
					}
					try {
						this.out.write(byteArray, 0, uart2irc.command.length());
						this.out.write(13); // return
						uart2irc.commandActive = false;
					} catch (IOException e) {
						e.printStackTrace();
						System.exit(-1);
					}
				}
			}
		}
	}

	public static void main(String[] args) throws Exception {

		try {
			UART2IRC bot = new UART2IRC();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Put this into a file called “UART2IRC.java” within a the folder com/wordpress/ygramulqc

After that, get a FDDI driver and a JDK and also the stuff from: http://rxtx.org/ and http://www.jibble.org/pircbot.php

Create uart2irc.properties file with content similar to this:

botname=Bot Name
server=name of the irc server
channel=#testchannel
device=COM6 or /dev/tty.usbserial or something similar
baud=57600
debug=true

Compile the code:

javac -cp .:pircbot.jar:RXTXcomm.jar com/wordpress/ygramulqc/UART2IRC.java

And execute it:

java -cp .:pircbot.jar:RXTXcomm.jar com/wordpress/ygramulqc/UART2IRC
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: