GithubHelp home page GithubHelp logo

ytai / ioio Goto Github PK

View Code? Open in Web Editor NEW
745.0 89.0 355.0 98.37 MB

Software, firmware and hardware of the IOIO - I/O for Android

License: Apache License 2.0

Makefile 1.12% C 67.20% C++ 2.63% Assembly 0.57% Java 27.84% Shell 0.22% Batchfile 0.01% Python 0.26% Kotlin 0.16%

ioio's Introduction

IOIO Logo The IOIO is a board that provides a host machine the capability of interfacing with external hardware over a variety of commonly used protocols. The original IOIO board has been specifically designed to work with Android devices. The newer IOIO-OTG ("on the go") boards work with both Android devices and PC's (details here). The IOIO board can be connected to its host over USB or Bluetooth, and provides a high-level Java API on the host side for using its I/O functions as if they were an integral part of the client.

All user documentation is on the Wiki.

You can get answers to questions and get news about IOIO on the ioio-users discussion group

The IOIO Gallery lists various IOIO projects to give you some ideas of what you can do with IOIO.

And this is the blog of Ytai, the inventor of IOIO, where new developments are normally announced. Specifically, this introductory post provides a good overview of this technology.

You can purchase a IOIO-OTG board online from:

Usage in Gradle

in top build.gradle

allprojects {
	repositories {
		...
		maven { url 'https://jitpack.io' }
	}
}

and in module build.gradle

dependencies {
        implementation "com.github.ytai.ioio:IOIOLibAndroidBluetooth:$LATEST"
        implementation "com.github.ytai.ioio:IOIOLibAndroidAccessory:$LATEST"
        implementation "com.github.ytai.ioio:IOIOLibAndroidDevice:$LATEST"
}

Please see details here https://jitpack.io/#ytai/ioio

ioio's People

Contributors

arshan avatar cristiangreco avatar danners avatar dependabot-preview[bot] avatar dependabot[bot] avatar gkelly avatar gradle-update-robot avatar hannesa2 avatar johannesc avatar lewispg228 avatar melchi avatar mfgmfg avatar mptei avatar neuron303 avatar robodchristian avatar topherbuckley avatar xxv avatar y-a-n-n avatar ytai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ioio's Issues

BUG: SPI3 respone data byte 0

I have a curious bug in App-IOIO0400:
In SPI respones in data byte 0 (the first byte send to Android) Bit5 is copied to Bit4.
This only happens in SPI module 3(!)

I can not debug - no pickit3 available.
I can only tell that the problem exists in "void SPITasks()" after line "ByteQueuePeekMax(q, msg.args.spi_data.size + 1, &data1, &size1, &data2, &size2);" Because I copied first byte to second byte and compiled firmware.

making a simple library for a IOIO daughter board

if i wanted to make a library for a ioio daughter board with led pushbuttons and some pots how would i go about this.

package com.example.ioiodaughter;

import ioio.lib.api.DigitalOutput;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;

public class Init_Led extends BaseIOIOLooper {

private DigitalOutput led_1,led_2,led_3,led_4,led_5,led_6,led_7,led_8;

public Init_Led() throws ConnectionLostException{
    try {

        led_1 = ioio_.openDigitalOutput(20, true);
        led_2 = ioio_.openDigitalOutput(21, true);
        led_3 = ioio_.openDigitalOutput(22, true);
        led_4 = ioio_.openDigitalOutput(23, true);
        led_5 = ioio_.openDigitalOutput(24, true);
        led_6 = ioio_.openDigitalOutput(25, true);
        led_7 = ioio_.openDigitalOutput(26, true);
        led_8 = ioio_.openDigitalOutput(27, true);

    } catch (ConnectionLostException e) {

        throw e;
    }
}

public void led1( boolean on) throws ConnectionLostException {
    try {   
    led_1.write(on);
}
    catch (ConnectionLostException e) {
    throw e;
}

}
public void led2( boolean on) throws ConnectionLostException {
try {
led_2.write(on);
}
catch (ConnectionLostException e) {
throw e;
}
}
public void led3( boolean on) throws ConnectionLostException {
try {
led_3.write(on);
}
catch (ConnectionLostException e) {
throw e;
}
}
public void led4( boolean on) throws ConnectionLostException {
try {
led_4.write(on);
}
catch (ConnectionLostException e) {
throw e;
}
}
public void led5( boolean on) throws ConnectionLostException {
try {
led_5.write(on);
}
catch (ConnectionLostException e) {
throw e;
}
}
public void led6( boolean on) throws ConnectionLostException {
try {
led_6.write(on);
}
catch (ConnectionLostException e) {
throw e;
}
}
public void led7( boolean on) throws ConnectionLostException {
try {
led_7.write(on);
}
catch (ConnectionLostException e) {
throw e;
}
}
public void led8( boolean on) throws ConnectionLostException {
try {
led_8.write(on);
}
catch (ConnectionLostException e) {
throw e;
}
}

public void led( byte on) throws ConnectionLostException {
    try {   
    boolean l1 = (on & 0x1)   != 0;
    boolean l2 = (on & 0x2)   != 0;
    boolean l3 = (on & 0x4)   != 0;
    boolean l4 = (on & 0x8)   != 0;
    boolean l5 = (on & 0x16)  != 0;
    boolean l6 = (on & 0x32)  != 0;
    boolean l7 = (on & 0x64)  != 0;
    boolean l8 = (on & 0x128) != 0;

    led_1.write(l1);
    led_2.write(l2);
    led_3.write(l3);
    led_4.write(l4);
    led_5.write(l5);
    led_6.write(l6);
    led_7.write(l7);
    led_8.write(l8);
}
    catch (ConnectionLostException e) {
    throw e;
}

}

}

