Showing posts with label scala. Show all posts
Showing posts with label scala. Show all posts

Wednesday, January 15, 2014

Scala/Akka library for serial communication

I like Scala and Akka a lot and am still doing some projects using an Arduino. Akka has a nice new interface for actor based interfacing (see Akka I/O) so I decided to write a little library that bridges the good old RXTX serial port library to it.

It was a rather easy exercise, it only took around 220 lines of code most of which are message definitions. RXTX is still nasty (esp. with regarding the handling of the native libraries), but at least my actor hides to ugly parts.
See my the rxtx-akka-io project on my github profile for the source code and some examples.

Short usage example (inside an akka actor):
override def preStart = IO(Serial) ! Open(port, 9600) 
override def receive = {
  case Opened(operator, _) =>
    println("Connected to port")
    context become open(operator)
}
The operator actor then accepts messages like Write(ByteString) and Close and starts sending Received(ByteArray) messages to the actor that started it.
Failure handling is easy, if something happens the operator actor will crash and leave it to it's parent (the actor that executes the code printed above) to restart it or handle it otherwise.

Happy Hacking!

Thursday, May 6, 2010

Read/Write binary data with Scala

In my project to communicate between my notebook and an Arduino over XBees I need to send binary commands to the XBee. The protocol is defined approx. like this: every packet start with 0x7E and then two bytes containing the length of the packed then the payload and afterwards a checksum.
So I decided to write a little library that allows me to parse and compose these commands in a natural way. The parsing should use pattern matching.

To define a structure use something like this:

val myPattern = <<(byte, integer, integer, byte)>>

('<<' is a imported function, the '>>' is just decoration, that returns itself)

then you can use

val bytes: Seq[Byte] = myPattern(12, 33321, 24432, 0)

to generate a binary representation (i.e 0x12, 0x00, 0x00,  0x82, 0x29, ...). To a byte sequence use

bytes match {
case myPattern((a,b,c,d), rest) =>
a should be(12)
b should be(33321)
c should be(24432)
d should be(0)
rest should be(Nil)
}

The variable "Rest" in the example will contain everything in the Seq[Byte] after the matched sequence.


It also allows to check for fixed values (in the example above 0x7E in the first byte):

val myPattern2 = <<(fix_byte(0x7E), integer, integer, byte) drop1
myPattern2(1234, 4321, 12) //will be 0x7E, 0x00, 0x00, 0x04, 0xD2


And you can map a pattern to some class:

case class Color(red: Byte, green: Byte, blue: Byte)

val rgbPattern = <<(byte, byte, byte)>>>(
(c: Color) => (color.red, color.green, color.blue),
t => Some(Color(t._1, t._2, t._3))
)

But what makes it really powerful is the ability to nest those patterns

val colorfulPattern = <<(fix_byte(0x7E), rgbPattern, rgbPattern, integer) drop1
val data = (0x7E :: 33 :: 21 :: 11 :: 0 :: 100 :: 12 :: 0 :: 0 :: 0 :: 4 :: Nil).map(_.toByte)
data match {
case colorfulPattern((foregroundColor, backgroundColor, pixelsToFill), _) =>
foregroundColor should be(Color(33,21,11))
backgroundColor should be(Color(0, 100, 12))
pixelsToFill should be(4)
}

so it's pretty easy to define complex structures pretty fast, easy and reusable. The framework also provides possibilities to parse/serialize lists (even of "complex" objects) and optional values.


Just check out the code a GitHub and feel free to use it and contribute to it!

Now on Github

As many other Scala-project are already present on GitHub I decided to host my little projects there as well. Check out my GitHub Profile. Currently there are only two projects:
  • scala-base: My base classes, i. e. Durations, BinaryParsing, Actor-library and Erlang OTP-like stateserver and supervisor
  • scala-xbee: An library to communicate with a usb-port attached XBee (and obviously XBees attached to this one).
I'll blog more about the projects later.

Monday, May 3, 2010

Run sbt inside emacs

