Saturday, January 10, 2015

Android Source Code

Many people are asking about the Android source code. The reason I haven't tried to give it public until now is that the source code was...and still is a mess! However, I think this project is not complete without the Android code.

1. The applications however are programmed using Android Processing v2. That means you have to have the Android SDK installed, Android Processing 

I am not going though how you are going to use Processing in Android Mode, since there is a lot of info on the web.

2. You will need is the Ketai Bluetotth Library, in order to use it to connect to the HC-05.

3. Make sure you select the following  Sketch Permissions in Processing:

ACCESS_FINE_LOCATION
BLUETOOTH
BLUETOOTH_ADMIN

4. In the Project folder of your Processing project, create a folder called data and put the contents of this .rar file there. These are fonts and an image used in the Application.

5. Make sure you enable USB Debugging in your Android device.

6. Finally you can use this image files in the root of the project folder (not in data, the one before), so when the application gets installed in the device

So lets get down to business. Copy this code into Processing and hit Run. If you did everything as you should, you will have a working application that communicates with the Arduino in no-time!

Second code snippet is for the Bluetooth Gauge version.

Good luck.

Code snippet 1



//****************************************************************************************
//
//      BT FUEL MANAGER by MaleBuffy
//      Works with the BT Fuel Manager Arduino sketch and Flow Sensor
// 
//****************************************************************************************

// Import Libs
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

// Import Libs for GPS
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;

// Import Libs for BT 
import ketai.net.bluetooth.*;
import ketai.ui.*;
import ketai.net.*;

// Declare Variables for Bluetooth
PFont fontMy;
boolean bReleased = true; //no permament sending when finger is tap
boolean isConfiguring = true;
String info = "";
KetaiList klist;
KetaiBluetooth bt;
ArrayList devicesDiscovered = new ArrayList();


// Set up the variables for the LocationManager and LocationListener
LocationManager locationManager;
MyLocationListener locationListener;


// Variables 
float speed = 0;
float speedinknots = 0;
PImage FuelIcon;
int dataDisplay = 0;
float inputfromarduino = 0 ;
int gpsfound = 0;
int screen = 0;
int divider = displayHeight/13; 


// Android fonts
PFont androidFont;
PFont BarFond;
PFont androidFontData;

//********************************************************************
// The following code is required to enable bluetooth at startup.
//********************************************************************

void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 bt = new KetaiBluetooth(this);

}

void onActivityResult(int requestCode, int resultCode, Intent data) {
 bt.onActivityResult(requestCode, resultCode, data);
}

//
// Setup code - Run once
// 


void setup ()
{

 noLoop();
// Define fonts
orientation(PORTRAIT);
  
  androidFont = createFont("arialbd.ttf",46,true);
  BarFond = createFont ("arial.ttf",46,true);
  androidFontData = createFont("arial.ttf",46,true);
 
 
 //************************* BT Code ***************************

 //start listening for BT connections
 bt.start();
 
 //at app start select device…
 isConfiguring = true;
  
 textFont(androidFontData);
//*************************************************************

 
 
 // Set Background and Alignment   
    
  textAlign(CENTER, CENTER);
  fill(0);
 
  //load Fuel Manager Icon
  FuelIcon = loadImage ("icon-72.png");
  
}

void draw()
{
 
  // Define in how many Lines the screen will be divided  
 
  
  
  // ********************  at app start select Bluetooth device *******************

 if (isConfiguring)
 {
  
  ArrayList names;
  //background(78, 93, 75);
  klist = new KetaiList(this, bt.getPairedDeviceNames());
  isConfiguring = false;
 }
 else
 {
  
  if((mousePressed) && (bReleased == true))
  {

  bReleased = false;
  }
  if(mousePressed == false)
  {
  bReleased = true; //finger is up
  }

 }
  
  // *****************************************************************************


//Print Layout if screen = 0
if (screen == 0 ) {
  mainlayout();
}

if (screen == 1 ) {
  setuplayout();
}



}  // End of Draw


// ******************************* KEY HANDLING *********************************

void keyPressed() {
 if (key == CODED) {
  if (keyCode == MENU) {
    screen = screen + 1;
    if (screen == 2) { screen = 0; }
   
  } else if (keyCode == android.view.KeyEvent.KEYCODE_BACK) {
     keyCode = 0;  // don't quit by default
     }
}
}



// *************************   Code For GPS ****************************** 

void onResume()
{
  super.onResume();

  locationListener = new MyLocationListener();
  locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);    

  // Register the listener with the Location Manager to receive location updates
  locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}