PulseInput returns incorrect frequency when no pulse is returned.

Dear Ytai!

Many thanks for creating IOIO, Some 6 years ago I built a weatherstation based on the Cinterion TV65 device, but it was horrible unstable so the IOIO will now be used for my next revision of www.surfvind.se.

However when experimenting with the pulseInput api it appears to me as if the getFrequency returns bogus data when no pulses at all are received.

I use:
pulseCounter = ioio.openPulseInput(spec, ClockRate.RATE_62KHz, PulseMode.FREQ, true);
freq = pulseCounter.getFrequency();

First of all, as getFrequency blocks while waiting for pulses, this means that this call blocks a very long time if no pulses arrive. (I have an anemometer connected to this pulsecounter, and if no wind = no pulses). At some point getFrequency returns, and it then returns an incorrect freq.

While debugging IncapImpl.java I see that dataReceived is called with either data[0] = 0 or data[0] = 1.
ByteArrayToLong is then called and at the end of this function we see the following lines:

if (result == 0) {
result = 1 << (size * 8);
}

For data[0] = 0 this results in lastDuration beeing set to 256, 65536 etc which ends up giving a frequency that is incorrect. I have not yet figured out why ByteArrayToLong does this at the end, am I missing any part?

Second issue is that the data[0] = 1 when in fact there is no pulses at all received.

Iยดm using version 4.00 of the App library.

Kind Regards
Thomas Hermansson
TNA Software AB
Sweden

UART between Arduino and IOIO

Hi, I'm trying to establish a serial link between the two aforementioned micro's and am finding it difficult to successfully send data from the Arduino to the IOIO. Obviously I'm not ruling out that the Arduino is where the problem lies. However in comparison to the Java code that the IOIO requires, the Arduino is much more familiar to me, so this makes me think itโ€™s probably my Java that's letting me down.

What should happen is the IOIO lies dormant until a button on the GUI is pressed, when this happens, an int message of '1' is transmitted to the Arduino ten times (this is part of my error checking, and this bit works fine). The Arduino then reads the one's and transmits 10 back to say that it has received this message correctly.

The problem that I'm having is that when I try to send the int '10' back from the Arduino to confirm that it has received the data correctly I get a load of garbage and I can't work out why that is . . . All i could think was that maybe it's a syncing error? but as both devices are running on the same baud rate I'm not sure.

Also as you can see in order to both read and write simultaneously with the IOIO I am running a separate thread that is always reading until the message sent back is successful, in which case the thread should close (I think this bit works)

Now my questions:
Q1. Have I implemented the Thread correctly, i.e. initiated and closed?
Q2. I am aware of the .available() function, but having read the blurb it doesn't sound very reliable, is this true?
Q3. Are there any obvious errors with my codes layout (I'm confident that there are probably many!)

I hope that I have explained myself enough so that whoever reads this has some idea of what I'm trying to accomplish, any questions feel free to ask!

Here is the code that I am using to read in the Serial UART message:

package ioio.examples.simple;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import ioio.lib.api.DigitalOutput;
import ioio.lib.api.IOIO;
import ioio.lib.api.PwmOutput;
import ioio.lib.api.Uart;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOActivity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.ToggleButton;

public class IOIOSimpleApp extends IOIOActivity {
private TextView textView_;
private SeekBar seekBar_;
private ToggleButton toggleButton_;

private InputStream in_;
int success = 0;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    textView_ = (TextView) findViewById(R.id.TextView);
    seekBar_ = (SeekBar) findViewById(R.id.SeekBar);
    toggleButton_ = (ToggleButton) findViewById(R.id.ToggleButton);

    enableUi(false);
}

class Looper extends BaseIOIOLooper {
    private PwmOutput pwmOutput_;
    private DigitalOutput led_;

    private Uart uart_;
    private OutputStream out_;
    int counter = 0;
    int test = 0;
    Thread readThread = new readDataThread();// creates the read thread

    @Override
    public void setup() throws ConnectionLostException {
        try {
            pwmOutput_ = ioio_.openPwmOutput(12, 100);
            led_ = ioio_.openDigitalOutput(IOIO.LED_PIN, true);

            uart_ = ioio_.openUart(4, 6, 38400, Uart.Parity.NONE,
                    Uart.StopBits.ONE);
            out_ = uart_.getOutputStream();
            in_ = uart_.getInputStream();

            readThread.start();// Starts the thread

            setText("in setup");
            enableUi(true);
        } catch (ConnectionLostException e) {
            enableUi(false);
            throw e;
        }
    }

    @Override
    public void loop() throws ConnectionLostException {
        try {

            if (success == 5) {
                readThread.interrupt();// Ends the thread
                setText("Successful transmission");
                Thread.sleep(2000);
                success = 0;
            }

            pwmOutput_.setPulseWidth(500 + seekBar_.getProgress() * 2);
            led_.write(!toggleButton_.isChecked());

            if (toggleButton_.isChecked() && counter < 10) {
                out_.write(1);
                counter = counter + 1;
            } else {
            }
        } catch (IOException e) {
        } catch (InterruptedException e) {
            ioio_.disconnect();
        } catch (ConnectionLostException e) {
            enableUi(false);
            throw e;
        }
    }
}

@Override
protected IOIOLooper createIOIOLooper() {
    return new Looper();
}

private void enableUi(final boolean enable) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            seekBar_.setEnabled(enable);
            toggleButton_.setEnabled(enable);
        }
    });
}

