Changeset 403fb9a in orbit


Ignore:
Timestamp:
12/11/12 04:42:08 (7 years ago)
Author:
Steve Castellotti <sc@…>
Branches:
master, RawEEG, Raw_EEG_Plot, Servo, Tab_Interface, pyramid
Children:
e511c74
Parents:
cd5d285
Message:
  • Correctly connects to any Bluetooth MAC address
  • Code comments added to all methods
  • Improved handling of disconnected headsets
Location:
android
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • android/res/values/strings.xml

    r30077ff r403fb9a  
    44    <string name="app_name">Orbit</string> 
    55    <string name="menu_settings">Settings</string> 
    6     <string name="label_attention">Attention</string> 
    7     <string name="label_meditation">Meditation</string> 
     6    <string name="label_attention">Concentration</string> 
     7    <string name="label_meditation">Mental Relaxation</string> 
    88    <string name="label_signal">Signal</string> 
    99    <string name="label_power">Throttle</string> 
  • android/src/info/puzzlebox/orbit/MainActivity.java

    rcd5d285 r403fb9a  
    1515 */ 
    1616 
     17//import java.io.IOException; 
     18//import java.util.ArrayList; 
     19//import java.util.Arrays; 
     20//import java.util.Set; 
     21//import java.util.concurrent.ExecutorService; 
     22//import java.util.concurrent.Executors; 
     23 
    1724import android.media.AudioFormat; 
    1825import android.media.AudioManager; 
     
    2633import android.app.Activity; 
    2734import android.bluetooth.BluetoothAdapter; 
     35//import android.bluetooth.BluetoothDevice; 
    2836//import android.content.Context; 
    2937import android.graphics.Color; 
     
    4351import android.text.method.ScrollingMovementMethod; 
    4452 
    45 //import java.io.IOException; 
    46 //import java.util.concurrent.ExecutorService; 
    47 //import java.util.concurrent.Executors; 
    48  
    4953import com.neurosky.thinkgear.TGDevice; 
    5054 
     
    5660public class MainActivity extends Activity implements SeekBar.OnSeekBarChangeListener { 
    5761 
    58         BluetoothAdapter bluetoothAdapter; 
    59  
     62        /** 
     63         * UI 
     64         */ 
    6065        ProgressBar progressBarAttention; 
    6166        ProgressBar progressBarMeditation; 
     
    6772        Button b; 
    6873 
     74 
     75        /** 
     76         * Logging 
     77         */ 
    6978        String TAG = "MainActivity"; 
    7079 
    71         /**  
    72          * The Bluetooth MAC address is temporarily hard-coded into the source code 
    73          */ 
    74         private static final String MAC_ADDRESS = "D0:DF:9A:69:5D:42"; // MindWave Mobile Dev (p1-dev-60-01) 
    75         //      private static final String MAC_ADDRESS = "9C:B7:0D:5E:E5:6A"; // UK So Television 
    76         //      private static final String MAC_ADDRESS = "9C:B7:0D:75:A8:05"; // Discovery Channel Canada 
    77         //      private static final String MAC_ADDRESS = "9C:B7:0D:90:EB:92"; // Steve Harvey Show 
    7880 
    7981        /** 
     82         * Audio  
    8083         * Currently the flight control command is hard-coded into WAV files 
    8184         * In a future release the tones used to communicate with the infrared dongle 
     
    8487        int audioFile = R.raw.throttle_hover_android_common; 
    8588        //      int audioFile = R.raw.throttle_hover_android_htc_one_x; 
    86  
    87  
    88         TGDevice tgDevice; 
    89         int tgSignal = 0; 
    90         int[] thresholdValuesAttention = new int[101]; 
    91         int[] thresholdValuesMeditation = new int[101]; 
    92         int minimumPower = 0; // minimum power for the helicopter throttle 
    93         int maximumPower = 100; // maximum power for the helicopter throttle 
    94         String currentCommand = "neutral"; 
    95         final boolean rawEnabled = false; 
    96  
    97         //      SerialDevice serial; 
    98         //      int serialBaudRate = 9600; 
    9989 
    10090        private SoundPool soundPool; 
     
    119109 
    120110        /** 
    121          * The device currently in use, or {@code null}. 
     111         * Bluetooth 
    122112         */ 
     113        BluetoothAdapter bluetoothAdapter; 
     114        //      ArrayList<String> pairedBluetoothDevices; 
     115 
     116 
     117        /** 
     118         * Neurosky ThinkGear Device 
     119         */ 
     120        TGDevice tgDevice; 
     121        int tgSignal = 0; 
     122        int[] thresholdValuesAttention = new int[101]; 
     123        int[] thresholdValuesMeditation = new int[101]; 
     124        int minimumPower = 0; // minimum power for the helicopter throttle 
     125        int maximumPower = 100; // maximum power for the helicopter throttle 
     126        String currentCommand = "neutral"; 
     127        final boolean rawEnabled = false; 
     128 
     129 
     130        /** 
     131         * USB Serial 
     132         */ 
     133        //      SerialDevice serial; 
     134        //      int serialBaudRate = 9600; 
     135 
     136        /** The device currently in use, or {@code null}. */ 
    123137        //      private UsbSerialDriver mSerialDevice; 
    124138 
    125         /** 
    126          * The system's USB service. 
    127          */ 
     139        /** The system's USB service. */ 
    128140        //      private UsbManager mUsbManager; 
    129141 
    130  
     142        /** Thread Service */ 
    131143        //      private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); 
    132144 
     
    153165        @Override 
    154166        public void onCreate(Bundle savedInstanceState) { 
    155                 /** Called when the activity is first created. */ 
     167 
     168                /**  
     169                 * This method called when the program is first loaded 
     170                 * or when it is re-loaded into memory after being killed 
     171                 * by the Task Manager. 
     172                 */ 
     173 
     174 
     175                /** 
     176                 * Configure the UI elements 
     177                 */ 
    156178                super.onCreate(savedInstanceState); 
    157179                setContentView(R.layout.activity_main); 
     
    206228 
    207229 
    208                 bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
    209                 if(bluetoothAdapter == null) { 
    210                         // Alert user that Bluetooth is not available 
    211                         Toast.makeText(this, "Bluetooth not available", Toast.LENGTH_LONG).show(); 
    212                         finish(); 
    213                         return; 
    214                 } else { 
    215                         /** create the TGDevice */ 
    216                         tgDevice = new TGDevice(bluetoothAdapter, handler); 
    217                 } 
    218  
    219  
    220                 //              mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE); 
    221                 //              serial = new SerialDevice(); 
    222                 //              serial.setSerialDevice(mSerialDevice); 
    223  
    224  
    225                 //              genTone(); 
    226  
     230                /** 
     231                 * Prepare audio stream 
     232                 */ 
    227233 
    228234                /** Set the hardware buttons to control the audio output */ 
     
    239245                soundID = soundPool.load(this, audioFile, 1); 
    240246 
     247                //              genTone(); 
     248 
     249 
     250                /** 
     251                 * Prepare Bluetooth and NeuroSky ThinkGear EEG interface 
     252                 */ 
     253                bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
     254 
     255                if(bluetoothAdapter == null) { 
     256                        // Alert user that Bluetooth is not available 
     257                        Toast.makeText(this, "Bluetooth not available", Toast.LENGTH_LONG).show(); 
     258                        finish(); 
     259                        return; 
     260                } else { 
     261                        /** create the TGDevice */ 
     262                        tgDevice = new TGDevice(bluetoothAdapter, handler); 
     263 
     264                        /** Retrieve a list of paired Bluetooth adapters */ 
     265                        //                      Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices(); 
     266                        //                      pairedBluetoothDevices = new ArrayList<String>(Arrays.asList(pairedDevices.toString())); 
     267                        /**  
     268                         * NOTE: To get device names iterate through pairedBluetoothDevices  
     269                         * and call the getName() method on each BluetoothDevice object.  
     270                         */ 
     271                } 
     272 
     273 
     274                /** 
     275                 * Prepare USB Serial 
     276                 */ 
     277                //              mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE); 
     278                //              serial = new SerialDevice(); 
     279                //              serial.setSerialDevice(mSerialDevice); 
     280 
    241281 
    242282        } // onCreate 
     
    245285        @Override 
    246286        protected void onResume() { 
     287 
     288                /** 
     289                 * This method is called when the Activity has been  
     290                 * resumed after being placed in the background 
     291                 */ 
     292 
    247293                super.onResume(); 
    248                 /**       This section handles the USB Serial device when the program is resumed */ 
     294 
     295                /** This section handles the USB Serial device when the program is resumed */ 
    249296                //              mSerialDevice = UsbSerialProber.acquire(mUsbManager); 
    250297                //              //        Log.d(TAG, "Resumed, mSerialDevice=" + mSerialDevice); 
     
    273320                //                      appendTextAndScroll("Serial device: " + mSerialDevice + "\n"); 
    274321                //              } 
    275                 onDeviceStateChange(); 
     322                // 
     323                //              onDeviceStateChange(); 
    276324        } 
    277325 
     
    280328        public void onDestroy() { 
    281329 
     330                /** 
     331                 * This method is called when the Activity is terminated 
     332                 */ 
     333 
    282334                tgDevice.close(); 
    283335 
     336                /** Handle USB Serial */ 
    284337                //              if (mSerialDevice != null) { 
    285338                //                      try { 
     
    296349 
    297350        private void appendTextAndScroll(String text) { 
     351 
     352                /**  
     353                 * This method is called to write a status message 
     354                 * to the text display area, then automatically 
     355                 * scroll to the bottom of visible text. 
     356                 */ 
     357 
    298358                if (tv != null) { 
    299359                        //              tv.append(text + "\n"); 
     
    312372        public void setButtonText(int buttonId, String text) { 
    313373 
     374                /** 
     375                 * Shortcut for changing the text on a button 
     376                 */ 
     377 
    314378                Button button = (Button) findViewById(buttonId); 
    315379                button.setText(text); 
     
    329393 
    330394        public void onStartTrackingTouch(SeekBar seekBar) { 
     395 
     396                /** 
     397                 * Method required by SeekBar.OnSeekBarChangeListener 
     398                 */ 
     399 
    331400                //appendTextAndScroll(getString(R.string.seekbar_tracking_on)); 
     401 
    332402        } // onStartTrackingTouch 
    333403 
    334404 
    335405        public void onStopTrackingTouch(SeekBar seekBar) { 
     406 
     407                /** 
     408                 * Method required by SeekBar.OnSeekBarChangeListener 
     409                 */ 
     410 
    336411                //appendTextAndScroll(getString(R.string.seekbar_tracking_off)); 
     412 
    337413        } // onStopTrackingTouch 
    338414 
    339415 
    340         private void stopIoManager() { 
    341                 //              if (mSerialIoManager != null) { 
    342                 //                      //            Log.i(TAG, "Stopping io manager .."); 
    343                 //                      mSerialIoManager.stop(); 
    344                 //                      mSerialIoManager = null; 
    345                 //              } 
    346         } // stopIoManager 
    347  
    348  
    349         private void startIoManager() { 
    350                 //              if (mSerialDevice != null) { 
    351                 //                      //            Log.i(TAG, "Starting io manager .."); 
    352                 //                      mSerialIoManager = new SerialInputOutputManager(mSerialDevice, mListener); 
    353                 //                      mExecutor.submit(mSerialIoManager); 
    354                 //              } 
    355         } // startIoManager 
    356  
    357  
    358         private void onDeviceStateChange() { 
    359                 stopIoManager(); 
    360                 startIoManager(); 
    361         } // onDeviceStateChange 
     416        //      private void stopIoManager() { 
     417        //               
     418        //              /** 
     419        //               * Method required by USB Serial 
     420        //               */ 
     421        //               
     422        //              if (mSerialIoManager != null) { 
     423        //                      //            Log.i(TAG, "Stopping io manager .."); 
     424        //                      mSerialIoManager.stop(); 
     425        //                      mSerialIoManager = null; 
     426        //              } 
     427        //      } // stopIoManager 
     428 
     429 
     430        //      private void startIoManager() { 
     431        //       
     432        //              /** 
     433        //               * Method required by USB Serial 
     434        //               */ 
     435        //       
     436        //              if (mSerialDevice != null) { 
     437        //                      //            Log.i(TAG, "Starting io manager .."); 
     438        //                      mSerialIoManager = new SerialInputOutputManager(mSerialDevice, mListener); 
     439        //                      mExecutor.submit(mSerialIoManager); 
     440        //              } 
     441        //      } // startIoManager 
     442 
     443 
     444        //      private void onDeviceStateChange() { 
     445        //               
     446        //              /** 
     447        //               * Called by onResume() to manage USB Serial 
     448        //               */ 
     449        //               
     450        //                              stopIoManager(); 
     451        //                              startIoManager(); 
     452        //      } // onDeviceStateChange 
    362453 
    363454 
     
    365456 
    366457                /** 
    367                  * Handles messages from TGDevice 
     458                 * Handles data packets from NeuroSky ThinkGear device 
    368459                 */ 
    369460 
     
    378469                                        break; 
    379470                                case TGDevice.STATE_CONNECTING: 
    380                                         Log.d(TAG, "Connecting to EEG: " + MAC_ADDRESS); 
    381                                         appendTextAndScroll("Connecting to EEG: " + MAC_ADDRESS + "\n"); 
     471                                        //                                      Log.d(TAG, "Connecting to EEG: " + MAC_ADDRESS); 
     472                                        //                                      appendTextAndScroll("Connecting to EEG: " + MAC_ADDRESS + "\n"); 
     473                                        Log.d(TAG, "Connecting to EEG"); 
     474                                        appendTextAndScroll("Connecting to EEG\n"); 
    382475                                        break; 
    383476                                case TGDevice.STATE_CONNECTED: 
     
    398491                                        Log.d(TAG, "EEG Disconnected"); 
    399492                                        appendTextAndScroll("EEG Disconnected\n"); 
     493                                        disconnectHeadset(); 
    400494                                        break; 
    401495                                } 
     
    455549        public void connectHeadset(View view) { 
    456550 
     551                /** 
     552                 * Called when the "Connect" button is pressed 
     553                 */ 
     554 
    457555                if (tgDevice.getState() != TGDevice.STATE_CONNECTING && tgDevice.getState() != TGDevice.STATE_CONNECTED) 
    458556                        tgDevice.connect(rawEnabled); 
    459557 
    460558                else if (tgDevice.getState() == TGDevice.STATE_CONNECTED) 
     559                        /** "Disconnect" button was pressed */ 
    461560                        disconnectHeadset(); 
    462561 
     
    466565 
    467566        public void disconnectHeadset() { 
     567 
     568                /** 
     569                 * Called when "Disconnect" button is pressed 
     570                 */ 
     571 
    468572                tgDevice.stop(); 
    469573                tgDevice.close(); 
     
    474578                progressBarPower.setProgress(0); 
    475579                setButtonText(R.id.button1, "Connect"); 
    476                 appendTextAndScroll("EEG Disconnected\n"); 
    477580        } // disconnectHeadset 
    478581 
     
    503606 
    504607        public void updatePowerThresholds() { 
     608 
     609                /** 
     610                 * The "Power" level refers to the Puzzlebox Orbit helicopter's 
     611                 * throttle setting. Typically this is an "off" or "on" state, 
     612                 * meaning the helicopter is either flying or not flying at all. 
     613                 * However this method could be used to increase the throttle 
     614                 * or perhaps the forward motion of the helicopter to a level 
     615                 * proportionate to how far past their target brainwave levels 
     616                 * are set (via the progress bar sliders). 
     617                 */ 
    505618 
    506619                int power; 
     
    563676        public int calculateSpeed() { 
    564677 
     678                /** 
     679                 * This method is used when calculating whether 
     680                 * or not the "Attention" or "Meditation" levels 
     681                 * are sufficient to trigger the helicopter throttle 
     682                 */ 
     683 
    565684                int attention = progressBarAttention.getProgress(); 
    566685                int meditation = progressBarMeditation.getProgress(); 
     
    587706        public void updatePower() { 
    588707 
     708                /** 
     709                 * This method updates the power level of the  
     710                 * "Throttle" and triggers the audio stream 
     711                 * which is used to fly the helicopter 
     712                 */ 
     713 
    589714                int new_speed = calculateSpeed(); 
    590715                String command = ""; 
     
    593718                if (new_speed > 0) { 
    594719 
     720                        /** Start playback of audio control stream */ 
    595721                        if (currentCommand == "neutral") { 
    596722                                playControl(); 
     
    601727                } else { 
    602728 
    603                         //                      if (currentCommand == "hover") { 
    604                         //                              stopControl(); 
    605                         //                      } 
     729                        /** Land the helicopter */ 
    606730                        stopControl(); 
    607731 
     
    612736                Log.v(TAG, "Command: " + command); 
    613737 
    614                 //              String command = getPowerCommand(new_speed); 
    615  
    616                 //              writeCommand(command); 
    617  
     738                /** This sequence is used for managing the USB Serial control */ 
     739                //              command = getPowerCommand(new_speed); 
     740                // 
    618741                //              if (mSerialDevice != null) { 
    619742                //                      serial.setCommand(command); 
     
    625748 
    626749 
    627         public String getPowerCommand(int speed) { 
    628  
    629                 String command = "%"; 
    630  
    631                 if (speed >= 100) 
    632                         command = "%100"; 
    633                 else if (speed >= 10) 
    634                         command = "%0" + speed; 
    635                 else if (speed >= 0) 
    636                         command = "%00" + speed; 
    637                 else 
    638                         command = "%000"; 
    639  
    640                 Log.v(TAG, "Power command: " + command); 
    641                 //              Log.v(TAG, "Command for serial device: " + command); 
    642                 //              appendTextAndScroll("Command for serial device: " + command + "\n"); 
    643  
    644                 return(command); 
    645  
    646         } // getPowerCommand 
     750        //      public String getPowerCommand(int speed) { 
     751        //               
     752        //              /** 
     753        //               * This method is used to set the throttle 
     754        //               * level using USB Serial to communicate 
     755        //               * with an Arduino device 
     756        //               */ 
     757        // 
     758        //              String command = "%"; 
     759        // 
     760        //              if (speed >= 100) 
     761        //                      command = "%100"; 
     762        //              else if (speed >= 10) 
     763        //                      command = "%0" + speed; 
     764        //              else if (speed >= 0) 
     765        //                      command = "%00" + speed; 
     766        //              else 
     767        //                      command = "%000"; 
     768        // 
     769        //              Log.v(TAG, "Power command: " + command); 
     770        //              //              Log.v(TAG, "Command for serial device: " + command); 
     771        //              //              appendTextAndScroll("Command for serial device: " + command + "\n"); 
     772        // 
     773        //              return(command); 
     774        // 
     775        //      } // getPowerCommand 
    647776 
    648777 
    649778        public void playControl() { 
    650                  
     779 
    651780                /**  
    652781                 * Play audio control file 
     
    668797 
    669798        public void stopControl() { 
    670                  
    671                 /** 
    672                  * Stop playing audio file 
     799 
     800                /** 
     801                 * Stop playing audio control file 
    673802                 */ 
    674803 
     
    684813 
    685814        void genTone(){ 
    686                 /** fill out the array */ 
     815                 
     816                /** 
     817                 * Generate a carrier signal for communication 
     818                 * with the IR Dongle 
     819                 */ 
     820                 
     821                /** Fill out the array */ 
    687822                for (int i = 0; i < numSamples; ++i) { 
    688823                        sample[i] = Math.sin(2 * Math.PI * i / (sampleRate/freqOfTone)); 
     
    690825 
    691826                /** 
    692                  *  convert to 16 bit pcm sound array 
    693                  *  assumes the sample buffer is normalized. 
     827                 *  Convert to 16 bit pcm sound array. 
     828                 *  The sample buffer is assumed to be normalized. 
    694829                 */ 
    695830                int idx = 0; 
    696831                for (final double dVal : sample) { 
    697                         /** scale to maximum amplitude */ 
     832                        /** Scale to maximum amplitude */ 
    698833                        final short val = (short) ((dVal * 32767)); 
    699                         /** in 16 bit wav PCM, first byte is the low order byte */ 
     834                        /** In 16 bit wav PCM, first byte is the low order byte */ 
    700835                        generatedSnd[idx++] = (byte) (val & 0x00ff); 
    701836                        generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8); 
     
    706841 
    707842        void playTone(){ 
     843                 
     844                /** 
     845                 * Play the generated carrier signal 
     846                 */ 
     847                 
    708848                final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
    709849                                //                sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
     
    720860 
    721861        public void demoMode(View view) { 
     862                 
     863                /** 
     864                 * Demo mode is called when the "Test Helicopter" button is pressed. 
     865                 * This method can be easily adjusted for testing new features 
     866                 * during development.  
     867                 */ 
    722868 
    723869                //              playTone(); 
Note: See TracChangeset for help on using the changeset viewer.