Problems sending accelerometer and GPS data to Arduino with ADB.
in
Android Processing
•
7 months ago
Hello!
We have a school project where we want to build a CanSat using some of the sensors found on an Android device, such as accelerometer data and GPS-coordinates, together with some on an Arduino board (pressure, temperature and a geiger counter). We bought the Sony Tipo ST21i and Arduino Mega ADK, and learned that the Tipo only supports ADB mode.
We don't have much programming experience, but found many great tutorials online and source codes from other projects which we tried to merge together. Unfortunately the USB communication between the Tipo and the Arduino doesn't work in this code. We don't know wether the problem lies on the Android or the Arduino side, but here are both codes:
(Android code is to collect accelerometer data and GPS coordinates and send them using ADB)
- public final byte COMMAND_SEND_TRUE = 1; // Allow data transfer
- import java.io.IOException;
- import android.util.Log;
- // Imports
- import android.content.Context;
- import android.location.Location;
- import android.location.LocationManager;
- import android.location.LocationListener;
- import android.location.GpsStatus.Listener;
- import android.os.Bundle;
- AccelerometerManager accel;
- float ax, ay, az;
- String[] fontList;
- PFont androidFont;
- LocationManager locationManager;
- MyLocationListener locationListener;
- // Variables to hold the current GPS data
- float currentLatitude = 0;
- float currentLongitude = 0;
- float currentAccuracy = 0;
- String currentProvider = "";
- private Server server;
- private int sensorValue;
- void setup()
- {
- accel = new AccelerometerManager(this);
- orientation(PORTRAIT);
- size(displayWidth, displayHeight);
- fontList = PFont.list();
- androidFont = createFont(fontList[4], 35, true);
- textFont(androidFont);
- noLoop();
- // 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);
- textSize(20);
- textAlign(CENTER, BOTTOM);
- text("x: " + nf(ax, 1, 2) + "\n" +
- "y: " + nf(ay, 1, 2) + "\n" +
- "z: " + nf(az, 1, 2), 160, 180);
- textAlign(CENTER, TOP);
- text("Latitude: "+(currentLatitude) + "\n" +
- "Longitude: "+(currentLongitude) + "\n" +
- "Accuracy: "+(currentAccuracy) + "\n" +
- "Provider: "+(currentProvider), 160, 300);
- }
- byte ux = byte(ax);
- byte uy = byte(ay);
- byte uz = byte(az);
- public void send() {
- try {
- server.send(new byte[] {
- (byte) (ux)
- ,(byte) (uy)
- ,(byte) (uz)
- }
- );
- }
- catch (IOException e)
- {
- println("We got problems");
- }
- try {
- Thread.sleep(500);
- }
- catch(InterruptedException ex) {
- println("Oh no");
- }
- }
- public void resume() {
- if (accel != null) {
- accel.resume();
- }
- }
- public void pause() {
- if (accel != null) {
- accel.pause();
- }
- }
- public void shakeEvent(float force) {
- println("shake : " + force);
- }
- public void accelerationEvent(float x, float y, float z) {
- // println("acceleration: " + x + ", " + y + ", " + z);
- ax = x;
- ay = y;
- az = z;
- redraw();
- }
- void onResume() {
- super.onResume();
- // Build Listener
- locationListener = new MyLocationListener();
- // Acquire a reference to the system Location Manager
- 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();
- }
- //-----------------------------------------------------------------------------------------
- // Define a listener that responds to location updates
- class MyLocationListener implements LocationListener {
- void onLocationChanged(Location location) {
- // Called when a new location is found by the network location provider.
- currentLatitude = (float)location.getLatitude();
- currentLongitude = (float)location.getLongitude();
- currentAccuracy = (float)location.getAccuracy();
- currentProvider = location.getProvider();
- }
- void onProviderDisabled (String provider) {
- currentProvider = "";
- }
- void onProviderEnabled (String provider) {
- currentProvider = provider;
- }
- void onStatusChanged (String provider, int status, Bundle extras) {
- // Nothing yet...
- }
- }
(The Arduino code is to receive the data sent from the Tipo, and write it to serial monitor)
- #include <SoftModem.h>
- #include <ctype.h>
- #include <Wire.h>
- #include <LiquidCrystal.h>
- #include <SPI.h>
- #include <Adb.h>
- #define MAX_RESET 8
- #define BMP085_ADDRESS 0x77 // I2C address of BMP085
- // Threshold values for the led bar
- #define TH1 45
- #define TH2 95
- #define TH3 200
- #define TH4 400
- #define TH5 600
- // Conversion factor - CPM to uSV/h
- #define CONV_FACTOR 0.00812
- // initialize the library with the numbers of the interface pins
- LiquidCrystal lcd(3,4,5,6,7,8);
- const unsigned char OSS = 0; // Oversampling Setting
- // Add these to the top of your program
- const float p0 = 101860; // Pressure at sea level (Pa)
- float altitude;
- // Calibration values
- int ac1;
- int ac2;
- int ac3;
- unsigned int ac4;
- unsigned int ac5;
- unsigned int ac6;
- int b1;
- int b2;
- int mb;
- int mc;
- int md;
- // Variables
- int ledArray [] = {10,11,12,13,9};
- int geiger_input = 2;
- long count = 0;
- long countPerSecond = 0;
- long timePrevious = 0;
- long timePreviousMeassure = 0;
- long time = 0;
- long countPrevious = 0;
- float radiationValue = 0.0;
- // b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...)
- // so ...Temperature(...) must be called before ...Pressure(...).
- long b5;
- short temperature;
- long pressure;
- SoftModem modem;
- Connection * connection;
- word ttemp;
- word ttrykk;
- word hhoyde;
- word ccps;
- long uusb;
- // Elapsed time for ADC sampling
- long lastTime;
- boolean r = true;
- void setup()
- {
- Serial.begin(9600);
- Wire.begin();
- bmp085Calibration();
- pinMode(geiger_input, INPUT);
- digitalWrite(geiger_input,HIGH);
- for (int i=0;i<5;i++){
- pinMode(ledArray[i],OUTPUT);
- modem.begin();
- pinMode(3,OUTPUT);
- pinMode(3, HIGH);
- // 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);
- }
- lcd.begin(16, 2);
- lcd.clear();
- lcd.setCursor(0, 0);
- lcd.print("Prosjekt Andoya");
- lcd.setCursor(0,1);
- lcd.print("Oh yeah!");
- delay(500);
- lcd.clear();
- lcd.setCursor(0, 0);
- lcd.print("CPS=");
- lcd.setCursor(4,0);
- lcd.print(6*count);
- lcd.setCursor(0,1);
- lcd.print(radiationValue);
- attachInterrupt(0,countPulse,FALLING);
- }
- // Event handler for the shell connection.
- void adbEventHandler(Connection * connection, adb_eventType event, uint16_t length, uint8_t * data)
- {
- byte i;
- switch (event)
- {
- case (ADB_CONNECTION_RECEIVE):
- Serial.println(data[i]);
- default:
- break;
- }
- }
- void loop()
- {
- unsigned long uusb = Serial.read();
- temperature = bmp085GetTemperature(bmp085ReadUT());
- pressure = bmp085GetPressure(bmp085ReadUP());
- altitude = (float)44330 * (1 - pow(((float) pressure/p0), 0.190295));
- /*
- Serial.print("Temperatur: ");
- Serial.print(temperature, DEC);
- Serial.println(" *0.1 deg C");
- Serial.print("Lufttrykk: ");
- Serial.print(pressure, DEC);
- Serial.println(" Pa");
- // Add this into loop(), after you've calculated the pressure
- Serial.print("Moh.: ");
- Serial.print(altitude, 2);
- Serial.println();
- Serial.println(uusb);
- delay(3000);
- Serial.println();
- */
- if (millis()-timePreviousMeassure > 1000){
- countPerSecond = count;
- /*
- radiationValue = countPerMinute * CONV_FACTOR;
- */
- timePreviousMeassure = millis();
- Serial.print("cps = ");
- Serial.println(countPerSecond,DEC);
- /*
- Serial.print(" - ");
- Serial.print("uSv/h = ");
- Serial.println(radiationValue,4);
- */
- lcd.clear();
- lcd.setCursor(0, 0);
- lcd.print("CPS=");
- lcd.setCursor(4,0);
- lcd.print(countPerSecond);
- lcd.setCursor(7,0);
- lcd.print("p=");
- lcd.setCursor(9,0);
- lcd.print(pressure, DEC);
- lcd.setCursor(0,1);
- lcd.print("a=");
- lcd.setCursor(2,1);
- lcd.print(altitude, 2);
- lcd.setCursor(10,1);
- lcd.print("t=");
- lcd.setCursor(12,1);
- lcd.print(temperature, DEC);
- /*
- lcd.setCursor(0,1);
- lcd.print(radiationValue,4);
- lcd.setCursor(6,1);
- lcd.print(" uSv/h");
- */
- ttrykk = pressure;
- ttemp = temperature;
- hhoyde = altitude;
- ccps = countPerSecond;
- modem.write(ttrykk);
- modem.write(ttemp);
- modem.write(hhoyde);
- modem.write(ccps);
- modem.write(uusb);
- //led var setting
- if(countPerSecond <= TH1) ledVar(0);
- if((countPerSecond <= TH2)&&(countPerSecond>TH1)) ledVar(1);
- if((countPerSecond <= TH3)&&(countPerSecond>TH2)) ledVar(2);
- if((countPerSecond <= TH4)&&(countPerSecond>TH3)) ledVar(3);
- if((countPerSecond <= TH5)&&(countPerSecond>TH4)) ledVar(4);
- if(countPerSecond>TH5) ledVar(5);
- count = 0;
- }
- ADB::poll();
- }
- void countPulse(){
- detachInterrupt(0);
- count++;
- while(digitalRead(2)==0){
- }
- attachInterrupt(0,countPulse,FALLING);
- }
- void ledVar(int value){
- if (value > 0){
- for(int i=0;i<=value;i++){
- digitalWrite(ledArray[i],HIGH);
- }
- for(int i=5;i>value;i--){
- digitalWrite(ledArray[i],LOW);
- }
- }
- else {
- for(int i=5;i>=0;i--){
- digitalWrite(ledArray[i],LOW);
- }
- }
- }
- // Stores all of the bmp085's calibration values into global variables
- // Calibration values are required to calculate temp and pressure
- // This function should be called at the beginning of the program
- void bmp085Calibration()
- {
- ac1 = bmp085ReadInt(0xAA);
- ac2 = bmp085ReadInt(0xAC);
- ac3 = bmp085ReadInt(0xAE);
- ac4 = bmp085ReadInt(0xB0);
- ac5 = bmp085ReadInt(0xB2);
- ac6 = bmp085ReadInt(0xB4);
- b1 = bmp085ReadInt(0xB6);
- b2 = bmp085ReadInt(0xB8);
- mb = bmp085ReadInt(0xBA);
- mc = bmp085ReadInt(0xBC);
- md = bmp085ReadInt(0xBE);
- }
- // Calculate temperature given ut.
- // Value returned will be in units of 0.1 deg C
- short bmp085GetTemperature(unsigned int ut)
- {
- long x1, x2;
- x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
- x2 = ((long)mc << 11)/(x1 + md);
- b5 = x1 + x2;
- return ((b5 + 8)>>4);
- }
- // Calculate pressure given up
- // calibration values must be known
- // b5 is also required so bmp085GetTemperature(...) must be called first.
- // Value returned will be pressure in units of Pa.
- long bmp085GetPressure(unsigned long up)
- {
- long x1, x2, x3, b3, b6, p;
- unsigned long b4, b7;
- b6 = b5 - 4000;
- // Calculate B3
- x1 = (b2 * (b6 * b6)>>12)>>11;
- x2 = (ac2 * b6)>>11;
- x3 = x1 + x2;
- b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
- // Calculate B4
- x1 = (ac3 * b6)>>13;
- x2 = (b1 * ((b6 * b6)>>12))>>16;
- x3 = ((x1 + x2) + 2)>>2;
- b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
- b7 = ((unsigned long)(up - b3) * (50000>>OSS));
- if (b7 < 0x80000000)
- p = (b7<<1)/b4;
- else
- p = (b7/b4)<<1;
- x1 = (p>>8) * (p>>8);
- x1 = (x1 * 3038)>>16;
- x2 = (-7357 * p)>>16;
- p += (x1 + x2 + 3791)>>4;
- return p;
- }
- // Read 1 byte from the BMP085 at 'address'
- char bmp085Read(unsigned char address)
- {
- unsigned char data;
- Wire.beginTransmission(BMP085_ADDRESS);
- Wire.write(address);
- Wire.endTransmission();
- Wire.requestFrom(BMP085_ADDRESS, 1);
- while(!Wire.available())
- ;
- return Wire.read();
- }
- // Read 2 bytes from the BMP085
- // First byte will be from 'address'
- // Second byte will be from 'address'+1
- int bmp085ReadInt(unsigned char address)
- {
- unsigned char msb, lsb;
- Wire.beginTransmission(BMP085_ADDRESS);
- Wire.write(address);
- Wire.endTransmission();
- Wire.requestFrom(BMP085_ADDRESS, 2);
- while(Wire.available()<2)
- ;
- msb = Wire.read();
- lsb = Wire.read();
- return (int) msb<<8 | lsb;
- }
- // Read the uncompensated temperature value
- unsigned int bmp085ReadUT()
- {
- unsigned int ut;
- // Write 0x2E into Register 0xF4
- // This requests a temperature reading
- Wire.beginTransmission(BMP085_ADDRESS);
- Wire.write(0xF4);
- Wire.write(0x2E);
- Wire.endTransmission();
- // Wait at least 4.5ms
- delay(5);
- // Read two bytes from registers 0xF6 and 0xF7
- ut = bmp085ReadInt(0xF6);
- return ut;
- }
- // Read the uncompensated pressure value
- unsigned long bmp085ReadUP()
- {
- unsigned char msb, lsb, xlsb;
- unsigned long up = 0;
- // Write 0x34+(OSS<<6) into register 0xF4
- // Request a pressure reading w/ oversampling setting
- Wire.beginTransmission(BMP085_ADDRESS);
- Wire.write(0xF4);
- Wire.write(0x34 + (OSS<<6));
- Wire.endTransmission();
- // Wait for conversion, delay time dependent on OSS
- delay(2 + (3<<OSS));
- // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
- Wire.beginTransmission(BMP085_ADDRESS);
- Wire.write(0xF6);
- Wire.endTransmission();
- Wire.requestFrom(BMP085_ADDRESS, 3);
- // Wait for data to become available
- while(Wire.available() < 3)
- ;
- msb = Wire.read();
- lsb = Wire.read();
- xlsb = Wire.read();
- up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
- return up;
- }
Got any suggestions?..
1