private void setText(final String str) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            textView_.setText(str);
        }
    });
}

public class readDataThread extends Thread {
    public void run() {
        while (true) {
            try {
                int i = in_.read();
                String aString = Integer.toString(i);

                    if (i == 10) {
                        success = 5;
                        setText("Read in successfully");
                        Thread.sleep(2000);
                    } else {
                        success = 0;
                        setText(aString);
                        Thread.sleep(2000);
                    }

            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt(); // very important
                break;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Shutting down thread");
    }
}

}

IOIO no power

Hi. I have an issue with IOIO OTG, v.3.24 Software. The IOIO was connected to a power supply with 2 ampere and 12 volt. Charge current trimmer was MAX and Host Mode was in Auto Mode. I have connected and disconnected the smartphone many times and after one hour, when I tried to connect with usb again, the IOIO didnt recognized my smartphone (Galaxy S2, 2.3.3) and after I have seen that the power LED was turned off.

On 5v and 3v output Pin is no tension. The board is not going hot. My friend told me that Charge current trimmer should not be on MAX. But if MAX is possible, then it should also work with MAX or not?

In instruction is written
"Power the IOIO either from 5V-15V input on the VIN line or from 5V directly on the 5V line. "
Where is the 5v line?

Clean-up UART disconnection

Properly handle disconnect() and close() in UART. Maybe return -1 on close and throw IOException on disconnect.

BT lockup on 256th open

I was doing some stress testing and ran into a repeatable hard lockup on the 256th connection open.

You have to either reconnect the BT module or power cycle the IOIO to get it to work again. Sending soft or hard resets doesn't work.

I'm connecting from a Linux PC over Bluetooth. I have the Sparkfun BT adapter.

I know this may be difficult to fix, but I wanted to report it in case other people run into it.

-Dan

TWI Khz rates too fast

Hi, 100KHz is too fast for single command reliability. is it easy for you to add something smaller too? like 20Khz or 30Khz for more reliable communications?

Can't open a connection on Linux

The "clear lingering bytes" doesn't work there - it actually eats the handshake. Probably because setDTR is behaving differently.

Android Market won't download IOIO Manager app

--Found the IOIO Manager app on Android Market
--Message below the icon: "You don't have any devices"
--Click INSTALL and see in the Checkout window:
"There are no Android phones associated with this account. Please sign in with different account"

--WHY DO I NEED TO HAVE A DEVICE TO DOWNLOAD THE APP?
--HOW DO I ASSOCIATE A PHONE WITH THE ACCOUNT?

deleted

deleted, wrong section, sorry!

I2C and the Texas Instruments TCA9555 chip?

Has anyone had any success getting a TI PCA or TCA 9555 GPIO expander chip to work with their IOIO board?

Kinda stuck, I got the twiMaster connected to the right I2C address (decimal 36), but I cant seem to affect any of the pins on P0 (Pins 0 to 7 of P0, A2 is connected to 5V, I have 10K pull-up resistors on SDA and SCL, LEDs have 330 ohm resistors).

Here's my MainActivity.java code:

package com.femtocnc;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;

import com.femtocnc.IOIOMotor;
import com.femtocnc.I2CMotor;

//Let's import our resources. We need them for this example.
import com.femtocnc.R;

//Import our IOIO library stuff
import ioio.lib.api.DigitalOutput;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOActivity;

import ioio.lib.api.IOIO;
import ioio.lib.api.TwiMaster;
import ioio.lib.api.TwiMaster.Rate;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends IOIOActivity {

    public static int MODE_ONE = 1;
    public static int MODE_TWO = 2;
    public static int MODE_FOUR = 4;
    public static int MODE_EIGHT = 8;

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

        Log.d("TEST", "Starting!!!");
    }

