Jan 20, 2010

Mvn Voodoo - eclipse:eclipse Doesn't Include AspectJ in the Classpath

Nice huh? Well, the answer is in MECLIPSE-544. I added this to my pom.xml to fix the problem:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins
<artifactId>maven-eclipse-plugin
<configuration>
<!-- http://jira.codehaus.org/browse/MECLIPSE-544 -->
<ajdtVersion>none
</configuration>
</plugin>
</plugins>
</build>

Jan 17, 2010

Upgrade Complete

if you've played any online flash games you may well find this amusing:

[Upgrade Complete]

Jan 16, 2010

Test & Code Edit Patterns - Part III

Okay. It works. Here's a picture with the Arduino showing that my main code is 8 minutes older than my test code. 0-2 minutes: one LED, 2-4 minutes: two LEDs, 4-8 minutes three LEDs, 8-15 minutes: four LEDs, 15+ minutes: four flashing LEDs:


Here's my Arduino code for driving the display:

#define RED 10
#define GREEN 11

void setup() {
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);

Serial.begin(9600);
}

int code = 0;
int test = 0;

void loop() {
if (Serial.available() > 0) {
int incomingByte = Serial.read();

code = incomingByte / 16;
test = incomingByte % 16;
}

draw(code, 2);
draw(test, 8);

if (code == 15 || test == 15) {
delay(100);
if (code == 15) {
erase(2);
}
if (test == 15) {
erase(8);
}
delay(900);
}
}

void draw(int value, int base) {
digitalWrite(base+0, (value >= 1) ? HIGH : LOW);
digitalWrite(base+1, (value >= 2) ? HIGH : LOW);
digitalWrite(base+2, (value >= 4) ? HIGH : LOW);
digitalWrite(base+3, (value >= 8) ? HIGH : LOW);
}

void erase(int base) {
digitalWrite(base+0, LOW);
digitalWrite(base+1, LOW);
digitalWrite(base+2, LOW);
digitalWrite(base+3, LOW);
}
Here's my sloppy Groovy code for providing the data:
import gnu.io.CommPortIdentifier
import gnu.io.SerialPort

CommPortIdentifier portId =
CommPortIdentifier.getPortIdentifier(
"/dev/tty.usbserial-A9007OMY")

SerialPort serialPort = (SerialPort) portId.open("Test", 5000)

serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE)

serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE)

// give the Arduino time to reset and Serial.begin
Thread.sleep(3000)

OutputStream outStream = serialPort.getOutputStream()

walk = { root ->
root.eachFile { file ->
if (file.name.endsWith(".java")) {
if (file.name.endsWith("Test.java")) {
if (test == null || file.lastModified() > test.lastModified()) {
test = file
}
} else {
if (code == null || file.lastModified() > code.lastModified()) {
code = file
}
}
}
}
root.eachDir { dir ->
if (!dir.name.startsWith(".")) {
walk(dir)
}
}
}

while(true) {
newestTest = 0
test = null
newestCode = 0
code = null

walk(new File(""))

def now = System.currentTimeMillis()
def codeAge = (now - code.lastModified())/60000
def testAge = (now - test.lastModified())/60000

println "Test (minutes old): $testAge ($test)"
println "Code (minutes old): $codeAge ($code)"
new File("monitor.csv").
append("$now, $codeAge, $testAge\r\n")

int encodedTest = (int)Math.max(Math.min(15,testAge-codeAge), 0)
int encodedCode = (int)Math.max(Math.min(15,codeAge-testAge), 0)

if (encodedTest == 0 && encodedCode == 0) {
if (codeAge > testAge) {
encodedCode = 1
} else {
encodedTest = 1
}
}

int encoded = encodedCode * 16 + encodedTest

outStream.write((byte)encoded)
outStream.flush()

Thread.sleep(20000);
}

outStream.close()
serialPort.close()

Test & Code Edit Patterns - Part II

I'm having some success with this project. I can communicate with the Arduino using RXTX and Serial.read(). I'm deriving my last-edit times and encoding them as a byte and sending it over the USB to the Arduino. It can read the byte and update my row of LEDs accordingly.

But.

This only works for some reason if I have the Serial Monitor window open in the Arduino IDE. There must be some communication going on with the Arduino that puts it in a happy state for receiving data. The only hint is that the LED marked L flashes when I open and also when I close the Serial Monitor window. Something is going on there...

Do you know the answer to my problem? I'm downloading the Arduino IDE code now to see if I can find out what's going on.

Edit: I've been using this guide. From looking at the source code app/src/processing/app/Serial.java I'm using the same API and constructing it similarly:

Their code:

port = (SerialPort)portId.open("serial madness", 2000);
input = port.getInputStream();
output = port.getOutputStream();
port.setSerialPortParams(rate, databits, stopbits, parity);
port.addEventListener(this);
port.notifyOnDataAvailable(true);
My code:
SerialPort serialPort = (SerialPort) portId.open("Test", 5000) 

serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE)

serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE)

OutputStream outStream = serialPort.getOutputStream()
I've found no documentation for the CommPortIdentifier.open method - just this javadoc.

I'm going to try mimicking the Arduino IDE code more closely...

Edit: I think I have the solution!

Opening communication with the Arduino resets it! Serial.begin is the first thing my Arduino code does in it's setup method and that seems to need some time to settle down before anything can be read using Serial.read. Furthermore, closing communication with the Arduino resets the damn thing again! I hope this is configurable somewhere...

Edit: Humph. It's by design. You can find out more about it here.