void onPause()
{
  super.onPause();
}



// Class for capturing the GPS data
class MyLocationListener implements LocationListener
{
  // Define all LocationListener methods
  void onLocationChanged(Location location)
  {
    // Save new GPS data
    
    speed = (float)location.getSpeed()*2.2369;
    speedinknots = speed * 0.8689;
    redraw();
  
}

 public void onProviderDisabled(String provider) {
  
   gpsfound = 1;
           
 }

  void onProviderEnabled (String provider)
  { 
   gpsfound = 0;
  }

  void onStatusChanged (String provider, int status, Bundle extras)
  {
    // Nothing yet...
  }
}

// ********************  GPS Code End ****************************



// ******************************* Bluetooth Code Start *******************************

void onKetaiListSelection(KetaiList klist) {
 String selection = klist.getSelection();
 bt.connectToDeviceByName(selection);
 //dispose of list for now
 klist = null;
}

//Call back method to manage data received
void onBluetoothDataEvent(String who, byte[] data) {
 if (isConfiguring)
 return;
 
 info = new String(data);
 
if (info.length() >2 ) { redraw(); }

}


// ******************************* MAIN LAYOUT *********************

void mainlayout() {
  int divider = displayHeight/13; 

  background(255,255,255);
  fill(0);

    
  // Create Black Bar
  rect(0,0,displayWidth,divider);
  image(FuelIcon, divider*10/100,divider*10/100,divider*0.8,divider*0.8);
  fill(255);
  textFont(BarFond,divider*0.6);
  text("BT Fuel Manager",(displayWidth/2),divider/2);
  
       
 // Speed in MPH
  
  fill(255);
  stroke(0);
  rect(0,divider*2,displayWidth,divider); 
  fill(0);
  stroke(255);
fill(255);
  stroke(0);
  rect(0,divider*3,displayWidth,divider); 
  fill(0);
  stroke(255);
   
  
  textFont(androidFontData,divider*0.8/2);
  text("Speed in mph: ",displayWidth/2,(divider*2)+(divider/2));
  textFont(androidFont,divider);
  dataDisplay = int(speed);
  text(dataDisplay,displayWidth/2,(divider*3)+(divider/2));

 
 // Speed in Knots 
  
  fill(255);
  stroke(0);
  rect(0,divider*4,displayWidth,divider); 
  fill(0);
  stroke(255);
fill(255);
  stroke(0);
  rect(0,divider*5,displayWidth,divider); 
  fill(0);
  stroke(255);

  textFont(androidFontData,divider*0.8/2);
  text("Speed in knots: ",displayWidth/2,(divider*4)+(divider/2));
  textFont(androidFont,divider);
  dataDisplay = int(speedinknots);
  text(dataDisplay,displayWidth/2,(divider*5)+(divider/2));
  
  // Convert string to float
  
  inputfromarduino = float(info);
  String newstring = String.format("%.4f", inputfromarduino);
  float ifa = float(newstring);
  
  // Liters/Sec
    fill(255);
  stroke(0);
  rect(0,divider*6,displayWidth,divider); 
  fill(0);
  stroke(255);
fill(255);
  stroke(0);
  rect(0,divider*7,displayWidth,divider); 
  fill(0);
  stroke(255);

  textFont(androidFontData,divider*0.8 /2);
 text("liters/sec: ",displayWidth/2,(divider*6)+(divider/2));
 
 textFont(androidFont,divider);
 
  if (info != "") {
    
    
    text(inputfromarduino,displayWidth/2,(divider*7)+(divider/2));
  
  }
  
  else
  
  {
   text("-",displayWidth/2,(divider*7)+(divider/2)); 
  }
  
  // Liters/Hour
    fill(255);
  stroke(0);
  rect(0,divider*8,displayWidth,divider); 
  fill(0);
  stroke(255);
fill(255);
  stroke(0);
  rect(0,divider*9,displayWidth,divider); 
  fill(0);
  stroke(255);

  textFont(androidFontData,divider*0.8 /2);
  text("liters/Hour: ",displayWidth/2,(divider*8)+(divider/2));
  textFont(androidFont,divider);
  
  dataDisplay = int(inputfromarduino*3600);
  
  if (info != "") {  text(round(dataDisplay),displayWidth/2,(divider*9)+(divider/2));
  } else { 
   text("-",displayWidth/2,(divider*9)+(divider/2)); 
  }
  
  // Liters/nm
    fill(255);
  stroke(0);
  rect(0,divider*10,displayWidth,divider); 
  fill(0);
  stroke(255);
fill(255);
  stroke(0);
  rect(0,divider*11,displayWidth,divider); 
  fill(0);
  stroke(255);

  textFont(androidFontData,divider*0.8 /2);
  text("liters/nm: ",displayWidth/2,(divider*10)+(divider/2));
  textFont(androidFont,divider);
  
  float literspernm = dataDisplay/speedinknots;
  
  // If Speed is zero then print dash instead of value
  if (round(speed) != 0) { text(nf(literspernm,1,1),displayWidth/2,(divider*11)+(divider/2));
    
  } else {
    
   //text("-",displayWidth/2,(divider*11)+(divider/2)); 
   text("0",displayWidth/2,(divider*11)+(divider/2));       
  }



if (gpsfound != 0) { 
    fill(255,0,0);
    textFont(androidFontData,divider*0.8 /2);
    text("Please enable GPS",displayWidth/2,(divider*12)+(divider/2));   
  }
  

}  // End of mainlayout