    @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;
    }


    public class AppIOIOLooper extends BaseIOIOLooper {

        private I2CMotor i2cMotor1;

        @Override
        public final void setup() throws ConnectionLostException, InterruptedException {

            Log.d("TEST", "Creating I2C motor object...");

            i2cMotor1 = new I2CMotor(ioio_, TwiMaster.Rate.RATE_400KHz, 2, true, 0x24); // TI TCA9555 address is 36 (hex 0x24) with current setup.

            i2cMotor1.setPinDir(0);
            i2cMotor1.setPinMS1(1);
            i2cMotor1.setPinMS2(2);
            i2cMotor1.setPinSleep(3);
            i2cMotor1.setPinStep(4);

            Log.d("TEST", "Setting GPIO dir...");
            i2cMotor1.gpioDir(I2CMotor.REGISTER_OUTPUT);
            timeout(1000);

            Log.d("TEST", "Setup complete. Starting loop...");
//          Log.d("TEST", "Setting GPIO direction: " + 
//              Boolean.toString(
//                  i2cMotor1.gpioDir( 
//                      I2CMotor.REGISTER_OUTPUT 
//                  )
//              )
//          );

        }

        @Override
        public void loop() throws ConnectionLostException, InterruptedException {
            Log.d("TEST", "Looping...");
            int data = 36 + ((1 + 2 + 4 + 8 + 16 + 32 + 64 + 128) - (1 + 2 + 4 + 8 + 16));
//          data = Integer.reverse(data);

            Log.d("TEST", "INT: " + String.valueOf(data) );

            i2cMotor1.gpioWrite(data);

            Log.d("TEST", "Timeout 100ms...");
            timeout(100);
        }



        /**
         * This is our custom timeout function, so we don't
         * need to write a bunch of try/catch blocks all over.
         * @param int ms Milliseconds.
         */
        private void timeout(int ms) {
            try {
                Thread.sleep(ms);
            } catch (InterruptedException e) {
                // Do nothing...
            }
        }

    }

    /**
     * A method to create our IOIO thread.
     */
    @Override
    protected IOIOLooper createIOIOLooper() {
        return new MainActivity.AppIOIOLooper();
    }
}

...And here's my I2CMotor.java code (just driving LEDs on and off for now)

package com.femtocnc;

//Import our IOIO library stuff
import java.math.BigInteger;
import java.nio.ByteBuffer;

import android.util.Log;
import ioio.lib.api.DigitalOutput;
import ioio.lib.api.IOIO;
import ioio.lib.api.TwiMaster;
import ioio.lib.api.TwiMaster.Rate;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOActivity;

/**
 * A class to represent a stepper motor connected to an IOIO board off an I2C 
 * bus chip/address, using the TI TCA9555 GPIO expander chip.
 * 
 * @author aalbino
 *
 */

public class I2CMotor {
    // I2C device address is 0 1 0 0   A2 A1 A0

    public static final int REGISTER_INPUT = (0);
    public static final int REGISTER_OUTPUT = (2);
    public static final int REGISTER_CONFIG = (6);

    // After selecting the device address, select the pin(s) you want to access 
    // using their pin address(es).
    public static final int IC_P0 = (1);
    public static final int IC_P1 = (2);
    public static final int IC_P2 = (4);
    public static final int IC_P3 = (8);
    public static final int IC_P4 = (16);
    public static final int IC_P5 = (32);
    public static final int IC_P6 = (64);
    public static final int IC_P7 = (128);

    public int intTwiModuleNumber; // The IOIO SDA/CLOCK lines to use. We're connected to CL2 and DA2.

    public int intAddress; // The GPIO Chip address on the I2C bus.
    public Rate dataRateKHz; // Can be 100, 400, or 1000
    public boolean I2CVoltageLevels; // Use I2C Voltage levels if true, else, use SMBus levels.

    public int pinDir; // What GPIO pin to use for "dir"
    public int pinStep; // What GPIO pin to use for "step"
    public int pinMS1; // What GPIO pin to use for "MS1"
    public int pinMS2; // What GPIO pin to use for "MS2"
    public int pinSleep; // What GPIO pin to use for "sleep"

    private int intPinMap; // The pin map, (the sum of all pins)
    private int intPinMask; // The pin mask to leave pins on per the pin map

    public boolean goForward;
    public int modeType;
    public boolean enable;
    public int stepAmount;

    private IOIO ioio;
    private TwiMaster twiMaster;

    public I2CMotor(IOIO ioio_, Rate dataRateKHz, Integer TwiModuleNumber, Boolean I2CVoltageLevels, Integer intAddress) throws ConnectionLostException {
        this.dataRateKHz = dataRateKHz ;
        this.intTwiModuleNumber = TwiModuleNumber;
        this.I2CVoltageLevels = I2CVoltageLevels;

        this.intAddress = intAddress;

        this.ioio = ioio_;

        this.intPinMask = IC_P0 + IC_P1 + IC_P2 + IC_P3 + IC_P4 + IC_P5 + IC_P6 + IC_P7;
    }

    public I2CMotor setPinDir(int pin) { this.pinDir = pin; return this; }
    public I2CMotor setPinStep(int pin) { this.pinStep = pin; return this; }
    public I2CMotor setPinMS1(int pin) { this.pinMS1 = pin; return this; }
    public I2CMotor setPinMS2(int pin) { this.pinMS2 = pin; return this; }
    public I2CMotor setPinSleep(int pin) { this.pinSleep = pin; return this; }
    public I2CMotor setTwiMaster(TwiMaster twi) { this.twiMaster = twi; return this; }
    public I2CMotor setTwiModuleNumber(int intTwiModuleNumber) { this.intTwiModuleNumber = intTwiModuleNumber; return this; }

