Skip to content

Instantly share code, notes, and snippets.

@badarshahzad
Last active April 3, 2018 16:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save badarshahzad/de809ff034ca26b194b0573f6052e760 to your computer and use it in GitHub Desktop.
Save badarshahzad/de809ff034ca26b194b0573f6052e760 to your computer and use it in GitHub Desktop.
Android Things MCP3008 example
package com.badarshahzad54.pcbs;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.PersistableBundle;
import android.util.Log;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toolbar;
import com.badarshahzad54.pcbs.mcp3008.MCP3008;
import com.badarshahzad54.pcbs.modelThings.AppliancesLog;
import com.badarshahzad54.pcbs.presentation.fragments.BillFragment;
import com.badarshahzad54.pcbs.presentation.fragments.HomeFragment;
import com.badarshahzad54.pcbs.presentation.utils.BoomMenuesUtils;
import com.google.android.things.pio.Gpio;
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.ServerValue;
import com.google.firebase.database.ValueEventListener;
import com.nightonke.boommenu.Animation.BoomEnum;
import com.nightonke.boommenu.BoomButtons.BoomButton;
import com.nightonke.boommenu.BoomButtons.ButtonPlaceEnum;
import com.nightonke.boommenu.BoomButtons.TextInsideCircleButton;
import com.nightonke.boommenu.BoomMenuButton;
import com.nightonke.boommenu.ButtonEnum;
import com.nightonke.boommenu.OnBoomListener;
import com.nightonke.boommenu.Piece.PiecePlaceEnum;
import java.io.IOException;
/**
* Skeleton of an Android Things activity.
* <p>
* Android Things peripheral APIs are accessible through the class
* PeripheralManagerService. For example, the snippet below will open a GPIO pin and
* set it to HIGH:
* <p>
* <pre>{@code
* PeripheralManagerService service = new PeripheralManagerService();
* mLedGpio = service.openGpio("BCM6");
* mLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
* mLedGpio.setValue(true);
* }</pre>
* <p>
* For more complex peripherals, look for an existing user-space driver, or implement one if none
* is available.
*
* @see <a href="https://github.com/androidthings/contrib-drivers#readme">https://github.com/androidthings/contrib-drivers#readme</a>
*/
/*
Initializing with a Raspberry Pi 3B and a TMP36 connected to ADC CH 0.
Can change these pin numbers in your own projects to be the proper board pins.
Pinout for sample like so:
ADC channel 0 -|* |- 5v in
ADC channel 1 -| |- 5v in
ADC channel 2 -| |- Analog GND (For this sample app, I used this ground)
ADC channel 3 -| |- Clock
ADC channel 4 -| |- MISO pin on board (sometimes listed as D-OUT on chip diagram)
ADC channel 5 -| |- MOSI pin on board (sometimes listed as DIN on chip diagram)
ADC channel 6 -| |- Chip select (CS)
ADC channel 7 -| |- Digital GND (For this sample app, I left this GND disconnected)
I wired BCM12 to CS, BCM21 to Clock, BCM16 to MOSI (D-OUT) and BCM20 to MISO (D-IN)
*/
//TODO: Give proper referance https://github.com/PaulTR/AndroidThingsMCP3008ADC/blob/master/MCP3008/app/src/main/java/com/paultrebilcoxruiz/mcp3008/MainActivity.java
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int INTERVAL_BETWEEN_BLINKS_MS = 500;
//pin number 33
private static final String GPIO_PIN_NAME = "BCM13";
int highLow = 0;
int hightScore = 0;
private Handler handler = new Handler();
private Gpio ledGpio;
private Switch switch1;
private TextView count;
private TextView device1;
private Toolbar toolbar;
private BoomMenuButton boomMenuButton;
//firebase
private DatabaseReference firebaseDatabase;
private AppliancesLog appliancesLog;
private FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
private HomeFragment homeFragment;
//Here is the MCP3008 communication class
private MCP3008 mMCP3008;
private Handler handlerForMCP3008;
/**
* ADC read runnble
*/
private Runnable mReadAdcRunnable = new Runnable() {
private static final long DELAY_MS = 3000L; // 3 seconds
@Override
public void run() {
if (mMCP3008 == null) {
return;
}
try {
Log.i("MCP3008", "ADC 0: " + mMCP3008.readAdc(0x0));
Log.i("MCP3008", "ADC 1: " + mMCP3008.readAdc(0x1));
Log.i("MCP3008", "ADC 2: " + mMCP3008.readAdc(0x2));
Log.i("MCP3008", "ADC 3: " + mMCP3008.readAdc(0x3));
Log.i("MCP3008", "ADC 4: " + mMCP3008.readAdc(0x4));
Log.i("MCP3008", "ADC 5: " + mMCP3008.readAdc(0x5));
Log.i("MCP3008", "ADC 6: " + mMCP3008.readAdc(0x6));
Log.i("MCP3008", "ADC 7: " + mMCP3008.readAdc(0x7));
} catch (IOException e) {
Log.i("MCP3008", "Something went wrong while reading from the ADC: " + e.getMessage());
}
handlerForMCP3008.postDelayed(this, DELAY_MS);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* MCP3008 initialize
*/
try {
mMCP3008 = new MCP3008("BCM12", "BCM21", "BCM16", "BCM20");
mMCP3008.register();
} catch (IOException e) {
Log.e("MCP3008", "MCP initialization exception occurred: " + e.getMessage());
}
handlerForMCP3008 = new Handler();
handlerForMCP3008.post(mReadAdcRunnable);
//good place to create the Realm instance
/* Realm.init(this);
RealmConfiguration configuration = new RealmConfiguration
.Builder()
.name("pcbs_things.realm")
.deleteRealmIfMigrationNeeded()
.build();
//development phase & as I need clean database each time
Realm.deleteRealm(configuration);
//helo to work with realm and realm objects
Realm.setDefaultConfiguration(configuration);
*/
HomeFragment homeFragment = new HomeFragment();
getFragmentManager().beginTransaction()
.add(R.id.fragment_container,homeFragment,"homefragment")
.commit();
// setTitle("Bachat Smart Board");
initViews();
initBoomMenu();
initFirebase();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mMCP3008 != null) {
mMCP3008.unregister();
}
if (handlerForMCP3008 != null) {
handlerForMCP3008.removeCallbacks(mReadAdcRunnable);
}
}
private void initViews() {
boomMenuButton = findViewById(R.id.bmb);
toolbar = findViewById(R.id.toolbar);
setActionBar(toolbar);
}
private void initBoomMenu() {
//boommenu
boomMenuButton.setButtonEnum(ButtonEnum.TextInsideCircle);
boomMenuButton.setPiecePlaceEnum(PiecePlaceEnum.DOT_8_3);
boomMenuButton.setButtonPlaceEnum(ButtonPlaceEnum.SC_8_3);
boomMenuButton.setBoomEnum(BoomEnum.HORIZONTAL_THROW_2);
boomMenuButton.setDraggable(true);
homeFragment = new HomeFragment();
fragmentTransaction.add(R.id.fragment_container, homeFragment);
fragmentTransaction.commit();
boomMenuButton.setOnBoomListener(new OnBoomListener() {
@Override
public void onClicked(int index, BoomButton boomButton) {
switch(index){
case 0:
homeFragment = new HomeFragment();
fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, homeFragment);
fragmentTransaction.commit();
break;
case 1:
BillFragment billFragment = new BillFragment();
fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, billFragment);
fragmentTransaction.commit();
break;
case 3:
//Intent intent_start_Wifi = new Intent(Settings.ACTION_WIFI_SETTINGS);
//startActivity(intent_start_Wifi);
break;
}
}
@Override
public void onBackgroundClick() {
}
@Override
public void onBoomWillHide() {
}
@Override
public void onBoomDidHide() {
}
@Override
public void onBoomWillShow() {
}
@Override
public void onBoomDidShow() {
}
});
/*****
* TODO: the number of dots on floatbutton 9 but the menus is 8 so
* I will later add suitable menu
* TODO: remember I have add -1 in the getPiecePlaceEnum to make 8 menus
*/
//bmb.addBuilder();
for (int i = 0; i < boomMenuButton.getPiecePlaceEnum().pieceNumber(); i++) {
TextInsideCircleButton.Builder builder = new TextInsideCircleButton.Builder()
.normalImageRes(BoomMenuesUtils.navigationMenuImages[i])
.normalText(BoomMenuesUtils.navigationMenuStrings[i])
.imagePadding(new Rect(8, 8, 8, 16));
boomMenuButton.addBuilder(builder);
// bmb.addBuilder(getSimpleCircleButtonBuilder());
}
}
private void initFirebase() {
final String FIREBASE_LOGS = "logs";
final String TAG = "ElectricityMonitor";
final String FIREBASE_ONLINE_ENDPOINT = "/online";
final String FIREBASE_INFO_CONNECTED = ".info/connected";
/********************
* Appliances Log Begin
*/
firebaseDatabase = FirebaseDatabase.getInstance().getReference();
final String key = firebaseDatabase.child(FIREBASE_LOGS).push().getKey();
appliancesLog = new AppliancesLog();
final DatabaseReference onlineRef = firebaseDatabase.child(FIREBASE_INFO_CONNECTED);
final DatabaseReference currentUserRef = firebaseDatabase.child(FIREBASE_ONLINE_ENDPOINT);
onlineRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "onDataChange: "+ dataSnapshot);
if(dataSnapshot.getValue(Boolean.class)){
appliancesLog.setTimestampOn(ServerValue.TIMESTAMP);
final DatabaseReference currentLogDbRef =
firebaseDatabase.child(FIREBASE_LOGS).child(key);
currentUserRef.setValue(true);
currentUserRef.onDisconnect().setValue(false);
appliancesLog.setTimestampOff(ServerValue.TIMESTAMP);
currentLogDbRef.onDisconnect().setValue(appliancesLog);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, "onCancelled: "+ databaseError);
}
});
/********************
* Appliances Log End
*/
/*
firebaseDatabase = FirebaseDatabase.getInstance().getReference();
//FirebaseDatabase.getInstance().setPersistenceEnabled(true);
firebaseDatabase.setValue(hightScore);
firebaseDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
hightScore = Integer.valueOf(dataSnapshot.getValue().toString());
Log.i(TAG, "onDataChange: 1"+dataSnapshot.getValue());
Log.i(TAG, "onDataChange: 2"+dataSnapshot.getKey());
Log.i(TAG, "onDataChange: 3"+dataSnapshot.getRef());
if(highLow==1){
device1.setText("ON");
turnDevice1(true);
count.setText("Count:" + hightScore);
Log.i(TAG, "onDataChange: ON");
}else {
device1.setText("Off");
count.setText("Count:" + hightScore);
turnDevice1(false);
Log.i(TAG, "onDataChange: OFF");
}
Log.i(TAG, "onDataChange: ");
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.i(TAG, "onCancelled: Database exception");
}
});
count = findViewById(R.id.count);
device1 = findViewById(R.id.device1);
//count.setText(count.getText()+""+ip);
try {
// Step 1. Create GPIO connection.
ledGpio = service.openGpio(GPIO_PIN_NAME);
} catch (IOException e) {
e.printStackTrace();
}
switch1 = (Switch) findViewById(R.id.switch1);
switch1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.i(TAG, "Value Switch 1: " + isChecked);
if (isChecked) {
device1.setText("On");
turnDevice1(true);
hightScore++;
Log.i(TAG, "onCheckedChanged: " + hightScore);
count.setText("Count:" + hightScore);
//Device device = new Device(0,true);
firebaseDatabase.setValue(hightScore);
} else {
turnDevice1(false);
hightScore++;
count.setText("Count:" + hightScore);
device1.setText("Off");
}
}
});
*/
}
/**
* Turn gpio pin on and off
* @param onOff
*/
private void turnDevice1(boolean onOff) {
if (onOff) {
try {
ledGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_HIGH);
} catch (IOException e) {
e.printStackTrace();
}
} else {
try {
ledGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Testing Code: This snippet code take from the https://github.com/androidthings/sample-button
*/
/*
protected void onDestroy() {
super.onDestroy();
// Step 4. Remove handler events on close.
handler.removeCallbacks(mBlinkRunnable);
// Step 5. Close the resource.
if (ledGpio != null) {
try {
ledGpio.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
}
private Runnable mBlinkRunnable = new Runnable() {
@Override
public void run() {
// Exit if the GPIO is already closed
if (ledGpio == null) {
return;
}
try {
// Step 3. Toggle the LED state
ledGpio.setValue(!ledGpio.getValue());
// Log.i(TAG, "thread is running****");
// Step 4. Schedule another event after delay.
handler.postDelayed(mBlinkRunnable, INTERVAL_BETWEEN_BLINKS_MS);
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
};
*/
//Just to watch the Life Cycle
/**
* When I run the applicatino onStart and onResume called when I stop not method called
* When I again run the applicaiotn from studio then onPause then on stop but not onStart
* onCreate or onResume called intereseting
* When rerun the applciaiton again onStart and onResume
*/
//Life Cycle
@Override
protected void onResume() {
super.onResume();
//here we will get the list
Log.i(TAG, "onResume: ");
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
Log.i(TAG, "onSaveInstanceState: ");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause: ");
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart: ");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "onRestart: ");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "onStop: ");
}
}
package com.badarshahzad54.pcbs.mcp3008;
import com.google.android.things.pio.Gpio;
import com.google.android.things.pio.PeripheralManagerService;
import java.io.IOException;
/*
Paul Trebilcox-Ruiz
PaulTR@Gmail.com
Library for communicating with the MCP3008 Analog to Digital Converter.
Based on an Arduino library by: Uros Petrevski (https://github.com/nodesign/MCP3008)
Ported from Python code originaly written by Adafruit learning system for rPI:
http://learn.adafruit.com/send-raspberry-pi-data-to-cosm/python-script
Initializing with a Raspberry Pi 3B and a TMP36 connected to ADC CH 0.
Can change these pin numbers in your own projects to be the proper board pins.
Pinout for sample like so:
ADC channel 0 -|* |- VIN
ADC channel 1 -| |- VIN
ADC channel 2 -| |- Analog GND (For this sample app, I used this ground)
ADC channel 3 -| |- Clock
ADC channel 4 -| |- MISO pin on board (sometimes listed as D-OUT on chip diagram)
ADC channel 5 -| |- MOSI pin on board (sometimes listed as DIN on chip diagram)
ADC channel 6 -| |- Chip select (CS)
ADC channel 7 -| |- Digital GND (For this sample app, I left this GND disconnected)
While testing I wired BCM12 to CS, BCM21 to Clock, BCM16 to MOSI (D-OUT) and
BCM20 to MISO (D-IN)
*/
//TODO: give proper referance
//https://github.com/PaulTR/AndroidThingsMCP3008ADC/blob/master/MCP3008/app/src/main/java/com/paultrebilcoxruiz/mcp3008/MainActivity.java
public class MCP3008 {
private final String csPin;
private final String clockPin;
private final String mosiPin;
private final String misoPin;
private Gpio mCsPin;
private Gpio mClockPin;
private Gpio mMosiPin;
private Gpio mMisoPin;
public MCP3008(String csPin, String clockPin, String mosiPin, String misoPin) {
this.csPin = csPin;
this.clockPin = clockPin;
this.mosiPin = mosiPin;
this.misoPin = misoPin;
}
public void register() throws IOException {
PeripheralManagerService service = new PeripheralManagerService();
mClockPin = service.openGpio(clockPin);
mCsPin = service.openGpio(csPin);
mMosiPin = service.openGpio(mosiPin);
mMisoPin = service.openGpio(misoPin);
mClockPin.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
mCsPin.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
mMosiPin.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
mMisoPin.setDirection(Gpio.DIRECTION_IN);
}
public int readAdc(int channel) throws IOException {
if (channel < 0 || channel > 7) {
throw new IOException("ADC channel must be between 0 and 7");
}
initReadState();
initChannelSelect(channel);
return getValueFromSelectedChannel();
}
private int getValueFromSelectedChannel() throws IOException {
int value = 0x0;
for (int i = 0; i < 12; i++) {
toggleClock();
value <<= 0x1;
if (mMisoPin.getValue()) {
value |= 0x1;
}
}
mCsPin.setValue(true);
value >>= 0x1; // first bit is 'null', so drop it
return value;
}
private void initReadState() throws IOException {
mCsPin.setValue(true);
mClockPin.setValue(false);
mCsPin.setValue(false);
}
private void initChannelSelect(int channel) throws IOException {
int commandout = channel;
commandout |= 0x18; // start bit + single-ended bit
commandout <<= 0x3; // we only need to send 5 bits
for (int i = 0; i < 5; i++) {
if ((commandout & 0x80) != 0x0) {
mMosiPin.setValue(true);
} else {
mMosiPin.setValue(false);
}
commandout <<= 0x1;
toggleClock();
}
}
private void toggleClock() throws IOException {
mClockPin.setValue(true);
mClockPin.setValue(false);
}
public void unregister() {
if (mCsPin != null) {
try {
mCsPin.close();
} catch (IOException ignore) {
// do nothing
}
}
if (mClockPin != null) {
try {
mClockPin.close();
} catch (IOException ignore) {
// do nothing
}
}
if (mMisoPin != null) {
try {
mMisoPin.close();
} catch (IOException ignore) {
// do nothing
}
}
if (mMosiPin != null) {
try {
mMosiPin.close();
} catch (IOException ignore) {
// do nothing
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment