As Halloween is approaching and the aftternoons grow rainy, it’s time for some tinkering. So, why not try to get the pumpkins a bit more interesting than cut-out veggies?
Getting some tinkerers together was no problem, so we got three families with kids, 4 pumpkins, one LEGO Mindstorms set and 2 Arduinos to start with. I recently discovered the awesome HiTechnic Prototype board, turning the LEGO Mindstorms set into a full IO-enabled prototyping experience with the added convenience of the thought-through LEGO sensors and the comfort of the LeJOS Java OS for the Brick. You get 6 analog inputs and 6 digital input or output pins – not bad.
So, I got one of these and started with wrapping the Proto Sensor into a LeJOS java class using the I2CSensor base. The communication protocol is fairly straightforward and not tight to the HiTechnic plugin software for the LEGO IDE they provide:
package org.peter; import lejos.nxt.I2CPort; import lejos.nxt.I2CSensor; public class ProtoSensor extends I2CSensor { public static final int A0 = 0x42; public static final int A1 = 0x44; public static final int A2 = 0x46; public static final int A3 = 0x48; public static final int A4 = 0x4A; public static final int DOUBLE = 2; public static final int SINGLE = 1; public static final int DIGITAL_READ = 0x4C; public static final int DIGITAL_WRITE = 0x4D; public static final int IO_MODE = 0x4E; public static final int PIN_OUTPUT = 1; public static final int PIN_INPUT = 0; public static final int B0 = 1; private byte[] buf = new byte[2]; public ProtoSensor(I2CPort port) { super(port); } public ProtoSensor(I2CPort port, int mode) { super(port, mode); } /** * Reads A0 Analog input * * @return byte[2], first byte is high, second byte low part */ public byte[] readA0() { return getAnalog(A0); } private byte[] getAnalog(int address) { int res = getData(address, buf, DOUBLE); if (res != 0) { System.out.println("Error: " + res); } return buf; } /** * * @return the one byte read on all digital PINs on bits 0-5. bist 6 and 7 * will be ignored */ public byte[] readDigital() { byte[] result = new byte[8]; int res = getData(DIGITAL_READ, result, SINGLE); if (res != 0) { System.out.println("Error: " + res); } return result; } /** * set the input (0) or output (1) mode for the digital pins * * @param d0 * @param d1 * @param d2 * @param d3 * @param d4 * @param d5 * @return 0 if success, fail otherwise */ public int setDigitalModes(int d0, int d1, int d2, int d3, int d4, int d5) { int mode = d5 * 32 + d4 * 16 + d3 * 8 + d2 * 4 + d1 * 2 + d0 * 1; return sendData(IO_MODE, (byte) mode); } public int setDigitalOutput(int d0, int d1, int d2, int d3, int d4, int d5) { int mode = d5 * 32 + d4 * 16 + d3 * 8 + d2 * 4 + d1 * 2 + d0 * 1; return sendData(DIGITAL_WRITE, (byte) mode); } public boolean isHigh(int pin) { return (readDigital()[0] & pin)==pin; } }
Now, you can communicate with the Prototype sensor with only minimal hassle. The first test was to just have a light resistor connected to one analog input, and light a LED upon shadowing it (see here) . Oskar and me settled on listening for the touch sensor to be pressed (sticking through the nose of the pumpkin). On press, we simply light the 2 LED-eyes (cool blue color) and play a short “Happy Halloween” file tw times that Oskar has been recording on an old iPaq, transforming it with Audacity into 8bit ECM WAV that the LEGO brick can play:
import java.io.File; import lejos.nxt.Button; import lejos.nxt.SensorPort; import lejos.nxt.Sound; import lejos.nxt.TouchSensor; import org.peter.ProtoSensor; public class Helloween { private static ProtoSensor proto; private static TouchSensor touch; public static void main(String[] args) throws Exception { proto = new ProtoSensor(SensorPort.S1); touch = new TouchSensor(SensorPort.S2); // set all digital pins to OUT proto.setDigitalModes(1, 1, 1, 1, 1, 1); while (!Button.ESCAPE.isPressed()) { if (touch.isPressed()) { proto.setDigitalOutput(1, 1, 1, 1, 1, 1); sayHello(); } else { proto.setDigitalOutput(0, 0, 0, 0, 0, 0); } } } private static void sayHello() { File hello = new File("helloshort.wav"); try { Sound.playSample(hello, 100); Thread.sleep(2000); Sound.playSample(hello, 100); Thread.sleep(1500); } catch (InterruptedException e) { } } }
And voilá, the super-scary pumpkin is done and we even got time for some Kanelbullar and hot chocolate!
The competing comic-art-eyes super-cool-pumpkin is made by David Cuartilles of Arduino and 1Scale1 fame. It won the competition without problems – thanks all Pumpkin Pimpers for a great 3 hours with the kids!
Happy Halloween!
/peter