Jan 15, 2010

Test & Code Edit Patterns

I put together a Groovy script to monitor my coding pattern of behaviour. The idea is that I can monitor when I last changed a source file or a test source file. Initially I plan to record a few days of data and graph it. My grand plan is to use my Arduino to drive some LEDs to tell me how long it's been and indicate when I've spent to long coding, writing tests, etc.

newestTest = 0
newestCode = 0

def walk(root) {
root.eachFile { file ->
if (file.name.endsWith(".java")) {
if (file.name.endsWith("Test.java")) {
newestTest = Math.max(newestTest, file.lastModified())
} else {
newestCode = Math.max(newestCode, file.lastModified())
}
}
}
root.eachDir { dir ->
if (!dir.name.startsWith(".")) {
walk(dir)
}
}
}

walk(new File(""))

def now = System.currentTimeMillis()
def code = (now - newestCode)/60000
def test = (now - newestTest)/60000

println "Test (minutes old): $test"
println "Code (minutes old): $code"

Jan 11, 2010

GAE + Gaelyk = Wow

Wow that was easy. I can't believe it just worked. Coming from a world of database schemas I was sure that I was missing something. But no, this just works:

def game = new Entity("game")
game['grid'] = grid // a list of strings
game.save()
And then:
def games = datastore.prepare( new Query("game") ).
asList( withLimit(10) )
That's it! Yes, seriously - zero configuration! Congrats to the GAE and Gaelyk folks!

Jan 4, 2010

Arduino Hack II

I managed a slightly more complicated circuit. Mostly in that I had to have a ton of resistors. It guesses your number as you tell it if your number is higher or lower. Along the way I got bit by a couple of problems:

  • You can't upload a new program while pin 0 is connected to something.
  • Likewise, if you use Serial then pin 1 will be used by it and you shouldn't try and use it yourself.
  • Serial writes junk initially it seems.
Here's what it looked like:

My First Arduino Hack

Yay! I got an Arduino as a present! So what do you do with it? I'm at DorkBotPDX and I'd just got as far as turning on an LED with a push button, and Ward suggested I try getting it to echo back to my a rhythm of clicks. I got that working, and then starting looking around in my starter kit. I had a speaker! Here's my circuit diagram and the code to go with it:

(The mystery component on the left is the buzzer - Fritzing didn't have a close match for that part)

The code:

#define BUZZER 3
#define BUTTON 7

int val = 0;
int old_val = 0;

long times[50];
long i = 0;

void setup() {
pinMode(BUZZER, OUTPUT);
pinMode(BUTTON, INPUT);
}

void loop() {
val = digitalRead(BUTTON);
if ((val == HIGH) && (old_val == LOW)) {
times[i] = millis();
i++;
analogWrite(BUZZER, 64);
delay(10);
}
if ((old_val == HIGH) && (val == LOW)) {
times[i] = millis();
i++;
analogWrite(BUZZER, 0);
delay(10);
}

old_val = val;

if (i > 0 && millis() - times[i-1] > 2000) {
delay(1000);
int state = 0;
for(int y=0; y<i; y++) {
state = 1 - state;
analogWrite(BUZZER, 64*state);
delay(times[y+1]-times[y]);
}
i = 0; // reset
analogWrite(BUZZER, 0);
}
}
Word to the wise: as with coding it pays to take small incremental steps!

Jan 2, 2010

Capturing an Image From Your WebCam in Mac OS X

I had a hard time finding an API I could use on the Mac to programmatically capture a still image from my built in iSight webcam. Finally I found LTI-CIVIL and it's example code CaptureSystemTest. Here I've distilled the example down to the basics (in Groovy). For me the first image in the stream was always black, so the odd part of the code is waiting for the second image capture. You will need lti-civil-no_s_w_t.jar on your classpath in order for this to work -- you can download it here.

import java.awt.image.BufferedImage

import com.lti.civil.*
import com.lti.civil.awt.AWTImageConverter
import com.sun.image.codec.jpeg.*

CaptureSystemFactory factory = DefaultCaptureSystemFactorySingleton.instance();
CaptureSystem system = factory.createCaptureSystem();
system.init();
CaptureDeviceInfo info = system.getCaptureDeviceInfoList().get(0)

CaptureStream captureStream = system.openCaptureDeviceStream(info.getDeviceID());

int count = 0
def capturedImage = null

captureStream.setObserver({ sender, image ->
count++;
if (count > 1) {
capturedImage = image
}
} as CaptureObserver);

captureStream.setVideoFormat(captureStream.enumVideoFormats().get(0));

captureStream.start();
while(!capturedImage) {
Thread.sleep(100);
}
captureStream.stop();
captureStream.dispose();

system.dispose();

BufferedImage bimg = AWTImageConverter.toBufferedImage(capturedImage);

FileOutputStream fos = new FileOutputStream("out.jpg");
JPEGCodec.createJPEGEncoder(fos).encode(bimg);
fos.close();

Dec 28, 2009

Test Your Documentation

Ever found yourself writing code fragments of example usage in your javadocs and wondering how you're going to test it and furthermore how you're going to regress it to make sure that the example code doesn't go stale? Probably not. But if you did you'd probably start down lines like this:

/** <pre class="groovyTestCase">def list = [1,2,3]
* assert list.contains(4)</pre>
*/
If that's what you're looking for then you're in luck! I was adding a number of examples to Groovy's JDK and wanted to automate the testing of the code. So you'll find JavadocAssertionTestSuite in Groovy 1.7.1 when it's released! See GROOVY-3958 for more.