I've been playing around with connecting an android device (HTC Wildfire) to an arduino Mega ADK using the ADB protocol (because it means I can use a cheaper Android device).
I found a great project by Illutron - http://illutron.dk/posts/319 that did most of the heavy lifting but I was struggling to work out how to send a large integer value.
Ultimately, I want to create a simple UI on the Android phone that can be used to set a load of values that then control something via the arduino - maybe a panoramic camera or something like that.
Anyway, it's probably a bit of a hack but here's the code. I figured out that if I split an integer into the number of times it can be divided by 127 (maximum integer that fits into 1 byte) and the remainder I can send a value of up to about 16,000 in two bytes. These are decoded on the arduino side.
I am not an expert programmer by a long shot so I am sure there is a better way to tdo this but I couldn't find anything after a bit of searching so this will work for me for now.
Processing code:
Arduino Code (needs a library too - see Illutron.dk sandbox for full code);
I found a great project by Illutron - http://illutron.dk/posts/319 that did most of the heavy lifting but I was struggling to work out how to send a large integer value.
Ultimately, I want to create a simple UI on the Android phone that can be used to set a load of values that then control something via the arduino - maybe a panoramic camera or something like that.
Anyway, it's probably a bit of a hack but here's the code. I figured out that if I split an integer into the number of times it can be divided by 127 (maximum integer that fits into 1 byte) and the remainder I can send a value of up to about 16,000 in two bytes. These are decoded on the arduino side.
I am not an expert programmer by a long shot so I am sure there is a better way to tdo this but I couldn't find anything after a bit of searching so this will work for me for now.
Processing code:
- /*
Processing code that converts large integer values into two bytes and sends them to arduino mega ADK
Uses Microbridge serial connection so the phone must have debug switched on
Relies heavily on code from Illutron - I just did the hack to turn a large integer into bytes!
Internet must be ticked in sketch permissions
*/
import java.io.IOException;
import android.util.Log;
private Server server;
private int sensorValue;
int startVal1 = 405; //this will work up until about 16,000 (because fullBytes number needs to be less than 127 to be ent as a single Byte)
int startVal2 = 999;
int fullBytes1; //variable to calculate how many 'full bytes' we need ie 1111111 = 127
int fullBytes2;
int remainder1; //variable for what's left over in the partial byte
int remainder2;
int sw;
int sh;
int y = 20;
int spacing = 20;
// Android fonts
String[] fontList;
PFont androidFont16;
void setup()
{
//for Android mode
size(screenWidth, screenHeight, A2D);
orientation(PORTRAIT);
//for standard Processing debugging
//size(320,480);
sw = screenWidth;
sh = screenHeight;
fontList = PFont.list();
androidFont16 = createFont(fontList[0], 16, true);
// Create TCP server
server = null;
try
{
server = new Server(4567);
server.start();
}
catch (IOException e)
{
println(e.toString());
}
this.server.addListener(new AbstractServerListener() {
@Override
public void onReceive(Client client, byte[] data)
{
if (data.length<2) return;
sensorValue = (data[0] & 0xff) | ((data[1] & 0xff) << 8);
};
}
);
}
void draw()
{
background(0);
fill(255);
if (mousePressed && mouseY<height/2)
{
text(startVal1, 20, y);
//calculate value of bytes depending on startVal
fullBytes1 = startVal1/127; //divide by 127 (max int for a byte)
remainder1= startVal17;
try
{
server.send(new byte[] {(byte) (fullBytes1), (byte)(remainder1)} );
}
catch (IOException e)
{
println("problem sending TCP message");
}
}
if (mousePressed && mouseY>height/2)
{
text(startVal2, 20, y);
//calculate value of bytes depending on startVal
fullBytes2 = startVal2/127; //divide by 127 (max int for a byte)
remainder2= startVal27;
gopause =1;
try
{
server.send(new byte[] {(byte) (fullBytes2), (byte)(remainder2)} );
}
catch (IOException e)
{
println("problem sending TCP message");
}
}
else
{
fill(255, 0, 0);
ellipse(width/2, height/2, sensorValue, sensorValue);
}
}
Arduino Code (needs a library too - see Illutron.dk sandbox for full code);
- /*
Arduino code for mega adk to accompany Processing sketch of the same name that runs on Android device
Demonstrates sending data between arduino and android app
Touching top half of screen sends one integer value and touching bottom semds another.
Values sent as 2 bytes in an array.
Arduino decodes two bytes into original value
first byte is number of full bytes (ie multiply by 127) second byte is value of remainder
*/
#include <SPI.h>
#include <Adb.h>
#define MAX_RESET 8
// Adb connection.
Connection * connection;
// Elapsed time for ADC sampling
long lastTime;
boolean r = true;
int sensorValue;
int val;
// Event handler for the shell connection.
void adbEventHandler(Connection * connection, adb_eventType event, uint16_t length, uint8_t * data)
{
int i;
// Data packets contain two bytes, one for each servo, in the range of [0..180]
if (event == ADB_CONNECTION_RECEIVE)
{
r = !r;
val = (data[0]*127) + data[1];
//Serial.println(data1);
}
}
void setup()
{
pinMode(10, OUTPUT);
// Initialise serial port
Serial.begin(57600);
// Note start time
lastTime = millis();
// Initialise the ADB subsystem.
ADB::init();
// Open an ADB stream to the phone's shell. Auto-reconnect
connection = ADB::addConnection("tcp:4567", true, adbEventHandler);
}
void loop()
{
Serial.println(val);
/*
if ((millis() - lastTime) > 20)
{
uint16_t data = analogRead(A0);
sensorValue = analogRead(A0);
connection->write(2, (uint8_t*)&data);
lastTime = millis();
// Serial.println("sdf");
}
*/
// Poll the ADB subsystem.
ADB::poll();
}