Today I found a nice emacs addon that allows you to run sbt inside emacs. It even has clickable compiler errors (although I don't need those because ensime does this nicer).
Actually it's mentioned in the scala wiki, but I managed to over read it until now :)

Add (setq comint-scroll-to-bottom-on-output t) to autoscroll to the bottom when new output is written (M-x eval-expression).

Sunday, May 2, 2010

Emacs and sbt

After selecting sbt as my new build-environment I still needed an editor to code in. First I went with TextMate with a Scala Bundle (don't remember which one, I installed that some time ago). While it offers just code highlighting and some code templates it works just fine. I didn't miss code completion all that much (probably because it didn't work very well in Eclipse either). But what I really missed was  compilation-error highlighting. I spent some time coding with the sbt-iTerm window beside the TextMate-editor and using Command+L (enter line number) to jump to the errors that showed up in iTerm. Works, but nothing to write home about..

I remembered a nice video about Aemon Cannon showing his ensime-Emacs mode (video on youtube). He shows syntax highlighting (actually that's provided by the scala-mode), code completion, compilation errors, type inspection and package overviews. Quite impressing, isn't it? And what I liked best about it, is that it directly uses scala itself (running in a "server-process") to provide those features. So they're accurate and not "guessed" by a second parser implementation. Also all the stuff happens in the background, so it doesn't slow down your typing. Great stuff!

So here's how I installed it

  • Install/Update to Emacs 23 for Mac OS X according to this blog. Ensime needs the Emacs 23.
  • Spent some time with various Emacs tutorials to refresh my Emacs-skills :)
  • Install the scala-mode for emacs as described on scala-lang.org
  • Download Ensime and unpack it to some path (i.e. to ~/scala/emacs/ensime)
  • Make sure you got a 'java' and a 'scala' on the path (i.e. ln -s /Applications/scala/bin/scala /usr/local/bin/scala)
  • add some lines to .emacs as described in the Ensime readme
  • create a .ensime file in your project root. Mine looks as follows (current version):
(
  :server-root "/Users/ms/scala/emacs/ensime/"
  :server-cmd  "bin/server.sh"
  :server-host "localhost"
  :server-env ()

  :project-package "ch.inventsoft.scalabase"
  :source ("src/main/scala")
  :exclude-source ()
  :classpath ("lib/jsr166y.jar"
        "lib_managed/scala_2.8.0-SNAPSHOT/compile/logback-classic-0.9.20.jar"
        "lib_managed/scala_2.8.0-SNAPSHOT/compile/logback-core-0.9.20.jar"
        "lib_managed/scala_2.8.0-SNAPSHOT/compile/slf4j-api-1.5.11.jar"
        "lib_managed/scala_2.8.0-SNAPSHOT/plugin/continuations-2.8.0-SNAPSHOT.jar"
        "project/boot/scala-2.8.0-SNAPSHOT/lib/scala-compiler.jar"
        "project/boot/scala-2.8.0-SNAPSHOT/lib/scala-library.jar"
        "lib_managed/scala_2.8.0-SNAPSHOT/test/scalatest-1.0.1-for-scala-2.8.0.RC1-SNAPSHOT.jar")        
)
  • fire up emacs, open a scala file of your project. If it doesn't have syntax highlighting enter 'M-x scala-mode'
  • Enter 'M-x ensime' and answer the questions.
  • See the Ensime readme for all the available shortcuts (Tab, C-c t, C-c p)
  • Feel happy :)

I still got some problems with the inspector (didn't figure out how to have it open in a separate window, probably due to my incomplete emacs know-how), but overall it works just great. With sbt ~test-quick executing all tests as I change the code it provides very fast feedback.

And it'll get even better. I just read on the scala-Maillist, that Cannon's proposal for Google's summer of code has been accepted. Looking forward to that! Great job, Aemon

Saturday, May 1, 2010

Searching a new IDE for Scala

Ever since I started trying and using Scala I used the nightly build of the Eclipse-Plugin. I was never really happy with it, it works fine for smaller projects but slows down to a crawl if used with larger projects. Also it has some annoying glitches with unit-tests (no support for scalatest and junit works sometimes and sometimes not), auto-completion, presentation compiler showing false errors and compilation.
Recently I started to lock up completely on certain code-fragments, forcing me to kill the process and restart Eclipse. Unfortunately it was "reproducible", so I actually had to (cosmetically) change some code I was trying to write in order to avoid to lockup. (Miles Sabin et al are doing a great work, it just needs some time, I really admire what they're doing)


That's why I started looking to alternative ways to code Scala. First I tried IntelliJ withthe  Scala-Plugin: Tried it, but didn't fall in love with it... I probably should've given it more time, but I was afraid, that it was going to have to same behavior as Eclipse (fine for small, bad for larger projects).


During surfing on the net I also found several posters, that really liked the sbt along with some text editor (some guys even pair it with an IDE), so I gave it a try. It does a great job at setting up your project and managing its dependencies (similar to maven, but easier).

Here's the scala/build/ScalaBase.scala (my project is named ScalaBase and uses the new cps-plugin of Scala 2.8):
import sbt._
 
class ScalaBaseProject(info: ProjectInfo) extends DefaultProject(info) with AutoCompilerPlugins {      
  val continuations = compilerPlugin("org.scala-lang.plugins" % "continuations" % "2.8.0-SNAPSHOT")
  override def compileOptions = CompileOption("-P:continuations:enable") :: super.compileOptions.toList
 
 
  val slf4j = "org.slf4j" % "slf4j-api" % "1.5.11"
  val logbackcore = "ch.qos.logback" % "logback-core" % "0.9.20"
  val logbackclassic = "ch.qos.logback" % "logback-classic" % "0.9.20"
 
  val scalatest = "org.scalatest" % "scalatest" % "1.0.1-for-scala-2.8.0.RC1-SNAPSHOT" % "test"
  val toolsSnapshot = ScalaToolsSnapshots
}

But what's really great: Start it up with
[~/scala/myproject] sbt
then type
~test-quick
and then edit your source files. As soon as you save a file it compiles all the affected classes and tests and then executes only the tests that were recompiled! This is great and gives you immediate feedback without stopping you from coding on. And it's really quick too (seems to take half the time of Eclipse-plugin to compile my code).

For more infos see the sbt documentation.