    public int getPinDir() { return this.pinDir; }
    public int getPinStep() { return this.pinStep; }
    public int getPinMS1() { return this.pinMS1; }
    public int getPinMS2() { return this.pinMS2; }
    public int getPinSleep() { return this.pinSleep; }
    public TwiMaster getTwiMaster() { return this.twiMaster; }
    public int getTwiModuleNumber() { return this.intTwiModuleNumber; }

    public TwiMaster initBus() throws ConnectionLostException {

        this.twiMaster = this.ioio.openTwiMaster(this.intTwiModuleNumber, this.dataRateKHz, false);

        return this.twiMaster;
    }

    public boolean write(byte[] request, byte[] response) throws ConnectionLostException, InterruptedException {
//      byte[] request = new byte[] {0x02, 0x01};
//      byte[] response = new byte[4]; // We don't care for a response. We're driving a stepper motor.

        //this.initBus();
        Boolean success = false;

        success = this.twiMaster.writeRead(
                this.intAddress, false, 
                request, request.length, 
                response, 0);
        //this.twiMaster.close();

        return success;
    }

    public boolean write(int request, byte[] response) throws ConnectionLostException, InterruptedException {

        Boolean success = false;

        byte[] rq = BigInteger.valueOf(request).toByteArray();
        success = this.write(rq, response);

        return success;
    }


    public boolean gpioDir(int dir) throws ConnectionLostException, InterruptedException {
        int register = REGISTER_CONFIG;
        byte[] response = new byte[0];
        boolean success = false;

        this.initBus();

        boolean setConfig = this.write(register, response);

        int lowByte  = 0xff & dir;
        int highByte = dir >> 8;

//      byte[] bytes = new byte[]{(byte) lowByte, (byte) highByte};
        boolean connectAndSend = this.write(lowByte, response) && this.write(highByte, response); // Low-byte, then high byte.
//      boolean connectAndSend = this.write(bytes, response);

        success = setConfig && connectAndSend;
        twiMaster.close();

        return success;
    }

    public boolean gpioWrite(int data) throws ConnectionLostException, InterruptedException {
        int register = REGISTER_OUTPUT;
        byte[] response = new byte[0];
        boolean success = false;

        this.initBus();

        boolean setConfig = this.write(register, response);

        int lowByte = 0xff & data;
        int highByte = data >> 8;

        Log.d("TEST", "gpioWrite LOW BYTE: ");
        Log.d("TEST", Integer.valueOf(lowByte).toString());
        boolean wroteDataLow = this.write(lowByte, response);// Low byte

        Log.d("TEST", "gpioWrite HIGH BYTE: ");
        Log.d("TEST", Integer.valueOf(highByte).toString());
        boolean wroteDataHigh = this.write(highByte, response);

        //byte[] bytes = new byte[] {(byte) lowByte, (byte) highByte};

        success = setConfig && wroteDataLow && wroteDataHigh;
        //success = setConfig && this.write(bytes, response);

        Log.d("TEST", "gpioWrite success? " + String.valueOf(success));
        twiMaster.close();
        return success;
    }

    public boolean sendBits() throws ConnectionLostException, InterruptedException {
        int intPinMap = this.getPinDir() + this.getPinMS1() + this.getPinMS2() + this.getPinSleep() + this.getPinStep();


        byte[] bits = new byte[] {0x01, 0x02, 0x03};

        byte[] response = new byte[0];

        boolean success = this.write(bits, response);
        Log.d("TEST", "Sent bits (" + bits.toString() + ")? " + String.valueOf(success));
        return success;
    }
}

Android 4.2.2 does not connet to IOIO

In 4.2.2. Adb needs to confirm each host.
Had cyanogenmod 10.1 (4.2.2) on N7000 did not work. Also on Nexus 7 with stock 4.2.2 does not work. Yellow led is on. Flashed stock 4.1.2 rom to N7000 and Ioio worked correctly.

OTG Driver install issue windows 8

I am getting:

"The folder you specified doesnt contain a compatible software driver for your device. If the folder contains a driver, make sure it is designed t work with Windows for x64-based systems."

when I point to the driver file downloaded from the wiki here: https://github.com/ytai/ioio/wiki/Downloads

Any ideas why it is not seeing it properly?

Blink versions

Perhaps have the bootloader and app layer blink their versions while not connected.

HelloIOIO.

Hi everyone,
I am new with IOIO and I have been working with HelloIOIO application.
My HelloIOIO doesn't turn on and off the LED.
Using IOIO Hardware Tester allows me to turn on and off the led (direct cable or BT).
My hardware:
Device Name: SGH-T959V
Android Version: 2.3.6
IOIO Hardware: SPRK0016
IOIO Bootloader: IOIO0303
IOIO Firmware: IOIO0323.
Any idea what is the problem?
Thanks,
Joel

Add flow control lines to UART

Just opening an issue to track a feature addition that I'm working on. The pic controls the flow control lines in hardware, so only proper setup is needed.

The conversation from ioio-users:
Dan Christian [email protected] Sep 21 to ioio-users:
So it seems like setPinUart would need to be extended with a bit to
specify the flow pin, and uartConfigure would need to add a flag to
use hardware flow control. There are bits free in both packet
definitions.

Then the API would need a version of openUart with rts and cts pin arguments.

