Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speaker only works once #77

Open
gustavotemple opened this issue Oct 22, 2017 · 9 comments
Open

Speaker only works once #77

gustavotemple opened this issue Oct 22, 2017 · 9 comments

Comments

@gustavotemple
Copy link

gustavotemple commented Oct 22, 2017

Hello @mangini,

I am using the last version of the speaker (0.3), it works very well when I interact with others hardware components, but, when I put inside a firebase callback, the method "stop" works only once.

Do you know why?

package com.example.androidthings.doorbell;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.things.contrib.driver.pwmspeaker.Speaker;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.io.IOException;

public class DoorbellActivity extends Activity {

    private static final String TAG = DoorbellActivity.class.getSimpleName();
    private static final String ALARM = "alarm";
    private static final int FREQ = 7000;

    private Speaker mSpeaker;
    private DatabaseReference alarmRef;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "Doorbell Activity created.");

        try {
            mSpeaker = new Speaker(BoardDefaults.getPwmPin());
            mSpeaker.stop();

            alarmRef = FirebaseDatabase.getInstance().getReference().child(ALARM);
            alarmRef.addValueEventListener(alarmListener);
        } catch (IOException e) {
            Log.e(TAG, e.toString());
        }
    }

    private final ValueEventListener alarmListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.i(TAG, "alarmListener");
            Boolean value = (Boolean) dataSnapshot.getValue();
            try {
                if (value) {
                    mSpeaker.play(FREQ);
                } else {
                    mSpeaker.stop();
                }
            } catch (IOException e) {
                Log.e(TAG, e.toString());
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e(TAG, "onCancelled: " + databaseError);
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mSpeaker != null) {
            try {
                mSpeaker.stop();
                mSpeaker.close();
            } catch (IOException e) {
                Log.e(TAG, "Error closing speaker", e);
            } finally {
                mSpeaker = null;
            }
        }
    }
}
@Fleker
Copy link
Contributor

Fleker commented Oct 24, 2017

Calling stop appears to disable the PWM but shouldn't completely prevent it from being inaccessible.

This may be a bug in the platform. Can you try a few other approaches and file a bug if your issue continues? This does appear to be unexpected behavior.

@gustavotemple
Copy link
Author

@Fleker,

I tried to do this approach (Handler.post) too:

https://github.com/androidthings/drivers-samples/blob/32f4ef79318afc922ba902da5524e709d16feb30/pwmspeaker/src/main/java/com/example/androidthings/driversamples/SpeakerActivity.java#L54

But the result was the same (the error happen just when I put inside a firebase callback)

@Fleker
Copy link
Contributor

Fleker commented Oct 24, 2017

So when you tried the sample, the speaker did stop and restart as expected?

@gustavotemple
Copy link
Author

Yes, because of this line:

https://github.com/androidthings/drivers-samples/blob/32f4ef79318afc922ba902da5524e709d16feb30/pwmspeaker/src/main/java/com/example/androidthings/driversamples/SpeakerActivity.java#L98

The speaker stop and restart by itself, there isn't something external controlling the flow.

@Fleker
Copy link
Contributor

Fleker commented Oct 25, 2017

Maybe there's a threading issue

@gustavotemple
Copy link
Author

gustavotemple commented Oct 25, 2017

@Fleker, do you mean in the Firebase ValueEventListener thread?

@Fleker
Copy link
Contributor

Fleker commented Oct 26, 2017

The sample uses a separate handler for playback events. Can you copy that design and see whether that allows the speaker to work as expected?

@gustavotemple
Copy link
Author

The same thing happen, the "stop" only works once:

package com.example.androidthings.doorbell;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;

import com.google.android.things.contrib.driver.pwmspeaker.Speaker;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.io.IOException;

public class DoorbellActivity extends Activity {

    private static final String TAG = DoorbellActivity.class.getSimpleName();
    private static final String ALARM = "alarm";
    private static final int FREQ = 7000;

    private boolean alarm;
    private Speaker mSpeaker;
    private HandlerThread mHandlerThread;
    private Handler mHandler;
    private DatabaseReference alarmRef;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "Doorbell Activity created.");

        try {
            mSpeaker = new Speaker(BoardDefaults.getPwmPin());
            mSpeaker.stop();

            mHandlerThread = new HandlerThread("pwm-playback");
            mHandlerThread.start();
            mHandler = new Handler(mHandlerThread.getLooper());

            alarmRef = FirebaseDatabase.getInstance().getReference().child(ALARM);
            alarmRef.addValueEventListener(alarmListener);
        } catch (IOException e) {
            Log.e(TAG, e.toString());
        }
    }

    private final Runnable mPlaybackRunnable = new Runnable() {
        @Override
        public void run() {
            if (mSpeaker == null) {
                return;
            }

            try {
                if (alarm) {
                    mSpeaker.play(FREQ);
                } else {
                    mSpeaker.stop();
                }
            } catch (IOException e) {
                Log.e(TAG, "Error playing speaker", e);
            }
        }
    };

    private final ValueEventListener alarmListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.i(TAG, "alarmListener");
            alarm = (boolean) dataSnapshot.getValue();
            mHandler.post(mPlaybackRunnable);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e(TAG, "onCancelled: " + databaseError);
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mHandler != null) {
            mHandler.removeCallbacks(mPlaybackRunnable);
            mHandlerThread.quitSafely();
        }
        if (mSpeaker != null) {
            try {
                mSpeaker.stop();
                mSpeaker.close();
            } catch (IOException e) {
                Log.e(TAG, "Error closing speaker", e);
            } finally {
                mSpeaker = null;
            }
        }
    }
}

@prasaanth-selvakumar
Copy link

Can you play an MP3 file with this driver ??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants