문제

I am attempting to use the IOIO board with a Galaxy SIII. I have already successfully been able to run the HelloIOIO program.

I am not sure why this program fails so spectacularly. From the console output on the phone, I can see that it fails at the line ioio.waitForConnect(); This line, according to the documentation, blocks the thread until communication is established. I've also tried putting the connect lines inside of each of the async threads, and the same symptoms occour (except instead of being able to access the UI, the program force closes). I'm prolly doing something silly...help anyone?

[code]

package com.example.pressure_test;

import ioio.lib.api.DigitalInput;
import ioio.lib.api.DigitalOutput;
import ioio.lib.api.IOIO;
import ioio.lib.api.IOIOFactory;
import ioio.lib.api.TwiMaster;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

    IOIO ioio = null;
    long CalibrationData[];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /*Find elements */
        Button Calibrate_Button = (Button)findViewById(R.id.Calibrate_Button);
        Button ReadSensor_Button = (Button)findViewById(R.id.Read_Button);
        TextView ConIO = (TextView)findViewById(R.id.Con_IO);

        try
        {
            ConIO.append("1.1\n");
            ioio = IOIOFactory.create();
            ConIO.append("2.2\n");
            ioio.waitForConnect(); //THIS THROWS AN EXCEPTION INSTANTLY!!!
            ConIO.append("3.3\n");

            /*Set onclick listeners to async threads*/
            Calibrate_Button.setOnClickListener(new OnClickListener()
            {
                public void onClick(View v)
                {
                    /*Run Async Thread*/
                    new GetSensorCalibration().execute();
                }

            });

            ReadSensor_Button.setOnClickListener(new OnClickListener()
            {
                public void onClick(View v)
                {
                    /*Run Async thread!*/
                }

            });

            ConIO.append("OnClickListeners created successfully\n");
        }
        catch (Exception e)
        {
            ConIO.append("Error: IO coms unsuccessful. \n");
            String s = e.toString();
            ConIO.append(s);
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

     protected class GetSensorCalibration extends AsyncTask<Context, Integer, String>
        {

            /*Modifies ConstantArray[][], uses XCLR_Array[]*/
            protected String doInBackground(Context...params)
            {
                //TextView Console_IO = (TextView)findViewById(R.id.Con_IO);

                //Console_IO.append("\nSTARTING CALIBRATION\n*****************************************\n");

                try
                {
                    //Console_IO.append("Connected!\n");
                    TwiMaster i2c = ioio.openTwiMaster(0, TwiMaster.Rate.RATE_1MHz, true);
                    DigitalOutput X_CLR = ioio.openDigitalOutput(6);
                    byte Start[] = {(byte)0xAA}; //pointer to first register to read for calibration
                    X_CLR.write(true);
                    for (int j = 0; j < 11; j++)
                    {

                        byte MSBResponse[] = new byte[1];
                        byte LSBResponse[] = new byte[1];

                        i2c.writeRead(238, false, Start, 1, MSBResponse, 1); //first argument is decimal equivilant of 0xEE...Eclipse wouldn't compile with 0xEE, even with casts!

                        Start[0] += 1; //increment to read next bit

                        i2c.writeRead(238, false, Start, 1, LSBResponse, 1);

                        Start[0] += 1; //point to next address

                        /* Read the data into the array */
                        CalibrationData[j] = ((int)MSBResponse[0] << 8) + (int)LSBResponse[0];

                        /* Write the data to the console */
                        String s = String.format("\tJust read: %ld\n", CalibrationData[j]);

                        //Console_IO.append(s);

                        MSBResponse[0] = (byte)0;
                        LSBResponse[0] = (byte)0;
                    }
                    //Console_IO.append("*******************************************\n");
                    //X_CLR.write(false);
                    ioio.waitForDisconnect();
                    //Console_IO.append("Disconnected\n");
                    return "Done!";
                }
                catch (Exception e)
                {
                    //TextView Con_IO = (TextView)findViewById(R.id.Con_IO);
                    String s = e.toString();
                    //Con_IO.append(s);
                    //Con_IO.append("BLURGH\n");
                    return null;
                }

            }

            protected void onPostExecute(String Result)
            {
                TextView Con_IO = (TextView)findViewById(R.id.Con_IO);
                Con_IO.append("yay!\n");
                /*Catch bad results*/
                if (!(Result.equals("Done!")))
                {
                    Con_IO.append("Calibration Sequence Returned Unsuccessfully.\n");
                    return;
                }

                Con_IO.append("\n\nBEGIN_PLAYBACK\n");

                for (int i = 0; i < CalibrationData.length; i++)
                {
                    String s = String.format("\tThe next Calibration Constant is %ld\n", CalibrationData[i]);
                    Con_IO.append(s);
                }

                return;
            }

            protected void onPreExecute ()
            {
                TextView Con_IO = (TextView)findViewById(R.id.Con_IO);
                Con_IO.append("Starting Thread!\n");
            }
        }
     /*An async class for getting sensor data */
        protected class GetSensorAsync extends AsyncTask<Context, Integer, String> 
        {

            IOIO ioio;
            @Override
            protected String doInBackground( Context... params )
            {
                /* TODO: Write TWI interface */

                /********************************/
                /* Read in the pressure sensors */
                /********************************/

                /* Static variables */

                int oss = 0; //Oversampling parameter
                int i = 0;
                byte WriteAddress = (byte)0xEE;
                byte ReadAddress = (byte)0xEF;
                long Temperature;
                long Pressure;

                TextView Con_IO = (TextView) findViewById(R.id.Con_IO);

                /*For optimization purposes, we will use this array to precompute the powers of two */

                long _2[] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536};

                try
                {
                    TwiMaster i2c = ioio.openTwiMaster(0, TwiMaster.Rate.RATE_1MHz, true); 

                    DigitalInput EOC_Pin = ioio.openDigitalInput(7);

                    /* Write 0x2E to register 0xF4 */

                    byte[] Response = {(byte)0x00, (byte)0x00, (byte)0x00}; //dummy for now...
                    byte[] SequenceToWrite = {(byte)0xEE, (byte)0xF4, (byte)0x2E}; //Write, Reg, Data

                    i2c.writeReadAsync(WriteAddress, false, SequenceToWrite, SequenceToWrite.length, Response, Response.length);

                    /* Wait until EOC goes high */

                    EOC_Pin.waitForValue(true);

                    /* Read data back in from 0xF6 and 0xF7 */
                    /* From the timing diagram, I think the data points are going to come back in series, so we don't need to 
                     * go about switching registers manually. 
                     */
                    byte SelectData[] = {(byte)0xEE, (byte) 0xF6};
                    byte Read[] = {(byte)0xEF};

                    i2c.writeReadAsync(WriteAddress, false, SelectData, SelectData.length, Response, Response.length);
                    i2c.writeRead(ReadAddress, false, Read, Read.length, Response, Response.length);
                    /* Now, we actually care about the value in Response! */
                    /* Convert the read data back into a long. */

                    Temperature = (((long)Response[0] << 16) + ((long)Response[1] << 8) + (long)Response[2]) >> (8 - oss); 

                    /* Send start command to sensor for pressure reading */
                    /* Write 0x34 + (oss << 6) to register 0xF4 */

                    byte PressureByte = (byte)0x34;
                    PressureByte += (byte)(oss << 6); //For some reason, eclipse whined when I put this on the same line

                    SequenceToWrite[3] = PressureByte;
                    i2c.writeReadAsync(WriteAddress, false, SequenceToWrite, SequenceToWrite.length, Response, Response.length);

                    EOC_Pin.waitForValue(true); //wait for action to complete

                    /* Read in pressure for each sensor. */
                    /* Pressure = [(Register 0xF6 << 16) + (Register0xF7 << 8) + (Register 0xF8) >> (8-oss)] */

                    Response[0] = (byte)0x00;
                    Response[1] = (byte)0x00;
                    Response[2] = (byte)0x00;

                    i2c.writeReadAsync(WriteAddress, false, SelectData, SelectData.length, Response, Response.length);
                    i2c.writeRead(ReadAddress, false, Read, Read.length, Response, Response.length);

                    Pressure = (((long)Response[0] << 16) + ((long)Response[1] << 8) + Response[2]) >> (8 - oss);

                    /* Compute temperature for each element of the temperature array */
                    /* Also compute B5 value (lol...who designed these freaking sensors?!) */

                    long TempArray[] = TemperatureFunction(Temperature, CalibrationData, oss, _2); //for CalibrationData, pass in the applicable array of sensor calibration values.
                    long ComputedTemperature = TempArray[0]; //Final Temperature



                    /* Compute true pressure for each sensor reading. */

                    long ComputedPressure = PressureFunction(TempArray, CalibrationData, oss, _2);

                    String s = String.format("Pressure: %ld\t Temperature: %ld\n", ComputedPressure, ComputedTemperature);
                    Con_IO.append(s);

                    /*********************************************/
                    /* Pressure sensors done by this point       */
                    /* ADD STUFF FOR OTHER SENSORS STARTING HERE */
                    /*********************************************/

                    return "Done!";
                }
                catch (Exception e)
                {
                    TextView Console_IO = (TextView)findViewById(R.id.Con_IO);

                    Console_IO.append("BLEURGH\n");
                    return "Error!";
                }
            }

            @Override
            protected void onCancelled()
            {
                /* Function for if we cancel threading */
                TextView ConIO = (TextView)findViewById(R.id.Con_IO);
                ConIO.append("Interrupted!\n");
            }

            private long[] TemperatureFunction(long UncompensatedTemp, long[] CalibrationData, int oss, long _2[])
            {
                /* The CalibrationData array must have the calibration coefficients of the sensors in the following order */
                /* [AC1, AC2, AC3, AC4, AC5, AC6, B1, B2, MB, MC, MD] */

                /* Let's define some variables to make this more readable */
                /* This whole block will remain constant, but I commented out the values not used in this function */
                //final int AC1 = 0;
                //final int AC2 = 1;
                //final int AC3 = 2;
                //final int AC4 = 3;
                final int AC5 = 4;
                final int AC6 = 5;
                //final int B1 = 6;
                //final int B2 = 7;
                //final int MB = 8;
                final int MC = 9;
                final int MD = 10;

                /* These formulas come straight from the datasheet...lol?*/

                long X1 = ((UncompensatedTemp - CalibrationData[AC6]) * CalibrationData[AC5]) / _2[15];
                long X2 = (CalibrationData[MC] * _2[11]) / (X1 + CalibrationData[MD]);
                long B5 = X1 + X2; 
                long FinalTemperature = (B5 + 8) / _2[4];

                /* Kind of a hack, TODO: Figure out a better way to do this */
                long ReturnArray[] = new long[2];
                ReturnArray[0] = FinalTemperature;
                ReturnArray[1] = B5;
                return ReturnArray;
            }

            private long PressureFunction(long[] InArray, long[] CalibrationData, int oss, long _2[])
            {
                /* The CalibrationData array must have the calibration coefficients of the sensors in the following order */
                /* [AC1, AC2, AC3, AC4, AC5, AC6, B1, B2, MB, MC, MD] */

                /* Let's define some variables to make this more readable */
                /* The same as in the previous function, but unused variables are commented out for readability */
                final int AC1 = 0;
                final int AC2 = 1;
                final int AC3 = 2;
                final int AC4 = 3;
                //final int AC5 = 4;
                //final int AC6 = 5;
                final int B1 = 6;
                final int B2 = 7;
                //final int MB = 8;
                //final int MC = 9;
                //final int MD = 10;

                final int UT = 0;
                final int B5 = 1;


                /* Again, straight from the datasheet...I do not want to think about how much heartache went into creating this algo...*/

                long B6 = InArray[B5] - 4000;
                long X1 = (CalibrationData[B2] * (long)(java.lang.Math.pow(B6, 2) / _2[11]));
                long X2 = (CalibrationData[AC2] * B6) / _2[11];
                long X3 = X1 + X2;
                long B3 = (((CalibrationData[AC1] * 4) + X3 ) << (oss + 2)) / 4;
                X1 = (CalibrationData[AC3] * B6) / _2[13];
                X2 = (CalibrationData[B1] * ((long)java.lang.Math.pow(B6,2) / _2[12])) / _2[16];
                X3 = ((X1 + X2) +2 ) / 4;
                /* Note: Java's 'long' datatype is equivilant to C's 'long long' datatype. Both have 64 bits */
                /* So, even though the example code asks for an unsigned long, it was written in C, so the numbers should
                 * fit within 32 bits. So, it should fit within a java long */
                long B4 = (CalibrationData[AC4] * (X3 + 32768)) / _2[15];
                long B7 = (InArray[UT] - B3) * (50000 >> oss);
                long p;
                if (B7 < (long)2147483648L) //0x80000000 in decimal
                {
                    p = (B7 * 2) / B4;
                }
                else
                {
                    p = (B7 / B4) * 2;
                }

                X1 = (long)java.lang.Math.pow((p / _2[8]) , 2);
                X1 = (X1 * 3038) / _2[16];
                X2 = (-7357 * p) / _2[16];
                p = p + ((X1 + X2 + 3791) / _2[4]);
                return p;
            }
        }

} [/code]

도움이 되었습니까?

해결책

Problem solved - I didn't have my permissions right.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top