Search code examples
javaandroidandroid-things

Android Things onTouch doesnt release GPIO


I am using Android Things v1 and trying to use an on-screen Button to activate a motor as long as the button is pressed (tap & long press).

The problem I have is once the button is pressed the motor will not stop. I would like it to stop once the button is released.

Here is the button code:

    mtrbtnGD.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            try {
                mtrGpio = manager.openGpio("BCM24");
                mtrGpio.setEdgeTriggerType(Gpio.EDGE_NONE);
                mtrGpio.setActiveType(Gpio.ACTIVE_HIGH);
                mtrGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
                mtrGpio.setValue(true);
                Log.i(TAG, "Motor started");

            }
            catch (IOException e) {
                Log.w(TAG, "Unable to access GPIO", e);
            }
           return true;
        }
    });

EDIT:

Here is the new code from Sam's reply:

public class MainActivity extends Activity {

private Gpio mtrGpio;
private GestureDetector mtrbtnGD;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button mtrbtnGD = (Button) findViewById(R.id.mtrbtn);
    Button closebtn = (Button) findViewById(R.id.closebtn);
    Button stopmtrbtn = (Button) findViewById(R.id.stopmtrbtn);

    final PeripheralManager manager = PeripheralManager.getInstance();
    List<String> portList = manager.getGpioList();
    if (portList.isEmpty()) {
        Log.i(TAG, "No GPIO port available on this device.");
    } else {
        Log.i(TAG, "List of available ports: " + portList);
    }

    mtrbtnGD.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            try {

                switch(event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        // PRESSED
                        mtrGpio = manager.openGpio("BCM24");
                        mtrGpio.setEdgeTriggerType(Gpio.EDGE_NONE);
                        mtrGpio.setActiveType(Gpio.ACTIVE_HIGH);
                        mtrGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
                        mtrGpio.setValue(true);
                        Log.i(TAG, "Motor started");
                        return true; // if you want to handle the touch event
                    case MotionEvent.ACTION_UP:
                        // RELEASED
                        mtrGpio.close();

                        return true; // if you want to handle the touch event
                }



            }
            catch (IOException e) {
                Log.w(TAG, "Unable to access GPIO", e);
            }
           return true;
        }
    });

The motor still doesn't stop when I release the on-screen button.


Solution

  • close() closes your connection to the GPIO peripheral, it does not change the value of that connection before closing it. You need to use setValue(false); as so:

                   switch(event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            // PRESSED
                            mtrGpio = manager.openGpio("BCM24");
                            mtrGpio.setEdgeTriggerType(Gpio.EDGE_NONE);
                            mtrGpio.setActiveType(Gpio.ACTIVE_HIGH);
                            mtrGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
                            mtrGpio.setValue(true);
                            Log.i(TAG, "Motor started");
                            return true; // if you want to handle the touch event
                        case MotionEvent.ACTION_UP:
                            // RELEASED
                            mtrGpio.setValue(false); // ADD THIS
                            mtrGpio.close();
    
                            return true; // if you want to handle the touch event
                    }
    

    Ideally, if you expect the motor to be turned on and off a lot, you should keep the connection open.

    public class MainActivity extends Activity {
    
    private Gpio mtrGpio;
    private GestureDetector mtrbtnGD;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        Button mtrbtnGD = (Button) findViewById(R.id.mtrbtn);
        try {
          PeripheralManager manager = PeripheralManager.getInstance();
          mtrGpio = manager.openGpio("BCM24");
          mtrGpio.setEdgeTriggerType(Gpio.EDGE_NONE);
          mtrGpio.setActiveType(Gpio.ACTIVE_HIGH);
          mtrGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
        } catch (IOException e) {
          throw new IllegalStateException("cannot open gpio", e);
        }
    
        mtrbtnGD.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                try {
                   switch(event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            // PRESSED
                            mtrGpio.setValue(true);
                            Log.i(TAG, "Motor started");
                            return true; 
                        case MotionEvent.ACTION_UP:
                            // RELEASED
                            mtrGpio.setValue(false);
                            return true; 
                    }
                } catch (IOException e) {
                    Log.w(TAG, "Unable to access GPIO", e);
                }
               return true;
            }
        });
    }
    
    @Override
    protected void onDestroy() {
       try {
          mtrGpio.close();
       } catch (IOException ignore) {
          Log.w(TAG, "Unable to close GPIO", ignore);
       }
       super.onDestroy();
    }