Tag Archives: Android

Remote Fireworks Launcher

P1010062

The goal of this project was to use a tablet computer to remotely ignite fireworks. The components of the system include:

A bluetooth serial profile is used to wirelessly communicate between the tablet and the control box. For this reason an Android tablet (Motorola XOOM) was used because iOS did not support the serial profile on bluetooth. This provides a range of about 10 yards between the operator with the tablet and the control box. Cabling between the control box and launch box and then launch box to ignites provides an additional 10-20 feet.

Click on the links above for details of each section.

Fireworks Tablet App

Photo Jul 06, 9 46 27 PM

This Android app is the UI for the Fireworks launcher project. Each igniter is represented by a circular button.

UI Description

The row color & outer circle color correspond to the cable bundle & wire color codes respectively. The names of the firework appear in the upper part of the circle and the connection status in the bottom. A green center indicates the igniter status is online, blue have been marked as ignited.

To trigger an ignition, the operator presses the center of a button and drags the finger outward until the outer circle turns red. The further away the finger is dragged the faster a pulsing ring will animate until the distance is sufficient to launch and the outer circle changes to red. Releasing the finger at this point will trigger an ignition sequence. To cancel the touch, the operator can drag the finger closer to the start point until the outer circle turns back to green. Ignite indicatorOnce triggered, the button will flash red/white as long as the igniter is powered (5 seconds by default).

Code Segments

The bluetooth device ID is hard coded in the sources. This was found by browsing for the device with the SENA BTerm app and viewing the properties. When the Connect button is pressed, a connection is made using the bluetooth stack. code segments below.

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;

    private BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter();
    private BluetoothDevice _btdevice;
    private BluetoothSocket _btsock = null;

   OnClickListener mConnectListener = new OnClickListener() {
        public void onClick(View v) {
            _bluetooth.enable();
            _btdevice = _bluetooth.getRemoteDevice("00:12:03:09:70:20");
    		try {
    			ParcelUuid[] uuids = _btdevice.getUuids();
    			_btsock = _btdevice.createInsecureRfcommSocketToServiceRecord (UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
    			_btsock.connect();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
        }
    };

// when ready to launch
String out = String.format("Launch %d", activeLaunch);
_btsock.getOutputStream().write(out.getBytes());
_btsock.getOutputStream().write(13);

Interpreting the return status stream of data. Each character represents an ignition status that is set into the button state for color coding and animation.

for (int i = 0; i < acount; i++) {
  String arg = args[i];
  if (arg.length() > 0) {
    // first char should be [
    if (arg.charAt(0) != '[') continue;
    int sysstate = arg.charAt(1) - '0';
    FireLaunch.this.controlStatus = sysstate;
    int arglen = arg.length();
    for (int b = 0; b < buttonCount; b++)
    {
      int buttonState = (b < arglen) ? arg.charAt(b + 2) : 2;
      LaunchButton lb = (LaunchButton) MainLayout.findViewWithTag("Button" + Integer.toString(b));
      int displayState = 0;
      switch (buttonState) {
        case '0' : displayState = 3; break; // ready
        case '1' : displayState = 10; break; // launching
        case '2' : displayState = 2; break; // control error/offline
      }
      if (lb != null) lb.setState(displayState);
    }
    lastCloseFrame = SystemClock.elapsedRealtime();
    argIndex++;
  }
}