Pimp-my-Pumpkin!

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

Leave a Reply

Close Menu