Ytai Ben-Tsvi [email protected] Sep 21:
I think that's everything. If you do that, make sure not to move existing bits around, and also to have these bits "0" behave like the current implementation. That way, your modified firmware will maintain compatibility with older versions of IOIOLib (i.e., with existing apps).

Surveillance Rover application by Simon Monk cannot communicate with IOIO board

IOIO Hardware: SPRK0016 (purchased from Jaycon Systems)
IOIO Bootloader: IOIO0304
IOIO Firmware: IOIO0324

I took exactly from the book Making Android Accessories with IOIO by Simon Monk (2012 - O'Reilly) under the project - Surveillance Rover

A Bluetooth connection has been established successfully but then when IOIORover application is executed, the rover did not move at all. The Bluetooth dongle that I used appeared blinking signaling some sort of data were transmitted to it. Do I need to downgrade to the boot loader 3.0 and firmware 3.10 for minimum requirement Bluetooth control relying to the fact that the application might compatible with? I do not know which hardware and firmware did Simon Monk used for this surveillance rover project.

IOIO Rover

IOIO Hardware Tester

No way to get the IOIO Hardware Tester working (from Play Store ).
I tried on Nexus S 4.1.2 and Nexus 7 4.2.1 but "Not connected" is the only answer I got...
I did not use any BT Dongle but only a USB wire in between my IOIO and my Android device.: Is that the reason why?

Remarks:
My IOIO is powered with a 12DCV 1,25 A max and the red led is on.
I can confirm that my Android device detects the IOIO because the charging signal is on

Thanks for your help.

IOIO Manager fixes

"Program" button looks bad.
URL is wrong.
The intent gets re-sent when getting into the app again.
Add Bluetooth
Allow overwrite
Allow starring via intent

IOIO V1 Updates

The IOIO V1 will continue to receive firmware updates ?
I'm from Brazil, and there's a store selling only this version, but i'm afraid that i will not be able to update to newer versions.

Thank you all

Proguard obfuscation of HelloIOIO not working

Hi!
I'm trying to obfuscate the example HelloIOIO application, but it does not work.

If I compile it without obfuscation, everything is fine, and I can switch on and off
the led on the IOIO OTG board.

But when I activate the obfuscation of the application, by adding the following
line in applications/HelloIOIO/project.properties file:
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

the compilation with "ant release" goes fine, but I cannot switch on the led on
the IOIO board.

Should I add some keep option?

I'm using App-IOIO0326 and a IOIO OTG board.

Thanks,

Francesc

IOIO.sync()

Need a call for waiting until all previous commands have been processed, e.g. for a charlieplexed button matrix.

Longer SPI messages

Support multi-packet messages. This is in order to be able to burst out SPI at a constant rate.

API for pulse counting

Either in conjunction with PulseInput or with DigitalInput.

The latter can be implemented on the Android-side, which is less efficient but easier. Probably not good enough if we want to support high pulse rates.

Maybe combine this into a full-blown encoder API.

I2C Multiple Readings

Hi all

I've been trying to use the IOIO board in a project of mine which utilizes sensors that communicate by I2C. I'm having the oddest bug: I can connect to the board fine, blink the status light fine, and take one reading from the sensors fine. When I attempt to take a second reading, the app force-closes. The addresses read for either the first or second attempt don't really matter (the first attempt will work correctly with any valid register, and the second attempt will force close with any register). I'm guessing that the port isn't getting closed correctly, but I can't be sure.

Anyways, here's the thread of interest. I can post the rest of the code, but there's not much of interest in it. The only things to note are that _ioio is a valid instance of a connection to the IOIO board. I have verified (through publishProgress()) that the app runs until the line that has the comment that says "CRASH."

Anyways, here's the thread:

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

        /*Modifies ConstantArray[][], uses XCLR_Array[]*/
        protected String doInBackground(IOIO...params)
        {
            //TextView Console_IO = (TextView)findViewById(R.id.Con_IO);
            IOIO _ioio = params[0]; //Unnecessary to do this..
            //Console_IO.append("\nSTARTING CALIBRATION\n*****************************************\n");

            try
            {
                //Console_IO.append("Connected!\n");
                TwiMaster i2c = _ioio.openTwiMaster(0, TwiMaster.Rate.RATE_1MHz, false);
                publishProgress(7);
                DigitalOutput LED = _ioio.openDigitalOutput(0,false);
                //DigitalOutput X_CLR = _ioio.openDigitalOutput(6);
                //DigitalInput EOC = _ioio.openDigitalInput(7);

                byte Start[] = {(byte)0xAA}; //pointer to first register to read for calibration
                publishProgress((int)Start[0]);
                int Addr[] = {(byte)0x77};
                X_CLR.write(true);
                for (int j = 0; j < 11; j++)
                {
                    publishProgress(1);
                    byte MSBResponse[] = new byte[1];
                    byte LSBResponse[] = new byte[1];

                    i2c.writeRead(Addr[0], false, Start, 1, MSBResponse, 1); //first argument is decimal equivilant of 0xEE...Eclipse wouldn't compile with 0xEE, even with casts!
                    publishProgress((int)MSBResponse[0]);
                    Start[0] += 1; //increment to read next bit
                    publishProgress((int)Start[0]);
                    Thread.sleep(5);

                    publishProgress((int)(byte)0xAB);

                    i2c.writeRead(Addr[0], false, Start, 1, LSBResponse, 1); //CRASH
                    publishProgress(4);
                    Start[0] += 1; //point to next address

                    /* Read the data into the array */
                    CalibrationData[j] = ((int)MSBResponse[0] << 8) + (int)LSBResponse[0];
                    publishProgress((int)CalibrationData[j]);
                    /* 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;
                    Thread.sleep(5);
                    publishProgress(6);
                }
                //Console_IO.append("*******************************************\n");
                //X_CLR.write(false);
                i2c.close();
                LED.close();
                X_CLR.close();
                publishProgress(6);
                //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");
        }

        protected void onProgressUpdate(Integer...values)
        {
            String S = values[0].toString();
            TextView Con_IO = (TextView)findViewById(R.id.Con_IO);
            Con_IO.append(S);
            Con_IO.append(" ");
        }
    }

And, if it's of interest, here's the datasheet for the sensor I'm using. Seems like standard I2C: https://www.sparkfun.com/products/11282

Thanks for any help you can give me!

TWI details not in TWI description

Can you add voltage details to the TWI description? The third argument of openTwiMaster sets I2C or SMBus levels, but both protocols have multiple standards with multiple voltages. Could you point out expected voltages of each option (I'm guessing 5 and 3.3V)? Are the threshold voltages the only difference between the two modes?

ByteQueue race condition

The ByteQueues (IOIO firmware) have a race condition around the size tracking. I was doing some high speed serial stuff and they were "losing" bytes, but then were forced out later. The size was dropping entries. I was checking size before reading and it looked like nothing was there, but the read-write pointers were not equal.

The read and write pointers aren't a problem because they are touched by different operations. However, the size field gets changed by both ends. With optimization on, this only takes 3 cycles (read, increment, write); but that still leaves a window where the interrupt routine can modify size. Without optimization, this becomes 5 cycles.

The fix is to disable interrupts during the size changes: asm ("DISI #3")

I'll post code later.

-Dan

Gracefully handle corrupt messages

Android doesn't gracefully handle corrupt protocol when it comes to passing the messages to listeners. An Analog input that hasn't been opened or has been closed is an example.

Running HelloIOIOService in Open Accessory mode

I have a problem running HelloIOIOService in accessory mode. If I start HelloIOIOService i get a message about using as USB accessory device. I tick the box and apply yes and get connection working OK.

If I unplug the usb cable to IOIO and plug it back I get the message that no accessory devices found and no connection achieved. If I stop the service and restart it again the connection is working as if I have done it for the first time.

I use IOIO V1 Bootloader 3.04 Firmware 3.26. The phone Galaxy Nexus - Android 4.2.2. I have USB debugging switched off when connecting in accessory mode. Also connection via Bluetooth work OK when USB debugging is enabled.

If I use IOIOSimle App in accessory mode it works fine with connecting and disconnecting usb cable.

I guess the problem with HelloIOIOService may be related to the Manifest configuration?

IOIOLIB V-1.0 applications not compatible Firmware ID IOIO0200, IOIO0300

IOIO applications built using the IOIOLIB version 1 (git hash id f2e3eab from April 27, 2011) are not compatible with IOIO Boards using newer Firmware ID IOIO0200 and Firmware ID IOIO0300.

Droid User applications built using IOIOLIB version 1 will fail on IOIO Boards with later Firmwares. Additionally, if developers upgrade their IOIOLIBs to version 3, then their applications will fail with IOIO Boards with earlier Firmwares.

This is a compatibility issue and should be corrected so that users are not forced to upgrade their firmware. The solution should allow applications built with IOIOLIB version 1 to run with later firmwares.

Below is a link and copy of the IOIO-Users usergroup discussion that defines the observed incompatibility:

https://groups.google.com/group/ioio-users/browse_thread/thread/2148e1119e221e18

Ytai,
We've been linking the IOIOLib into xcsoar.org our open source project
since June. It has worked successfully. However, it is failing with
IOIO0300 Firmware ID.
We want to remain compatible with Firmware IDs IOIO0100, IOIO0200 and
IOIO0300 so we are using IOIOLib version V-10 (IOIO0001) (from April
27, git hash f2e3eab).
This works for Firmware ID IOIO0100 and IOIO0200. However with IOIO
boards running IOIO0300, we get the following error (see code below):
11-18 17:01:14.514 8939 8947 D IOIOImpl: Waiting for IOIO connection
11-18 17:01:14.514 8939 8947 D IOIOImpl: Waiting for underlying
connection
11-18 17:01:14.514 8939 8947 D SocketIOIOConnection: Creating server
socket
11-18 17:01:14.514 8939 8947 D SocketIOIOConnection: Waiting for TCP
connection
11-18 17:01:14.514 8939 8947 D SocketIOIOConnection: TCP connected
11-18 17:01:14.521 8939 8947 D IOIOImpl: Waiting for handshake
11-18 17:01:14.521 8939 8949 I IncomingState: IOIO Connection
established. Hardware ID: SPRK0015 Bootloader ID: IOIO0100 Firmware
ID: IOIO0300
11-18 17:01:14.521 8939 8947 D IOIOImpl: Querying for required
interface ID
11-18 17:01:14.529 8939 8949 V IncomingState:
handleCheckInterfaceResponse(true)
11-18 17:01:14.529 8939 8947 D IOIOImpl: Required interface ID is
supported
11-18 17:01:14.529 8939 8947 I IOIOImpl: IOIO connection established
11-18 17:01:14.529 8939 8947 W IOIOHelper: IOIOJopenUart():0 ENTER
<<-- here it enters the openUart() method below
11-18 17:01:14.529 8939 8947 W IOIOHelper: IOIOJopenUart():0
EXIT <<--- this means it exited from our openUart() method below
successfully.
11-18 17:01:14.537 8939 8949 V IncomingState: handleUartClose(0)
11-18 17:01:14.537 8939 8949 V IncomingState: handleUartClose(1)
11-18 17:01:14.537 8939 8949 V IncomingState: handleUartClose(2)
11-18 17:01:14.537 8939 8949 V IncomingState: handleUartClose(3)
11-18 17:01:14.537 8939 8949 V IncomingState: handleSpiClose(0)
11-18 17:01:14.537 8939 8949 V IncomingState: handleSpiClose(1)
11-18 17:01:14.537 8939 8949 V IncomingState: handleSpiClose(2)
11-18 17:01:14.537 8939 8949 V IncomingState: handleI2cClose(0)
11-18 17:01:14.537 8939 8949 V IncomingState: handleI2cClose(1)
11-18 17:01:14.537 8939 8949 V IncomingState: handleI2cClose(2)
11-18 17:01:14.537 8939 8949 E IOIOProtocol: Protocol error
11-18 17:01:14.537 8939 8949 E IOIOProtocol: java.io.IOException:
Received unexpected command: 0x1b
11-18 17:01:14.537 8939 8949 E IOIOProtocol: at
IOIO.lib.impl.IOIOProtocol$IncomingThread.run(IOIOProtocol.java:616)
11-18 17:01:14.537 8939 8949 V IncomingState: handleConnectionLost()
11-18 17:01:14.537 8939 8949 D SocketIOIOConnection: Client
initiated disconnect
Here is our openUart() method which is using pins are 3=out, 4=in and
baud=4800. This works w/ IOIO Firmware IOIO0100 and IOIO0200 but
fails with IOIO0300. I am not showing the our waitConnect() code
which is successful. The openUart() method below exits successfully,
but appears the incomingThread is causing an exception:
public int openUart(IOIO ioio, int baud) {
Log.w("IOIOHelper", "IOIOJopenUart():" + ID + " ENTER"); <<<--
see this message in the logcat above
if (!isAvailable) {
Log.e("IOIOHelper", "IOIOJopenUart() is not available: " +
ID);
return -1;
}
ioio
= ioio;
baudrate = baud;
try {
uart = ioio
.openUart(inPin, outPin, baudrate,
Uart.Parity.NONE,
Uart.StopBits.ONE);
} catch (ConnectionLostException e) {
Log.w("IOIOHelper", "IOIOJopenUart() Connection Lost. Baud: "

  • _baud, e);
    return -1;
    } catch (Exception e) {
    Log.e("IOIOHelper", "IOIOJopenUart() Unexpected exception
    caught", e);
    return -1;
    }
    input = uart.getInputStream();
    output = new OutputThread(uart.getOutputStream());
    output.setTimeout(5000);
    isAvailable = false;
    Log.w("IOIOHelper", "IOIOJopenUart():" + ID + " EXIT");
    return ID;
    }
    Do you have any suggestions about how we might fix this without
    upgrading to IOIO0003?
    Thanks,
    Rob

    Hi,
    First, thanks for the excellent explanation of the problem. You provided
    enough information for me to understand what's going on.
    Apparently you have indeed revealed a bug in backward compatibility. I
    think it can be fixed. And I believe it is not at all related to UART but
    would happen if you were trying to do other operations as well (or maybe
    even without doing anything, but not sure).
    I'll try to fix it soon. Would be nice if you can open a (first) bug in the
    github site for that.
    Out of curiosity - what prevents you from upgrading the boards' firmware?
    Most importantly for you, one thing that I cannot promise is to back-port
    any bugs I'm fixing to early library version, so by running IOIOLib V1.0, I
    can actually guarantee you that you're using a version with some known
    bugs (one of them being in UART, reacting badly to an incoming byte of
    0xFF). So by sticking to an early version you're missing not only new
    features, but also bug fixes.
    Last, I'm so happy to see IOIO being used for this exciting application!
    Ytai.

IOIOImpl#checkInterfaceVersion() fails on the 'IOIO 0001/0002' board.

In the class ioio.lib.impl.IOIOImpl, the constant below,
private static final byte[] REQUIRED_INTERFACE_ID = new byte[] { 'I', 'O', 'I', 'O', '0', '0', '0', '3'};

... will cause the older IOIO board not to connect.
I have IOIO 0001 board, so changed it to "IOIO0001".getBytes() to fix the problem.

Please change that codes to check all supported IOIO boards.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.