// ********************************** SETUP LAYTOUT **************************************************

void setuplayout() {
  int divider = displayHeight/13; 
  background(0);
  fill(255);
  text("SETUP",displayWidth/2,divider);
  redraw();
}

Code snippet 2 - BT Fuel Gauge


//****************************************************************************************
//
//      BT FUEL Gauge by MaleBuffy
//      Works with the BT Fuel Manager Arduino sketch and Flow Sensor
// 
//****************************************************************************************

// draws a radial line in a circle 
// according to the mouse, X-value 

// Import Libs
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

// Import Libs for GPS
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;

// Import Libs for BT 
import ketai.net.bluetooth.*;
import ketai.ui.*;
import ketai.net.*;


// Declare Variables for Bluetooth
PFont fontMy;
boolean bReleased = true; //no permament sending when finger is tap
boolean isConfiguring = true;
String info = "0";
int flagdisplay = 1;
KetaiList klist;
KetaiBluetooth bt;
ArrayList devicesDiscovered = new ArrayList();

// Set up the variables for the LocationManager and LocationListener 
LocationManager locationManager; 
MyLocationListener locationListener; 

// Variables to hold the current GPS data
float speed = 0;
float inputfromarduino = 0 ;
int gpsfound = 0;


float boomX;
float boomY;
float boomX2;
float boomY2;
float boomX3;
float boomY3;
float boomY4;
float boomX4;
float boomX5;
float boomY5;


// Variables for Gauge
int boom = 0;
int mph= 0;
int knots= 0;
float mphgps= 0;
float knotsgps= 0;
PFont androidFontData;

int loopflag=0;

float phi = 2.354 ;  // 100 mph value = 7.063    //.  Step per mile = 0.047


//********************************************************************
// The following code is required to enable bluetooth at startup.
//********************************************************************

void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 bt = new KetaiBluetooth(this);
}
 
void onActivityResult(int requestCode, int resultCode, Intent data) {
 bt.onActivityResult(requestCode, resultCode, data);
}


void setup() {
  
  //************************* BT Code ***************************

 //start listening for BT connections
 bt.start();
 
 //at app start select device…
 isConfiguring = true;
  
 //*************************************************************
  
  size (displayWidth, displayHeight);
  boom=round(displayWidth/2.5);
  androidFontData = createFont("arial.ttf",46,true);
 // noLoop();
  textAlign (CENTER, CENTER);
  orientation(PORTRAIT);
  
 
}

