Using the Rasp Pi to make Halloween really spooky
The Ghost Program
The entire Halloween ghost program is found on the FTP site [2]. As is typically the case with Java imports, it defines the class containing the main()
method. All of the data needed by the LEDs for creating the eyes and the mouth are found in the two-dimensional array eye[][]
. The task of calculating values for display is simple but nonetheless time intensive.
Listing 5 shows the crucial section, which defines an input port for the PIR sensor. You should attach an event listener to this port by means of an anonymous class of type GpioPinListenerDigital()
. In this class, you overwrite the method handleGpioPinDigitalStateChangeEvent()
with your own code.
Listing 5
Define PIR Input Port
01 final static File soundFile = new File("gost.wav"); 02 static AudioInputStream audioIn=null; 03 static Clip clip=null; 04 05 public static void main(String args[])throws Exception { 06 final GpioController gpio = GpioFactory.getInstance(); 07 final GpioPinDigitalInput pir = gpio.provisionDigitalInputPin(RaspiPin.GPIO_00,PinPullResistance.PULL_DOWN); 08 09 audioIn = AudioSystem.getAudioInputStream(soundFile); 10 clip = AudioSystem.getClip(); 11 clip.open(audioIn); 12 13 pir.addListener(new GpioPinListenerDigital() { 14 @Override 15 public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) { 16 if((event.getState()==PinState.HIGH) && !running) { 17 running=true; 18 System.out.println("wake up"); 19 eyeOpen(); 20 slp(1000); 21 gost.clip.setFramePosition(0); 22 gost.clip.start(); 23 spuk(); 24 spuk(); 25 spuk(); 26 eyeClose(); 27 eyeInit(); 28 slp(60000); 29 gost.clip.stop(); 30 running=false; 31 } 32 } 33 }); 34 35 int fd = Spi.wiringPiSPISetup(SPI_CHANNEL, 1000000); 36 37 if (fd <= -1) {System.out.println("Can't init SPI");return;} 38 init(SPI_CHANNEL, MODULES, INTENSITY); 39 initBuffer(); 40 eyeInit(); 41 SoftPwm.softPwmCreate( 1, 0, 100 ); 42 SoftPwm.softPwmCreate( 2, 0, 100 ); 43 SoftPwm.softPwmWrite( 1, 20 ); 44 SoftPwm.softPwmWrite( 2, 10 ); 45 SoftPwm.softPwmWrite( 1, 0 ); 46 SoftPwm.softPwmWrite( 2, 0 ); 47 slp(1000*60*60*10);// the program remains active for 10 hours 48 } //main
The first thing to do is to check that the pin is set to HIGH
. This prevents the ghost from continuing to shriek when the sensor switches off. The computer should not execute the method more than once, so the script sets the running
variable to prevent this from happening. The methods that follow are named so that it is self-evident what you should do.
The program plays the WAV file asynchronously. It therefore continues to run as soon as playback begins and does not wait for the audio file to come to an end. This occurs because it calls the spuk()
method three times in succession. The time needed for these three calls corresponds almost exactly to the playback time for the WAV file.
As a result, everything important happens in this section. The slp()
method involves a wrapper for the Java method Thread.sleep()
, which hides the bothersome try
/catch
. At the end of the handleGpioPinDigitalStateChangeEvent()
method, you can recognize the call to slp()
. It prevents the ghost from shrieking on and on. The predefined length of time during which the ghost should shriek can be adapted as needed.
The main()
method contains the steps for initializing the hardware. Listing 6 shows another important section in the code, which is the copyBufferToLed()
method. This transmits the local buffer, found in the buffer[][]
variables, by way of the SPI bus to the LED module. All of the methods responsible for the animation, like eyeClose()
, only work initially on the local buffer.
Listing 6
Transmit Local Buffer
01 public static void copyBufferToLed(){ 02 byte packet[] = new byte[MODULES*2]; 03 for (int row = 0; row <= 7; row++) { 04 for (int col = 0; col < MODULES; col++) { 05 packet[0+(2*col)] = (byte)(row+1); 06 packet[1+(2*col)] = (byte) buffer[col][row]; 07 Spi.wiringPiSPIDataRW(0, packet, MODULES * 2); 08 } 09 } 10 }
The servomotors are controlled with the SoftPwm
methods from the Pi4J library. This works surprisingly well. If you would like to have more exact control over the servos, it pays to review the ServoBlaster project.
Last but not least, a series of methods are responsible for initializing the SPI devices. You should study the data sheet for the MAX7219 [9] before working with it. Then, you transfer the program to the Rasp Pi (e.g., using SFTP). Next, the program is compiled on the Rasp Pi and then booted (Listing 7). Now nothing is in the way of the ghost scaring those who venture near.
Listing 7
Compile and Boot Program
$ pi4j -c gost.java + javac -classpath '.:classes:*:classes:/opt/pi4j/lib/*' -d . gost.java $ pi4j -r gost + sudo java -classpath '.:classes:*:classes:/opt/pi4j/lib/*' gost
Conclusion
This project once again shows what the Rasp Pi is capable of doing. The program proves that the Pi4J library provides elegant access to the hardware. The software presented in this article is just one example of how a ghost like the one described here can be created. It can be adapted and expanded as desired. For example, the ghost could howl more gruesomely or be integrated into its environment. It is relatively unlikely, however, that you can have the ghost open the door for trick or treaters and hand out candy. Nonetheless, Halloween visitors should enjoy this Halloween Rasp Pi creation.
Infos
- LED module: http://www.banggood.com/5Pcs-MAX7219-Dot-Matrix-Module-MCU-LED-Control-Module-Kit-For-Arduino-p-1031709.html
- Code, videos of the ghost in action, sound file, and circuit diagrams: ftp://ftp.linux-magazine.com/pub/listings/raspberry-pi-geek.com/18
- Header strip: http://www.ebay.com/bhp/female-header
- AC/DC converter: http://www.ebay.com/itm/5V-700mA-AC-DC-Power-Supply-Buck-Converter-Step-Down-Module-/371064465501
- PIR sensor: http://www.electrodragon.com/product/pir/
- wiringPi: https://projects.drogon.net
- Oracle Java: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
- WinSCP: https://winscp.net/eng/download.php
- Datasheet for MAX7219: https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf
« Previous 1 2 3 4 Next »