Friday, April 5, 2013

Read analog input at Arduino Due, display on Android graphically.

This example have same function as previous version in "Write and read analog on Arduino Due from Android using ADK" and "Android code to write and read analog on Arduino Due with ADK"; with a custom view to display the Analog input graphically. The video show how it work, with DAC1 pin and A0 pin connected together, such that the analog out loop back to analog input.



The main difference is in Android side.

Create a new class MyGraphView.java extends View, it is our custom View to display the input graphically.
package com.example.androidadkadc;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

public class MyGraphView extends View {
 
 final static int MAX_ITEM = 100;
 final static int MAX_VAL = 0x0FFF;
 final static int VIEW_WIDTH = 500; //Have to match with width of the View
 final static int VIEW_HEIGHT = 500; //Have to match with height of the View
 final static float X_DIV = (float)VIEW_WIDTH/MAX_ITEM;
 final static float Y_DIV = (float)VIEW_HEIGHT/MAX_VAL;
 
 Paint paintBackground;
 Paint paintGraph;
 Context myContext;
  
 class Item{
  int x;
  int y;
   
  Item(int nx, int ny){
   x = nx;
   y = ny; 
  } 
 }
 
 private List<Item> itemList = new ArrayList<Item>();
 Path pathGraph = new Path();
 
 public MyGraphView(Context context) {
  super(context);
  init(context); 
 }

 public MyGraphView(Context context, AttributeSet attrs) {
  super(context, attrs);
  init(context);
  
 }
 
 public MyGraphView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  init(context); 
 }
   
 private void init(Context c){
  myContext = c;
    
  paintBackground = new Paint();
  paintBackground.setStyle(Paint.Style.FILL);
  paintBackground.setColor(Color.BLACK);
    
  paintGraph = new Paint();
  paintGraph.setStyle(Paint.Style.STROKE);
  paintGraph.setColor(Color.WHITE);
  paintGraph.setStrokeWidth(3);

 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  int w = MeasureSpec.getSize(widthMeasureSpec);
  int h = MeasureSpec.getSize(heightMeasureSpec);
  setMeasuredDimension(w, h);
 }
 
 @Override
 protected void onDraw(Canvas canvas) {
  
  if(!itemList.isEmpty()){
   
   Item lastItem = itemList.get(itemList.size()-1);
   float invY = getHeight() - (lastItem.y * Y_DIV);
   
   if(itemList.size() == 1){
    pathGraph.reset();
    pathGraph.moveTo(0, invY);
   }else{
    pathGraph.lineTo(lastItem.x * X_DIV, invY);
   }
   canvas.drawPath(pathGraph, paintGraph);
  }
  
 }
 
 void addItem(long v){
  if(itemList.size() >= MAX_ITEM){
   itemList.clear();
  }
  
  itemList.add(new Item(itemList.size(), (int)v));
 }

}


Modify the MainActivity.java. The dummySource() method and MyAsyncTask() are for testing only, to simulate input data when no Arduino board available.

package com.example.androidadkadc;

import java.util.Random;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class MainActivity extends AbstractAdkActivity {
 
 MyGraphView myGraphView;
 SeekBar seekBarBrightness;
 
 Random dummyRandom;

 @Override
 protected void doOnCreate(Bundle savedInstanceState) {
  setContentView(R.layout.activity_main);
  myGraphView = (MyGraphView)findViewById(R.id.myview);
  seekBarBrightness = (SeekBar)findViewById(R.id.seekbarbrightness);
  seekBarBrightness.setOnSeekBarChangeListener(
    new OnSeekBarChangeListener(){

     @Override
     public void onProgressChanged(SeekBar seekBar, 
       int progress, boolean fromUser) {
      WriteByteAdk((byte)(progress & 0xFF));
     }

     @Override
     public void onStartTrackingTouch(SeekBar arg0) {
      // TODO Auto-generated method stub
      
     }

     @Override
     public void onStopTrackingTouch(SeekBar arg0) {
      // TODO Auto-generated method stub
      
     }});
  
  //dummySource(); //for testing without Arduino Due board
 }

 @Override
 protected void doAdkRead_inBackGroundThread(int length, byte[] bfr) {
  //Accept only if 2 byte data received
  if(length == 2){

   final long val = (bfr[0] << 8) + (bfr[1] & 0xFF);

   runOnUiThread(new Runnable(){

    @Override
    public void run() {
     myGraphView.addItem(val);
     myGraphView.postInvalidate();
    }});
   
  }
  
 }
 
 //for testing without Arduino Due board
 private void dummySource(){
  dummyRandom = new Random();
  new MyAsyncTask().execute();
 }
 
 public class MyAsyncTask extends AsyncTask<Void, Void, Void> {

  @Override
  protected Void doInBackground(Void... arg0) {
   while(true){
    byte[] b = new byte[2];
    dummyRandom.nextBytes(b);
    b[0] = (byte)(b[0] & 0x0F);
    doAdkRead_inBackGroundThread(2, b);
    SystemClock.sleep(500);
   }
  }
 }

}


Modify the layout, main_activity.xml to add our custom view <com.example.androidadkadc.MyGraphView>.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    <com.example.androidadkadc.MyGraphView
        android:id="@+id/myview"
        android:background="@android:color/black"
        android:layout_gravity="center_horizontal"
        android:layout_margin="10px"
        android:layout_width="500px"
        android:layout_height="500px" />
    <SeekBar
        android:id="@+id/seekbarbrightness"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="255"
        android:progress="0" />

</LinearLayout>


Modify /res/xml/myfilter.xml to update version.
<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <usb-accessory
        manufacturer="Arduino-er"
        model="ArduinoDueAdkADC"
        version="0.2"/>
</resources>


The AndroidManifest.xml is same as previous version in Android side.

download filesDownload the files.



In Arduino, same as previous version in Arduino side, with update of:
  • char versionNumber[] = "0.2";
  • char url[] = "https://sites.google.com/site/arduinosite/exercise/androidadkadc/AndroidAdkADC_0.2.apk";


No comments:

Post a Comment