void draw() {
  int divider = displayHeight/13;
  background (0); 
  stroke (255);
  strokeWeight (5);
  fill (255);
  loopflag = 10;
  mph = -10;
  
   // ********************  at app start select Bluetooth device *******************

 if (isConfiguring)
 {
  
  ArrayList names;
  
  klist = new KetaiList(this, bt.getPairedDeviceNames());
  isConfiguring = false;
 }
 else
 {
  
  if((mousePressed) && (bReleased == true))
  {

  bReleased = false;
  }
  if(mousePressed == false)
  {
  bReleased = true; //finger is up
  }

 }
  
  // *****************************************************************************

  
  
  

textSize(displayWidth/15);
text("mph",displayWidth/2,displayHeight/2.5);
textSize(displayWidth/30);
text("knots",displayWidth/2,displayHeight/2.3);


mphgps = speed * 60 * 60 /1000 * 0.621 ;
knotsgps = mphgps * 0.854;

displayInfo();

for (float i=2.354; i<7.064; i=i+0.04709) {
  strokeWeight (2);
  boomX = boom*cos(i);
  boomY = boom*sin(i);
  boomX2= (boom-10) * cos(i);
  boomY2= (boom-10) * sin(i);
  
  line(width / 2+boomX2, height / 2+boomY2, width / 2 + boomX, height / 2 + boomY);

if (loopflag == 10) {  
    boomX3= (boom-20) * cos(i);
    boomY3= (boom-20) * sin(i);
    line(width / 2+boomX3, height / 2+boomY3, width / 2 + boomX, height / 2 + boomY);
    loopflag = 0;

    textSize(40);
    mph = mph + 10;
    boomX4= (boom+30) * cos(i);
    boomY4= (boom+30) * sin(i);
    text(mph,width / 2+boomX4, height / 2+boomY4);

    textSize(20);
    knots = round( mph * 0.854);
    boomX5= (boom -40) * cos(i);
    boomY5= (boom-40) * sin(i);
    text(knots,width / 2+boomX5, height / 2+boomY5); 


         }
loopflag=loopflag+1;

  strokeWeight (5);
    }


boomX = boom*cos(phi);
  boomY = boom*sin(phi);
line(width / 2, height / 2, width / 2 + boomX, height / 2 + boomY);

if (gpsfound != 0) { 
    fill(255,0,0);
    textFont(androidFontData,divider*0.8 /2);
    text("Please enable GPS",displayWidth/2,(divider*12)+(divider/2));   
  }

}

/*
void mousePressed() {
if (phi < 7.063) {  phi = phi + .0277;
  redraw();
  }
}
*/


// Override the activity class methods 
void onResume() 
{ 
  super.onResume(); 

  locationListener = new MyLocationListener(); 
  locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);    

  // Register the listener with the Location Manager to receive location updates 
  locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); 
} 

void onPause() 
{ 
  super.onPause(); 
} 

/*****************************************************************/ 

// Class for capturing the GPS data 
class MyLocationListener implements LocationListener 
{ 
  // Define all LocationListener methods 
  void onLocationChanged(Location location) 
 { 
    // Save new GPS data 
    speed  = (float)location.getSpeed(); 
      phi = 2.354 + (mphgps*0.04709);
   //  redraw();
    
  } 

  void onProviderDisabled (String provider) 
  { 
    gpsfound = 0;
  } 

  void onProviderEnabled (String provider) 
  { 
    gpsfound = 1;
  } 

  void onStatusChanged (String provider, int status, Bundle extras) 
  { 
    // Nothing yet... 
  } 
}

// ******************************* Bluetooth Code Start *******************************

void onKetaiListSelection(KetaiList klist) {
 String selection = klist.getSelection();
 bt.connectToDeviceByName(selection);
 //dispose of list for now
 klist = null;
}

//Call back method to manage data received
void onBluetoothDataEvent(String who, byte[] data) {
 if (isConfiguring)
 return;

 info = new String(data);
 if (info.length() >2 ) { redraw(); }
}
 

void displayInfo () {
  
textSize(displayWidth/15);
inputfromarduino = float(info);

if (flagdisplay == 1) { text(inputfromarduino+"l/sec",displayWidth/2,(displayHeight/2)+boom*0.8); } 
if (flagdisplay == 2) { text(int(inputfromarduino*3600)+" l/hour",displayWidth/2,(displayHeight/2)+boom*0.8); } 
if (flagdisplay == 3) { text((int(inputfromarduino*3600)/knotsgps)+" l/nm",displayWidth/2,(displayHeight/2)+boom*0.8); } 
 
  
}

void mousePressed () {

  flagdisplay = flagdisplay +1;
  if (flagdisplay == 4) { flagdisplay = 1; }
}

Installing it on the boat!

I managed to install it on the boat today! I haven't finished with hiding the cables because I have to do some other things as well.

What I managed to do is take some pictures of where the flow meter is installed. I removed the Both switch.


The negative (brown) cable is connected to ground.  In this setup I am connecting it to the negative of one battery. 


Firstly I connected the positive wire (blue cable) to the COM port of the BOTH Switch (1,2,Both Battery switch) so that it always runs when there is current flowing to the engine.


The sensor must be installed according to the flow that is usually writen on the sensor. Most sensors support only one direction.


Take notice of the angles the flow sensor supports and install accordingly. 

Here is another pictures of where the device is. I will eventually mount it somewhere else, you can find the correct place for your setup.


When I will have some spare time again, I will show you the tidying up I am hopefully going to do.